Security

The following table lists the technologies included in Platform SDK Security.

Technology | Description
Access Control | Application developers use this technology to control access to securable objects such as files, registry keys, and directory service objects. This material also describes programmatically controlling access to administrative functions, such as setting the system time and auditing user activity.
Security Packages | Covers technologies that client/server applications use to access or develop security protocols such as Kerberos and NTLM.
Logon Authentication | Covers technologies that manage the interactive logon process. Included are password filtering and change notification, Winlogon and GINA, and Local Security Authority authentication.
Certificate Services and Components | Covers issuing and managing certificates, and developing customizable public-key infrastructures. Certificate and smart card enrollment, certificate management, and custom module development are described.
Cryptography | Covers services, components, and tools that enable application developers to add cryptographic security to their applications. This includes CryptoAPI 2.0, Cryptographic Service Providers, CryptoAPI Tools, and WinTrust.
Smart Card | Describes operating system support and services for developing and using a smart card-based authentication system.
Policy Management | Describes technologies which are used to programmatically set and manage local security policy.
Security Glossary | Covers terms and acronyms used in the Security documentation.

Microsoft Platform SDK, February 2001 Edition.
This content last built on Wednesday, February 07, 2001.


Access Control

The security provisions of Microsoft® Windows NT®/Windows® 2000 are automatically available to Win32®-based applications. Every application running on the system is subject to the security imposed by the particular configuration of the local Windows NT/Windows 2000 implementation. Windows NT/Windows 2000 is the only platform that supports Win32 security.

The impact of security on most Win32 functions is minimal. A Win32-based application that does not require a security functionality need not incorporate special code. However, you can use the security features of Windows NT/Windows 2000 to provide security services to a Win32-based application.

This overview describes the Windows NT/Windows 2000 security model for controlling access to Win32 objects, such as files, and for controlling access to administrative functions, such as setting the system time or auditing user actions. The Access-Control Model topic provides a high-level description of the access-control components and how they interact with each other.

The following topics are the access-control components:

  • Access Tokens
  • Security Descriptors
  • Access-Control Lists (ACLs)
  • Access-Control Entries (ACEs)
  • Access Rights and Access Masks
  • Security Identifiers (SIDs)

The following are common access-control tasks:

  • How DACLs Control Access to an Object
  • Controlling Child Object Creation
  • ACEs to Control Access to an Object's Properties
  • Requesting Access Rights to an Object

The following topics provide sample code for access-control tasks:

  • Modifying an Object's ACLs
  • Creating a Security Descriptor for a New Object
  • Controlling Child Object Creation
  • Enabling and Disabling Privileges
  • Searching for a SID in an Access Token
  • Finding the Owner of a File Object
  • Taking Object Ownership
  • Converting a Binary SID to String Format
  • Creating a Null DACL


About Access Control

The Win32® security functions support the following access-control features:

  • Selective access to securable objects. You can specify different kinds of access for particular users or groups of users. For example, you can grant read and write access to all members of a group while denying write access to a particular member of the group.
  • Administrative privileges. You can control which users or groups have the privileges necessary to perform various administrative functions. For example, any application that manipulates a system-wide resource must use the security system to gain access to that resource.
  • Monitoring access to securable objects. For example, an administrator can cause the system to generate an audit record in the security event log every time a specified user reads a given file.


C2-Level Security

Microsoft® Windows NT®/Microsoft Windows® 2000 supports C2-level security as defined by the U.S. Department of Defense. Following are some of the most important requirements of C2-level security:

  • It must be possible to control access to a resource by granting or denying access to individual users or named groups of users.
  • Memory must be protected so that its contents cannot be read after a process frees it. Similarly, a secure file system, such as NTFS, must protect deleted files from being read.
  • Users must identify themselves in a unique manner, such as by password, when they log on. All auditable actions must identify the user performing the action.
  • System administrators must be able to audit security-related events. However, access to the security-related events audit data must be limited to authorized administrators.
  • The system must be protected from external interference or tampering, such as modification of the running system or of system files stored on disk.


Access-Control Model

Windows NT/Windows 2000 security enables you to control the ability of a process to access securable objects or to perform various system administration tasks. Windows NT/Windows 2000 is the only platform that supports Win32 security.

The following topics provide a high-level description of the components of the access-control model and how they interact with each other.

  • Access-Control Components
  • Interaction Between Threads and Securable Objects
  • DACLs and ACEs
  • Null DACLs and Empty DACLs
  • Pre-Windows 2000-Compatible Access Group


Access-Control Components

There are two basic components of the access-control model:

  • Access tokens, which contain information about a logged-on user
  • Security descriptors, which contain the security information that protects a securable object

When a user logs on to a Windows NT/Windows 2000 system, the system authenticates the user's account name and password. If the logon is successful, the system creates an access token. Every process executed on behalf of this user will have a copy of this access token. The access token contains security identifiers (SIDs) that identify the user's account and any group accounts to which the user belongs. The token also contains a list of the privileges held by the user or the user's groups. The system uses this token to identify the associated user when a process tries to access a securable object or perform a system administration task that requires privileges.

When a securable object is created, the system assigns it a security descriptor containing security information specified by its creator, or default security information if none is specified. Applications can use Win32 functions to retrieve and set the security information for an existing object.

A security descriptor identifies the object's owner and can also contain the following access-control lists (ACLs):

  • A discretionary access-control list (DACL) that identifies the users and groups allowed or denied access to the object
  • A system access-control list (SACL) that controls how the system audits attempts to access the object

An ACL contains a list of access-control entries (ACEs). Each ACE specifies a set of access rights and contains a SID that identifies a trustee for whom the rights are allowed, denied, or audited. A trustee can be a user account, group account, or logon session.

Use the Win32 functions to manipulate the contents of security descriptors, SIDs, and ACLs rather than accessing them directly. This helps ensure that these structures remain syntactically accurate and prevents future enhancements to the security system from breaking existing code.


Interaction Between Threads and Securable Objects

When a thread attempts to use a securable object, the system performs an access check before allowing the thread to proceed. In an access check, the system compares the security information in the thread's access token against the security information in the object's security descriptor.

  • The access token contains SIDs that identify the user associated with the thread.
  • The security descriptor identifies the object's owner and contains a discretionary access-control list (DACL). The DACL contains access-control entries (ACEs), each of which specify the access rights allowed or denied to a specific user or group.

The system checks the object's DACL, looking for ACEs that apply to the user and group SIDs from the thread's access token. The system checks each ACE until access is either granted or denied or until there are no more ACEs to check. Conceivably, an ACL could have several ACEs that apply to the token's SIDs. And, if this occurs, the access rights granted by each ACE accumulate. For example, if one ACE grants read access to a group and another ACE grants write access to a user who is a member of the group, the user can have both read/write access to the object.

The following illustration shows the relationship between these blocks of security information:


DACLs and ACEs

If a Win32 object does not have a discretionary access-control list (DACL), the system allows everyone full access to it. If an object has a DACL, the system allows only the access that is explicitly allowed by the access-control entries (ACEs) in the DACL. If there are no ACEs in the DACL, the system does not allow access to anyone. Similarly, if a DACL has ACEs that allow access to a limited set of users or groups, the system implicitly denies access to all trustees not included in the ACEs.

In most cases, you can control access to an object by using access-allowed ACEs; you don't need to explicitly deny access to an object. The exception is when an ACE allows access to a group, and you want to deny access to a member of the group. To do this, place an access-denied ACE for the user in the DACL ahead of the access-allowed ACE for the group. Note that the order of the ACEs is important because the system reads the ACEs in sequence until access is granted or denied. The user's access-denied ACE must appear first; otherwise, when the system reads the group's access allowed ACE, it will grant access to the restricted user.

The following table shows a DACL that denies access to one user and grants access to two groups. The members of Group A get Read, Write, and Execute access rights by accumulating the rights allowed to Group A and rights allowed to Everyone. The exception is User X, who is denied access by the access-denied ACE in spite of being a member of the Everyone Group.


Null DACLs and Empty DACLs

If the DACL belonging to an object's security descriptor is set to NULL, a null DACL is created. A null DACL grants full access to any user that requests it; normal security checking is not performed with respect to the object. A null DACL should not be confused with an empty DACL. An empty DACL is a properly allocated and initialized DACL containing no ACEs. An empty DACL grants no access to the object it is assigned to.

Refer to Creating a Null DACL for an example of how to create a null DACL.


Pre-Windows 2000-Compatible Access Group

New in Windows 2000, the default security policy restricts anonymous local access to having no rights. Administrators can then add or subtract rights as they see fit. Before Windows 2000, anonymous access allowed access equal to the group Everyone, which involved security issues.

In Windows 2000, a local access group has been created for applications with the same access rights as Everyone (equivalent to Windows NT anonymous access). Administrators can then appropriately increase or decrease the number of users in that group, named the Pre-Windows 2000-compatible access group.

For more information, refer to the reference pages for the functions listed in the table of the Local Group Functions section.


Access Tokens

An access token is an object that describes the security context of a process or thread. The information in a token includes the identity and privileges of the user account associated with the process or thread. When a user logs on, the system verifies the user's password by comparing it with information stored in a security database. If the password is authenticated, the system produces an access token. Every process executed on behalf of this user has a copy of this access token.

The system uses an access token to identify the user when a thread interacts with a securable object or tries to perform a system task that requires privileges. Access tokens contain the following information:

  • The security identifier (SID) for the user's account
  • SIDs for the groups of which the user is a member
  • A logon SID that identifies the current logon session
  • A list of the privileges held by either the user or the user's groups
  • An owner SID
  • The SID for the primary group
  • The default DACL that the system uses when the user creates a securable object without specifying a security descriptor
  • The source of the access token
  • Whether the token is a primary or impersonation token
  • An optional list of restricting SIDs
  • Current impersonation levels
  • Other statistics

Every process has a primary token that describes the security context of the user account associated with the process. By default, the system uses the primary token when a thread of the process interacts with a securable object. Moreover, a thread can impersonate a client account. Impersonation allows the thread to interact with securable objects using the client's security context. A thread that is impersonating a client has both a primary token and an impersonation token.

Use the OpenProcessToken function to retrieve a handle to the primary token of a process. Use the OpenThreadToken function to retrieve a handle to the impersonation token of a thread. For more information, see Impersonation.

You can use the following functions to manipulate access tokens.

Function | Description
AdjustTokenGroups | Changes the group information in an access token.
AdjustTokenPrivileges | Enables or disables the privileges in an access token. It does not grant new privileges or revoke existing ones.
CheckTokenMembership | Determines whether a specified SID is enabled in a specified access token.
CreateRestrictedToken | Creates a new token that is a restricted version of an existing token. The restricted token can have disabled SIDs, deleted privileges, and a list of restricted SIDs.
DuplicateToken | Creates a new primary impersonation token that duplicates an existing token.
DuplicateTokenEx | Creates a new primary token or impersonation token that duplicates an existing token.
GetTokenInformation | Retrieves information about a token.
IsTokenRestricted | Determines whether a token has a list of restricting SIDs.
OpenProcessToken | Retrieves a handle to the primary access token for a process.
OpenThreadToken | Retrieves a handle to the impersonation access token for a thread.
SetThreadToken | Assigns or removes an impersonation token for a thread.
SetTokenInformation | Changes a token's owner, primary group, or default DACL.

The access token functions use the following structures to describe the components of an access token.

Structure | Description
TOKEN_CONTROL | Information that identifies an access token.
TOKEN_DEFAULT_DACL | The default DACL that the system uses in the security descriptors of new objects created by a thread.
TOKEN_GROUPS | Specifies the SIDs and attributes of the group SIDs in an access token.
TOKEN_OWNER | The default owner SID for the security descriptors of new objects.
TOKEN_PRIMARY_GROUP | The default primary group SID for the security descriptors of new objects.
TOKEN_PRIVILEGES | The privileges associated with an access token. Also determines whether the privileges are enabled.
TOKEN_SOURCE | The source of an access token.
TOKEN_STATISTICS | Statistics associated with an access token.
TOKEN_USER | The SID of the user associated with an access token.

The access token functions use the following enumeration types.

Enumeration Type | Specifies
TOKEN_INFORMATION_CLASS | Identifies the type of information being set or retrieved from an access token.
TOKEN_TYPE | Identifies an access token as a primary or impersonation token.


Restricted Tokens

A restricted token is a primary or impersonation access token that has been modified by the CreateRestrictedToken function. A process or impersonating thread running in the security context of a restricted token is restricted in its ability to access securable objects or perform privileged operations. The CreateRestrictedToken function can restrict a token in the following ways:

  • Remove privileges from the token.
  • Apply the deny-only attribute to SIDs in the token so that they cannot be used to access secured objects. For more information about the deny-only attribute, see SID Attributes in an Access Token.
  • Specify a list of restricting SIDs, which can limit access to securable objects.

The system uses the list of restricting SIDs when it checks the token's access to a securable object. When a restricted process or thread tries to access a securable object, the system performs two access checks: one using the token's enabled SIDs, and another using the list of restricting SIDs. Access is granted only if both access checks allow the requested access rights. For more information about access checks, see How DACLs Control Access to an Object.

You can use a restricted primary token in a call to the CreateProcessAsUser function. Typically, the process that calls CreateProcessAsUser must have the SE_ASSIGNPRIMARYTOKEN_NAME privilege, which is usually held only by system code or by services running in the LocalSystem account. However, if the CreateProcessAsUser call specifies a restricted version of the caller's primary token, this privilege is not required. This enables ordinary applications to create restricted processes.

You can also use a restricted primary or impersonation token in the ImpersonateLoggedOnUser function.

To determine whether a token has a list of restricting SIDs, call the IsTokenRestricted function.


SID Attributes in an Access Token

Each user and group SID in an access token has a set of attributes that control how the system uses the SID in an access check. The following table lists the attributes that control access checking.

Attribute | Description
SE_GROUP_ENABLED | A SID with this attribute is enabled for access checks. When the system performs an access check, it checks for access-allowed and access-denied ACEs that apply to one of the enabled SIDs in the access token. A SID without this attribute is ignored during an access check unless the SE_GROUP_USE_FOR_DENY_ONLY attribute is set.
SE_GROUP_USE_FOR_DENY_ONLY | Windows 2000 or later: A SID with this attribute is a deny-only SID. When the system performs an access check, it checks for access-denied ACEs that apply to the SID, but ignores access-allowed ACEs for the SID. If this attribute is set, the SE_GROUP_ENABLED attribute is not set, and the SID cannot be re-enabled.

To set or clear the SE_GROUP_ENABLED attribute of a group SID, use the AdjustTokenGroups function. You cannot disable a group SID that has the SE_GROUP_MANDATORY attribute. You cannot use AdjustTokenGroups to disable the user SID of an access token.

To determine whether a SID is enabled in a token, that is, whether it has the SE_GROUP_ENABLED attribute, call the CheckTokenMembership function.

To set the SE_GROUP_USE_FOR_DENY_ONLY attribute of a SID, include the SID in the list of deny-only SIDs that you specify when you call the CreateRestrictedToken function. CreateRestrictedToken can apply the SE_GROUP_USE_FOR_DENY_ONLY attribute to any SID, including the user SID and group SIDs that have the SE_GROUP_MANDATORY attribute. However, you cannot remove the deny-only attribute from a SID, nor can you use AdjustTokenGroups to set the SE_GROUP_ENABLED attribute on a deny-only SID.

To get the attributes of a SID, call the GetTokenInformation function with the TokenGroups value. The function returns an array of SID_AND_ATTRIBUTES structures that identify the group SIDs and their attributes.


Access Rights for Access-Token Objects

Windows NT/Windows 2000 provides security support that enables you to control access to access-token objects. For more information about security, see Access-Control Model.

To get or set the security descriptor for an access token, call theGetKernelObjectSecurity and SetKernelObjectSecurity functions.

When you call the OpenProcessToken or OpenThreadToken function to get a handle to an access token, the system checks the requested access rights against the DACL in the token's security descriptor.

The following are valid access rights for access-token objects:

  • The DELETE, READ_CONTROL, WRITE_DAC, and WRITE_OWNER standard access rights. Access tokens do not support the SYNCHRONIZE standard access right.
  • The ACCESS_SYSTEM_SECURITY right to get or set the SACL in the object's security descriptor.
  • The specific access rights for access tokens, which are listed in the following table.
    Value | Meaning
    TOKEN_ADJUST_DEFAULT | Required to change the default owner, primary group, or DACL of an access token.
    TOKEN_ADJUST_GROUPS | Required to adjust the attributes of the groups in an access token.
    TOKEN_ADJUST_PRIVILEGES | Required to enable or disable the privileges in an access token.
    TOKEN_ADJUST_SESSIONID | Required to adjust the session ID of an access token. The SE_TCB_NAME privilege is required.
    TOKEN_ASSIGN_PRIMARY | Required to attach a primary token to a process. The SE_ASSIGNPRIMARYTOKEN_NAME privilege is also required to accomplish this task.
    TOKEN_DUPLICATE | Required to duplicate an access token.
    TOKEN_EXECUTE | Combines STANDARD_RIGHTS_EXECUTE and TOKEN_IMPERSONATE.
    TOKEN_IMPERSONATE | Required to attach an impersonation access token to a process.
    TOKEN_QUERY | Required to query an access token.
    TOKEN_QUERY_SOURCE | Required to query the source of an access token.
    TOKEN_READ | Combines STANDARD_RIGHTS_READ and TOKEN_QUERY.
    TOKEN_WRITE | Combines STANDARD_RIGHTS_WRITE, TOKEN_ADJUST_PRIVILEGES, TOKEN_ADJUST_GROUPS, and TOKEN_ADJUST_DEFAULT.
    TOKEN_ALL_ACCESS | Combines all possible access rights for a token.


Security Descriptors

A security descriptor contains the security information associated with a securable object. A security descriptor consists of a SECURITY_DESCRIPTOR structure and its associated security information. A security descriptor can include the following security information:

  • Security identifiers (SIDs) for the owner and primary group of an object.
  • A DACL that specifies the access rights allowed or denied to particular users or groups.
  • A SACL that specifies the types of access attempts that generate audit records for the object.
  • A set of control bits that qualify the meaning of a security descriptor or its individual members.

Applications must not directly manipulate the contents of a security descriptor. The Win32 API provides functions for setting and retrieving the security information in an object's security descriptor. In addition, there are functions for creating and initializing a security descriptor for a new object.

This overview describes the Win32 security functions for working with security descriptors for applications running on Windows NT version 4.0 and later. For applications that must be compatible with earlier versions of Windows NT, see Low-Level Access Control.

Applications working with security descriptors on Active Directory objects can use the Win32 security functions or the security interfaces provided by the Active Directory Service Interfaces (ADSI). For more information about ADSI security interfaces, see Controlling Access to Active Directory Objects.


Security Descriptor Operations

The Win32 API provides functions for getting and setting the components of the security descriptor associated with a securable object. Use the GetSecurityInfo and GetNamedSecurityInfo functions to retrieve a pointer to an object's security descriptor. These functions can also retrieve pointers to the individual components of the security descriptor: DACL, SACL, owner SID, and primary group SID. Use the SetSecurityInfo and SetNamedSecurityInfo functions to set the components of an object's security descriptor.

In general, you should use GetSecurityInfo and SetSecurityInfo with objects identified by a handle, and SetNamedSecurityInfo and GetNamedSecurityInfo with objects identified by a name. For more information about the specific functions to use when working with the various types of objects, see Securable Objects.

The Win32 API provides additional functions for manipulating the components of a security descriptor. For information about working with access-control lists (DACLs or SACLs), see Getting Information from an ACL and Creating or Modifying an ACL. For information about SIDs, see Security Identifiers (SIDs).

To get the control information in a security descriptor, call the GetSecurityDescriptorControl function. To set the control bits that relate to automatic ACE inheritance, call the SetSecurityDescriptorControl function. Other control bits are set by the various functions that set a security descriptor component. For example, if you use SetSecurityInfo to change an object's DACL, the function sets or clears the bits as appropriate to indicate whether the security descriptor has a DACL, whether it's a default DACL, and so on. Another example is the resource manager (RM) control bits contained in the security descriptor. These bits are used according to the implementation of the resource manager, and are accessed through the GetSecurityDescriptorRMControl and SetSecurityDescriptorRMControl functions.


Security Descriptors for New Objects

When you create a securable object, you can assign a security descriptor to the new object. The Win32 functions for creating securable objects, such as CreateFile or RegCreateKeyEx, have a parameter that points to the SECURITY_ATTRIBUTES structure that can contain a pointer to the new object's security descriptor. For sample code that builds a security descriptor and then calls RegCreateKeyEx to assign the security descriptor to a new registry key, see Creating a Security Descriptor for a New Object.

The system component or server that manages the object can store the specified or default security descriptor to make it a persistent attribute of the object. If an object's creator does not specify a security descriptor, the system uses inherited or default security information to create a security descriptor. You can use Win32 functions to change the information in an object's security descriptor.

Directory service objects, files, directories, registry keys, and desktops are securable objects that can have a parent object. When you create one of these objects, the system checks for inheritable ACEs in the security descriptor of the parent object. The system typically merges any inheritable ACEs into the ACLs of the new object's security descriptor. You can prevent a DACL or SACL from inheriting ACEs by setting the SE_DACL_PROTECTED or SE_SACL_PROTECTED bits in the security descriptor's control bits. For more information, see ACE inheritance.


DACL for a New Object

The system uses the following algorithm to build a DACL for most types of new securable objects:

  1. The object's DACL is the DACL from the security descriptor specified by the object's creator. The system merges any inheritable ACEs into the specified DACL unless the SE_DACL_PROTECTED bit is set in the security descriptor's control bits.
  2. If the creator does not specify a security descriptor, the system builds the object's DACL from inheritable ACEs.
  3. If no security descriptor is specified and there are no inheritable ACEs, the object's DACL is the default DACL from the primary or impersonation token of the creator.
  4. If there is no specified, inherited, or default DACL, the system creates the object with no DACL, which allows everyone full access to the object.

The system uses a different algorithm to build a DACL for a new Active Directory object. For more information, see How Security Descriptors are Set on New Directory Objects.


SACL for a New Object

The system uses the following algorithm to build a SACL for most types of new securable objects:

  1. The object's SACL is the SACL from the security descriptor specified by the object's creator. The system merges any inheritable ACEs into the specified SACL unless the SE_SACL_PROTECTED bit is set in the security descriptor's control bits.
  2. If the creator does not specify a security descriptor, the system builds the object's SACL from inheritable ACEs.
  3. If there is no specified or inherited SACL, the object has no SACL.

To specify a SACL for a new object, the object's creator must have the SE_SECURITY_NAME privilege enabled. The creator does not need this privilege if the object's SACL is built from inherited ACEs.

The system uses a different algorithm to build a SACL for a new Active Directory object. For more information, see How Security Descriptors are Set on New Directory Objects.


Owner of a New Object

An object's owner implicitly has WRITE_DAC access to the object. This means that the owner can modify the object's DACL, and thus, can control access to the object.

The owner of a new object is the default owner SID from the primary or impersonation token of the creating process. To get or set the default owner in an access token, call the GetTokenInformation or SetTokenInformation function with the TOKEN_OWNER structure. The system does not allow you to set a token's default owner to an invalid SID, such as the SID of another user's account.

A process with the SE_TAKE_OWNERSHIP privilege enabled can set itself as the owner of an object. A process with the SE_RESTORE_NAME privilege enabled or with WRITE_OWNER access to the object can set any valid user or group SID as the owner of an object.


Primary Group of a New Object

A new object's primary group is the primary group from the security descriptor specified by the object's creator. If an object's creator does not specify a primary group, the object's primary group is the default primary group from the creator's primary or impersonation token.


Security Descriptor Strings

A valid functional security descriptor contains security information in binary format. The Win32 API provides functions for converting binary security descriptors to and from text strings. Security descriptors in string format are not functional, but they can be useful for storing or transporting security descriptor information.

To convert a security descriptor to a string format, call the ConvertSecurityDescriptorToStringSecurityDescriptor function. To convert a string-format security descriptor back to a valid functional security descriptor, call the ConvertStringSecurityDescriptorToSecurityDescriptor function.

For more information, see Security Descriptor Definition Language.


Access-Control Lists (ACLs)

An access-control list (ACL) is a list of access-control entries (ACEs). Each ACE in an ACL identifies a trustee and specifies the access rights allowed, denied, or audited for that trustee. The security descriptor for a securable object can contain two ACLs: a DACL and a SACL.

A DACL (discretionary access-control list) identifies the trustees that are allowed or denied access to a securable object. When a process tries to access a securable object, the system checks the ACEs in the object's DACL to determine whether to grant access to it. If the object does not have a DACL, the system grants full access to everyone. If the object's DACL has no ACEs, the system denies all attempts to access the object because the DACL does not allow any access rights. The system checks the ACEs in sequence until it finds one or more ACEs that allow all the requested access rights, or until any of the requested access rights are denied. For more information, see How DACLs Control Access to an Object.

A system access-control list (SACL) enables administrators to log attempts to access a secured object. Each ACE specifies the types of access attempts by a specified trustee that cause the system to generate a record in the security event log. An ACE in a SACL can generate audit records when an access attempt fails, when it succeeds, or both. In future releases, a SACL will also be able to raise an alarm when an unauthorized user attempts to gain access to an object. For more information about SACLs, see Audit Generation and SACL Access Right.

Do not try to work directly with the contents of an ACL. To ensure that ACLs are semantically correct, use the appropriate Win32 functions to create and manipulate ACLs. For more information, see Getting Information from an ACL and Creating or Modifying an ACL.

ACLs also provide access control to Active Directory objects. Active Directory™ Service Interfaces (ADSI) include routines to create and modify the contents of these ACLs. Refer to the Access Control section of the ADSI documentation for more information on these routines.


How DACLs Control Access to an Object

When a thread tries to access a securable object, the system either grants or denies access. If the object does not have a DACL, the system grants access; otherwise, the system looks for ACEs in the object's DACL that apply to the thread. Each ACE in the object's DACL specifies the access rights allowed or denied for a trustee, which can be a user account, a group account, or a logon session.

The system compares the trustee in each ACE to the trustees identified in the thread's access token. An access token contains SIDs that identify the user and the group accounts to which the user belongs. A token also contains a logon SID that identifies the current logon session. During an access check, the system ignores group SIDs that are not enabled. For more information on enabled, disabled, and deny-only SIDs, see SID Attributes in an Access Token.

Typically, the system uses the primary access token of the thread that is requesting access. However, if the thread is impersonating another user, the system uses the thread's impersonation token.

The system examines each ACE in sequence until one of the following events occurs:

  • An access-denied ACE explicitly denies any of the requested access rights to one of the trustees listed in the thread's access token.
  • One or more access-allowed ACEs for trustees listed in the thread's access token explicitly grant all the requested access rights.
  • All ACEs have been checked and there is still at least one requested access right that has not been explicitly allowed, in which case, access is implicitly denied.

The following diagram illustrates how an object's DACL can allow access to one thread while denying access to another.

For Thread A, the system reads ACE 1 and immediately denies access because the access-denied ACE applies to the user in the thread's access token. In this case, the system does not check ACEs 2 and 3. For Thread B, ACE 1 does not apply, so the system proceeds to ACE 2, which allows Write access, and ACE 3 which allows Read and Execute access.

Because the system stops checking ACEs when the requested access is explicitly granted or denied, the order of ACEs in a DACL is important. Note that if the ACE order were different in the example, the system might have granted access to Thread A. For system objects, the operating system defines a preferred order of ACEs in a DACL.


Getting Information from an ACL

Windows NT versions 4.0 and later provide several functions for retrieving access-control information from an ACL. These include functions for determining the access rights that an ACL grants or audits for a specified trustee. Other functions enable you to extract information about the ACEs in an ACL.

The GetExplicitEntriesFromAcl function retrieves an array of EXPLICIT_ACCESS structures that describe the ACEs in an ACL. This can be useful when copying ACE information from one ACL to another. For example, a call to GetExplicitEntriesFromAcl to get information about the ACEs in one ACL can be followed by passing the returned EXPLICIT_ACCESS structures in a call to the SetEntriesInAcl function to create equivalent ACEs in a new ACL.

The GetEffectiveRightsFromAcl function enables you to determine the effective access rights that a DACL grants to a specified trustee. The trustee's effective access rights are the access rights that a DACL grants to the trustee or to any groups of which the trustee is a member. GetEffectiveRightsFromAcl checks all access-allowed and access-denied ACEs in the specified DACL.

Use the following steps to determine a trustee's access rights to an object

  1. Call the GetSecurityInfo or GetNamedSecurityInfo function to get a pointer to an object's DACL.
  2. Call the GetEffectiveRightsFromAcl function to retrieve the access rights that the DACL grants to a specified trustee.

The GetAuditedPermissionsFromAcl function enables you to check a SACL to determine the audited access rights for a specified trustee or for any groups of which the trustee is a member. The audited rights indicate the types of access attempts that cause the system to generate an audit record in the security event log. The function returns two access masks: one containing the access rights monitored for failed access attempts, and another containing the access rights monitored for successful access. GetAuditedPermissionsFromAcl checks all system-audit ACEs in a SACL.


Creating or Modifying an ACL

Windows NT versions 4.0 and later support a set of functions for creating an access-control list (ACL) or for modifying the access-control entries (ACEs) in an existing ACL.

The SetEntriesInAcl function creates a new ACL. SetEntriesInAcl can specify a completely new set of ACEs for the ACL, or it can merge one or more new ACEs with the ACEs of an existing ACL. The SetEntriesInAcl function uses an array of EXPLICIT_ACCESS structures to specify the information for the new ACEs. Each EXPLICIT_ACCESS structure contains information that describes a single ACE. This information includes the access rights, the type of ACE, the flags that control ACE inheritance, and a TRUSTEE structure that identifies the trustee.

To add a new ACE to an existing ACL

  1. Use the GetSecurityInfo or GetNamedSecurityInfo function to get the existing DACL or SACL from an object's security descriptor.
  2. For each new ACE, call the BuildExplicitAccessWithName function to fill an EXPLICIT_ACCESS structure with the information that describes the ACE.
  3. Call SetEntriesInAcl, specifying the existing ACL and an array of EXPLICIT_ACCESS structures for the new ACEs. The SetEntriesInAcl function allocates and initializes the ACL and its ACEs.
  4. Call the SetSecurityInfo or SetNamedSecurityInfo function to attach the new ACL to the object's security descriptor.

If the caller specifies an existing ACL, SetEntriesInAcl merges the new ACE information with the existing ACEs in the ACL. Consider the case, for example, in which the existing ACL grants access to a specified trustee and an EXPLICIT_ACCESS structure denies access to the same trustee. In this case, SetEntriesInAcl adds a new access-denied ACE for the trustee and deletes or modifies the existing access-allowed ACE for the trustee.

For sample code that merges a new ACE into an existing ACL, see Modifying an Object's ACLs.


Access-Control Entries (ACEs)

An access-control entry (ACE) is an element in an access-control list (ACL). An ACL can have zero or more ACEs. Each ACE controls or monitors access to an object by a specified trustee. For information about adding, removing, or changing the ACEs in an object's ACLs, see Modifying an Object's ACLs.

Windows NT/Windows 2000 currently supports six types of ACEs. There are three ACE types supported by all securable objects. In addition, there are three types of object-specific ACEs supported by directory service objects.

All types of ACEs contain the following access-control information:

  • A security identifier (SID) that identifies the trustee to which the ACE applies.
  • An access mask that specifies the access rights controlled by the ACE.
  • A flag that indicates the type of ACE.
  • A set of bit flags that determine whether child containers or objects can inherit the ACE from the primary object to which the ACL is attached.

The following table lists the three ACE types supported by all securable objects.

Type | Description
Access-denied ACE | Used in a DACL to deny access rights to a trustee.
Access-allowed ACE | Used in a DACL to allow access rights to a trustee.
System-audit ACE | Used in a SACL to generate an audit record when the trustee attempts to exercise the specified access rights.

For a table of object-specific ACEs, see Object-Specific ACEs.

Note System-alarm object ACEs are not currently supported.


Trustees

A trustee is the user account, group account, or logon session to which an ACE applies. Each ACE in an ACL has one SID that identifies a trustee. User accounts include accounts that human users or programs such as Win32 services use to log on to the local computer. Group accounts cannot be used to log on to a computer, but are useful in ACEs to allow or deny a set of access rights to one or more user accounts. A logon SID that identifies the current logon session is useful to allow or deny access rights only until the user logs off.

The access-control functions for Windows NT version 4.0 and later use the TRUSTEE structure to identify a trustee. This structure enables you to use a name string or a SID to identify a trustee. If you use a name, the Win32 functions that create an ACE from the TRUSTEE structure perform the task of allocating the SID buffers and looking up the SID that corresponds to the account name. There are two helper functions, BuildTrusteeWithSid and BuildTrusteeWithName, that initialize a TRUSTEE structure with a specified SID or name. BuildTrusteeWithObjectsAndSid and BuildTrusteeWithObjectsAndName allow you to initialize a TRUSTEE structure with object-specific ACE information. Three other helper functions, GetTrusteeForm, GetTrusteeName, and GetTrusteeType, retrieve the values of the various members of a TRUSTEE structure.

Windows 2000 or later: The ptstrName member of the TRUSTEE structure can be a pointer to an OBJECTS_AND_NAME or OBJECTS_AND_SID structure. These structures specify information about an object-specific ACE in addition to a trustee name or SID. This enables functions such as SetEntriesInAcl and GetExplicitEntriesFromAcl to store object-specific ACE information in the Trustee member of the EXPLICIT_ACCESS structure.


Object-Specific ACEs

Windows 2000 supports object-specific ACEs for directory service (DS) objects. An object-specific ACE contains a pair of globally unique identifiers (GUIDs) that expand the ways in which the ACE can protect an object.

ObjectType: GUID
Identifies one of the following:
  • A type of child object. The ACE controls the right to create a specified type of child object. For more information, see Controlling Child Object Creation.
  • A property set or property. The ACE controls the right to read or write the property or property set. For more information, see ACEs to Control Access to an Object's Properties.
  • An extended right. The ACE controls the right to perform the operation associated with the extended right.
  • A validated write. The ACE controls the right to perform certain write operations. These validated write permissions, defined and exposed in the ACL Editor, provide permissions for validated writes of properties rather than unchecked low-level writes of any value to a property that is granted with a "write property" permission.
InheritedObjectType: GUID
Indicates the type of child object that can inherit the ACE. Inheritance is also controlled by the inheritance flags in the ACE_HEADER, as well as by any protection against inheritance placed on the child objects. For more information, see ACE Inheritance.

Windows 2000 supports three types of object-specific ACEs.

Note System-alarm object ACEs are not currently supported.

Type | Description
Access-denied object ACE | Windows 2000 or later: Used in a DACL to deny a trustee access to a property or property set on the object, or to limit ACE inheritance to a specified type of child object. Uses the ACCESS_DENIED_OBJECT_ACE structure.
Access-allowed object ACE | Windows 2000 or later: Used in a DACL to allow a trustee access to a property or property set on the object, or to limit ACE inheritance to a specified type of child object. Uses the ACCESS_ALLOWED_OBJECT_ACE structure.
System-audit object ACE | Windows 2000 or later: Used in a SACL to log a trustee's attempts to access a property or property set on the object, or to limit ACE inheritance to a specified type of child object. Uses the SYSTEM_AUDIT_OBJECT_ACE structure.

Any ACL that contains an object-specific ACE must use the revision ACL_REVISION_DS.


Order of ACEs in a DACL

When a process tries to access a securable object, the system steps through the ACEs in the object's DACL until it finds ACEs that allow or deny the requested access. The access rights that a DACL allows a user could vary depending on the order of ACEs in the DACL. Consequently, the Windows NT/Windows 2000 operating system defines a preferred order for ACEs in the DACL of a securable object. The preferred order provides a simple framework to be assured that an access-denied ACE actually denies access. For more information about the system's algorithm for checking access, see How DACLs Control Access to an Object.

For Windows NT versions 4.0 and earlier, the preferred order of ACEs is simple: In a DACL, all access-denied ACEs should precede any access-allowed ACEs. The SetEntriesInAcl function creates a DACL with ACEs in this order. However, the low-level functions for adding ACEs to a DACL do not enforce the preferred order. The AddAce function adds ACEs at a specified location in an ACL. Functions such as AddAccessAllowedAce add an ACE to the end of an ACL. It is the caller's responsibility to ensure that the ACEs are added in the preferred order.

The following diagram illustrates how the same ACEs can allow different access rights, depending on their order in the DACL. The system denies access to object A when it reads the access-denied ACE, but the out-of-order DACL for Object B causes the system to grant access without reading the access-denied ACE.

For Windows 2000, the proper order of ACEs is more complicated because of the introduction of object-specific ACEs and automatic inheritance.

The following describes the preferred order for Windows 2000:

  • To ensure that noninherited ACEs have precedence over inherited ACEs, place all noninherited ACEs in a group before any inherited ACEs. This ordering ensures, for example, that a noninherited access-denied ACE is enforced regardless of any inherited ACE that allows access.
  • Within the groups of noninherited ACEs and inherited ACEs, order ACEs according to ACE type, as the following shows:
    1. Access-denied ACEs that apply to the object itself
    2. Access-denied ACEs that apply to a subobject of the object, such as a property set or property
    3. Access-allowed ACEs that apply to the object itself
    4. Access-allowed ACEs that apply to a subobject of the object

Of course, not all ACE types are required in an ACL.

Functions such as AddAccessAllowedAceEx and AddAccessAllowedObjectAce add an ACE to the end of an ACL. It is the caller's responsibility to ensure that the ACEs are added in the proper order.


ACE Inheritance

An object's ACL can contain ACEs that it inherited from its parent container. For example, a registry subkey can inherit ACEs from the key above it in the registry hierarchy. Likewise, a file in an NTFS file system can inherit ACEs from the directory that contains it.

The ACE_HEADER structure of an ACE contains a set of inheritance flags that control ACE inheritance and the effect of an ACE on the object to which it is attached. The system interprets the inheritance flags and other inheritance information according to the rules of ACE inheritance.

For Windows 2000, these rules have been enhanced with the following features:

  • Support for automatic propagation of inheritable ACEs.
  • A flag that differentiates between inherited ACEs and ACEs that were directly applied to an object.
  • Object-specific ACEs that allow you to specify the type of child object that can inherit the ACE.
  • The ability to prevent a DACL or SACL from inheriting ACEs by setting the SE_DACL_PROTECTED or SE_SACL_PROTECTED bits in the security descriptor's control bits.


Automatic Propagation of Inheritable ACEs

In Windows NT versions 4.0 and earlier, a securable object could inherit ACEs only when it was being created or when a new ACL was being applied to the object. The system did not propagate inheritable ACEs to existing child objects, did not differentiate between inherited ACEs and ACEs that were applied directly to the object, nor did it allow an object to protect itself from inherited ACEs.

For Windows 2000, the SetNamedSecurityInfo and SetSecurityInfo functions support automatic propagation of inheritable ACEs. For example, if you use these functions to add an inheritable ACE to a directory in an NTFS file system, the system applies the ACE as appropriate to the ACLs of any existing subdirectories or files.

Windows 2000 also introduces a new inheritance model in which directly applied ACEs have precedence over inherited ACEs. The system implements this precedence by placing directly applied ACEs ahead of inherited ACEs in a DACL. Earlier versions of Windows NT did not distinguish between inherited and directly applied ACEs. Consequently, the order of ACEs in a DACL is different for the current and the previous inheritance models. When you call SetNamedSecurityInfo and SetSecurityInfo to set an object's security information, the system imposes the new inheritance model on the ACLs of all objects in the hierarchy below the target object. For objects that have been converted to the new inheritance model, the SE_DACL_AUTO_INHERITED and SE_SACL_AUTO_INHERITED bits are set in the control field of the object's security descriptor.

When building a new security descriptor reflecting the new inheritance model, care is taken not to change the semantics of the security descriptor. As such, allow and deny ACEs are never moved in relation to one another. If such movement is needed (for instance to place all non-inherited ACEs at the front of an ACL), the ACL is marked as protected to prevent the semantic change.

The system uses the following rules for propagating inherited ACEs to child objects:

  • If a child object with no DACL inherits an ACE, the result is a child object with a DACL containing only the inherited ACE.
  • If a child object with an empty DACL inherits an ACE, the result is a child object with a DACL containing only the inherited ACE.
  • If you remove an inheritable ACE from a parent object, automatic inheritance removes any copies of the ACE inherited by child objects.
  • If automatic inheritance results in the removal of all ACEs from a child object's DACL, the child object has an empty DACL rather than no DACL.

These rules can have the unexpected result of converting an object with no DACL to an object with an empty DACL. An object with no DACL allows full access, but an object with an empty DACL allows no access. As an example of how these rules can create an empty DACL, suppose you add an inheritable ACE to the root object of a tree of objects. Automatic inheritance propagates the inheritable ACE to all the objects in the tree. Child objects that started with no DACL now have a DACL with the inherited ACE. If you remove the inheritable ACE from the root object, the system automatically propagates the change to the child objects. Child objects that started with no DACL (allowing full access) now have an empty DACL (allowing no access).

To ensure that a child object with no DACL is not affected by inheritable ACEs, set the SE_DACL_PROTECTED flag in the object's security descriptor.


ACE Inheritance Rules

The system propagates inheritable ACEs to child objects according to a set of inheritance rules. The system places inherited ACEs in the child's DACL according to the preferred order of ACEs in a DACL. For Windows 2000, the system sets the INHERITED_ACE flag in all inherited ACEs.

The following table shows the ACEs inherited by container and noncontainer child objects for different combinations of inheritance flags. These inheritance rules work the same for both DACLs and SACLs.

Parent ACE type | Effect on Child ACL
OBJECT_INHERIT_ACE only | Noncontainer child objects: Inherited as an effective ACE. Container child objects: Containers inherit an inherit-only ACE unless the NO_PROPAGATE_INHERIT_ACE bit flag is also set.
CONTAINER_INHERIT_ACE only | Noncontainer child objects: No effect on the child object. Container child objects: The child object inherits an effective ACE. The inherited ACE is inheritable unless the NO_PROPAGATE_INHERIT_ACE bit flag is also set.
CONTAINER_INHERIT_ACE and OBJECT_INHERIT_ACE | Noncontainer child objects: Inherited as an effective ACE. Container child objects: The child object inherits an effective ACE. The inherited ACE is inheritable unless the NO_PROPAGATE_INHERIT_ACE bit flag is also set.
No inheritance flags set | No effect on child container or noncontainer objects.

If an inherited ACE is an effective ACE for the child object, the system maps any generic rights to the specific rights for the child object. Similarly, the system maps generic SIDs, such as CREATOR_OWNER, to the appropriate SID. If an inherited ACE is an inherit-only ACE, any generic rights or generic SIDs are left unchanged so that they can be mapped appropriately when the ACE is inherited by the next generation of child objects.

For a case in which a container object inherits an ACE that is both effective on the container and inheritable by its descendants, the container may inherit two ACEs. This occurs if the inheritable ACE contains generic information. The container inherits an inherit-only ACE containing the generic information and an effective-only ACE in which the generic information has been mapped.

An object-specific ACE has an InheritedObjectType member that can contain a GUID to identify the type of object that can inherit the ACE. If the InheritedObjectType GUID is not specified, the inheritance rules for an object-specific ACE are the same as for a standard ACE.

If the InheritedObjectType GUID is specified, the ACE is inheritable by objects that match the GUID if OBJECT_INHERIT_ACE is set, and by containers that match the GUID if CONTAINER_INHERIT_ACE is set. Note that currently only DS objects support object-specific ACEs, and the DS treats all object types as containers.


ACEs to Control Access to an Object's Properties

The DACL of a directory service (DS) object can contain a hierarchy of ACEs, as follows:

  1. ACEs that protect the object itself
  2. Object-specific ACEs that protect a specified property set on the object
  3. Object-specific ACEs that protect a specified property on the object

Within this hierarchy, the rights granted or denied at a higher level apply also to the lower levels. For example, if an object-specific ACE on a property set allows a trustee the ADS_RIGHT_DS_READ_PROP right, the trustee has implicit read access to all of the properties of that property set. Similarly, an ACE on the object itself that allows ADS_RIGHT_DS_READ_PROP access gives the trustee read access to all of the object's properties.

The following illustration shows the tree of a hypothetical DS object and its property sets and properties.

Suppose you want to allow the following access to the properties of this DS object:

  • Allow Group A read/write access to all of the object's properties
  • Allow everyone else read/write access to all properties except Property D

To do this, set the ACEs in the object's DACL as shown in the following table.

Trustee | Object GUID | ACE Type | Access Rights
Group A | None | Access-allowed ACE | ADS_RIGHT_DS_READ_PROP | ADS_RIGHT_DS_WRITE_PROP
Everyone | Property Set 1 | Access-allowed object ACE | ADS_RIGHT_DS_READ_PROP | ADS_RIGHT_DS_WRITE_PROP
Everyone | Property C | Access-allowed object ACE | ADS_RIGHT_DS_READ_PROP | ADS_RIGHT_DS_WRITE_PROP

The ACE for Group A does not have an object GUID, which means that it allows access to all the object's properties. The object-specific ACE for Property Set 1 allows everyone access to Properties A and B. The other object-specific ACE allows everyone access to Property C. Note that although this DACL does not have any access-denied ACEs, it implicitly denies Property D access to everyone except Group A.

When a user tries to access an object's property, the system checks the ACEs, in order, until the requested access is explicitly granted, denied, or there are no more ACEs, in which case, access is implicitly denied. The system evaluates:

  • ACEs that apply to the object itself
  • Object-specific ACEs that apply to the property set that contains the property being accessed
  • Object-specific ACEs that apply to the property being accessed

The system ignores object-specific ACEs that apply to other property sets or properties.


Access Rights and Access Masks

An access right is a bit flag that corresponds to a particular set of operations that a thread can perform on a securable object. For example, a registry key has the KEY_SET_VALUE access right, which corresponds to the ability of a thread to set a value under the key. If a thread tries to perform an operation on an object, but does not have the necessary access right to the object, the system does not carry out the operation.

An access mask is a 32-bit value whose bits correspond to the access rights supported by an object. All Windows NT/Windows 2000 securable objects use a Windows 2000/Windows NT access mask format that includes bits for the following types of access rights:

  • Generic access rights
  • Standard access rights
  • SACL access right
  • Directory services access rights

When a thread tries to open a handle to an object, the thread typically specifies an access mask to request a set of access rights. For example, an application that needs to set and query the values of a registry key can open the key by using an access mask to request the KEY_SET_VALUE and KEY_QUERY_VALUE access rights.

The following table shows the functions that manipulate the security information for each type of securable object.

Object type | Security descriptor functions
Files or directories on an NTFS file system | GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo
Named pipes Anonymous pipes | GetSecurityInfo, SetSecurityInfo
Console screen buffers | Not supported.
Processes Threads | GetSecurityInfo, SetSecurityInfo
File-mapping objects | GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo
Access tokens | SetKernelObjectSecurity, GetKernelObjectSecurity
Window-management objects (window stations and desktops) | GetSecurityInfo, SetSecurityInfo
Registry keys | GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo
Win32 services | GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo
Local or remote printers | GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo
Network shares | GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo
Interprocess synchronization objects (events, mutexes, semaphores, and waitable timers) | GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo
Job objects | GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo


Windows 2000/Windows NT Access Mask Format

All securable objects on Windows 2000\Windows NT systems arrange their access rights using the access mask format shown in the following diagram.

In this format, the low-order 16 bits are for object-specific access rights, the next 7 bits are for standard access rights, which apply to most types of objects, and the 4 high-order bits are used to specify generic access rights that each object type can map to a set of standard and object-specific rights. The ACCESS_SYSTEM_SECURITY bit corresponds to the right to access the object's SACL.


Generic Access Rights

Securable objects use a Windows 2000/Windows NT access mask formatin which the four high-order bits specify generic access rights. Each type of securable object maps these bits to a set of its standard and object-specific access rights. For example, a Win32 file object maps the GENERIC_READ bit to the READ_CONTROL and SYNCHRONIZE standard access rights and to the FILE_READ_DATA, FILE_READ_EA, and FILE_READ_ATTRIBUTES object-specific access rights. Other types of objects map the GENERIC_READ bit to whatever set of access rights is appropriate for that type of object.

You can use generic access rights to specify the type of access you need when you are opening a handle to an object. This is typically simpler than specifying all the corresponding standard and specific rights.

The following table shows the constants defined for the generic access rights.

Constant | Generic meaning
GENERIC_ALL | Read, write, and execute access
GENERIC_EXECUTE | Execute access
GENERIC_READ | Read access
GENERIC_WRITE | Write access

Applications that define private securable objects can also use the generic access rights.


Standard Access Rights

Each type of securable object has a set of access rights that correspond to operations specific to that type of object. In addition to these object-specific access rights, there is a set of standard access rights that correspond to operations common to most types of securable objects.

The Windows 2000/Windows NT access mask format includes a set of bits for the standard access rights. The following table shows the Win32 constants defined for the standard access rights.

Constant | Meaning
DELETE | The right to delete the object.
READ_CONTROL | The right to read the information in the object's security descriptor, not including the information in the SACL.
SYNCHRONIZE | The right to use the object for synchronization. This enables a thread to wait until the object is in the signaled state. Some object types do not support this access right.
WRITE_DAC | The right to modify the DACL in the object's security descriptor.
WRITE_OWNER | The right to change the owner in the object's security descriptor.

The Win32 API also defines the following combinations of the standard access rights constants.

Constant | Meaning
STANDARD_RIGHTS_ALL | Combines DELETE, READ_CONTROL, WRITE_DAC, WRITE_OWNER, and SYNCHRONIZE access.
STANDARD_RIGHTS_EXECUTE | Currently defined to equal READ_CONTROL.
STANDARD_RIGHTS_READ | Currently defined to equal READ_CONTROL.
STANDARD_RIGHTS_REQUIRED | Combines DELETE, READ_CONTROL, WRITE_DAC, and WRITE_OWNER access.
STANDARD_RIGHTS_WRITE | Currently defined to equal READ_CONTROL.


SACL Access Right

The ACCESS_SYSTEM_SECURITY access right controls the ability to get or set the SACL in an object's security descriptor. The system grants this access right only if the SE_SECURITY_NAME privilege is enabled in the access token of the requesting thread.

To access an object's SACL

  1. Call the AdjustTokenPrivileges function to enable the SE_SECURITY_NAME privilege.
  2. Request the ACCESS_SYSTEM_SECURITY access right when you open a handle to the object.
  3. Get or set the object's SACL by using a function such as GetSecurityInfo or SetSecurityInfo.
  4. Call AdjustTokenPrivileges to disable the SE_SECURITY_NAME privilege.

To access a SACL using the GetNamedSecurityInfo or SetNamedSecurityInfo functions, enable the SE_SECURITY_NAME privilege. The function internally requests the access right.

The ACCESS_SYSTEM_SECURITY access right is not valid in a DACL because DACLs do not control access to a SACL. However, you can use the ACCESS_SYSTEM_SECURITY access right in a SACL to audit attempts to use the access right.


Directory Services Access Rights

Each Active Directory object has a security descriptor assigned to it. A set of trustee rights specific to directory service objects can be set within these security descriptors. These rights are listed in the following table. For information see Control Access Rights under Networking and Directory Services.

Rights | Meaning
ACTRL_DS_OPEN | Open a DS object.
ACTRL_DS_CREATE_CHILD | Create a child DS object.
ACTRL_DS_DELETE_CHILD | Delete a child DS object.
ACTRL_DS_LIST | Enumerate a DS object.
ACTRL_DS_READ_PROP | Read the properties of a DS object.
ACTRL_DS_WRITE_PROP | Write properties for a DS object.
ACTRL_DS_SELF | Access allowed only after validated writes checks supported by the object are performed. This flag can be used alone to perform all validated writes checks of the object or it can be combined with an identifier of a specific validated write to perform only that check.
ACTRL_DS_DELETE_TREE | Delete a tree of DS objects.
ACTRL_DS_LIST_OBJECT | List a tree of DS objects.
ACTRL_DS_CONTROL_ACCESS | Access allowed only after extended rights checks supported by the object are performed. This flag can be used alone to perform all extended rights checks on the object or it can be combined with an identifier of a specific extended right to perform only that check.


Requesting Access Rights to an Object

When you open a handle to an object, the returned handle has some combination of access rights to the object. Some functions, such as CreateSemaphore, do not require a specific set of requested access rights. These functions always try to open the handle for full access. Other functions, such as CreateFile and OpenProcess, allow you to specify the set of access rights that you want. You should request only the access rights that you need, rather than opening a handle for full access. This prevents using the handle in an unintended way, and increases the chances that the access request will succeed if the object's DACL only allows limited access.

Use generic access rights to specify the type of access needed when opening a handle to an object. This is typically simpler than specifying all the corresponding standard and specific rights. Alternatively, use the MAXIMUM_ALLOWED constant to request that the object be opened with all the access rights that are valid for the caller.

Note The MAXIMUM_ALLOWED constant cannot be used in an ACE.

To get or set the SACL in an object's security descriptor, request the ACCESS_SYSTEM_SECURITY access right when opening a handle to the object.


Security Identifiers (SIDs)

A security identifier (SID) is a unique value of variable length used to identify a trustee. Each account has a unique SID issued by an authority, such as a Windows NT/Windows 2000 domain, and stored in a security database. Each time a user logs on, the system retrieves the user's SID from the database and places it in the user's access token. The system uses the SID in the user's access token to identify the user in all subsequent interactions with Windows NT/Windows 2000 security. When a SID has been used as the unique identifier for a user or group, it cannot ever be used again to identify another user or group.

Windows NT/Windows 2000 security uses SIDs in the following security elements:

  • In security descriptors to identify an object's owner and primary group
  • In access-control entries (ACEs), to identify the trustee for whom access is allowed, denied, or audited
  • In access tokens, to identify the user and the groups to which the user belongs

In addition to the uniquely-created, domain-specific SIDs assigned to specific users and groups, there are well-known SIDs that identify generic groups and generic users. For example, the well-known SIDs, Everyone and World, identify a group that includes all users.

Most applications never need to work with SIDs. For example, in Windows NT versions 4.0 and later, the security functions for getting and setting the ACEs in an ACL allow you to use names rather than SIDs to identify users and groups. Because the names of well-known SIDs can vary, you should use the Win32 functions to build the SID from predefined constants rather than using the name of the well-known SID. For example, the U.S. English version of Windows NT/Windows 2000 has a well-known SID named "BUILTIN\Administrators" that might have a different name on international versions of the system. For sample code that builds a well-known SID, see Searching for a SID in an Access Token.

If you do need to work with SIDs, do not manipulate them directly. Instead, use the following Win32 functions.

Function | Description
AllocateAndInitializeSid | Allocates and initializes a SID with the specified number of subauthorities.
ConvertSidToStringSid | Converts a SID to a string format suitable for display, storage, or transport.
ConvertStringSidToSid | Converts a string-format SID to a valid, functional SID.
CopySid | Copies a source SID to a buffer.
EqualPrefixSid | Tests two SID prefix values for equality. A SID prefix is the entire SID except for the last subauthority value.
EqualSid | Tests two SIDs for equality. They must match exactly to be considered equal.
FreeSid | Frees a previously allocated SID by using the AllocateAndInitializeSid function.
GetLengthSid | Retrieves the length of a SID.
GetSidIdentifierAuthority | Retrieves a pointer to a SID's identifier authority.
GetSidLengthRequired | Retrieves the size of the buffer required to store a SID with a specified number of subauthorities.
GetSidSubAuthority | Retrieves a pointer to a specified subauthority in a SID.
GetSidSubAuthorityCount | Retrieves the number of subauthorities in a SID.
InitializeSid | Initializes a SID structure.
IsValidSid | Tests the validity of a SID by verifying that the revision number is within a known range and that the number of subauthorities is less than the maximum.
LookupAccountName | Retrieves the SID corresponding to a specified account name.
LookupAccountSid | Retrieves the account name corresponding to a specified SID.


SID Components

A SID value includes components that provide information about the SID structure and components that uniquely identify a trustee. A SID consists of the following components:

  • The revision level of the SID structure
  • A 48-bit identifier authority value that identifies the authority that issued the SID, such as a Windows NT/Windows 2000 domain
  • A variable number of subauthority or relative identifier (RID) values that uniquely identify the trustee relative to the authority that issued the SID

The combination of the identifier authority value and the subauthority values ensures that no two SIDs will be the same, even if two different SID-issuing authorities issue the same combination of RID values. Each SID-issuing authority issues a given RID only once.

SIDs are stored in binary format in a SID structure. To display a SID, you can call the ConvertSidToStringSid function to convert a binary SID to string format. To convert a SID string back to a valid, functional SID, call the ConvertStringSidToSid function.

These functions use the following standardized string notation for SIDs, which makes it simpler to visualize their components:

S-R-I-S-S...

In this notation, the literal character S identifies the series of digits as a SID, R is the revision level, I is the identifier-authority value, and S... is one or more subauthority values.

The following example uses this notation to display the well-known domain-relative SID of the local Administrators group:

S-1–5-32-544

In this example, the SID has the following components. The constants in parentheses are well-known identifier authority and RID values defined in Winnt.h:

  • A revision level of 1
  • An identifier-authority value of 5 (SECURITY_NT_AUTHORITY)
  • A first subauthority value of 32 (SECURITY_BUILTIN_DOMAIN_RID)
  • A second subauthority value of 544 (DOMAIN_ALIAS_RID_ADMINS)


Well-Known SIDs

Well-known SIDs identify generic groups and generic users. For example, there are well-known SIDs to identify the following groups and users:

  • Everyone or World, which is a group that includes all users.
  • CREATOR_OWNER, which is used as a placeholder in an inheritable ACE. When the ACE is inherited, the system replaces the CREATOR_OWNER SID with the SID of the object's creator.
  • The Administrators group for the built-in domain on the local computer.

There are universal well-known SIDs, which are meaningful on all secure systems using this security model, including operating systems other than Windows NT/Windows 2000. In addition, there are well-known SIDs that are meaningful only on Windows NT/Windows 2000 systems.

The Win32 API defines a set of constants for well-known identifier authority and RID values. You can use these constants to create well-known SIDs. The following example combines the SECURITY_WORLD_SID_AUTHORITY and SECURITY_WORLD_RID constants to show the universal well-known SID for the special group representing all users (Everyone or World):

S-1–1–0

This example uses the string notation for SIDs in which S identifies the string as a SID, the first 1 is the revision level of the SID, and the remaining two digits are the SECURITY_WORLD_SID_AUTHORITY and SECURITY_WORLD_RID constants.

You can use the AllocateAndInitializeSid function to build a SID by combining an identifier authority value with up to eight subauthority values. For example, to determine whether the logged-on user is a member of a particular well-known group, call AllocateAndInitializeSid to build a SID for the well-known group and use the EqualSid function to compare that SID to the group SIDs in the user's access token. For sample code, see Searching for a SID in an Access Token. You must call the FreeSid function to free a SID allocated by AllocateAndInitializeSid.

The remainder of this section contains tables of well-known SIDs and tables of identifier authority and subauthority constants that you can use to build well-known SIDs.

The following are some universal well-known SIDs.

Universal well-known SID | Value | Identifies
Null SID | (S-1–0–0) | A group with no members. This is often used when a SID value is not known.
World | (S-1–1–0) | A group that includes all users.
Local | (S-1–2–0) | Users who log on to terminals locally (physically) connected to the system.
Creator Owner ID | (S-1–3–0) | A security identifier to be replaced by the security identifier of the user who created a new object. This SID is used in inheritable ACEs.
Creator Group ID | (S-1–3–1) | Identifies a security identifier to be replaced by the primary-group SID of the user who created a new object. Use this SID in inheritable ACEs.

The following table lists the predefined identifier authority constants. The first four values are used with universal well-known SIDs; the last value is used with Windows NT/Windows 2000 well-known SIDs.

Identifier authority | Value | SID string prefix
SECURITY_NULL_SID_AUTHORITY | 0 | S-1–0
SECURITY_WORLD_SID_AUTHORITY | 1 | S-1–1
SECURITY_LOCAL_SID_AUTHORITY | 2 | S-1–2
SECURITY_CREATOR_SID_AUTHORITY | 3 | S-1–3
SECURITY_NT_AUTHORITY | 5 | S-1–5

The following RID values are used with universal well-known SIDs. The Identifier authority column shows the prefix of the identifier authority with which you can combine the RID to create a universal well-known SID.

Relative identifier authority | Value | Identifier authority
SECURITY_NULL_RID | 0 | S-1–0
SECURITY_WORLD_RID | 0 | S-1–1
SECURITY_LOCAL_RID | 0 | S-1–2
SECURITY_CREATOR_OWNER_RID | 0 | S-1–3
SECURITY_CREATOR_GROUP_RID | 1 | S-1–3

The SECURITY_NT_AUTHORITY (S-1–5) predefined identifier authority produces SIDs that are not universal but are meaningful only on Windows NT/Windows 2000 installations. You can use the following RID values with SECURITY_NT_AUTHORITY to create well-known SIDs.

Constant | Identifies
SECURITY_DIALUP_RID (S-1–5–1) | Users who log on to terminals using a dial-up modem. This is a group identifier.
SECURITY_NETWORK_RID (S-1–5–2) | Users who can log on across a network. This is a group identifier.
SECURITY_BATCH_RID (S-1–5–3) | Users who can log on using a batch queue facility. This is a group identifier.
SECURITY_INTERACTIVE_RID (S-1–5–4) | Users who can log on for interactive operation. This is a group identifier.
SECURITY_LOGON_IDS_RID (S-1–5–5-X-Y) | A logon session. This is used to ensure that only processes in a given logon session can gain access to the window-station objects for that session. The X and Y values for these SIDs are different for each logon session. The value SECURITY_LOGON_IDS_RID_COUNT is the number of RIDs in this identifier (5-X-Y).
SECURITY_SERVICE_RID (S-1–5–6) | Accounts authorized to log on as a service.
SECURITY_ANONYMOUS_LOGON_RID (S-1–5–7) | Anonymous logon, or null session logon.
SECURITY_PROXY_RID (S-1–5–8) |
SECURITY_ENTERPRISE_CONTROLLERS_RID (S-1–5–9) |
SECURITY_PRINCIPAL_SELF_RID (S-1–5–10) | The PRINCIPAL_SELF security identifier can be used in the ACL of a user or group object. During an access check, the system replaces the SID with the SID of the object. The PRINCIPAL_SELF SID is useful for specifying an inheritable ACE that applies to the user or group object that inherits the ACE. It the only way of representing the SID of a created object in the default security descriptor of the schema.
SECURITY_AUTHENTICATED_USER_RID (S-1–5–11) | The authenticated users.
SECURITY_RESTRICTED_CODE_RID (S-1–5–12) | Restricted code.
SECURITY_TERMINAL_SERVER_RID (S-1-5-13) | Terminal Services: Automatically added to the security token of a user who logs on to a Terminal Server.
SECURITY_LOCAL_SYSTEM_RID (S-1–5–18) | A special account used by the operating system.
SECURITY_NT_NON_UNIQUE (S-1–5–21) |
SECURITY_BUILTIN_DOMAIN_RID (S-1–5–32) | The built-in system domain.

The following RIDs are relative to each domain.

RID | Identifies
DOMAIN_USER_RID_ADMIN | The administrative user account in a domain.
DOMAIN_USER_RID_GUEST | The guest-user account in a domain. Users who do not have an account can automatically log on to this account.
DOMAIN_GROUP_RID_ADMINS | The domain administrators' group. This account exists only on systems running Windows NT Server/Windows 2000 Server.
DOMAIN_GROUP_RID_USERS | A group containing all user accounts in a domain. All users are automatically added to this group.
DOMAIN_GROUP_RID_GUESTS | The guest-group account in a domain.
DOMAIN_GROUP_RID_COMPUTERS | The domain computers' group. All computers in the domain are members of this group.
DOMAIN_GROUP_RID_CONTROLLERS | The domain controllers' group. All DCs in the domain are members of this group.
DOMAIN_GROUP_RID_CERT_ADMINS | The certificate publishers' group. Computers running Certificate Services are members of this group.
DOMAIN_GROUP_RID_SCHEMA_ADMINS | The schema administrators' group. Members of this group can modify the Active Directory schema.
DOMAIN_GROUP_RID_ENTERPRISE_ADMINS | The enterprise administrators' group. Members of this group have full access to all domains in the Active Directory forest. Enterprise administrators are responsible for forest-level operations such as adding or removing new domains.
DOMAIN_GROUP_RID_POLICY_ADMINS | The policy administrators' group.

The following table has examples of domain-relative RIDs you can use to form well-known SIDs for local groups (aliases). For more information about local and global groups, see Local Group Functions and Group Functions.

RID | Identifies
DOMAIN_ALIAS_RID_ADMINS | A local group used for administration of the domain.
DOMAIN_ALIAS_RID_USERS | A local group representing all users in the domain.
DOMAIN_ALIAS_RID_GUESTS | A local group representing guests of the domain.
DOMAIN_ALIAS_RID_POWER_USERS | A local group used to represent a user or set of users who expect to treat a system as if it were their personal computer rather than as a workstation for multiple users.
DOMAIN_ALIAS_RID_ACCOUNT_OPS | A local group existing only on systems running Windows NT Server/Windows 2000 Server. This local group permits control over non-administrator accounts.
DOMAIN_ALIAS_RID_SYSTEM_OPS | A local group existing only on systems running Windows NT Server/Windows 2000 Server. This local group performs system administrative functions, not including security functions. It establishes network shares, controls printers, unlocks workstations, and performs other operations.
DOMAIN_ALIAS_RID_PRINT_OPS | A local group existing only on systems running Windows NT Server/Windows 2000 Server. This local group controls printers and print queues.
DOMAIN_ALIAS_RID_BACKUP_OPS | A local group used for controlling assignment of file backup-and-restore privileges.
DOMAIN_ALIAS_RID_REPLICATOR | A local group responsible for copying security databases from the primary domain controller to the backup domain controllers. These accounts are used only by the system.
DOMAIN_ALIAS_RID_RAS_SERVERS | A local group representing RAS and IAS servers. This group permits access to various attributes of user objects.
DOMAIN_ALIAS_RID_PREW2KCOMPACCESS | A local group existing only on systems running Windows 2000 Server. It provides access rights and privileges equal to anonymous access under Windows NT, which is Everyone access.


Privileges

A privilege is the right of an account, such as a user or group account, to perform various system-related operations on the local computer, such as shutting down the system, loading device drivers, or changing the system time. Privileges differ from access rights in two ways:

  • Privileges control access to system resources and system-related tasks, whereas access rights control access to securable objects.
  • A system administrator assigns privileges to user and group accounts, whereas the system grants or denies access to a securable object based on the access rights granted in the ACEs in the object's DACL.

Each Windows NT/Windows 2000 system has an account database that stores the privileges held by user and group accounts. When a user logs on, the system produces an access token that contains a list of the user's privileges, including those granted to the user or to groups to which the user belongs. Note that the privileges apply only to the local computer; a domain account can have different privileges on different computers.

When the user tries to perform a privileged operation, the system checks the user's access token to determine whether the user holds the necessary privileges, and if so, it checks whether the privileges are enabled. If the user fails these tests, the system does not perform the operation. For a table of the privileges defined by Windows NT/Windows 2000, see Windows NT Privileges.

To determine the privileges held in an access token, call the GetTokenInformation function, which also indicates which privileges are enabled. Most privileges are disabled by default.

Before you can perform a privileged operation, you must first enable the necessary privileges in your access token. To do this, call the OpenThreadToken function to get a handle to your primary or impersonation access token, then call the AdjustTokenPrivileges function to enable the necessary privileges. After performing the privileged operation, call AdjustTokenPrivileges again to disable the privileges. For sample code that enables and disables a token's privileges, see Enabling and Disabling Privileges.

The GetTokenInformation and AdjustTokenPrivileges functions use a TOKEN_PRIVILEGES structure to specify an array of privileges and their attributes. This structure contains an array of LUID_AND_ATTRIBUTES structures, each of which specifies the LUID of a privilege and a set of bit flags that indicate the attributes of the privilege, such as whether the privilege is enabled.

The Win32 API defines a set of string constants to identify the various privileges. These constants are the same on all Windows NT/Windows 2000 systems. However, the functions that get and adjust the privileges in an access token use the LUID type to identify privileges. The LUID values for a privilege can differ from one computer to another, and from one boot to another on the same computer. To get the current LUID that corresponds to one of the string constants, use the LookupPrivilegeValue function. Use the LookupPrivilegeName function to convert a LUID to its corresponding string constant.

The system provides a set of strings that describe each of the Windows NT privileges defined in Winnt.h. These are useful when you need to display a description of a privilege to the user. Use the LookupPrivilegeDisplayName function to retrieve a description string that corresponds to the string constant for a privilege. For example, on systems that use U.S. English, the display name for the SE_SYSTEMTIME_NAME privilege is "Change the system time".

You can use the PrivilegeCheck function to determine whether an access token holds a specified set of privileges. This is useful primarily to server applications that are impersonating a client.

A system administrator can use administrative tools, such as User Manager, to add or remove privileges for user and group accounts. Administrators can programmatically use the Lsa functions to work with privileges. The LsaAddAccountRights and LsaRemoveAccountRights functions add or remove privileges from an account. The LsaEnumerateAccountRights function enumerates the privileges held by a specified account. The LsaEnumerateAccountsWithUserRight function enumerates the accounts that hold a specified privilege.


Audit Generation

C2-level security requirements specify that system administrators must be able to audit security-related events and that access to this audit data must be limited to authorized administrators. The Win32 API provides functions enabling an administrator to monitor security-related events.

The security descriptor for a securable object can have a system access-control list (SACL). A SACL contains access-control entries (ACEs) that specify the types of access attempts that generate audit reports. Each ACE identifies a trustee, a set of access rights, and a set of flags that indicate whether the system generates audit messages for failed access attempts, successful access attempts, or both.

The system writes audit messages to the security event log. For information about accessing the records in a security event log, see Event Logging.

To read or write an object's SACL, a thread must first enable the SE_SECURITY_NAME privilege. For more information, see SACL Access Right.

The Win32 API also provides support for server applications to generate audit messages when a client tries to access a private object. For more information, see Auditing Access To Private Objects.


Securable Objects

A securable object is an object that can have a security descriptor. All named Win32 objects are securable. Some unnamed objects, such as process and thread objects, can have security descriptors too. For most securable objects, you can specify an object's security descriptor in the function call that creates the object. For example, you can specify a security descriptor in the CreateFile and CreateProcess functions.

In addition, the Win32 security functions enable you to get and set the security information for securable objects created on operating systems other than Windows NT/Windows 2000. The Win32 security functions also provide support for using security descriptors with private, application-defined objects. For more information about private securable objects, see Client-Server Access Control.

Each type of securable object defines its own set of specific access rights and its own mapping of generic access rights. For information about the specific and generic access rights for each type of securable object, see the overview for that type of object.

The following table shows the functions to use to manipulate the security information for each type of securable object.

Object type | Security Descriptor Functions
Files or directories on an NTFS file system | GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo
Named pipes Anonymous pipes | GetSecurityInfo, SetSecurityInfo
Console screen buffers | Not supported.
Processes Threads | GetSecurityInfo, SetSecurityInfo
File-mapping objects | GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo
Access tokens | SetKernelObjectSecurity, GetKernelObjectSecurity
Window-management objects (window stations and desktops) | GetSecurityInfo, SetSecurityInfo
Registry keys | GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo
Win32 services | GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo
Local or remote printers | GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo
Network shares | GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo
Interprocess synchronization objects (events, mutexes, semaphores, and waitable timers) | GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo
Job objects | GetNamedSecurityInfo, SetNamedSecurityInfo, GetSecurityInfo, SetSecurityInfo


Using Access Control

The topics in this section demonstrate some practical applications of the Win32 security functions and structures.

For examples that use the older low-level access control functions, see Using Low-Level Access Control.

The topics covered in this section are:

  • Modifying an Object's ACLs
  • Creating a Security Descriptor for a New Object
  • Controlling Child Object Creation
  • Enabling and Disabling Privileges
  • Searching for a SID in an Access Token
  • Finding the Owner of a File Object
  • Taking Object Ownership
  • Converting a Binary SID to String Format
  • Creating a Null DACL


Modifying an Object's ACLs

The following example adds an ACE to an object's DACL. The sample code uses the GetSecurityInfo function to get the existing DACL. Then it fills an EXPLICIT_ACCESS structure with information about an ACE and uses the SetEntriesInAcl function to merge the new ACE with any existing ACEs in the DACL. Finally, the example calls the SetSecurityInfo function to attach the new DACL to the object's security descriptor.

The ACCESS_MODE parameter determines the type of new ACE and how the new ACE is combined with any existing ACEs for the specified trustee.

  • GRANT_ACCESS allows access, combining the specified access rights with any existing access-allowed or access-denied ACEs for the trustee.
  • SET_ACCESS adds an access-allowed ACE that replaces any existing access-allowed or access-denied ACEs for the trustee.
  • DENY_ACCESS denies the specified access rights, combining them with any existing access-allowed or access-denied ACEs for the trustee.
  • REVOKE_ACCESS does not create a new ACE; it removes any existing access-allowed or access-denied ACEs for the trustee.

Similar code can be used to work with a SACL. Specify SACL_SECURITY_INFORMATION in the GetSecurityInfo and SetSecurityInfo functions to get and set the object's SACL. Use the SET_AUDIT_SUCCESS, SET_AUDIT_FAILURE, and REVOKE_ACCESS flags in the AccessMode parameter.

Windows 2000 or later: Use this code to add an object-specific ACE to the DACL of a directory service object. To specify the GUIDs in an object-specific ACE, set the TrusteeForm parameter to TRUSTEE_IS_OBJECTS_AND_NAME or TRUSTEE_IS_OBJECTS_AND_SID and set the pszTrustee parameter to be a pointer to an OBJECTS_AND_NAME or OBJECTS_AND_SID structure.

DWORD AddAceToObjectsSecurityDescriptor (
    HANDLE hObject,             // handle to object
    SE_OBJECT_TYPE ObjectType,  // type of object
    LPTSTR pszTrustee,          // trustee for new ACE
    TRUSTEE_FORM TrusteeForm,   // format of trustee structure
    DWORD dwAccessRights,       // access mask for new ACE
    ACCESS_MODE AccessMode,     // type of ACE
    DWORD dwInheritance         // inheritance flags for new ACE
)
{
DWORD dwRes;
PACL pOldDACL = NULL, pNewDACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
EXPLICIT_ACCESS ea;

if (NULL == hObject)
    return ERROR_INVALID_PARAMETER;

// Get a pointer to the existing DACL.

dwRes = GetSecurityInfo(hObject, ObjectType,
      DACL_SECURITY_INFORMATION,
      NULL, NULL, &pOldDACL, NULL, &pSD);
if (ERROR_SUCCESS != dwRes) {
    printf( "GetSecurityInfo Error %u\n", dwRes );
    goto Cleanup;
}

// Initialize an EXPLICIT_ACCESS structure for the new ACE.

ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = dwAccessRights;
ea.grfAccessMode = AccessMode;
ea.grfInheritance= dwInheritance;
ea.Trustee.TrusteeForm = TrusteeForm;
ea.Trustee.ptstrName = pszTrustee;

// Create a new ACL that merges the new ACE
// into the existing DACL.

dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);
if (ERROR_SUCCESS != dwRes)  {
    printf( "SetEntriesInAcl Error %u\n", dwRes );
    goto Cleanup;
}

// Attach the new ACL as the object's DACL.

dwRes = SetSecurityInfo(hObject, ObjectType,
      DACL_SECURITY_INFORMATION,
      NULL, NULL, pNewDACL, NULL);
if (ERROR_SUCCESS != dwRes)  {
    printf( "SetSecurityInfo Error %u\n", dwRes );
    goto Cleanup;
}

Cleanup:

    if(pSD != NULL)
        LocalFree((HLOCAL) pSD);
    if(pNewDACL != NULL)
        LocalFree((HLOCAL) pNewDACL);

    return dwRes;
}


Creating a Security Descriptor for a New Object

The following example creates a security descriptor for a new registry key using the following process. Similar code can be used to create a security descriptor for other object types.

  • The example fills an array of EXPLICIT_ACCESS structures with the information for two ACEs. One ACE allows read access to everyone; the other ACE allows full access to administrators.
  • The EXPLICIT_ACCESS array is passed to the SetEntriesInAcl function to create a DACL for the security descriptor.
  • After allocating memory for the security descriptor, the example calls the InitializeSecurityDescriptor and SetSecurityDescriptorDacl functions to initialize the security descriptor and attach the DACL.
  • The security descriptor is then stored in a SECURITY_ATTRIBUTES structure and passed to the RegCreateKeyEx function, which attaches the security descriptor to the newly created key.
    #include <windows.h>
#include <stdio.h>
#include <aclapi.h>

void main(int argc, char *argv[]) {

DWORD dwRes, dwDisposition;
PSID pEveryoneSID = NULL, pAdminSID = NULL;
PACL pACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
EXPLICIT_ACCESS ea[2];
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
SECURITY_ATTRIBUTES sa;
LONG lRes;
HKEY hkSub = NULL;

// Create a well-known SID for the Everyone group.

if(! AllocateAndInitializeSid( &SIDAuthWorld, 1,
                 SECURITY_WORLD_RID,
                 0, 0, 0, 0, 0, 0, 0,
                 &pEveryoneSID) ) {
    printf( "AllocateAndInitializeSid Error %u\n", GetLastError() );
    return;
}

// Initialize an EXPLICIT_ACCESS structure for an ACE.
// The ACE will allow Everyone read access to the key.

ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS));
ea[0].grfAccessPermissions = KEY_READ;
ea[0].grfAccessMode = SET_ACCESS;
ea[0].grfInheritance= NO_INHERITANCE;
ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea[0].Trustee.ptstrName  = (LPTSTR) pEveryoneSID;

// Create a SID for the BUILTIN\Administrators group.

if(! AllocateAndInitializeSid( &SIDAuthNT, 2,
                 SECURITY_BUILTIN_DOMAIN_RID,
                 DOMAIN_ALIAS_RID_ADMINS,
                 0, 0, 0, 0, 0, 0,
                 &pAdminSID) ) {
    printf( "AllocateAndInitializeSid Error %u\n", GetLastError() );
    goto Cleanup;
}

// Initialize an EXPLICIT_ACCESS structure for an ACE.
// The ACE will allow the Administrators group full access to the key.

ea[1].grfAccessPermissions = KEY_ALL_ACCESS;
ea[1].grfAccessMode = SET_ACCESS;
ea[1].grfInheritance= NO_INHERITANCE;
ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
ea[1].Trustee.ptstrName  = (LPTSTR) pAdminSID;

// Create a new ACL that contains the new ACEs.

dwRes = SetEntriesInAcl(2, ea, NULL, &pACL);
if (ERROR_SUCCESS != dwRes) {
    printf( "SetEntriesInAcl Error %u\n", GetLastError() );
    goto Cleanup;
}

// Initialize a security descriptor.

pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
                         SECURITY_DESCRIPTOR_MIN_LENGTH);
if (pSD == NULL) {
    printf( "LocalAlloc Error %u\n", GetLastError() );
    goto Cleanup;
}

if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {
    printf( "InitializeSecurityDescriptor Error %u\n",
                            GetLastError() );
    goto Cleanup;
}

// Add the ACL to the security descriptor.

if (!SetSecurityDescriptorDacl(pSD,
        TRUE,     // fDaclPresent flag
        pACL,
        FALSE))   // not a default DACL
{
    printf( "SetSecurityDescriptorDacl Error %u\n", GetLastError() );
    goto Cleanup;
}

// Initialize a security attributes structure.

sa.nLength = sizeof (SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = pSD;
sa.bInheritHandle = FALSE;

// Use the security attributes to set the security descriptor
// when you create a key.

lRes = RegCreateKeyEx(HKEY_CURRENT_USER, "mykey", 0, "", 0,
        KEY_READ | KEY_WRITE, &sa, &hkSub, &dwDisposition);
printf( "RegCreateKeyEx result %u\n", lRes );

Cleanup:

    if (pEveryoneSID)
        FreeSid(pEveryoneSID);
    if (pAdminSID)
        FreeSid(pAdminSID);
    if (pACL)
        LocalFree(pACL);
    if (pSD)
        LocalFree(pSD);
    if (hkSub)
        RegCloseKey(hkSub);
    return;

}


Controlling Child Object Creation

You can use the DACL of a container object to control who is allowed to create child objects within the container. This can be important because the creator of an object is typically assigned as the object's owner, and an object's owner can control access to the object.

The various types of container objects have specific access rights that control the ability to create child objects. For example, a thread must have KEY_CREATE_SUB_KEY access to a registry key in order to create a subkey under the key. The DACL of a registry key can contain ACEs that allow or deny this access right. Similarly, the NTFS file system supports the FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY access rights for controlling the ability to create files or directories in a directory.

Windows 2000 or later: The ADS_RIGHT_DS_CREATE_CHILD access right controls the creation of child objects in a directory service (DS) object. However, DS objects can contain different types of objects, so the system supports a finer granularity of control. You can use object-specific ACEs to allow or deny the right to create a specified type of child object. You can allow a user to create one type of child object while preventing the user from creating other types of child objects.

The following code fragment uses the SetEntriesInAcl function to add an object-specific ACE to an ACL. The ACE grants permission to create a specified type of child object. The grfAccessPermissions member of the EXPLICIT_ACCESS structure is set to ADS_RIGHT_DS_CREATE_CHILD to indicate that the ACE controls the child object creation. The ObjectFlags member of the OBJECTS_AND_SID structure is set to OBJECT_TYPE_PRESENT to indicate that the ObjectType member contains a valid GUID. The GUID identifies a type of child object whose creation is being controlled.

DWORD dwRes;
PACL pOldDACL;
PACL pNewDACL = NULL;
GUID guidChildObjectType;   // GUID of object to control creation of
PSID pTrusteeSID;           // trustee for new ACE
EXPLICIT_ACCESS ea;
OBJECTS_AND_SID ObjectsAndSID;

// Initialize an OBJECTS_AND_SID structure with object type GUIDs and
// the SID of the trustee for the new ACE.

ZeroMemory(&ObjectsAndSID, sizeof(OBJECTS_AND_SID));
ObjectsAndSID.ObjectFlags = OBJECT_TYPE_PRESENT;
ObjectsAndSID.ObjectType = guidChildObjectType;
ObjectsAndSID.InheritedObjectType  = GUID_NULL;
ObjectsAndSID.pSID = pTrusteeSID;

// Initialize an EXPLICIT_ACCESS structure for the new ACE.

ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = ADS_RIGHT_DS_CREATE_CHILD;
ea.grfAccessMode = GRANT_ACCESS;
ea.grfInheritance= NO_INHERITANCE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
ea.Trustee.ptstrName = (LPTSTR) &ObjectsAndSID;

// Create a new ACL that merges the new ACE
// into the existing DACL.

dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);


Enabling and Disabling Privileges

The following example shows how to enable or disable a privilege in an access token. The example calls the LookupPrivilegeValue function to get the LUID that the local system uses to identify the privilege. Then the example calls the AdjustTokenPrivileges function, which either enables or disables the privilege that depends on the value of the bEnablePrivilege parameter.

BOOL SetPrivilege(
    HANDLE hToken,          // access token handle
    LPCTSTR lpszPrivilege,  // name of privilege to enable/disable
    BOOL bEnablePrivilege   // to enable or disable privilege
    )
{
TOKEN_PRIVILEGES tp;
LUID luid;

if ( !LookupPrivilegeValue(
        NULL,            // lookup privilege on local system
        lpszPrivilege,   // privilege to lookup
        &luid ) ) {      // receives LUID of privilege
    printf("LookupPrivilegeValue error: %u\n", GetLastError() );
    return FALSE;
}

tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege)
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
    tp.Privileges[0].Attributes = 0;

// Enable the privilege or disable all privileges.

AdjustTokenPrivileges(
       hToken,
       FALSE,
       &tp,
       sizeof(TOKEN_PRIVILEGES),
       (PTOKEN_PRIVILEGES) NULL,
       (PDWORD) NULL);

// Call GetLastError to determine whether the function succeeded.

if (GetLastError() != ERROR_SUCCESS) {
      printf("AdjustTokenPrivileges failed: %u\n", GetLastError() );
      return FALSE;
}

return TRUE;
}


Searching for a SID in an Access Token

The following example uses the OpenProcessToken and GetTokenInformation functions to get the group memberships in an access token. Then it uses the AllocateAndInitializeSid function to create a SID that identifies the well-known SID of the administrator's group for the local computer. Next, it uses the EqualSid function to compare the well-known SID with the group SIDs from the access token. If the SID is present in the token, the function checks the SIDs attributes to see if it is enabled.

Windows 2000 or later: The CheckTokenMembership function should be used with Windows 2000 and later to determine whether a specified SID is present and enabled in an access token. This function eliminates potential misinterpretations of the active group membership if changes to access tokens are made in future releases.

#define MAX_NAME 256

BOOL SearchTokenGroupsForSID (VOID)
{
DWORD i, dwSize = 0, dwResult = 0;
HANDLE hToken;
PTOKEN_GROUPS pGroupInfo;
SID_NAME_USE SidType;
char lpName[MAX_NAME];
char lpDomain[MAX_NAME];
BYTE sidBuffer[100];
PSID pSID = (PSID)&sidBuffer;
SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;

// Open a handle to the access token for the calling process.

if (!OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hToken )) {
    printf( "OpenProcessToken Error %u\n", GetLastError() );
    return FALSE;
}

// Call GetTokenInformation to get the buffer size.

if(!GetTokenInformation(hToken, TokenGroups, NULL, dwSize, &dwSize)) {
    dwResult = GetLastError();
    if( dwResult != ERROR_INSUFFICIENT_BUFFER ) {
        printf( "GetTokenInformation Error %u\n", dwResult );
        return FALSE;
    }
}

// Allocate the buffer.

pGroupInfo = (PTOKEN_GROUPS) GlobalAlloc( GPTR, dwSize );

// Call GetTokenInformation again to get the group information.

if(! GetTokenInformation(hToken, TokenGroups, pGroupInfo,
                        dwSize, &dwSize ) ) {
    printf( "GetTokenInformation Error %u\n", GetLastError() );
    return FALSE;
   }

// Create a SID for the BUILTIN\Administrators group.

if(! AllocateAndInitializeSid( &SIDAuth, 2,
                 SECURITY_BUILTIN_DOMAIN_RID,
                 DOMAIN_ALIAS_RID_ADMINS,
                 0, 0, 0, 0, 0, 0,
                 &pSID) ) {
    printf( "AllocateAndInitializeSid Error %u\n", GetLastError() );
    return FALSE;
   }

// Loop through the group SIDs looking for the administrator SID.

for(i=0; i<pGroupInfo->GroupCount; i++) {
    if ( EqualSid(pSID, pGroupInfo->Groups[i].Sid) ) {

        // Lookup the account name and print it.

        dwSize = MAX_NAME;
        if( !LookupAccountSid( NULL, pGroupInfo->Groups[i].Sid,
                              lpName, &dwSize, lpDomain,
                              &dwSize, &SidType ) ) {
            dwResult = GetLastError();
            if( dwResult == ERROR_NONE_MAPPED )
                strcpy( lpName, "NONE_MAPPED" );
            else {
                printf("LookupAccountSid Error %u\n", GetLastError());
                return FALSE;
            }
        }
        printf( "Current user is a member of the %s\\%s group\n",
                lpDomain, lpName );

        // Find out if the SID is enabled in the token.
        if (pGroupInfo->Groups[i].Attributes & SE_GROUP_ENABLED)
            printf("The group SID is enabled.\n");
         else if (pGroupInfo->Groups[i].Attributes &
                          SE_GROUP_USE_FOR_DENY_ONLY)
            printf("The group SID is a deny-only SID.\n");
         else
            printf("The group SID is not enabled.\n");
    }
}

if (pSID)
    FreeSid(pSID);
if ( pGroupInfo )
    GlobalFree( pGroupInfo );
return TRUE;
}


Finding the Owner of a File Object

The following example uses the GetSecurityInfo and LookupAccountSid functions to find and print the name of the owner of a file. The file exists in the current working directory on the local server.

#include <stdio.h>
#include <windows.h>
#include <tchar.h>
#include "accctrl.h"
#include "aclapi.h"

int main(int argc, char **argv)
{
DWORD dwRtnCode = 0;
PSID pSidOwner;
BOOL bRtnBool = TRUE;
LPTSTR AcctName, DomainName;
DWORD dwAcctName = 1, dwDomainName = 1;
SID_NAME_USE eUse = SidTypeUnknown;
HANDLE hFile;
PSECURITY_DESCRIPTOR pSD;

// Get the handle of the file object.
hFile = CreateFile(
                  "myfile.txt",
                  GENERIC_READ,
                  FILE_SHARE_READ,
                  NULL,
                  OPEN_EXISTING,
                  FILE_ATTRIBUTE_NORMAL,
                  NULL);

// Check GetLastError for CreateFile error code.
if (hFile == INVALID_HANDLE_VALUE) {
          DWORD dwErrorCode = 0;

          dwErrorCode = GetLastError();
          _tprintf(TEXT("CreateFile error = %d\n"), dwErrorCode);
          return -1;
}

// Allocate memory for the SID structure.
pSidOwner = (PSID)GlobalAlloc(
          GMEM_FIXED,
          sizeof(PSID));

// Allocate memory for the security descriptor structure.
pSD = (PSECURITY_DESCRIPTOR)GlobalAlloc(
          GMEM_FIXED,
          sizeof(PSECURITY_DESCRIPTOR));

// Get the owner SID of the file.
dwRtnCode = GetSecurityInfo(
                  hFile,
                  SE_FILE_OBJECT,
                  OWNER_SECURITY_INFORMATION,
                  &pSidOwner,
                  NULL,
                  NULL,
                  NULL,
                  &pSD);

// Check GetLastError for GetSecurityInfo error condition.
if (dwRtnCode != ERROR_SUCCESS) {
          DWORD dwErrorCode = 0;

          dwErrorCode = GetLastError();
          _tprintf(TEXT("GetSecurityInfo error = %d\n"), dwErrorCode);
          return -1;
}

// First call to LookupAccountSid to get the buffer sizes.
bRtnBool = LookupAccountSid(
                  NULL,           // local computer
                  pSidOwner,
                  AcctName,
                  (LPDWORD)&dwAcctName,
                  DomainName,
                  (LPDWORD)&dwDomainName,
                  &eUse);

// Reallocate memory for the buffers.
AcctName = (char *)GlobalAlloc(
          GMEM_FIXED,
          dwAcctName);

// Check GetLastError for GlobalAlloc error condition.
if (AcctName == NULL) {
          DWORD dwErrorCode = 0;

          dwErrorCode = GetLastError();
          _tprintf(TEXT("GlobalAlloc error = %d\n"), dwErrorCode);
          return -1;
}

    DomainName = (char *)GlobalAlloc(
           GMEM_FIXED,
           dwDomainName);

    // Check GetLastError for GlobalAlloc error condition.
    if (DomainName == NULL) {
          DWORD dwErrorCode = 0;

          dwErrorCode = GetLastError();
          _tprintf(TEXT("GlobalAlloc error = %d\n"), dwErrorCode);
          return -1;

    }

    // Second call to LookupAccountSid to get the account name.
    bRtnBool = LookupAccountSid(
          NULL,                          // name of local or remote computer
          pSidOwner,                     // security identifier
          AcctName,                      // account name buffer
          (LPDWORD)&dwAcctName,          // size of account name buffer
          DomainName,                    // domain name
          (LPDWORD)&dwDomainName,        // size of domain name buffer
          &eUse);                        // SID type

    // Check GetLastError for LookupAccountSid error condition.
    if (bRtnBool == FALSE) {
          DWORD dwErrorCode = 0;

          dwErrorCode = GetLastError();

          if (dwErrorCode == ERROR_NONE_MAPPED)
              _tprintf(TEXT("Account owner not found for specified SID.\n"));
          else
              _tprintf(TEXT("Error in LookupAccountSid.\n"));
          return -1;

    } else if (bRtnBool == TRUE)

        // Print the account name.
        _tprintf(TEXT("Account owner = %s\n"), AcctName);

    return 0;
}


Taking Object Ownership

The following example tries to change the DACL of a file object. This will succeed only if the caller has WRITE_DAC access to the object or is the owner of the object. If the initial attempt to change the DACL fails, an administrator can take ownership of the object. To give the administrator ownership, the example enables the SE_TAKE_OWNERSHIP_NAME privilege in the caller's access token, and makes the local system's Administrators group the owner of the object. If the caller is a member of the Administrators group, the code will then be able to change the object's DACL.

To enable and disable privileges, this example uses the SetPrivilege sample function described in Enabling and Disabling Privileges.

BOOL TakeOwnership(LPTSTR lpszOwnFile)
{

HANDLE hToken;
BYTE sidBuffer[100];
PSID pSID = (PSID)&sidBuffer;
SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
DWORD dwRes;

// Try to remove the object's DACL.

dwRes = SetNamedSecurityInfo(
    lpszOwnFile,                 // name of the object
    SE_FILE_OBJECT,              // type of object
    DACL_SECURITY_INFORMATION,   // change only the object's DACL
    NULL, NULL,                  // don't change owner or group
    NULL,                        // no DACL specified - allows everyone access
    NULL);                       // don't change SACL

if (dwRes == ERROR_SUCCESS)
    return TRUE;
else if (dwRes != ERROR_ACCESS_DENIED) {
    printf("First SetNamedSecurityInfo call failed: %u\n", dwRes);
    return FALSE;
}

// If the preceding call failed because access was denied,
// enable the SE_TAKE_OWNERSHIP_NAME privilege, create a SID for
// the Administrators group, take ownership of the object, and
// disable the privilege. Then try again to set the object's DACL.

// Open a handle to the access token for the calling process.
if (!OpenProcessToken(GetCurrentProcess(),
                      TOKEN_ADJUST_PRIVILEGES, &hToken)) {
      printf("OpenProcessToken failed: %u\n", GetLastError());
      return FALSE;
}

// Enable the SE_TAKE_OWNERSHIP_NAME privilege.
if (!SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, TRUE)) {
    printf("You must be logged on as Administrator.\n");
    return FALSE;
}

// Create a SID for the BUILTIN\Administrators group.
if (!AllocateAndInitializeSid(&SIDAuth, 2,
                 SECURITY_BUILTIN_DOMAIN_RID,
                 DOMAIN_ALIAS_RID_ADMINS,
                 0, 0, 0, 0, 0, 0,
                 &pSID)) {
    printf("AllocateAndInitializeSid error %u\n", GetLastError());
    return FALSE;
}

// Set the owner in the object's security descriptor.
dwRes = SetNamedSecurityInfo(
    lpszOwnFile,                 // name of the object
    SE_FILE_OBJECT,              // type of object
    OWNER_SECURITY_INFORMATION,  // change only the object's owner
    pSID,                        // SID of Administrator group
    NULL, NULL, NULL);

if (pSID)
    FreeSid(pSID);

if (dwRes != ERROR_SUCCESS) {
    printf("Could not set owner. Error: %u\n", dwRes);
    return FALSE;
}

// Disable the SE_TAKE_OWNERSHIP_NAME privilege.
if (!SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, FALSE)) {
    printf("You must be logged on as Administrator.\n");
    return FALSE;
}

// Try again to remove the object's DACL, now that we are the owner.
dwRes = SetNamedSecurityInfo(
    lpszOwnFile,                 // name of the object
    SE_FILE_OBJECT,              // type of object
    DACL_SECURITY_INFORMATION,   // change only the object's DACL
    NULL, NULL,                  // don't change owner or group
    NULL,                        // no DACL specified - allows everyone access
    NULL);                       // don't change SACL

if (dwRes == ERROR_SUCCESS)
    return TRUE;

printf("Second SetNamedSecurityInfo call failed: %u\n", dwRes);
return FALSE;
}


Converting a Binary SID to String Format

Windows 2000 provides the ConvertSidToStringSid and ConvertStringSidToSid functions for converting a SID to and from string format. For a description of the SID string format, see SID Components.

On earlier versions of Windows NT, use the following sample code to convert a SID to string format.

BOOL GetTextualSid(
    PSID pSid,            // binary Sid
    LPTSTR TextualSid,    // buffer for Textual representation of Sid
    LPDWORD lpdwBufferLen // required/provided TextualSid buffersize
    )
{
    PSID_IDENTIFIER_AUTHORITY psia;
    DWORD dwSubAuthorities;
    DWORD dwSidRev=SID_REVISION;
    DWORD dwCounter;
    DWORD dwSidSize;

    // Validate the binary SID.

    if(!IsValidSid(pSid)) return FALSE;

    // Get the identifier authority value from the SID.

    psia = GetSidIdentifierAuthority(pSid);

    // Get the number of subauthorities in the SID.

    dwSubAuthorities = *GetSidSubAuthorityCount(pSid);

    // Compute the buffer length.
    // S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL

    dwSidSize=(15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);

    // Check input buffer length.
    // If too small, indicate the proper size and set last error.

    if (*lpdwBufferLen < dwSidSize)
    {
        *lpdwBufferLen = dwSidSize;
        SetLastError(ERROR_INSUFFICIENT_BUFFER);
        return FALSE;
    }

    // Add 'S' prefix and revision number to the string.

    dwSidSize=wsprintf(TextualSid, TEXT("S-%lu-"), dwSidRev );

    // Add SID identifier authority to the string.

    if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) )
    {
        dwSidSize+=wsprintf(TextualSid + lstrlen(TextualSid),
                    TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
                    (USHORT)psia->Value[0],
                    (USHORT)psia->Value[1],
                    (USHORT)psia->Value[2],
                    (USHORT)psia->Value[3],
                    (USHORT)psia->Value[4],
                    (USHORT)psia->Value[5]);
    }
    else
    {
        dwSidSize+=wsprintf(TextualSid + lstrlen(TextualSid),
                    TEXT("%lu"),
                    (ULONG)(psia->Value[5]      )   +
                    (ULONG)(psia->Value[4] <<  8)   +
                    (ULONG)(psia->Value[3] << 16)   +
                    (ULONG)(psia->Value[2] << 24)   );
    }

    // Add SID subauthorities to the string.
    //
    for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++)
    {
        dwSidSize+=wsprintf(TextualSid + dwSidSize, TEXT("-%lu"),
                    *GetSidSubAuthority(pSid, dwCounter) );
    }

    return TRUE;
}


Creating a Null DACL

The following example creates a mutex with a null DACL.

If you are creating one of these objects in an application and the object will be shared with a service, you could also use a null DACL to grant everyone access. As an alternative, you could add an access-control entry (ACE) to the DACL that grants access to the user account that the service is running under. This would restrict access to the object to the service.

PSECURITY_DESCRIPTOR pSD;
SECURITY_ATTRIBUTES sa;

pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
      SECURITY_DESCRIPTOR_MIN_LENGTH);

if (pSD == NULL)
   Error(...);

if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
   Error(...);

// Add a null DACL to the security descriptor.
if (!SetSecurityDescriptorDacl(pSD, TRUE, (PACL) NULL, FALSE))
    Error(...);

sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = pSD;
sa.bInheritHandle = TRUE;
mutex = CreateMutex(&sa, FALSE, "SOMENAME");


Access Control Reference

The Win32 API provides two sets of functions for working with security descriptors and access-control lists (ACLs).

  • Functions for Microsoft Windows NT version 4.0 and later provide an interface for working with security descriptors and access-control lists (ACLs). For Microsoft Windows 2000, these functions have been enhanced to support object-specific ACEs, directory service (DS) objects, and automatic inheritance. These functions are described in this overview.
  • Low-level functions for manipulating security descriptors, ACLs, and ACEs. You must use these functions if your application needs to be compatible with Windows NT versions 3.51 and earlier. Windows 2000 provides additional low-level functions for working with object-specific ACEs. For more information, see Low-Level Access Control.

Windows 2000 support both sets. In general, you should use one set of access-control functions throughout your application.

All versions of Windows NT/Windows 2000 support a single set of security functions for working with privileges, access tokens, and SIDs.

The following elements are used with access control.

  • Access Control Functions
  • Access Control Structures
  • Access Control Enumeration Types
  • Windows NT Privileges
  • Security Descriptor Definition Language


Access Control Functions

The following functions are used with access tokens.

Function | Description
AdjustTokenGroups | Changes the group information in an access token.
AdjustTokenPrivileges | Enables or disables the privileges in an access token. It does not grant new privileges or revoke existing ones.
CheckTokenMembership | Determines whether a specified SID is enabled in a specified access token.
CreateRestrictedToken | Creates a new token that is a restricted version of an existing token. The restricted token can have disabled SIDs, deleted privileges, and a list of restricting SIDs.
DuplicateToken | Creates a new impersonation token that duplicates an existing token.
DuplicateTokenEx | Creates a new primary token or impersonation token that duplicates an existing token.
GetTokenInformation | Retrieves information about a token.
IsTokenRestricted | Determines whether a token has a list of restricting SIDs.
OpenProcessToken | Retrieves a handle to the primary access token for a process.
OpenThreadToken | Retrieves a handle to the impersonation access token for a thread.
SetThreadToken | Assigns or removes an impersonation token for a thread.
SetTokenInformation | Changes a token's owner, primary group, or default DACL.

The following functions are used with privileges.

Function | Description
AllocateLocallyUniqueId | Allocates a locally unique identifier (LUID).
LookupPrivilegeDisplayName | Retrieves a displayable name representing a specified privilege.
LookupPrivilegeName | Retrieves the name corresponding to the privilege represented on a specific system by a specified LUID.
LookupPrivilegeValue | Retrieves the LUID used on a specified system to locally represent the specified privilege name.

The following functions are used with security identifiers (SIDs).

Function | Description
AllocateAndInitializeSid | Allocates and initializes a SID with the specified number of subauthorities.
ConvertSidToStringSid | Converts a SID to a string format suitable for display, storage, or transport.
ConvertStringSidToSid | Converts a string-format SID to a valid, functional SID.
CopySid | Copies a source SID to a buffer.
EqualPrefixSid | Tests two SID prefix values for equality. A SID prefix is the entire SID except for the last subauthority value.
EqualSid | Tests two SIDs for equality. They must match exactly to be considered equal.
FreeSid | Frees a SID previously allocated by using the AllocateAndInitializeSid function.
GetLengthSid | Retrieves the length of a SID.
GetSidIdentifierAuthority | Retrieves a pointer to a SID's identifier authority.
GetSidLengthRequired | Retrieves the size of the buffer required to store a SID with a specified number of subauthorities.
GetSidSubAuthority | Retrieves a pointer to a specified subauthority in a SID.
GetSidSubAuthorityCount | Retrieves the number of subauthorities in a SID.
InitializeSid | Initializes a SID structure.
IsValidSid | Tests the validity of a SID by verifying that the revision number is within a known range and that the number of subauthorities is less than the maximum.
LookupAccountName | Retrieves the SID corresponding to a specified account name.
LookupAccountSid | Retrieves the account name corresponding to a specified SID.

The following functions are used with security descriptors.

Function | Description
ConvertSecurityDescriptorToStringSecurityDescriptor | Converts a security descriptor to a string format.
ConvertStringSecurityDescriptorToSecurityDescriptor | Converts a string-format security descriptor into a valid, functional security descriptor.
GetNamedSecurityInfo | Retrieves a copy of the security descriptor for an object specified by name.
GetSecurityDescriptorControl | Retrieves a security descriptor's control and revision information.
GetSecurityDescriptorRMControl | Retrieves the resource manager control bits.
GetSecurityInfo | Retrieves a copy of the security descriptor for an object specified by a handle.
SetNamedSecurityInfo | Sets specified security information in the security descriptor of a specified object.
SetSecurityDescriptorControl | Sets the control bits of a security descriptor.
SetSecurityDescriptorRMControl | Sets the resource manager control bits.
SetSecurityInfo | Sets specified security information in the security descriptor of a specified object.

The following functions are used to manipulate access-control lists.

Function | Description
BuildExplicitAccessWithName | Initializes an EXPLICIT_ACCESS structure.
BuildTrusteeWithName | Initializes a TRUSTEE structure. The caller specifies the trustee name.
BuildTrusteeWithObjectsAndName | Initializes a TRUSTEE structure with the specified object-specific ACE information.
BuildTrusteeWithObjectsAndSid | Initializes a TRUSTEE structure with the specified object-specific ACE information.
BuildTrusteeWithSid | initializes a TRUSTEE structure. The caller specifies the security identifier of the trustee.
GetAuditedPermissionsFromAcl | Retrieves the audited access rights for a specified trustee.
GetEffectiveRightsFromAcl | Retrieves the effective access rights that an ACL grants to a specified trustee.
GetExplicitEntriesFromAcl | Retrieves an array of structures that describe the ACEs in an ACL.
GetTrusteeForm | Retrieves the trustee form from a TRUSTEE structure.
GetTrusteeName | Retrieves the trustee name from a TRUSTEE structure.
GetTrusteeType | Retrieves the trustee type from a TRUSTEE structure.
SetEntriesInAcl | Creates a new ACL by merging new access-control or audit-control information into an existing ACL.

Obsolete

The following access-control functions are obsolete. Do not use them.

  • BuildImpersonateExplicitAccessWithName
  • BuildImpersonateTrustee
  • GetMultipleTrustee
  • GetMultipleTrusteeOperation


AdjustTokenGroups

The AdjustTokenGroups function adjusts groups in the specified access token. Access to TOKEN_ADJUST_GROUPS is required to enable or disable groups in an access token.

BOOL AdjustTokenGroups(
  HANDLE TokenHandle,          // handle to token
  BOOL ResetToDefault,         // default settings
  PTOKEN_GROUPS NewState,      // new group information
  DWORD BufferLength,          // previous information size
  PTOKEN_GROUPS PreviousState, // previous information
  PDWORD ReturnLength          // required buffer size
);

Parameters

TokenHandle
[in] Handle to the access token containing the groups to be modified. The handle must have TOKEN_ADJUST_GROUPS access to the token. If the PreviousState parameter is not NULL, the handle must also have TOKEN_QUERY access.
ResetToDefault
[in] Specifies whether the groups are to be set to their default enabled and disabled states. If this value is TRUE, the groups are set to their default states and the NewState parameter is ignored. If this value is FALSE, the groups are set according to the information pointed to by the NewState parameter.
NewState
[in] Pointer to a TOKEN_GROUPS structure containing the groups whose states are to be set. If the ResetToDefault parameter is FALSE, the function sets each of the groups to the value of that group's SE_GROUP_ENABLED attribute in the TOKEN_GROUPS structure. If ResetToDefault is TRUE, this parameter is ignored.
BufferLength
[in] Specifies the size, in bytes, of the buffer pointed to by the PreviousState parameter. This parameter can be zero if the PreviousState parameter is NULL.
PreviousState
[out] Pointer to a buffer that receives a TOKEN_GROUPS structure containing the previous state of any groups the function modifies. This parameter can be NULL.

If a buffer is specified but it does not contain enough space to receive the complete list of modified groups, no group states are changed and the function fails. In this case, the function sets the variable pointed to by the ReturnLength parameter to the number of bytes required to hold the complete list of modified groups.

ReturnLength
[out] Pointer to a variable that receives the actual number of bytes needed for the buffer pointed to by the PreviousState parameter. This parameter can be NULL and is ignored if PreviousState is NULL.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The information retrieved in the PreviousState parameter is formatted as a TOKEN_GROUPS structure. This means a pointer to the buffer can be passed as the NewState parameter in a subsequent call to the AdjustTokenGroups function, restoring the original state of the groups.

The NewState parameter can list groups to be changed that are not present in the access token. This does not affect the successful modification of the groups in the token.

Mandatory groups cannot be disabled. They are identified by the SE_GROUP_MANDATORY attribute in the TOKEN_GROUPS structure. If an attempt is made to disable any mandatory groups, AdjustTokenGroups fails and leaves the state of all groups unchanged.

You cannot enable a group that has the SE_GROUP_USE_FOR_DENY_ONLY attribute.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, AdjustTokenPrivileges, GetTokenInformation, OpenProcessToken, OpenThreadToken, SetTokenInformation, TOKEN_GROUPS


AdjustTokenPrivileges

The AdjustTokenPrivileges function enables or disables privileges in the specified access token. Enabling or disabling privileges in an access token requires TOKEN_ADJUST_PRIVILEGES access.

BOOL AdjustTokenPrivileges(
  HANDLE TokenHandle,              // handle to token
  BOOL DisableAllPrivileges,       // disabling option
  PTOKEN_PRIVILEGES NewState,      // privilege information
  DWORD BufferLength,              // size of buffer
  PTOKEN_PRIVILEGES PreviousState, // original state buffer
  PDWORD ReturnLength              // required buffer size
);

Parameters

TokenHandle
[in] Handle to the access token that contains the privileges to be modified. The handle must have TOKEN_ADJUST_PRIVILEGES access to the token. If the PreviousState parameter is not NULL, the handle must also have TOKEN_QUERY access.
DisableAllPrivileges
[in] Specifies whether the function disables all of the token's privileges. If this value is TRUE, the function disables all privileges and ignores the NewState parameter. If it is FALSE, the function modifies privileges based on the information pointed to by the NewState parameter.
NewState
[in] Pointer to a TOKEN_PRIVILEGES structure that specifies an array of privileges and their attributes. If the DisableAllPrivileges parameter is FALSE, AdjustTokenPrivileges enables or disables these privileges for the token. If you set the SE_PRIVILEGE_ENABLED attribute for a privilege, the function enables that privilege; otherwise, it disables the privilege. If DisableAllPrivileges is TRUE, the function ignores this parameter.
BufferLength
[in] Specifies the size, in bytes, of the buffer pointed to by the PreviousState parameter. This parameter can be zero if the PreviousState parameter is NULL.
PreviousState
[out] Pointer to a buffer that the function fills with a TOKEN_PRIVILEGES structure that contains the previous state of any privileges that the function modifies. This parameter can be NULL.

If you specify a buffer that is too small to receive the complete list of modified privileges, the function fails and does not adjust any privileges. In this case, the function sets the variable pointed to by the ReturnLength parameter to the number of bytes required to hold the complete list of modified privileges.

ReturnLength
[out] Pointer to a variable that receives the required size, in bytes, of the buffer pointed to by the PreviousState parameter. This parameter can be NULL if PreviousState is NULL.

Return Values

If the function succeeds, the return value is nonzero. To determine whether the function adjusted all of the specified privileges, call GetLastError, which returns one of the following values when the function succeeds:

Value | Description
ERROR_SUCCESS | The function adjusted all specified privileges.
ERROR_NOT_ALL_ASSIGNED | The token does not have one or more of the privileges specified in the NewState parameter. The function may succeed with this error value even if no privileges were adjusted. The PreviousState parameter indicates the privileges that were adjusted.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The AdjustTokenPrivileges function cannot add new privileges to the access token. It can only enable or disable the token's existing privileges. To determine the token's privileges, call the GetTokenInformation function.

Note The NewState parameter can specify privileges that the token does not have, without causing the function to fail. In this case, the function adjusts the privileges that the token does have and ignores the other privileges so that the function succeeds. Call the GetLastError function to determine whether the function adjusted all of the specified privileges. The PreviousState parameter indicates the privileges that were adjusted.

The PreviousState parameter retrieves a TOKEN_PRIVILEGES structure that contains the original state of the adjusted privileges. To restore the original state, pass the PreviousState pointer as the NewState parameter in a subsequent call to the AdjustTokenPrivileges function

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, AdjustTokenGroups, GetTokenInformation, OpenProcessToken, OpenThreadToken, SetTokenInformation, TOKEN_PRIVILEGES


AllocateAndInitializeSid

The AllocateAndInitializeSid function allocates and initializes a security identifier (SID) with up to eight subauthorities.

BOOL AllocateAndInitializeSid(
  PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, // authority
  BYTE nSubAuthorityCount,                        // count of subauthorities
  DWORD dwSubAuthority0,                          // subauthority 0
  DWORD dwSubAuthority1,                          // subauthority 1
  DWORD dwSubAuthority2,                          // subauthority 2
  DWORD dwSubAuthority3,                          // subauthority 3
  DWORD dwSubAuthority4,                          // subauthority 4
  DWORD dwSubAuthority5,                          // subauthority 5
  DWORD dwSubAuthority6,                          // subauthority 6
  DWORD dwSubAuthority7,                          // subauthority 7
  PSID *pSid                                      // SID
);

Parameters

pIdentifierAuthority
[in] Pointer to a SID_IDENTIFIER_AUTHORITY structure, giving the top-level identifier authority value to set in the SID.
nSubAuthorityCount
[in] Specifies the number of subauthorities to place in the SID. This parameter also identifies how many of the subauthority parameters have meaningful values. This parameter must contain a value from 1 to 8.

For example, a value of 3 indicates that the subauthority values specified by the dwSubAuthority0, dwSubAuthority1, and dwSubAuthority2 parameters have meaningful values and to ignore the remainder.

dwSubAuthority0
[in] Subauthority value to place in the SID.
dwSubAuthority1
[in] Subauthority value to place in the SID.
dwSubAuthority2
[in] Subauthority value to place in the SID.
dwSubAuthority3
[in] Subauthority value to place in the SID.
dwSubAuthority4
[in] Subauthority value to place in the SID.
dwSubAuthority5
[in] Subauthority value to place in the SID.
dwSubAuthority6
[in] Subauthority value to place in the SID.
dwSubAuthority7
[in] Subauthority value to place in the SID.
pSid
[out] Pointer to a variable that receives the pointer to the allocated and initialized SID structure.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

A SID allocated with the AllocateAndInitializeSid function must be freed by using the FreeSid function.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, Well-Known SIDs, FreeSid, GetSidIdentifierAuthority, InitializeSid, SID_IDENTIFIER_AUTHORITY


AllocateLocallyUniqueId

The AllocateLocallyUniqueId function allocates a locally unique identifier (LUID).

BOOL AllocateLocallyUniqueId(
  PLUID Luid     // locally unique identifier
);

Parameters

Luid
[out] Pointer to a buffer that receives the allocated LUID.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

An LUID is unique only within a single session. The same LUID value can be used on different computers or on the same computer after it has been restarted.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, LookupPrivilegeValue


BuildExplicitAccessWithName

The BuildExplicitAccessWithName function initializes an EXPLICIT_ACCESS structure with data specified by the caller. The trustee is identified by a name string.

VOID BuildExplicitAccessWithName(
  PEXPLICIT_ACCESS pExplicitAccess,  // structure
  LPTSTR pTrusteeName,               // trustee name
  DWORD AccessPermissions,           // access mask
  ACCESS_MODE AccessMode,            // access mode
  DWORD Inheritance                  // inheritance type
);

Parameters

pExplicitAccess
[in, out] Pointer to an EXPLICIT_ACCESS structure to initialize. The BuildExplicitAccessWithName function does not allocate any memory. If this parameter is NULL, the function does nothing.
pTrusteeName
[in] Pointer to a null-terminated string that contains the name of the trustee for the ptstrName member of the TRUSTEE structure. The BuildExplicitAccessWithName function sets the other members of the TRUSTEE structure as follows.
Member | Value
pMultipleTrustee | NULL
MultipleTrusteeOperation | NO_MULTIPLE_TRUSTEE
TrusteeForm | TRUSTEE_IS_NAME
TrusteeType | TRUSTEE_IS_UNKNOWN

AccessPermissions
[in] Specifies an access mask for the grfAccessPermissions member of the EXPLICIT_ACCESS structure. The mask is a set of bit flags that use the ACCESS_MASK format to specify the access rights that an ACE allows, denies, or audits for the trustee. The functions that use the EXPLICIT_ACCESS structure do not convert, interpret, or validate the bits in this mask.
AccessMode
[in] Specifies an access mode for the grfAccessMode member of the EXPLICIT_ACCESS structure. The access mode indicates whether the ACE allows, denies, or audits the specified rights. For a DACL, this parameter can be one of the values from the ACCESS_MODE enumeration. For a SACL, this parameter can be a combination of ACCESS_MODE values.
Inheritance
[in] Specifies an inheritance type for the grfInheritance member of the EXPLICIT_ACCESS structure. This value is a set of bit flags that determine whether other containers or objects can inherit the ACE from the primary object to which the ACL is attached. The value of this member corresponds to the inheritance portion (low-order byte) of the AceFlags member of the ACE_HEADER structure. This parameter can be NO_INHERITANCE to indicate that the ACE is not inheritable, or it can be a combination of the following values.
Value | Meaning
CONTAINER_INHERIT_ACE | Other containers that are contained by the primary object inherit the ACE.
INHERIT_ONLY_ACE | The ACE does not apply to the primary object to which the ACL is attached, but objects contained by the primary object inherit the ACE.
NO_PROPAGATE_INHERIT_ACE | The OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE flags are not propagated to an inherited ACE.
OBJECT_INHERIT_ACE | Noncontainer objects contained by the primary object inherit the ACE.
SUB_CONTAINERS_AND_OBJECTS_INHERIT | Both containers and noncontainer objects that are contained by the primary object inherit the ACE. This flag corresponds to the combination of the CONTAINER_INHERIT_ACE and OBJECT_INHERIT_ACE flags.
SUB_CONTAINERS_ONLY_INHERIT | Other containers that are contained by the primary object inherit the ACE. This flag corresponds to the CONTAINER_INHERIT_ACE flag.
SUB_OBJECTS_ONLY_INHERIT | Noncontainer objects contained by the primary object inherit the ACE. This flag corresponds to the OBJECT_INHERIT_ACE flag.

Return Values

This function does not return a value.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Aclapi.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Access Control Overview, Access Control Functions, ACE, ACL, EXPLICIT_ACCESS, GetExplicitEntriesFromAcl, SetEntriesInAcl, TRUSTEE


BuildImpersonateExplicitAccessWithName

Obsolete; do not use.

See Also

Access Control Overview, Access Control Functions


BuildImpersonateTrustee

Obsolete; do not use.

See Also

Access Control Overview, Access Control Functions


BuildTrusteeWithName

The BuildTrusteeWithName function initializes a TRUSTEE structure. The caller specifies the trustee name. The function sets other members of the structure to default values.

VOID BuildTrusteeWithName(
  PTRUSTEE pTrustee,  // structure
  LPTSTR pName        // trustee name
);

Parameters

pTrustee
[in, out] Pointer to a TRUSTEE structure to initialize. The BuildTrusteeWithName function does not allocate any memory. If this parameter is NULL, the function does nothing.
pName
[in] Pointer to a null-terminated string that contains the name of the trustee for the ptstrName member of the TRUSTEE structure. The BuildTrusteeWithName function sets the other members of the TRUSTEE structure as follows.
Member | Value
pMultipleTrustee | NULL
MultipleTrusteeOperation | NO_MULTIPLE_TRUSTEE
TrusteeForm | TRUSTEE_IS_NAME
TrusteeType | TRUSTEE_IS_UNKNOWN

Return Values

This function does not return a value.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Aclapi.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Access Control Overview, Access Control Functions, BuildTrusteeWithObjectsAndSid, BuildTrusteeWithObjectsAndName, BuildTrusteeWithSid, TRUSTEE


BuildTrusteeWithObjectsAndName

The BuildTrusteeWithObjectsAndName function initializes a TRUSTEE structure with the object-specific ACE information, initializing the remaining members of the structure to default values. The caller also specifies the name of the trustee.

VOID BuildTrusteeWithObjectsAndName(
  PTRUSTEE pTrustee,
  POBJECTS_AND_NAME pObjName,
  SE_OBJECT_TYPE ObjectType,
  LPSTR ObjectTypeName,
  LPSTR InheritedObjectTypeName,
  LPSTR Name
);

Parameters

pTrustee
[in, out] Pointer to a TRUSTEE structure that will be initialized by this function. If the value of this parameter is NULL, the function does nothing.
pObjName
[in] Pointer to an OBJECTS_AND_NAME structure that contains information about the trustee and the securable object.
ObjectType
[in] Pointer to an SE_OBJECT_TYPE structure that contains information about the type of securable object.
ObjectTypeName
[in] Pointer to a string that specifies the name corresponding to the ObjectType GUID to be added to the TRUSTEE structure returned in pTrustee. This function determines the ObjectType GUID corresponding to this name.
InheritedObjectTypeName
[in] Pointer to a string that specifies the name corresponding to the InheritedObjectType GUID to be added to the TRUSTEE structure returned in pTrustee. This function determines the InheritedObjectType GUID corresponding to this name.
Name
[in] Pointer to a string that specifies the name used to identify the trustee.

Return Values

This function does not return a value.

Remarks

This function does not allocate memory for the TRUSTEE, OBJECTS_AND_NAME, and SE_OBJECT_TYPE structures.

For more information on object-specific ACEs, refer to Object-Specific ACEs.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Aclapi.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows 2000.

See Also

Access Control Overview, Access Control Functions, BuildTrusteeWithName, BuildTrusteeWithSid, BuildTrusteeWithObjectsAndSid, TRUSTEE, OBJECTS_AND_NAME, SE_OBJECT_TYPE, Object-Specific ACEs


BuildTrusteeWithObjectsAndSid

The BuildTrusteeWithObjectsAndSid function initializes a TRUSTEE structure with the object-specific ACE information, initializing the remaining members of the structure to default values. The caller also specifies the SID of the trustee.

VOID BuildTrusteeWithObjectsAndSid(
  PTRUSTEE pTrustee,
  POBJECTS_AND_SID pObjSid,
  GUID *pObjectGuid,
  GUID *pInheritedObjectGuid,
  PSID pSid
);

Parameters

pTrustee
[in, out] Pointer to a TRUSTEE structure to initialize. The BuildTrusteeWithSid function does not allocate any memory. If this parameter is NULL, the function does nothing.
pObjSid
[in] Pointer to an OBJECTS_AND_SID structure that contains information about the trustee and the securable object.
pObjectGuid
[in] Pointer to a GUID structure that describes the ObjectType GUID to be added to the TRUSTEE structure.
pInheritedObjectGuid
[in] Pointer to a GUID structure that describes the InheritedObjectType GUID to be added to the TRUSTEE structure.
pSid
[in] Pointer to a SID structure that identifies the trustee.

Return Values

This function does not return a value.

Remarks

This function does not allocate memory for the TRUSTEE, OBJECTS_AND_NAME, and SE_OBJECT_TYPE structures.

For more information on object-specific ACEs, refer to Object-Specific ACEs.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Aclapi.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows 2000.

See Also

Access Control Overview, Access Control Functions, BuildTrusteeWithName, BuildTrusteeWithObjectsAndName, BuildTrusteeWithSid, TRUSTEE, SID, OBJECTS_AND_NAME, SE_OBJECT_TYPE, Object-Specific ACEs


BuildTrusteeWithSid

The BuildTrusteeWithSid function initializes a TRUSTEE structure. The caller specifies the security identifier (SID) of the trustee. The function sets other members of the structure to default values and does not look up the name associated with the SID.

VOID BuildTrusteeWithSid(
  PTRUSTEE pTrustee,  // structure
  PSID pSid           // trustee name
);

Parameters

pTrustee
[in, out] Pointer to a TRUSTEE structure to initialize. The BuildTrusteeWithSid function does not allocate any memory. If this parameter is NULL, the function does nothing.
pSid
[in] Pointer to a SID structure that identifies the trustee. The BuildTrusteeWithSid function assigns this pointer to the ptstrName member of the TRUSTEE structure. The function sets the other members of the TRUSTEE structure as follows.
Member | Value
pMultipleTrustee | NULL
MultipleTrusteeOperation | NO_MULTIPLE_TRUSTEE
TrusteeForm | TRUSTEE_IS_SID
TrusteeType | TRUSTEE_IS_UNKNOWN

Return Values

This function does not return a value.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Aclapi.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Access Control Overview, Access Control Functions, BuildTrusteeWithName, BuildTrusteeWithObjectsAndName, BuildTrusteeWithObjectsAndSid, TRUSTEE


CheckTokenMembership

The CheckTokenMembership function determines whether a specified SID is enabled in an access token.

BOOL CheckTokenMembership(
  HANDLE TokenHandle,  // handle to access token
  PSID SidToCheck,     // SID
  PBOOL IsMember       // result
);

Parameters

TokenHandle
[in] Handle to an access token. The handle must have TOKEN_QUERY access to the token. The token must be an impersonation token.

If TokenHandle is NULL, CheckTokenMembership uses the impersonation token of the calling thread. If the thread is not impersonating, the function duplicates the thread's primary token to create an impersonation token.

SidToCheck
[in] Pointer to a SID structure. The CheckTokenMembership function checks for the presence of this SID in the user and group SIDs of the access token.
IsMember
[out] Pointer to a variable that receives the results of the check. If the SID is present and has the SE_GROUP_ENABLED attribute, IsMember returns TRUE; otherwise, it returns FALSE.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The CheckTokenMembership function simplifies the process of determining whether a SID is both present and enabled in an access token.

Just because a SID is present in the token, doesn't mean that the system will use it in an access check. The SID may be disabled or have the SE_GROUP_USE_FOR_DENY_ONLY attribute. The system uses only enabled SIDs to grant access when performing an access check. For more information, see SID Attributes in an Access Token.

If TokenHandle is a restricted token, or if TokenHandle is NULL and the current effective token of the calling thread is a restricted token, CheckTokenMembership also checks whether the SID is present in the list of restricting SIDs.

Examples

BOOL IsUserAdmin(VOID)

/*++
Routine Description: This routine returns TRUE if the caller's process is a member of the Administrators local group. Caller is NOT expected to be impersonating anyone and is expected to be able to open their own process and process token.
Arguments: None.
Return Value:
   TRUE - Caller has Administrators local group.
   FALSE - Caller does not have Administrators local group. --
*/
{
BOOL b;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
PSID AdministratorsGroup;
b = AllocateAndInitializeSid(
    &NtAuthority,
    2,
    SECURITY_BUILTIN_DOMAIN_RID,
    DOMAIN_ALIAS_RID_ADMINS,
    0, 0, 0, 0, 0, 0,
    &AdministratorsGroup);
if(b)
{
    if (!CheckTokenMembership( NULL, AdministratorsGroup, &b))
    {
         b = FALSE;
    }
    FreeSid(AdministratorsGroup);
}

return(b);
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, AccessCheck, CreateRestrictedToken


ConvertSecurityDescriptorToStringSecurityDescriptor

The ConvertSecurityDescriptorToStringSecurityDescriptor function converts a security descriptor to a string format. You can use the string format to store or transmit the security descriptor.

To convert the string-format security descriptor back to a valid, functional security descriptor, call the ConvertStringSecurityDescriptorToSecurityDescriptor function.

BOOL ConvertSecurityDescriptorToStringSecurityDescriptor(
  PSECURITY_DESCRIPTOR SecurityDescriptor,  // SD
  DWORD RequestedStringSDRevision,          // revision level
  SECURITY_INFORMATION SecurityInformation, // component
  LPTSTR *StringSecurityDescriptor,         // security descriptor string
  PULONG StringSecurityDescriptorLen        // size of security descriptor string
);

Parameters

SecurityDescriptor
[in] Pointer to the security descriptor to convert. The security descriptor can be in absolute or self-relative format.
RequestedStringSDRevision
[in] Specifies the revision level of the output StringSecurityDescriptor string. Currently this value must be SDDL_REVISION_1.
SecurityInformation
[in] Specifies a combination of the following SECURITY_INFORMATION bit flags to indicate the components of the security descriptor to include in the output string.
Value | Meaning
OWNER_SECURITY_INFORMATION | Include the owner.
GROUP_SECURITY_INFORMATION | Include the primary group.
DACL_SECURITY_INFORMATION | Include the DACL.
SACL_SECURITY_INFORMATION | Include the SACL.

StringSecurityDescriptor
[out] Pointer to a variable that receives a pointer to a null-terminated security descriptor string. For a description of the string format, see Security Descriptor String Format. To free the returned buffer, call the LocalFree function.
StringSecurityDescriptorLen
[out] Pointer to a variable that receives the size, in TCHARs, of the security descriptor string returned in the StringSecurityDescriptor buffer. This parameter can be NULL if you don't need to retrieve the size.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. The GetLastError function may return one of the following error codes.

Error Code | Meaning
ERROR_INVALID_PARAMETER | Invalid parameter.
ERROR_UNKNOWN_REVISION | The revision level is invalid.
ERROR_NONE_MAPPED | A SID in the input security descriptor could not be found in an account lookup operation.
ERROR_INVALID_ACL | Invalid ACL. This error is returned if the SE_DACL_PRESENT flag is set in the input security descriptor and the DACL is NULL.

Remarks

If the DACL is NULL, and the SE_DACL_PRESENT control bit is set in the input security descriptor, the function fails.

If the DACL is NULL, and the SE_DACL_PRESENT control bit is not set in the input security descriptor, the resulting security descriptor string does not have a D: component. For more information, see Security Descriptor String Format.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Sddl.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows 2000.

See Also

Access Control Overview, Access Control Functions, ConvertSidToStringSid, ConvertStringSecurityDescriptorToSecurityDescriptor, ConvertStringSidToSid, SECURITY_DESCRIPTOR


ConvertStringSecurityDescriptorToSecurityDescriptor

The ConvertStringSecurityDescriptorToSecurityDescriptor function converts a string-format security descriptor into a valid, functional security descriptor. This function retrieves a security descriptor that the ConvertSecurityDescriptorToStringSecurityDescriptor function converted to string format.

BOOL ConvertStringSecurityDescriptorToSecurityDescriptorW(
  LPCTSTR StringSecurityDescriptor,          // security descriptor string
  DWORD StringSDRevision,                    // revision level
  PSECURITY_DESCRIPTOR *SecurityDescriptor,  // SD
  PULONG SecurityDescriptorSize              // SD size
);

Parameters

StringSecurityDescriptor
[in] Pointer to a null-terminated string containing the string-format security descriptor to convert.
StringSDRevision
[in] Specifies the revision level of the StringSecurityDescriptor string. Currently this value must be SDDL_REVISION_1.
SecurityDescriptor
[out] Pointer to a variable that receives a pointer to the converted security descriptor. The returned security descriptor is self-relative. To free the returned buffer, call the LocalFree function. To convert the security descriptor to an absolute security descriptor, use the MakeAbsoluteSD function.
SecurityDescriptorSize
[out] Pointer to a variable that receives the size, in bytes, of the converted security descriptor. This parameter can be NULL.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. GetLastError may return one of the following error codes.

Error Code | Meaning
ERROR_INVALID_PARAMETER | Invalid parameter.
ERROR_UNKNOWN_REVISION | The SDDL revision level is invalid.
ERROR_NONE_MAPPED | A SID in the input security descriptor string could not be found in an account lookup operation.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Sddl.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows 2000.

See Also

Access Control Overview, Access Control Functions, ConvertSecurityDescriptorToStringSecurityDescriptor, ConvertSidToStringSid, ConvertStringSidToSid, MakeAbsoluteSD, SECURITY_DESCRIPTOR


ConvertSidToStringSid

The ConvertSidToStringSid function converts a SID to a string format suitable for display, storage, or transmission.

To convert the string-format SID back to a valid, functional SID, call the ConvertStringSidToSid function.

BOOL ConvertSidToStringSid(
  PSID Sid,          // SID
  LPTSTR *StringSid  // SID string
);

Parameters

Sid
[in] Pointer to the SID to convert.
StringSid
[out] Pointer to a variable that receives a pointer to a null-terminated SID string. To free the returned buffer, call the LocalFree function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. The GetLastError function may return one of the following error codes.

Error Code | Meaning
ERROR_NOT_ENOUGH_MEMORY | Insufficient memory.
ERROR_NONE_MAPPED | The SID could not be found in an account lookup operation.

Remarks

The ConvertSidToStringSid function uses the standard S-R-I-S-S... format for SID strings. For more information about SID string notation, see SID Components.

Example Code

See Converting a Binary SID to String Format

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Sddl.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows 2000.

See Also

Access Control Overview, Access Control Functions, ConvertSecurityDescriptorToStringSecurityDescriptor, ConvertStringSecurityDescriptorToSecurityDescriptor, ConvertStringSidToSid, SID


ConvertStringSidToSid

The ConvertStringSidToSid function converts a string-format SID into a valid, functional SID. You can use this function to retrieve a SID that the ConvertSidToStringSid function converted to string format.

BOOL ConvertStringSidToSid(
  LPCTSTR StringSid,  // SID string
  PSID *Sid           // SID
);

Parameters

StringSid
[in] Pointer to a null-terminated string containing the string-format SID to convert.

The SID string must use the standard S-R-I-S-S... format for SID strings. For more information about SID string notation, see SID Components.

Sid
[out] Pointer to a variable that receives a pointer to the converted SID. To free the returned buffer, call the LocalFree function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. The GetLastError function may return one of the following error codes.

Error Code | Meaning
ERROR_INVALID_PARAMETER | Invalid parameter.
ERROR_INVALID_SID | Invalid SID.

Examples

See Converting a Binary SID to String Format

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Sddl.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows 2000.

See Also

Access Control Overview, Access Control Functions, ConvertSecurityDescriptorToStringSecurityDescriptor, ConvertSidToStringSid, ConvertStringSecurityDescriptorToSecurityDescriptor, SID


CopySid

The CopySid function copies a security identifier (SID) to a buffer.

BOOL CopySid(
  DWORD nDestinationSidLength,  // size of SID buffer
  PSID pDestinationSid,         // SID buffer
  PSID pSourceSid               // source SID
);

Parameters

nDestinationSidLength
[in] Specifies the length, in bytes, of the buffer receiving the copy of the SID.
pDestinationSid
[out] Pointer to a buffer that receives a copy of the source SID structure.
pSourceSid
[in] Pointer to a SID structure that the function copies to the buffer pointed to by the pDestinationSid parameter.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

An application can use the CopySid function to make a copy of a SID in an access token (for example, in a TOKEN_GROUPS structure) to use in an access-control entry (ACE).

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, AllocateAndInitializeSid, EqualSid, GetLengthSid, GetSidIdentifierAuthority, GetSidLengthRequired, GetSidSubAuthority, GetSidSubAuthorityCount, InitializeSid, IsValidSid, SID


CreateRestrictedToken

The CreateRestrictedToken function creates a new access token that is a restricted version of an existing access token. For more information, see Restricted Tokens.

BOOL CreateRestrictedToken(
  HANDLE ExistingTokenHandle,              // handle to existing token
  DWORD Flags,                             // privilege options
  DWORD DisableSidCount,                   // number of deny-only SIDs
  PSID_AND_ATTRIBUTES SidsToDisable,       // deny-only SIDs
  DWORD DeletePrivilegeCount,              // number of privileges
  PLUID_AND_ATTRIBUTES PrivilegesToDelete, // privileges
  DWORD RestrictedSidCount,                // number of restricting SIDs
  PSID_AND_ATTRIBUTES SidsToRestrict,      // list of restricting SIDs
  PHANDLE NewTokenHandle                   // handle to new token
);

Parameters

ExistingTokenHandle
[in] Handle to a primary or impersonation token. The token can also be a restricted token. The handle must have TOKEN_DUPLICATE access to the token.
Flags
[in] Specifies additional privilege options. This parameter can be zero or a combination of the following bits.
Value | Meaning
DISABLE_MAX_PRIVILEGE | Disables all privileges in the new token. If this value is specified, the DeletePrivilegeCount and PrivilegesToDelete parameters are ignored.
SANDBOX_INERT | Stores this flag in the token. A token may be queried for existence of this flag using GetTokenInformation.

DisableSidCount
[in] Specifies the number of entries in the SidsToDisable array.
SidsToDisable
[in] Pointer to an array of SID_AND_ATTRIBUTES structures that specify the deny-only SIDs in the restricted token. The system uses a deny-only SID to deny access to a securable object. The absence of a deny-only SID does not allow access.

Disabling a Sid turns ON SE_GROUP_USE_FOR_DENY_ONLY and turns OFF SE_GROUP_ENABLED and SE_GROUP_ENABLED_BY_DEFAULT. All other attributes are ignored.

Deny-only attributes apply to any combination of an existing token's SIDs, including the user SID and group SIDs that have the SE_GROUP_MANDATORY attribute. To get the SIDs associated with the existing token, use the GetTokenInformation function with the TokenUser and TokenGroups flags. The function ignores any SIDs in the array that are not also found in the existing token.

The function ignores the Attributes members of the SID_AND_ATTRIBUTES structures.

This parameter can be NULL if no SIDs are to be disabled.

DeletePrivilegeCount
[in] Specifies the number of entries in the PrivilegesToDelete array.
PrivilegesToDelete
[in] Pointer to an array of LUID_AND_ATTRIBUTES structures that specify the privileges to delete in the restricted token.

The GetTokenInformation function can be used with the TokenPrivileges flag to retrieve the privileges held by the existing token. The function ignores any privileges in the array that are not held by the existing token.

The function ignores the Attributes members of the LUID_AND_ATTRIBUTES structures.

This parameter can be NULL if you don't want to delete any privileges.

RestrictedSidCount
[in] Specifies the number of entries in the SidsToRestrict array.
SidsToRestrict
[in] Pointer to an array of SID_AND_ATTRIBUTES structures that specify a list of restricting SIDs for the new token. If the existing token is a restricted token, the list of restricting SIDs for the new token is the intersection of this array and the list of restricting SIDs for the existing token. No check is performed to remove duplicate SIDs that were placed on the SidsToRestrict parameter. Duplicate SIDs allow a restricted token to have redundant information in the restricting SID list.

The Attributes members of the SID_AND_ATTRIBUTES structures must be zero. Restricting SIDs are always enabled for access checks.

This parameter can be NULL if you don't want to specify any restricting SIDs.

NewTokenHandle
[out] Pointer to a variable that receives a handle to the new restricted token. This handle has the same access rights as ExistingTokenHandle. The new token is the same type, primary or impersonation, as the existing token. The handle returned in NewTokenHandle can be duplicated.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The CreateRestrictedToken function can restrict the token in the following ways:

  • Apply the deny-only attribute to SIDs in the token so they cannot be used to access secured objects. For more information about the deny-only attribute, see SID Attributes in an Access Token.
  • Remove privileges from the token.
  • Specify a list of restricting SIDs, which the system uses when it checks the token's access to a securable object. The system performs two access checks: one using the token's enabled SIDs, and another using the list of restricting SIDs. Access is granted only if both access checks allow the requested access rights.

You can use the restricted token in the CreateProcessAsUser function to create a process that has restricted access rights and privileges. If a process calls CreateProcessAsUser using a restricted version of its own token, the calling process does not need to have the SE_ASSIGNPRIMARYTOKEN_NAME privilege.

You can use the restricted token in the ImpersonateLoggedOnUser function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, CreateProcessAsUser, GetTokenInformation, ImpersonateLoggedOnUser, IsTokenRestricted, LUID_AND_ATTRIBUTES, SID_AND_ATTRIBUTES


DuplicateToken

The DuplicateToken function creates a new access token that duplicates one already in existence.

BOOL DuplicateToken(
  HANDLE ExistingTokenHandle,                      // handle to token
  SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, // level
  PHANDLE DuplicateTokenHandle                     // handle to duplicate token
);

Parameters

ExistingTokenHandle
[in] Handle to an access token opened with TOKEN_DUPLICATE access.
ImpersonationLevel
[in] Specifies a SECURITY_IMPERSONATION_LEVEL enumerated type that supplies the impersonation level of the new token.
DuplicateTokenHandle
[out] Pointer to a variable that receives a handle to the duplicate token. This handle has TOKEN_IMPERSONATE and TOKEN_QUERY access to the new token.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The DuplicateToken function creates an impersonation token, which you can use in functions such as SetThreadToken and ImpersonateLoggedOnUser. The token created by DuplicateToken cannot be used in the CreateProcessAsUser function, which requires a primary token. To create a token that you can pass to CreateProcessAsUser, use the DuplicateTokenEx function.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, CreateProcessAsUser, DuplicateTokenEx, ImpersonateLoggedOnUser, SECURITY_IMPERSONATION_LEVEL, SetThreadToken


DuplicateTokenEx

The DuplicateTokenEx function creates a new access token that duplicates an existing token. This function can create either a primary token or an impersonation token.

BOOL DuplicateTokenEx(
  HANDLE hExistingToken,                           // handle to token to duplicate
  DWORD dwDesiredAccess,                           // access rights of new token
  LPSECURITY_ATTRIBUTES lpTokenAttributes,         // attributes
  SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, // level
  TOKEN_TYPE TokenType,                            // primary or impersonation token
  PHANDLE phNewToken                               // handle to duplicated token
);

Parameters

hExistingToken
[in] Handle to an access token opened with TOKEN_DUPLICATE access.
dwDesiredAccess
[in] Specifies the requested access rights for the new token. The DuplicateTokenEx function compares the requested access rights with the existing token's discretionary access-control list (DACL) to determine which rights are granted or denied. To request the same access rights as the existing token, specify zero. To request all access rights that are valid for the caller, specify MAXIMUM_ALLOWED.

For a list of access rights for access tokens, see Access Rights for Access-Token Objects.

lpTokenAttributes
[in] Pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new token and determines whether child processes can inherit the token. If lpTokenAttributes is NULL, the token gets a default security descriptor and the handle cannot be inherited.
ImpersonationLevel
[in] Specifies a value from the SECURITY_IMPERSONATION_LEVEL enumeration that indicates the impersonation level of the new token.
TokenType
[in] Specifies one of the following values from the TOKEN_TYPE enumeration.
Value | Meaning
TokenPrimary | The new token is a primary token that you can use in the CreateProcessAsUser function.
TokenImpersonation | The new token is an impersonation token.

phNewToken
[out] Pointer to a HANDLE variable that receives the new token.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The DuplicateTokenEx function allows you to create a primary token that you can use in the CreateProcessAsUser function. This allows a server application that is impersonating a client to create a process that has the security context of the client. Note that the DuplicateToken function can create only impersonation tokens, which are not valid for CreateProcessAsUser.

The following is a typical scenario for using DuplicateTokenEx to create a primary token. A server application creates a thread that calls one of the impersonation functions, such as ImpersonateNamedPipeClient, to impersonate a client. The impersonating thread then calls the OpenThreadToken function to get its own token, which is an impersonation token that has the security context of the client. The thread specifies this impersonation token in a call to DuplicateTokenEx, specifying the TokenPrimary flag. The DuplicateTokenEx function creates a primary token that has the security context of the client.

When you have finished using the new token, call the CloseHandle function to close the token handle.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, CloseHandle, CreateProcessAsUser, DdeImpersonateClient, DuplicateToken, ImpersonateNamedPipeClient, OpenThreadToken, RevertToSelf, RpcImpersonateClient, SECURITY_ATTRIBUTES, SECURITY_IMPERSONATION_LEVEL


EqualPrefixSid

The EqualPrefixSid function tests two security-identifier (SID) prefix values for equality. A SID prefix is the entire SID except for the last subauthority value.

BOOL EqualPrefixSid(
  PSID pSid1,  // first SID
  PSID pSid2   // second SID
);

Parameters

pSid1
[in] Pointer to the first SID structure to compare. This structure is assumed to be valid.
pSid2
[in] Pointer to the second SID structure to compare. This structure is assumed to be valid.

Return Values

If the SID prefixes are equal, the return value is nonzero.

If the SID prefixes are not equal, the return value is zero. To get extended error information, call GetLastError.

Remarks

The EqualPrefixSid function enables a server application in one domain to verify an attempt by a user to log on to another domain. For example, if a user attempts to log on to RemoteDomain from a workstation in LocalDomain, the server for LocalDomain can request the SIDs for the user and the user's groups from RemoteDomain. The domain controller for RemoteDomain responds with the relevant SIDs.

All SIDs for a specified domain have the same prefix. When the server receives the user's SIDs, it can call the EqualPrefixSid function for each SID, comparing the user or group SID against the SID for RemoteDomain. If any of the SID prefixes are not equal, the server refuses the logon attempt.

It is advisable to modify the SID for a domain before comparing it with a group or user SID. If the SID for RemoteDomain is S-1–1234–8, each group or user SID for that domain will have S-1–1234–8 as its prefix. To compare the SIDs by using the EqualPrefixSid function, an application copies the domain SID and adds any subauthority (RID) value to the copy, thereby creating a SID in the form S-1–1234–8–0. The application then uses the modified domain SID as a template against which the group and user SIDs are compared.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, CopySid, EqualSid, IsValidSid, SID


EqualSid

The EqualSid function tests two security identifier (SID) values for equality. Two SIDs must match exactly to be considered equal.

BOOL EqualSid(
  PSID pSid1,  // first SID
  PSID pSid2   // second SID
);

Parameters

pSid1
[in] Pointer to the first SID structure to compare. This structure is assumed to be valid.
pSid2
[in] Pointer to the second SID structure to compare. This structure is assumed to be valid.

Return Values

If the SID structures are equal, the return value is nonzero.

If the SID structures are not equal, the return value is zero. To get extended error information, call GetLastError.

If either SID structure is invalid, the return value is undefined.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, EqualPrefixSid, IsValidSid, SID


FreeSid

The FreeSid function frees a security identifier (SID) previously allocated by using the AllocateAndInitializeSid function.

PVOID FreeSid(
  PSID pSid   // SID to free
);

Parameters

pSid
[in] Pointer to the SID structure to free.

Return Values

This function does not return a value.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, AllocateAndInitializeSid, SID


GetAuditedPermissionsFromAcl

The GetAuditedPermissionsFromAcl function retrieves the audited access rights for a specified trustee. The audited rights are based on the access-control entries (ACEs) of a specified access-control list (ACL). The audited access rights indicate the types of access attempts that cause the system to generate an audit record in the system event log. The audited rights include those that the ACL specifies for the trustee or for any groups of which the trustee is a member. In determining the audited rights, the function does not consider the security privileges held by the trustee.

DWORD GetAuditedPermissionsFromAcl(
  PACL pacl,                             // source ACL
  PTRUSTEE pTrustee,                     // trustee
  PACCESS_MASK pSuccessfulAuditedRights, // access rights
  PACCESS_MASK pFailedAuditRights        // failed access rights
);

Parameters

pacl
[in] Pointer to an ACL structure from which to get the trustee's audited access rights.
pTrustee
[in] Pointer to a TRUSTEE structure that identifies the trustee. A trustee can be a user, group, or program (such as a Win32 service). You can use a name or a security identifier (SID) to identify a trustee.
pSuccessfulAuditedRights
[out] Pointer to an ACCESS_MASK structure that receives a set of access rights. The system generates an audit record when the trustee successfully uses any of these access rights.
pFailedAuditRights
[out] Pointer to an ACCESS_MASK structure that receives a set of access rights based on the ACEs in the specified ACL. The system generates an audit record when the trustee fails in an attempt to use any of these rights.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in Winerror.h.

Remarks

The GetAuditedPermissionsFromAcl function checks all system-audit ACEs in the ACL to determine the audited rights for the trustee. For all ACEs that specify audited rights for a group, GetAuditedPermissionsFromAcl enumerates the members of the group to determine whether the trustee is a member. The function returns an error if it cannot enumerate the members of a group.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Aclapi.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Access Control Overview, Access Control Functions, ACCESS_MASK, ACE, ACL, GetEffectiveRightsFromAcl, SID, SYSTEM_AUDIT_ACE, TRUSTEE


GetEffectiveRightsFromAcl

The GetEffectiveRightsFromAcl function retrieves the effective access rights that an ACL grants to a specified trustee. The trustee's effective access rights are the access rights that the ACL grants to the trustee or to any groups of which the trustee is a member.

Windows NT: Prior to Windows 2000, this function did not return group rights. Beginning with Windows 2000, group rights information is returned.

DWORD GetEffectiveRightsFromAcl(
  PACL pacl,                   // source ACL
  PTRUSTEE pTrustee,           // trustee
  PACCESS_MASK pAccessRights   // trustee's access rights
);

Parameters

pacl
[in] Pointer to an ACL structure from which to get the trustee's effective access rights.
pTrustee
[in] Pointer to a TRUSTEE structure that identifies the trustee. A trustee can be a user, group, or program (such as a Win32 service). You can use a name or a security identifier (SID) to identify a trustee.
pAccessRights
[out] Pointer to an ACCESS_MASK variable that receives the effective access rights of the trustee.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in Winerror.h.

Remarks

The GetEffectiveRightsFromAcl function checks all access-allowed and access-denied ACEs in the ACL to determine the effective rights for the trustee. For all ACEs that allow or deny rights to a group, GetEffectiveRightsFromAcl enumerates the members of the group to determine whether the trustee is a member. The function returns an error if it cannot enumerate the members of a group.

A trustee's group rights are enumerated by GetEffectiveRightsFromAcl on the local machine, even if the trustee is accessing objects on a remote machine. This function does not evaluate group rights on remote machines.

GetEffectiveRightsFromAcl does not take into account implicitly granted access rights, namely READ_CONTROL and WRITE_DAC, for the owner of an object when determining effective rights.

GetEffectiveRightsFromAcl does not take privileges held by the trustee into account when determining effective access rights.

GetEffectiveRightsFromAcl does not take into account group rights associated with the logon session, such as interactive, network, authenticated users, etc., in determining effective access rights.

GetEffectiveRightsFromAcl does not take into account resource manager policy when determining effective access rights. For example, for file objects, Delete and Read attributes can be provided by the parent even if they have been denied on the object.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Aclapi.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Access Control Overview, Access Control Functions, ACCESS_ALLOWED_ACE, ACCESS_DENIED_ACE, ACCESS_MASK, ACE, ACL, GetAuditedPermissionsFromAcl, SID, TRUSTEE


GetExplicitEntriesFromAcl

The GetExplicitEntriesFromAcl function retrieves an array of structures that describe the access-control entries (ACEs) in an access-control list (ACL).

DWORD GetExplicitEntriesFromAcl(
  PACL pacl,                               // ACL
  PULONG pcCountOfExplicitEntries,         // entries
  PEXPLICIT_ACCESS *pListOfExplicitEntries // array
);

Parameters

pacl
[in] Pointer to an ACL structure from which to get ACE information.
pcCountOfExplicitEntries
[out] Pointer to a variable that receives the number of EXPLICIT_ACCESS structures returned in the pListOfExplicitEntries array.
pListOfExplicitEntries
[out] Pointer to a variable that receives a pointer to an array of EXPLICIT_ACCESS structures that describe the ACEs in the ACL. If the function succeeds, you must call the LocalFree function to free the returned buffer.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in Winerror.h.

Remarks

Each entry in the array of EXPLICIT_ACCESS structures describes access-control information from an ACE for a trustee. A trustee can be a user, group, or program (such as a Win32 service).

With Windows 2000, ACEs that have a flag type of INHERITED_ACE are not returned by this function. A DACL for an object can return zero ACEs if all existing ACEs are flagged as INHERITED_ACE.

Each EXPLICIT_ACCESS structure specifies a set of access rights and an access mode flag that indicates whether the ACE allows, denies, or audits the specified rights.

For a discretionary ACL (DACL), the access mode flag can be one of the following values from the ACCESS_MODE enumeration.

Value | Meaning
GRANT_ACCESS | Indicates that an access-allowed ACE for the trustee allows the specified access rights.
DENY_ACCESS | Indicates that an access-denied ACE for the trustee denies the specified access rights.

For a system ACL (SACL), the access mode flag can be a combination of the following values from the ACCESS_MODE enumeration.

Value | Meaning
SET_AUDIT_SUCCESS | Indicates that a system-audit ACE for the trustee generates audit messages for successful attempts to use the specified access rights.
SET_AUDIT_FAILURE | Indicates that a system-audit ACE for the trustee generates audit messages for failed attempts to use the specified access rights.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Aclapi.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Access Control Overview, Access Control Functions, ACCESS_ALLOWED_ACE, ACCESS_DENIED_ACE, ACE, ACL, EXPLICIT_ACCESS, LocalFree, SYSTEM_AUDIT_ACE


GetLengthSid

The GetLengthSid function returns the length, in bytes, of a valid security identifier (SID).

DWORD GetLengthSid(
  PSID pSid   // SID to query
);

Parameters

pSid
[in] Pointer to the SID structure whose length is returned. The structure is assumed to be valid.

Return Values

If the SID structure is valid, the return value is the length, in bytes, of the SID structure.

If the SID structure is not valid, the return value is undefined. Before calling GetLengthSid, pass the SID to the IsValidSid function to verify that it is valid.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, GetSidLengthRequired, GetSidSubAuthorityCount, IsValidSid, SID


GetMultipleTrustee

Obsolete; do not use.

See Also

Access Control Overview, Access Control Functions


GetMultipleTrusteeOperation

Obsolete; do not use.

See Also

Access Control Overview, Access Control Functions


GetNamedSecurityInfo

The GetNamedSecurityInfo function retrieves a copy of the security descriptor for an object specified by name.

DWORD GetNamedSecurityInfo(
  LPTSTR pObjectName,                        // object name
  SE_OBJECT_TYPE ObjectType,                 // object type
  SECURITY_INFORMATION SecurityInfo,         // information type
  PSID *ppsidOwner,                          // owner SID
  PSID *ppsidGroup,                          // primary group SID
  PACL *ppDacl,                              // DACL
  PACL *ppSacl,                              // SACL
  PSECURITY_DESCRIPTOR *ppSecurityDescriptor // SD
);

Parameters

pObjectName
[in] Pointer to a null-terminated string that specifies the name of the object from which to retrieve security information. For descriptions of the string formats for the different object types, see SE_OBJECT_TYPE.
ObjectType
[in] Specifies a value from the SE_OBJECT_TYPE enumeration that indicates the type of object named by the pObjectName parameter.
SecurityInfo
[in] A set of SECURITY_INFORMATION bit flags that indicate the type of security information to retrieve. This parameter can be a combination of the following values.
Value | Meaning
DACL_SECURITY_INFORMATION | If this flag is set, the ppDacl parameter receives the object's discretionary access-control list (DACL).
GROUP_SECURITY_INFORMATION | If this flag is set, the ppsidGroup parameter receives the security identifier (SID) of the object's primary group.
OWNER_SECURITY_INFORMATION | If this flag is set, the ppsidOwner parameter receives the SID of the object's owner.
SACL_SECURITY_INFORMATION | If this flag is set, the ppSacl parameter receives the object's system access-control list (SACL).

ppsidOwner
[out] Pointer to a variable that receives a pointer to the owner SID in the security descriptor returned in ppSecurityDescriptor. The returned pointer is valid only if you set the OWNER_SECURITY_INFORMATION flag. This parameter can be NULL if you do not need the owner SID.
ppsidGroup
[out] Pointer to a variable that receives a pointer to the primary group SID in the returned security descriptor. The returned pointer is valid only if you set the GROUP_SECURITY_INFORMATION flag. This parameter can be NULL if you do not need the group SID.
ppDacl
[out] Pointer to a variable that receives a pointer to the DACL in the returned security descriptor. The returned pointer is valid only if you set the DACL_SECURITY_INFORMATION flag. This parameter can be NULL if you do not need the DACL.
ppSacl
[out] Pointer to a variable that receives a pointer to the SACL in the returned security descriptor. The returned pointer is valid only if you set the SACL_SECURITY_INFORMATION flag. This parameter can be NULL if you do not need the SACL.
ppSecurityDescriptor
[out] Pointer to a variable that receives a pointer to the security descriptor of the object. You must call the LocalFree function to free the returned buffer.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in Winerror.h.

Remarks

If the ppsidOwner, ppsidGroup, ppDacl, ppSacl parameters are non-NULL, and the SecurityInfo parameter specifies that they be retrieved from the object, those parameters will point to the corresponding parameters in the security descriptor returned in ppSecurityDescriptor.

To read the owner, group, or DACL from the object's security descriptor, the object's DACL must grant READ_CONTROL access to the caller, or the caller must be the owner of the object.

To read the system access-control list (SACL) of the object, the SE_SECURITY_NAME privilege must be enabled for the calling process.

You can use the GetNamedSecurityInfo function with the following types of objects:

  • Local or remote files or directories on an NTFS file system
  • Local or remote printers
  • Local or remote Win32 services
  • Network shares
  • Registry keys
  • Semaphores, events, mutexes, and waitable timers
  • File-mapping objects
  • Directory service objects

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Aclapi.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Access Control Overview, Access Control Functions, ACL, GetSecurityInfo, LocalFree, SE_OBJECT_TYPE, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetNamedSecurityInfo, SetSecurityInfo, SID


GetSecurityDescriptorControl

The GetSecurityDescriptorControl function retrieves a security descriptor's control and revision information.

BOOL GetSecurityDescriptorControl(
  PSECURITY_DESCRIPTOR pSecurityDescriptor,  // SD
  PSECURITY_DESCRIPTOR_CONTROL pControl,     // control
  LPDWORD lpdwRevision                       // revision
);

Parameters

pSecurityDescriptor
[in] Pointer to a SECURITY_DESCRIPTOR structure whose control and revision information the function retrieves.
pControl
[out] Pointer to a SECURITY_DESCRIPTOR_CONTROL structure that receives the security descriptor's control information.
lpdwRevision
[out] Pointer to a variable that receives the security descriptor's revision value. This value is always set, even when GetSecurityDescriptorControl returns an error.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, GetSecurityDescriptorDacl, GetSecurityDescriptorGroup, GetSecurityDescriptorLength, GetSecurityDescriptorOwner, GetSecurityDescriptorSacl, IsValidSecurityDescriptor, SECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL


GetSecurityDescriptorRMControl

The GetSecurityDescriptorRMControl function retrieves the resource manager control bits.

DWORD GetSecurityDescriptorRMControl(
  PSECURITY DESCRIPTOR SecurityDescriptor,
  PUCHAR RMControl
);

Parameters

SecurityDescriptor
[in] Pointer to a SECURITY_DESCRIPTOR structure that contains the resource manager control bits. The value of the Control member is set to SE_RM_CONTROL_VALID.
RMControl
[out] Pointer to a buffer that receives the resource manger control bits.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the following value is returned.

Error value | Description
ERROR_INVALID_DATA | The SE_RM_CONTROL_VALID bit flag is not set in the specified SECURITY_DESCRIPTOR structure.

Remarks

The resource manager control bits are eight bits in the Sbz1 member of the SECURITY_DESCRIPTOR structure that contains information specific to the resource manager accessing the structure. These bits should be accessed only through the GetSecurityDescriptorRMControl and SetSecurityDescriptorRMControl functions.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, SECURITY_DESCRIPTOR, SetSecurityDescriptorRMControl


GetSecurityInfo

The GetSecurityInfo function retrieves a copy of the security descriptor for an object specified by a handle.

DWORD GetSecurityInfo(
  HANDLE handle,                             // handle to object
  SE_OBJECT_TYPE ObjectType,                 // object type
  SECURITY_INFORMATION SecurityInfo,         // information type
  PSID *ppsidOwner,                          // owner SID
  PSID *ppsidGroup,                          // primary group SID
  PACL *ppDacl,                              // DACL
  PACL *ppSacl,                              // SACL
  PSECURITY_DESCRIPTOR *ppSecurityDescriptor // SD
);

Parameters

handle
[in] Handle to the object from which to retrieve security information.
ObjectType
[in] Specifies a value from the SE_OBJECT_TYPE enumeration that indicates the type of object.
SecurityInfo
[in] Specifies a set of SECURITY_INFORMATION bit values that indicate the type of security information to retrieve. This parameter can be a combination of the following values.
Value | Meaning
DACL_SECURITY_INFORMATION | If this flag is set, the ppDacl parameter receives the object's discretionary access-control list (DACL).
GROUP_SECURITY_INFORMATION | If this flag is set, the ppsidGroup parameter receives the security identifier (SID) of the object's primary group.
OWNER_SECURITY_INFORMATION | If this flag is set, the ppsidOwner parameter receives the SID of the object's owner.
SACL_SECURITY_INFORMATION | If this flag is set, the ppSacl parameter receives the object's system access-control list (SACL).

ppsidOwner
[out] Pointer to a variable that receives a pointer to the owner SID in the security descriptor returned in ppSecurityDescriptor. The returned pointer is valid only if you set the OWNER_SECURITY_INFORMATION flag. This parameter can be NULL if you do not need the owner SID.
ppsidGroup
[out] Pointer to a variable that receives a pointer to the primary group SID in the returned security descriptor. The returned pointer is valid only if you set the GROUP_SECURITY_INFORMATION flag. This parameter can be NULL if you do not need the group SID.
ppDacl
[out] Pointer to a variable that receives a pointer to the DACL in the returned security descriptor. The returned pointer is valid only if you set the DACL_SECURITY_INFORMATION flag. This parameter can be NULL if you do not need the DACL.
ppSacl
[out] Pointer to a variable that receives a pointer to the SACL in the returned security descriptor. The returned pointer is valid only if you set the SACL_SECURITY_INFORMATION flag. This parameter can be NULL if you do not need the SACL.
ppSecurityDescriptor
[out] Pointer to a variable that receives a pointer to the security descriptor of the object. You must call the LocalFree function to free the returned buffer.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in Winerror.h.

Remarks

If the ppsidOwner, ppsidGroup, ppDacl, ppSacl parameters are non-NULL, and the SecurityInfo parameter specifies that they be retrieved from the object, those parameters will point to the corresponding parameters in the security descriptor returned in ppSecurityDescriptor.

To read the owner, group, or DACL from the object's security descriptor, the calling process must have been granted READ_CONTROL access when the handle was opened. To get READ_CONTROL access, the caller must be the owner of the object or the object's DACL must grant the access.

To read the SACL from the security descriptor, the calling process must have been granted ACCESS_SYSTEM_SECURITY access when the handle was opened. The proper way to get this access is to enable the SE_SECURITY_NAME privilege in the caller's current token, open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege.

You can use the GetSecurityInfo function with the following types of objects:

  • Local or remote files or directories on an NTFS file system
  • Named pipes
  • Local or remote printers
  • Local or remote Win32 services
  • Network shares
  • Registry keys
  • Semaphores, events, mutexes, and waitable timers
  • Processes, threads, jobs, and file-mapping objects
  • Window stations and desktops
  • Directory service objects

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Aclapi.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, ACL, GetNamedSecurityInfo, LocalFree, SE_OBJECT_TYPE, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetNamedSecurityInfo, SetSecurityInfo, SID


GetSidIdentifierAuthority

The GetSidIdentifierAuthority function returns a pointer to the SID_IDENTIFIER_AUTHORITY structure in a specified security identifier (SID).

PSID_IDENTIFIER_AUTHORITY GetSidIdentifierAuthority(
  PSID pSid   // SID to query
);

Parameters

pSid
[in] Pointer to the SID structure for which a pointer to the SID_IDENTIFIER_AUTHORITY structure is returned.

Return Values

If the function succeeds, the return value is a pointer to the SID_IDENTIFIER_AUTHORITY structure for the specified SID structure.

If the function fails, the return value is undefined. The function fails if the SID structure pointed to by the pSid parameter is invalid. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, GetLengthSid, GetSidLengthRequired, GetSidSubAuthority, GetSidSubAuthorityCount, IsValidSid, SID, SID_IDENTIFIER_AUTHORITY


GetSidLengthRequired

The GetSidLengthRequired function returns the length, in bytes, of the buffer required to store a SID with a specified number of subauthorities.

DWORD GetSidLengthRequired(
  UCHAR nSubAuthorityCount   // count of subauthorities
);

Parameters

nSubAuthorityCount
[in] Specifies the number of subauthorities to be stored in the SID structure.

Return Values

The return value is the length, in bytes, of the buffer required to store the SID structure. This function cannot fail.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, AllocateAndInitializeSid, GetLengthSid, GetSidIdentifierAuthority, GetSidSubAuthority, GetSidSubAuthorityCount, InitializeSid, IsValidSid, SID


GetSidSubAuthority

The GetSidSubAuthority function returns a pointer to a specified subauthority in a security identifier (SID). The subauthority value is a relative identifier (RID).

PDWORD GetSidSubAuthority(
  PSID pSid,            // security identifier
  DWORD nSubAuthority   // index of subauthority
);

Parameters

pSid
[in] Pointer to the SID structure from which a pointer to a subauthority is to be returned.
nSubAuthority
[in] Specifies an index value identifying the subauthority array element whose address the function will return. The function performs no validation tests on this value. An application can call the GetSidSubAuthorityCount function to discover the range of acceptable values.

Return Values

If the function succeeds, the return value is a pointer to the specified SID subauthority. To get extended error information, call GetLastError.

If the function fails, the return value is undefined. The function fails if the specified SID structure is invalid or if the index value specified by the nSubAuthority parameter is out of bounds.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, GetLengthSid, GetSidIdentifierAuthority, GetSidLengthRequired, GetSidSubAuthorityCount, IsValidSid, SID


GetSidSubAuthorityCount

The GetSidSubAuthorityCount function returns a pointer to the member in a security identifier (SID) structure containing the subauthority count.

PUCHAR GetSidSubAuthorityCount(
  PSID pSid   // security identifier
);

Parameters

pSid
[in] Pointer to the SID structure from which a pointer to the subauthority count is returned.

Return Values

If the function succeeds, the return value is a pointer to the subauthority count for the specified SID structure.

If the function fails, the return value is undefined. The function fails if the specified SID structure is invalid. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, GetLengthSid, GetSidIdentifierAuthority, GetSidLengthRequired, GetSidSubAuthority, IsValidSid, SID


GetTokenInformation

The GetTokenInformation function retrieves a specified type of information about an access token. The calling process must have appropriate access rights to obtain the information.

To determine if a user is a member of a specific group, use the CheckTokenMembership function.

BOOL GetTokenInformation(
  HANDLE TokenHandle,                            // handle to access token
  TOKEN_INFORMATION_CLASS TokenInformationClass, // token type
  LPVOID TokenInformation,                       // buffer
  DWORD TokenInformationLength,                  // size of buffer
  PDWORD ReturnLength                            // required buffer size
);

Parameters

TokenHandle
[in] Handle to an access token from which information is retrieved. If TokenInformationClass specifies TokenSource, the handle must have TOKEN_QUERY_SOURCE access. For all other TokenInformationClass values, the handle must have TOKEN_QUERY access.
TokenInformationClass
[in] Specifies a value from the TOKEN_INFORMATION_CLASS enumerated type to identify the type of information the function retrieves.
TokenInformation
[out] Pointer to a buffer the function fills with the requested information. The structure put into this buffer depends upon the type of information specified by the TokenInformationClass parameter, as shown in the following table.
Value | Description
NULL | The function returns the required buffer size. No data is stored in the buffer.
TokenDefaultDacl | The buffer receives a TOKEN_DEFAULT_DACL structure containing the default DACL for newly created objects.
TokenGroups | The buffer receives a TOKEN_GROUPS structure containing the group accounts associated with the token.
TokenImpersonationLevel | The buffer receives a SECURITY_IMPERSONATION_LEVEL value indicating the impersonation level of the token. If the access token is not an impersonation token, the function fails.
TokenOwner | The buffer receives a TOKEN_OWNER structure containing the default owner SID for newly created objects.
TokenPrimaryGroup | The buffer receives a TOKEN_PRIMARY_GROUP structure containing the default primary group SID for newly created objects.
TokenPrivileges | The buffer receives a TOKEN_PRIVILEGES structure containing the token's privileges.
TokenRestrictedSids | The buffer receives a TOKEN_GROUPS structure containing the list of restricting SIDs in a restricted token.
TokenSessionId | The buffer receives a DWORD value that indicates the Terminal Services session identifier associated with the token. If the token is associated with the Terminal Server console session, the session identifier is zero. A nonzero session identifier indicates a Terminal Services client session. In a non-Terminal Services environment, the session identifier is zero.
TokenSource | The buffer receives a TOKEN_SOURCE structure containing the source of the token. TOKEN_QUERY_SOURCE access is needed to retrieve this information.
TokenStatistics | The buffer receives a TOKEN_STATISTICS structure containing various token statistics.
TokenType | The buffer receives a TOKEN_TYPE value indicating whether the token is a primary or impersonation token.
TokenUser | The buffer receives a TOKEN_USER structure containing the token's user account.

TokenInformationLength
[in] Specifies the size, in bytes, of the buffer pointed to by the TokenInformation parameter. If TokenInformation is NULL, this parameter must be zero.
ReturnLength
[out] Pointer to a variable that receives the number of bytes needed for the buffer pointed to by the TokenInformation parameter. If this value is larger than the value specified in the TokenInformationLength parameter, the function fails and stores no data in the buffer.

If the value of the TokenInformationClass parameter is TokenDefaultDacl and the token has no default DACL, the function sets the variable pointed to by ReturnLength to sizeof(TOKEN_DEFAULT_DACL) and sets the DefaultDacl member of the TOKEN_DEFAULT_DACL structure to NULL.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, AdjustTokenGroups, AdjustTokenPrivileges, CheckTokenMembership, OpenProcessToken, OpenThreadToken, SetTokenInformation, SECURITY_IMPERSONATION_LEVEL, TOKEN_DEFAULT_DACL, TOKEN_GROUPS, TOKEN_INFORMATION_CLASS, TOKEN_OWNER, TOKEN_PRIMARY_GROUP, TOKEN_PRIVILEGES, TOKEN_SOURCE, TOKEN_STATISTICS, TOKEN_TYPE, TOKEN_USER


GetTrusteeForm

The GetTrusteeForm function retrieves the trustee name from the specified TRUSTEE structure. This value indicates whether the structure uses a name string or a security identifier (SID) to identify the trustee.

TRUSTEE_FORM GetTrusteeForm(
  PTRUSTEE pTrustee  // trustee structure
);

Parameters

pTrustee
[in] Pointer to a TRUSTEE structure.

Return Values

The return value is one of the constants from the TRUSTEE_FORM enumeration.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Aclapi.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Access Control Overview, Access Control Functions, GetTrusteeName, GetTrusteeType, TRUSTEE, TRUSTEE_FORM


GetTrusteeName

The GetTrusteeName function retrieves the trustee name from the specified TRUSTEE structure.

LPTSTR GetTrusteeName(
  PTRUSTEE pTrustee  // trustee structure
);

Parameters

pTrustee
[in] Pointer to a TRUSTEE structure.

Return Values

If the TrusteeForm member of the TRUSTEE structure is TRUSTEE_IS_NAME, the return value is the pointer assigned to the ptstrName member of the structure.

If the TrusteeForm member is TRUSTEE_IS_SID, the return value is NULL. The function does not look up the name associated with a security identifier (SID).

Remarks

The GetTrusteeName function does not allocate any memory.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Aclapi.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Access Control Overview, Access Control Functions, TRUSTEE, SID


GetTrusteeType

The GetTrusteeType function retrieves the trustee type from the specified TRUSTEE structure. This value indicates whether the trustee is a user, a group, or the trustee type is unknown.

TRUSTEE_TYPE GetTrusteeType(
  PTRUSTEE pTrustee  // trustee structure
);

Parameters

pTrustee
[in] Pointer to a TRUSTEE structure.

Return Values

The return value is one of the constants from the TRUSTEE_TYPE enumeration.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Aclapi.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Access Control Overview, Access Control Functions, TRUSTEE, TRUSTEE_TYPE


ImpersonateAnonymousToken

The ImpersonateAnonymousToken function enables the specified thread to impersonate the system's anonymous logon token. To ensure that a token matches the operating system's concept of anonymous access, this function should be called before attempting network access to generate an anonymous token on the remote server.

Note An anonymous token for Windows 2000 and earlier includes the Everyone group SID. However, Whistler, anonymous tokens do not include the Everyone Group SID unless the system default has been overridden by setting the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\EveryoneIncludesAnonymous registry value to DWORD=1.

BOOL ImpersonateAnonymousToken(
  HANDLE ThreadHandle  // handle to thread
);

Parameters

ThreadHandle
[in] Handle to the thread to impersonate the system's anonymous logon token.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions


InitializeSid

The InitializeSid function initializes a security identifier (SID).

BOOL InitializeSid(
  PSID Sid,                                       // SID
  PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, // SIA
  BYTE nSubAuthorityCount                         // count of subauthorities
);

Parameters

Sid
[out] Pointer to a SID structure to be initialized.
pIdentifierAuthority
[in] Pointer to a SID_IDENTIFIER_AUTHORITY structure to set in the SID structure.
nSubAuthorityCount
[in] Specifies the number of subauthorities to set in the SID. Values of the subauthority must be set separately, as described in the following Remarks section.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Although the InitializeSid function sets the number of subauthorities for the SID, it does not set the subauthority values. This must be done separately, using functions, such as GetSidSubAuthority.

An application can use the AllocateAndInitializeSid function to initialize a SID and set its subauthority values.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, AllocateAndInitializeSid, GetLengthSid, GetSidIdentifierAuthority, GetSidLengthRequired, GetSidSubAuthority, GetSidSubAuthorityCount, IsValidSid, SID, SID_IDENTIFIER_AUTHORITY


IsTokenRestricted

The IsTokenRestricted function indicates whether a token contains a list of restricted SIDs.

BOOL IsTokenRestricted(
  HANDLE TokenHandle    // handle to access token
);

Parameters

TokenHandle
[in] Handle to an access token to test.

Return Values

If the token contains a list of restricting SIDs, the return value is nonzero.

If the token does not contain a list of restricting SIDs, the return value is zero.

If an error occurs, the return value is zero. To get extended error information, call GetLastError.

Remarks

The CreateRestrictedToken function can restrict a token by disabling SIDs, deleting privileges, and specifying a list of restricting SIDs. The IsTokenRestricted function checks only for the list of restricting SIDs. If a token does not have any restricting SIDs, IsTokenRestricted returns FALSE, even though the token was created by a call to CreateRestrictedToken.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, CreateRestrictedToken


IsValidSid

The IsValidSid function validates a security identifier (SID) by verifying that the revision number is within a known range, and that the number of subauthorities is less than the maximum.

BOOL IsValidSid(
  PSID pSid   // SID to verify
);

Parameters

pSid
[in] Pointer to the SID structure to validate. This parameter cannot be NULL.

Return Values

If the SID structure is valid, the return value is nonzero.

If the SID structure is not valid, the return value is zero. There is no extended error information for this function; do not call GetLastError.

Remarks

If pSid is NULL, the application will fail with an access violation.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, GetLengthSid, GetSidIdentifierAuthority, GetSidLengthRequired, GetSidSubAuthority, GetSidSubAuthorityCount, SID


LookupAccountName

The LookupAccountName function accepts the name of a system and an account as input. It retrieves a security identifier (SID) for the account and the name of the domain on which the account was found.

BOOL LookupAccountName(
  LPCTSTR lpSystemName,   // system name
  LPCTSTR lpAccountName,  // account name
  PSID Sid,               // security identifier
  LPDWORD cbSid,          // size of security identifier
  LPTSTR DomainName,      // domain name
  LPDWORD cbDomainName,   // size of domain name
  PSID_NAME_USE peUse     // SID-type indicator
);

Parameters

lpSystemName
[in] Pointer to a null-terminated string specifying the system. This string can be the name of a remote computer. If this string is NULL, the account name is looked up on the local system.
lpAccountName
[in] Pointer to a null-terminated string specifying the account name.
Sid
[out] Pointer to a buffer receiving the SID structure that corresponds to the account name, pointed to by the lpAccountName parameter. If this parameter is NULL, the function returns the required buffer size.
cbSid
[in, out] Pointer to a variable. On input, this value specifies the size, in bytes, of the Sid buffer. If the function fails because the buffer is too small, this variable receives the required buffer size. If the Sid parameter is NULL, this parameter must be zero.
DomainName
[out] Pointer to a buffer receiving the name of the domain where the account name is found. If this parameter is NULL, the function returns the required buffer size.
cbDomainName
[in, out] Pointer to a variable. On input, this value specifies the size, in TCHARs, of the DomainName buffer. If the function fails because the buffer is too small, this variable receives the required buffer size, including the terminating null character. If the DomainName parameter is NULL, this parameter must be zero.
peUse
[out] Pointer to a SID_NAME_USE enumerated type indicating the type of the account when the function returns.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The LookupAccountName function attempts to find a SID for the specified name by first checking a list of well-known SIDs. If the name does not correspond to a well-known SID, the function checks built-in and administratively defined local accounts. Next, the function checks the primary domain. If the name is not found there, trusted domains are checked.

Windows 2000 or later: In addition to lookup local accounts, local domain accounts, and explicitly trusted domain accounts, LookupAccountName can look up the name for any account in any domain in the Windows 2000 forest.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Access Control Overview, Access Control Functions, EqualPrefixSid, GetUserName, LookupAccountSid


LookupAccountSid

The LookupAccountSid function accepts a security identifier (SID) as input. It retrieves the name of the account for this SID and the name of the first domain on which this SID is found.

BOOL LookupAccountSid(
  LPCTSTR lpSystemName,  // name of local or remote computer
  PSID Sid,              // security identifier
  LPTSTR Name,           // account name buffer
  LPDWORD cbName,        // size of account name buffer
  LPTSTR DomainName,     // domain name
  LPDWORD cbDomainName,  // size of domain name buffer
  PSID_NAME_USE peUse    // SID type
);

Parameters

lpSystemName
[in] Pointer to a null-terminated string specifying the target computer. This string can be the name of a remote computer. If this string is NULL, the SID is looked up on the local computer.
Sid
[in] Pointer to the SID to look up.
Name
[out] Pointer to a buffer that receives a null-terminated string containing the account name corresponding to the Sid parameter.
cbName
[in, out] On input, specifies the size, in characters, of the Name buffer. If the function fails because the buffer is too small, cbName receives the required buffer size, including the terminating null character.
DomainName
[out] Pointer to a buffer that receives a null-terminated string containing the name of the domain where the account name was found.

For Microsoft Windows NT/Windows 2000 systems, the domain name returned for most accounts in the local computer's security database is the computer's name as of the last start of the system (backslashes are excluded). If the computer's name changes, the old name continues to be returned as the domain name until the system is restarted.

For Microsoft Windows NT Server/Windows 2000 Server systems, the domain name returned for most accounts in the local computer's security database is the name of the domain for which the server is a domain controller.

Some accounts are predefined by the system. The domain name returned for these accounts is BUILTIN.

cbDomainName
[in, out] On input, specifies the size, in characters, of the DomainName buffer. If the function fails because the buffer is too small, cbDomainName receives the required buffer size, including the terminating null character.
peUse
[out] Pointer to a variable that receives a SID_NAME_USE value indicating the type of the account.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The LookupAccountSid function attempts to find a name for the specified SID by first checking a list of well-known SIDs. If the supplied SID does not correspond to a well-known SID, the function checks built-in and administratively defined local accounts. Next, the function checks the primary domain. Security identifiers not recognized by the primary domain are checked against the trusted domains corresponding to their SID prefixes.

LookupAccountSid fails and GetLastError returns ERROR_NONE_MAPPED if it cannot find an account name for the SID. This can occur if a network time-out prevents the function from finding the name. It also occurs for SIDs that have no corresponding account name, such as a logon SID that identifies a logon session.

Windows 2000 or later: In addition to looking up SIDs for local accounts, local domain accounts, and explicitly trusted domain accounts, LookupAccountSid can look up SIDs for any account in any domain in the Windows 2000 forest, including SIDs that appear only in the SIDhistory field of an account in the forest. The SIDhistory field stores former SIDs of an account that has been moved from another domain. To perform these look-ups, the function queries the global catalog of the forest. However, these look-ups require that the computer from which LookupAccountSid is called be either running Windows 2000 or in a domain running in Windows 2000 native mode. Account lookup by SIDhistory is not possible if the calling computer is a Windows NT 4.0 system in either a Windows NT 4.0 domain or a mixed-mode Windows 2000 domain.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Access Control Overview, Access Control Functions, EqualPrefixSid, LookupAccountName


LookupPrivilegeDisplayName

The LookupPrivilegeDisplayName function retrieves a displayable name representing a specified privilege.

BOOL LookupPrivilegeDisplayName(
  LPCTSTR lpSystemName,  // system name
  LPCTSTR lpName,        // privilege name
  LPTSTR lpDisplayName,  // displayable name
  LPDWORD cbDisplayName, // size of displayable name
  LPDWORD lpLanguageId   // language identifier
);

Parameters

lpSystemName
[in] Pointer to a null-terminated string specifying the name of the system on which the displayable privilege name is looked up. If a null string is specified, the function attempts to find the displayable name on the local system.
lpName
[in] Pointer to a null-terminated string that specifies the name of the privilege, as defined in the Winnt.h header file. For example, this parameter could specify the constant SE_REMOTE_SHUTDOWN_NAME, or its corresponding string, "SeRemoteShutdownPrivilege".
lpDisplayName
[out] Pointer to a buffer receiving a null-terminated string giving the privilege's displayable name. For example, if the lpName parameter is SE_REMOTE_SHUTDOWN_NAME, the displayable name is "Force shutdown from a remote system."
cbDisplayName
[in, out] Pointer to a variable specifying the size, in characters, of the lpDisplayName buffer. When the function returns, this parameter contains the length of the displayable privilege name, not including the terminating null character. If the buffer pointed to by the lpDisplayName parameter is too small, this variable contains the required size when the function returns.
lpLanguageId
[out] Pointer to a variable receiving the language identifier for the returned displayable name.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The LookupPrivilegeDisplayName function retrieves display names only for the privileges specified in the Defined Privileges section of Winnt.h.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Access Control Overview, Access Control Functions, LookupPrivilegeName, LookupPrivilegeValue


LookupPrivilegeName

The LookupPrivilegeName function retrieves the name corresponding to the privilege represented on a specific system by a specified locally unique identifier (LUID).

BOOL LookupPrivilegeName(
  LPCTSTR lpSystemName,  // system name
  PLUID lpLuid,          // locally unique identifier
  LPTSTR lpName,         // privilege name
  LPDWORD cbName         // displayable name
);

Parameters

lpSystemName
[in] Pointer to a null-terminated string specifying the name of the system on which the privilege name is looked up. If a null string is specified, the function attempts to find the privilege name on the local system.
lpLuid
[in] Pointer to the locally unique identifier by which the privilege is known on the target system.
lpName
[out] Pointer to a buffer that receives a null-terminated string that represents the privilege's name. For example, this string could be "SeSecurityPrivilege".
cbName
[in, out] Pointer to a variable specifying the size, in characters, of the lpName buffer. When the function returns, this parameter contains the length of the privilege name, not including the terminating null character. If the buffer pointed to by the lpName parameter is too small, this variable contains the required size when the function returns.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The LookupPrivilegeName function supports only the privileges specified in the Defined Privileges section of Winnt.h.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Access Control Overview, Access Control Functions, LookupPrivilegeDisplayName, LookupPrivilegeValue


LookupPrivilegeValue

The LookupPrivilegeValue function retrieves the locally unique identifier (LUID) used on a specified system to locally represent the specified privilege name.

BOOL LookupPrivilegeValue(
  LPCTSTR lpSystemName,  // system name
  LPCTSTR lpName,        // privilege name
  PLUID lpLuid           // locally unique identifier
);

Parameters

lpSystemName
[in] Pointer to a null-terminated string specifying the name of the system on which the privilege name is looked up. If a null string is specified, the function attempts to find the privilege name on the local system.
lpName
[in] Pointer to a null-terminated string that specifies the name of the privilege, as defined in the Winnt.h header file. For example, this parameter could specify the constant SE_SECURITY_NAME, or its corresponding string, "SeSecurityPrivilege".
lpLuid
[out] Pointer to a variable that receives the locally unique identifier by which the privilege is known on the system, specified by the lpSystemName parameter.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The LookupPrivilegeValue function supports only the privileges specified in the Defined Privileges section of Winnt.h.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Access Control Overview, Access Control Functions, LookupPrivilegeDisplayName, LookupPrivilegeName


OpenProcessToken

The OpenProcessToken function opens the access token associated with a process.

BOOL OpenProcessToken(
  HANDLE ProcessHandle, // handle to process
  DWORD DesiredAccess,  // desired access to process
  PHANDLE TokenHandle   // handle to open access token
);

Parameters

ProcessHandle
[in] Handle to the process whose access token is opened.
DesiredAccess
[in] Specifies an access mask that specifies the requested types of access to the access token. These requested access types are compared with the token's discretionary access-control list (DACL) to determine which accesses are granted or denied.

For a list of access rights for access tokens, see Access Rights for Access-Token Objects.

TokenHandle
[out] Pointer to a handle identifying the newly-opened access token when the function returns.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Remember to close the access token handle returned through the TokenHandle parameter by calling CloseHandle.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, AdjustTokenGroups, AdjustTokenPrivileges, GetTokenInformation, OpenThreadToken, SetTokenInformation


OpenThreadToken

The OpenThreadToken function opens the access token associated with a thread.

BOOL OpenThreadToken(
  HANDLE ThreadHandle,  // handle to thread
  DWORD DesiredAccess,  // access to process
  BOOL OpenAsSelf,      // process or thread security
  PHANDLE TokenHandle   // handle to open access token
);

Parameters

ThreadHandle
[in] Handle to the thread whose access token is opened.
DesiredAccess
[in] Specifies an access mask that specifies the requested types of access to the access token. These requested access types are reconciled against the token's discretionary access-control list (DACL) to determine which accesses are granted or denied.

For a list of access rights for access tokens, see Access Rights for Access-Token Objects.

OpenAsSelf
[in] Indicates whether the access check is to be made against the security context of the thread calling the OpenThreadToken function or against the security context of the process for the calling thread.

If this parameter is FALSE, the access check is performed using the security context for the calling thread. If the thread is impersonating a client, this security context can be that of a client process. If this parameter is TRUE, the access check is made using the security context of the process for the calling thread.

TokenHandle
[out] Pointer to a variable that receives a handle the newly opened access token.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The OpenAsSelf parameter allows a server process to open the access token for a client process when the client process has specified the SecurityIdentification impersonation level for the SECURITY_IMPERSONATION_LEVEL enumerated type. Without this parameter, the calling process is not be able to open the client's access token using the client's security context because it is impossible to open executive-level objects using the SecurityIdentification impersonation level.

Remember to close the access token handle returned through the TokenHandle parameter by calling CloseHandle.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, AdjustTokenGroups, AdjustTokenPrivileges, GetTokenInformation, OpenProcessToken, SetThreadToken, SetTokenInformation


SetEntriesInAcl

The SetEntriesInAcl function creates a new access-control list (ACL) by merging new access-control or audit-control information into an existing ACL.

DWORD SetEntriesInAcl(
  ULONG cCountOfExplicitEntries,           // number of entries
  PEXPLICIT_ACCESS pListOfExplicitEntries, // buffer
  PACL OldAcl,                             // original ACL
  PACL *NewAcl                             // new ACL
);

Parameters

cCountOfExplicitEntries
[in] Specifies the number of EXPLICIT_ACCESS structures in the pListOfExplicitEntries array.
pListOfExplicitEntries
[in] Pointer to an array of EXPLICIT_ACCESS structures that describe the access control information to merge into the existing ACL.
OldAcl
[in] Pointer to the existing ACL. This parameter can be NULL, in which case, the function creates a new ACL based on the EXPLICIT_ACCESS entries.
NewAcl
[out] Pointer to a variable that receives a pointer to the new ACL. If the function succeeds, you must call the LocalFree function to free the returned buffer.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in Winerror.h.

Remarks

Each entry in the array of EXPLICIT_ACCESS structures specifies access-control or audit-control information for a specified trustee. A trustee can be a user, group, or other SID value, such as a logon identifier or logon type (for instance, a Win32 service or batch job). You can use a name or a security identifier (SID) to identify a trustee.

You can use the SetEntriesInAcl function to modify the list of ACEs in a DACL or a SACL. A DACL controls access to an object, and a SACL controls the system's auditing of attempts to access an object. Note that SetEntriesInAcl does not prevent you from mixing access-control and audit-control information in the same ACL; however, the resulting ACL will contain meaningless entries.

For a DACL, the grfAccessMode member of the EXPLICIT_ACCESS structure specifies whether to allow, deny, or revoke access rights for the trustee. This member can specify one of the following values from the ACCESS_MODE enumeration.

Value | Meaning
GRANT_ACCESS | Creates a new access-allowed ACE that combines the specified rights with any existing rights of the trustee. The new ACE replaces any existing access-allowed ACE for the trustee. The function also modifies or deletes any existing access-denied ACE for the trustee that denies the specified rights.
SET_ACCESS | Similar to GRANT_ACCESS except that the new access-allowed ACE allows only the specified rights, discarding any existing rights. This flag also removes any existing access-denied ACE for the trustee.
DENY_ACCESS | Creates a new access-denied ACE that replaces any existing access-denied ACE for the trustee. The new ACE denies the specified rights in addition to any currently denied rights of the trustee.
REVOKE_ACCESS | Removes any existing ACEs for the specified trustee. The function ignores the rights specified in the grfAccessPermissions member of the EXPLICIT_ACCESS structure.

The SetEntriesInAcl function places any new access-denied ACEs at the beginning of the list of ACEs for the new ACL. It places any new access-allowed ACEs just before any existing access-allowed ACEs.

For a SACL, the grfAccessMode member of the EXPLICIT_ACCESS structure can specify the following values.

Value | Meaning
REVOKE_ACCESS | Removes any existing ACEs for the specified trustee. The function ignores the rights specified in the grfAccessPermissions member of the EXPLICIT_ACCESS structure.
SET_AUDIT_SUCCESS | Creates a new system-audit ACE that replaces any existing system-audit ACE for the trustee. The new ACE generates audit messages when the specified trustee successfully uses the specified access rights. The new ACE combines the specified rights with any existing audited access rights for the trustee. You can combine this value with SET_AUDIT_FAILURE.
SET_AUDIT_FAILURE | Creates a new system-audit ACE that replaces any existing system-audit ACE for the trustee. The new ACE generates audit messages for failed attempts to use the specified access rights. The new ACE combines the specified rights with any existing audited access rights for the trustee. You can combine this value with SET_AUDIT_SUCCESS.

The SetEntriesInAcl function places any new system-audit ACEs at the beginning of the list of ACEs for the new ACL.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Aclapi.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Access Control Overview, Access Control Functions, ACCESS_ALLOWED_ACE, ACCESS_DENIED_ACE, ACL, EXPLICIT_ACCESS, LocalFree, SYSTEM_AUDIT_ACE


SetNamedSecurityInfo

The SetNamedSecurityInfo function sets specified security information in the security descriptor of a specified object. The caller identifies the object by name.

Microsoft Windows 2000 or later: If you are setting the object's DACL or SACL, the system automatically propagates any inheritable ACEs to existing child objects, according to the rules of inheritance.

DWORD SetNamedSecurityInfo(
  LPTSTR pObjectName,                // object name
  SE_OBJECT_TYPE ObjectType,         // object type
  SECURITY_INFORMATION SecurityInfo, // type
  PSID psidOwner,                    // new owner SID
  PSID psidGroup,                    // new primary group SID
  PACL pDacl,                        // new DACL
  PACL pSacl                         // new SACL
);

Parameters

pObjectName
[in] Pointer to a null-terminated string that specifies the name of the object for which to set security information. This can be the name of a local or remote file or directory on a NTFS file system, network share, registry key, semaphore, event, mutex, file mapping, or waitable timer.

For descriptions of the string formats for the different object types, see SE_OBJECT_TYPE.

ObjectType
[in] Specifies a value from the SE_OBJECT_TYPE enumeration that indicates the type of object named by the pObjectName parameter.
SecurityInfo
[in] A set of SECURITY_INFORMATION bit flags that indicate the type of security information to set. This parameter can be a combination of the following values.
Value | Meaning
DACL_SECURITY_INFORMATION Set the discretionary access-control list (DACL) in the object's security descriptor. The pDacl parameter is a pointer to the new DACL.

If neither PROTECTED_DACL_SECURITY_INFORMATION nor UNPROTECTED_DACL_SECURITY_INFORMATION is set, the current inheritance settings are preserved.
GROUP_SECURITY_INFORMATION | Set the primary group SID in the object's security descriptor. The psidGroup parameter is a pointer to the new SID.
OWNER_SECURITY_INFORMATION | Set the owner SID in the object's security descriptor. The psidOwner parameter is a pointer to the new SID.
PROTECTED_DACL_SECURITY_INFORMATION Windows 2000 or later: Protects the DACL from inheriting ACEs.

This value is ignored unless DACL_SECURITY_INFORMATION is also used.
PROTECTED_SACL_SECURITY_INFORMATION Windows 2000 or later: Protects the SACL from inheriting ACEs.

This value is ignored unless SACL_SECURITY_INFORMATION is also used.
SACL_SECURITY_INFORMATION Set the system access-control list (SACL) in the object's security descriptor. The pSacl parameter is a pointer to the new SACL.

If neither PROTECTED_SACL_SECURITY_INFORMATION nor UNPROTECTED_SACL_SECURITY_INFORMATION is set, the current inheritance settings are preserved.
UNPROTECTED_DACL_SECURITY_INFORMATION Windows 2000 or later: Inherits ACEs from the parent whenever applicable.

This value is ignored unless DACL_SECURITY_INFORMATION is also used.
UNPROTECTED_SACL_SECURITY_INFORMATION Windows 2000 or later: Inherits ACEs from the parent whenever applicable.

This value is ignored unless SACL_SECURITY_INFORMATION is also used.

psidOwner
[in] Pointer to a SID that identifies the object's owner. The SID must be one that can be assigned as the owner SID of a security descriptor. The SecurityInfo parameter must include the OWNER_SECURITY_INFORMATION flag. The caller must have WRITE_OWNER access to the object or have the SE_TAKE_OWNERSHIP_NAME privilege enabled. This parameter can be NULL if you are not setting the owner SID.
psidGroup
[in] Pointer to a SID that identifies the object's primary group. The SecurityInfo parameter must include the GROUP_SECURITY_INFORMATION flag. This parameter can be NULL if you are not setting the primary group SID.
pDacl
[in] Pointer to the new DACL for the object. The SecurityInfo parameter must include the DACL_SECURITY_INFORMATION flag. The caller must have WRITE_DAC access to the object or be the object's owner. This parameter can be NULL if you are not setting the DACL.
pSacl
[in] Pointer to the new SACL for the object. The SecurityInfo parameter must include the SACL_SECURITY_INFORMATION flag. The caller must have the SE_SECURITY_NAME privilege enabled. This parameter can be NULL if you are not setting the SACL.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in Winerror.h.

Remarks

You can use the SetNamedSecurityInfo function with the following types of objects:

  • Local or remote files or directories on an NTFS file system
  • Local or remote printers
  • Local or remote Win32 services
  • Network shares
  • Registry keys
  • Semaphores, events, mutexes, and waitable timers
  • File-mapping objects
  • Directory service objects

The SetNamedSecurityInfo function does not reorder access-allowed or access-denied ACEs based on the preferred order. When propagating inheritable ACEs to existing child objects, SetNamedSecurityInfo puts inherited ACEs in order after all of the non-inherited ACEs in the DACLs of the child objects.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Aclapi.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Access Control Overview, Access Control Functions, ACL, GetNamedSecurityInfo, GetSecurityInfo, SE_OBJECT_TYPE, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetSecurityInfo, SID


SetSecurityDescriptorControl

The SetSecurityDescriptorControl function sets the control bits of a security descriptor. The function can set only the control bits that relate to automatic inheritance of ACEs. To set the other control bits of a security descriptor, use the Win32 functions, such as SetSecurityDescriptorDacl, for modifying the components of a security descriptor.

BOOL SetSecurityDescriptorControl(
  PSECURITY_DESCRIPTOR pSecurityDescriptor,          // SD
  SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest, // control bits
  SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet       // new control bits
);

Parameters

pSecurityDescriptor
[in] Pointer to a SECURITY_DESCRIPTOR structure whose control and revision information are set.
ControlBitsOfInterest
[in] A SECURITY_DESCRIPTOR_CONTROL mask that indicates the control bits to set. This mask can be a combination of the following flags.
Value | Meaning
SE_DACL_AUTO_INHERIT_REQ | Requests that the provider for the object protected by the security descriptor automatically propagate the DACL to existing child objects. If the provider supports automatic inheritance, it propagates the DACL to any existing child objects, and sets the SE_DACL_AUTO_INHERITED bit in the security descriptors of the object and its child objects.
SE_DACL_AUTO_INHERITED Indicates a security descriptor in which the DACL is set up to support automatic propagation of inheritable ACEs to existing child objects. This bit is set only if the automatic inheritance algorithm has been performed for the object and its existing child objects.

This bit is not set in security descriptors for Windows NT versions 4.0 and earlier, which did not support automatic propagation of inheritable ACEs.
SE_DACL_PROTECTED | Protects the DACL of the security descriptor from being modified by inheritable ACEs.
SE_SACL_AUTO_INHERIT_REQ | Requests that the provider for the object protected by the security descriptor automatically propagate the SACL to existing child objects. If the provider supports automatic inheritance, it propagates the SACL to any existing child objects, and sets the SE_SACL_AUTO_INHERITED bit in the security descriptors of the object and its child objects.
SE_SACL_AUTO_INHERITED Indicates a security descriptor in which the SACL is set up to support automatic propagation of inheritable ACEs to existing child objects. This bit is set only if the automatic inheritance algorithm has been performed for the object and its existing child objects.

This bit is not set in security descriptors for Microsoft Windows NT versions 4.0 and earlier, which did not support automatic propagation of inheritable ACEs.
SE_SACL_PROTECTED | Protects the SACL of the security descriptor from being modified by inheritable ACEs.

ControlBitsToSet
[in] A SECURITY_DESCRIPTOR_CONTROL mask that indicates the new values for the control bits specified by the ControlBitsOfInterest mask. This parameter can be a combination of the flags listed for the ControlBitsOfInterest parameter.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The SetSecurityDescriptorControl function specifies the control bit or bits to modify, and whether the bits are on or off. For example, the following code marks the DACL on the security descriptor as protected:

    SetSecurityDescriptorControl( &SecDesc,
            SE_DACL_PROTECTED, SE_DACL_PROTECTED );

And this code marks the DACL as not protected:

    SetSecurityDescriptorControl( &SecDesc,
            SE_DACL_PROTECTED, 0 );

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, GetSecurityDescriptorControl, SECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL


SetSecurityDescriptorRMControl

The SetSecurityDescriptorRMControl function sets the resource manager control bits in the SECURITY_DESCRIPTOR structure.

DWORD SetSecurityDescriptorRMControl(
  PSECURITY DESCRIPTOR SecurityDescriptor,
  PUCHAR RMControl
);

Parameters

SecurityDescriptor
[in] Pointer to a SECURITY_DESCRIPTOR structure that contains the resource manager control bits.
RMControl
[out] Pointer to the bit field value the resource manager control bits in the SECURITY_DESCRIPTOR structure will be set to. If the value of this parameter is NULL, the resource manager control bits will be cleared.

Return Values

The return value is ERROR_SUCCESS.

Remarks

The resource manager control bits are eight bits in the Sbz1 member of the SECURITY_INFORMATION structure that contains information specific to the resource manager accessing the structure. These bits should be accessed only through the GetSecurityDescriptorRMControl and SetSecurityDescriptorRMControl functions.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, GetSecurityDescriptorRMControl, SECURITY_DESCRIPTOR, SECURITY_INFORMATION


SetSecurityInfo

The SetSecurityInfo function sets specified security information in the security descriptor of a specified object. The caller identifies the object by a handle.

Microsoft Windows 2000 or later: If you are setting the object's DACL or SACL, the system automatically propagates any inheritable ACEs to existing child objects, according to the rules of inheritance.

DWORD SetSecurityInfo(
  HANDLE handle,                     // handle to object
  SE_OBJECT_TYPE ObjectType,         // object type
  SECURITY_INFORMATION SecurityInfo, // buffer
  PSID psidOwner,                    // new owner SID
  PSID psidGroup,                    // new primary group SID
  PACL pDacl,                        // new DACL
  PACL pSacl                         // new SACL
);

Parameters

handle
[in] Handle to the object for which to set security information.
ObjectType
[in] Specifies a value from the SE_OBJECT_TYPE enumeration that indicates the type of object identified by the handle parameter.
SecurityInfo
[in] Specifies the components of the security descriptor to set. This parameter can be a combination of the following values.
Value | Meaning
DACL_SECURITY_INFORMATION Set the discretionary access-control list (DACL) in the object's security descriptor. The pDacl parameter is a pointer to the new DACL.

If neither PROTECTED_DACL_SECURITY_INFORMATION nor UNPROTECTED_DACL_SECURITY_INFORMATION is set, the current inheritance settings are preserved.
GROUP_SECURITY_INFORMATION | Set the primary group SID in the object's security descriptor. The psidGroup parameter is a pointer to the new SID.
OWNER_SECURITY_INFORMATION | Set the owner SID in the object's security descriptor. The psidOwner parameter is a pointer to the new SID.
PROTECTED_DACL_SECURITY_INFORMATION Windows 2000 or later: Protect the DACL from inheriting ACEs.

This value is ignored unless DACL_SECURITY_INFORMATION is also used.
PROTECTED_SACL_SECURITY_INFORMATION Windows 2000 or later: Protect the SACL from inheriting ACEs.

This value is ignored unless SACL_SECURITY_INFORMATION is also used.
SACL_SECURITY_INFORMATION Set the system access-control list (SACL) in the object's security descriptor. The pSacl parameter is a pointer to the new SACL.

If neither PROTECTED_SACL_SECURITY_INFORMATION nor UNPROTECTED_SACL_SECURITY_INFORMATION is set, the current inheritance settings are preserved.
UNPROTECTED_DACL_SECURITY_INFORMATION Windows 2000 or later: Inherit ACEs from the parent whenever applicable.

This value is ignored unless DACL_SECURITY_INFORMATION is also used.
UNPROTECTED_SACL_SECURITY_INFORMATION Windows 2000 or later: Inherit ACEs from the parent whenever applicable.

This value is ignored unless SACL_SECURITY_INFORMATION is also used.

psidOwner
[in] Pointer to a SID that identifies the object's owner. The SID must be one that can be assigned as the owner SID of a security descriptor. The SecurityInfo parameter must include the OWNER_SECURITY_INFORMATION flag. This parameter can be NULL if you are not setting the owner SID.
psidGroup
[in] Pointer to a SID that identifies the object's primary group. The SecurityInfo parameter must include the GROUP_SECURITY_INFORMATION flag. This parameter can be NULL if you are not setting the primary group SID.
pDacl
[in] Pointer to the new DACL for the object. The SecurityInfo parameter must include the DACL_SECURITY_INFORMATION flag. This parameter can be NULL if you are not setting the DACL.
pSacl
[in] Pointer to the new SACL for the object. The SecurityInfo parameter must include the SACL_SECURITY_INFORMATION flag. This parameter can be NULL if you are not setting the SACL.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in Winerror.h.

Remarks

You can use the SetSecurityInfo function with the following types of objects:

  • Local or remote files or directories on an NTFS file system
  • Named pipes
  • Local or remote printers
  • Local or remote Win32 services
  • Network shares
  • Registry keys
  • Semaphores, events, mutexes, and waitable timers
  • Processes, threads, jobs, and file-mapping objects
  • Window stations and desktops
  • Directory service objects

The SetSecurityInfo function does not reorder access-allowed or access-denied ACEs based on the preferred order. When propagating inheritable ACEs to existing child objects, SetSecurityInfo puts inherited ACEs in order after all of the non-inherited ACEs in the DACLs of the child objects.

Note If share access to the children of the object is not available, this function will not propagate non-protected ACEs to the children. For example, if a directory is opened with exclusive access, the operating system will not propagate non-protected ACEs to that directory's subdirectories or files when the security on the directory, itself, is changed.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Aclapi.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, ACL, GetNamedSecurityInfo, GetSecurityInfo, SE_OBJECT_TYPE, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetNamedSecurityInfo, SID


SetThreadToken

The SetThreadToken function assigns an impersonation token to a thread. The function can also cause a thread to stop using an impersonation token.

BOOL SetThreadToken(
  PHANDLE Thread,  // pointer to handle to thread
  HANDLE Token     // handle to impersonation token
);

Parameters

Thread
[in] Pointer to a handle to the thread to which the function assigns the impersonation token.

If Thread is NULL, the function assigns the impersonation token to the calling thread.

Token
[in] Handle to the impersonation token to assign to the thread. This handle must have been opened with TOKEN_IMPERSONATE access rights. For more information, see Access Rights for Access-Token Objects.

If Token is NULL, the function causes the thread to stop using an impersonation token.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, OpenThreadToken


SetTokenInformation

The SetTokenInformation function sets various types of information for a specified access token. The information it sets replaces existing information. The calling process must have appropriate access rights to set the information.

BOOL SetTokenInformation(
  HANDLE TokenHandle,                            // handle to access token
  TOKEN_INFORMATION_CLASS TokenInformationClass, // type
  LPVOID TokenInformation,                       // buffer
  DWORD TokenInformationLength                   // size of buffer
);

Parameters

TokenHandle
[in] Handle to the access token for which information is to be set.
TokenInformationClass
[in] Specifies a value from the TOKEN_INFORMATION_CLASS enumerated type identifying the type of information the function sets. The valid values from TOKEN_INFORMATION_CLASS are TokenOwner, TokenPrimaryGroup, and TokenDefaultDacl. For more information about these values, see the description of the TokenInformation parameter, following.
TokenInformation
[in] Pointer to a buffer containing the information set in the access token. The structure of this buffer depends on the type of information specified by the TokenInformationClass parameter. The following three values are valid in calls to this function:
Token Information Class | Structure Provided
TokenOwner | TOKEN_OWNER structure. The TOKEN_ADJUST_DEFAULT access right is needed to set owner information. A valid owner value is a user or group identifier with an attribute allowing assignment as the owner of objects.
TokenPrimaryGroup | TOKEN_PRIMARY_GROUP structure. The TOKEN_ADJUST_DEFAULT access right is needed to set primary group information.
TokenDefaultDacl | TOKEN_DEFAULT_DACL structure. The TOKEN_ADJUST_DEFAULT access right is needed to set information in the default discretionary access-control list (ACL). The ACL structure provided as a new default discretionary ACL is not validated for correctness or consistency. If the TokenInformation parameter is NULL, the current default discretionary ACL is removed and no replacement is established.

The formats for the structures this function can set are listed in the following Remarks section.

TokenInformationLength
[in] Specifies the length, in bytes, of the buffer pointed to by TokenInformation.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

To set privilege information, an application can call the AdjustTokenPrivileges function. To set a token's groups, an application can call the AdjustTokenGroups function.

Token-type information can be set only when an access token is created.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Access Control Overview, Access Control Functions, AdjustTokenGroups, AdjustTokenPrivileges, GetTokenInformation, OpenProcessToken, OpenThreadToken, TOKEN_DEFAULT_DACL, TOKEN_INFORMATION_CLASS, TOKEN_OWNER, TOKEN_PRIMARY_GROUP


Access Control Structures

The following structures are used with access control.

ACCESS_MASK
ACE
ACE_HEADER
ACL
EXPLICIT_ACCESS
LUID
LUID_AND_ATTRIBUTES
OBJECTS_AND_NAME
OBJECTS_AND_SID
SECURITY_ATTRIBUTES
SECURITY_DESCRIPTOR
SECURITY_INFORMATION
SID
SID_AND_ATTRIBUTES
SID_IDENTIFIER_AUTHORITY
TOKEN_CONTROL
TOKEN_DEFAULT_DACL
TOKEN_GROUPS
TOKEN_OWNER
TOKEN_PRIMARY_GROUP
TOKEN_PRIVILEGES
TOKEN_SOURCE
TOKEN_STATISTICS
TOKEN_USER
TRUSTEE


ACCESS_MASK

The ACCESS_MASK structure is one doubleword value containing standard, specific, and generic rights. These rights are used in access-control entries (ACEs) and are the primary means of specifying the requested or granted access to an object.

typedef DWORD ACCESS_MASK;

The bits in this value are allocated as follows.

Bits | Meaning
0 through 15 | Specific rights. Contains the access mask specific to the object type associated with the mask.
16 through 23 | Standard rights. Contains the object's standard access rights and can be a combination of the following predefined flags:
 | Bit | Flag | Meaning
 | 16 | DELETE | Delete access
 | 17 | READ_CONTROL | Read access to the owner, group, and discretionary access-control list (ACL) of the security descriptor
 | 18 | WRITE_DAC | Write access to the discretionary access-control list (ACL)
 | 19 | WRITE_OWNER | Write access to owner
 | 20 | SYNCHRONIZE | Windows NT/2000 or later: Synchronize access
Bits | Meaning
24 | Access system security (ACCESS_SYSTEM_SECURITY). This flag is not a typical access type. It is used to indicate access to a system ACL. This type of access requires the calling process to SE_SECURITY_NAME (Manage auditing and security log) privilege. If this flag is set in the access mask of an audit access ACE (successful or unsuccessful access), the SACL access will be audited.
25 | Maximum allowed (MAXIMUM_ALLOWED)
26 through 27 | Reserved
28 | Generic all (GENERIC_ALL)
29 | Generic execute (GENERIC_EXECUTE)
30 | Generic write (GENERIC_WRITE)
31 | Generic read (GENERIC_READ)

The following constants represent the specific and standard access rights:

#define SPECIFIC_RIGHTS_ALL           0x0000FFFF
#define STANDARD_RIGHTS_REQUIRED      0x000F0000
#define STANDARD_RIGHTS_ALL           0x001F0000

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Structures, GENERIC_MAPPING, Access Rights and Access Masks


ACE

An ACE is an access-control entry (ACE) in an access-control list (ACL).

Following are the currently defined ACE types.

ACE type | Structure | ACL type
Access allowed | ACCESS_ALLOWED_ACE | Discretionary
Access allowed, object-specific | ACCESS_ALLOWED_OBJECT_ACE | Discretionary
Access denied | ACCESS_DENIED_ACE | Discretionary
Access denied, object-specific | ACCESS_DENIED_OBJECT_ACE | Discretionary
System alarm | SYSTEM_ALARM_ACE | System
System alarm, object-specific | SYSTEM_ALARM_OBJECT_ACE | System
System audit | SYSTEM_AUDIT_ACE | System
System audit, object-specific | SYSTEM_AUDIT_OBJECT_ACE | System

System-alarm and object-specific system-alarm ACEs are not currently supported.

Remarks

An ACL contains a list of ACEs. An ACE defines access to an object for a specific user or group or defines the types of access that generate system-administration messages or alarms for a specific user or group. The user or group is identified by a security identifier (SID).

Each ACE starts with an ACE_HEADER structure. The format of the data following the header varies according to the ACE type specified in the header.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Structures, AddAce, ACCESS_ALLOWED_ACE, ACCESS_DENIED_ACE, ACL, SYSTEM_ALARM_ACE, SYSTEM_AUDIT_ACE


ACE_HEADER

The ACE_HEADER structure describes the type and size of an access-control entry (ACE).

typedef struct _ACE_HEADER {
  BYTE AceType;
  BYTE AceFlags;
  WORD AceSize;
} ACE_HEADER;
typedef ACE_HEADER *PACE_HEADER;

Members

AceType
Specifies the ACE type. This member can be one of the following values:
Value | Meaning
ACCESS_ALLOWED_ACE_TYPE | Access-allowed ACE that uses the ACCESS_ALLOWED_ACE structure.
ACCESS_ALLOWED_OBJECT_ACE_TYPE | Windows 2000 or later: Object-specific access-allowed ACE that uses the ACCESS_ALLOWED_OBJECT_ACE structure.
ACCESS_DENIED_ACE_TYPE | Access-denied ACE that uses the ACCESS_DENIED_ACE structure.
ACCESS_DENIED_OBJECT_ACE_TYPE | Windows 2000 or later: Object-specific access-denied ACE that uses the ACCESS_DENIED_OBJECT_ACE structure.
SYSTEM_AUDIT_ACE_TYPE | System-audit ACE that uses the SYSTEM_AUDIT_ACE structure.
SYSTEM_AUDIT_OBJECT_ACE_TYPE | Windows 2000 or later: Object-specific system-audit ACE that uses the SYSTEM_AUDIT_OBJECT_ACE structure.

AceFlags
Specifies a set of ACE type-specific control flags. This member can be a combination of the following values:
Value | Meaning
CONTAINER_INHERIT_ACE | Child objects that are containers, such as directories, inherit the ACE as an effective ACE. The inherited ACE is inheritable unless the NO_PROPAGATE_INHERIT_ACE bit flag is also set.
FAILED_ACCESS_ACE_FLAG | Used with system-audit ACEs in a SACL to generate audit messages for failed access attempts.
INHERIT_ONLY_ACE Indicates an inherit-only ACE which does not control access to the object to which it is attached. If this flag is not set, the ACE is an effective ACE which controls access to the object to which it is attached.

Both effective and inherit-only ACEs can be inherited depending on the state of the other inheritance flags.

INHERITED_ACE | Windows 2000 or later: Indicates that the ACE was inherited. The system sets this bit when it propagates an inherited ACE to a child object.
NO_PROPAGATE_INHERIT_ACE | If the ACE is inherited by a child object, the system clears the OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE flags in the inherited ACE. This prevents the ACE from being inherited by subsequent generations of objects.
OBJECT_INHERIT_ACE Noncontainer child objects inherit the ACE as an effective ACE.

For child objects that are containers, the ACE is inherited as an inherit-only ACE unless the NO_PROPAGATE_INHERIT_ACE bit flag is also set.
SUCCESSFUL_ACCESS_ACE_FLAG | Used with system-audit ACEs in a SACL to generate audit messages for successful access attempts.

AceSize
Specifies the size, in bytes, of the ACE.

Remarks

The ACE_HEADER structure is the first member of the various types of ACE structures, such as ACCESS_ALLOWED_ACE.

System-alarm ACEs are not currently supported. The AceType member cannot specify the SYSTEM_ALARM_ACE_TYPE or SYSTEM_ALARM_OBJECT_ACE_TYPE values. Do not use the SYSTEM_ALARM_ACE or SYSTEM_ALARM_OBJECT_ACE structures.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Structures, ACCESS_ALLOWED_ACE, ACCESS_ALLOWED_OBJECT_ACE, ACCESS_DENIED_ACE, ACCESS_DENIED_OBJECT_ACE, ACL, SYSTEM_AUDIT_ACE, SYSTEM_AUDIT_OBJECT_ACE


ACL

The ACL structure is the header of an access-control list (ACL). A complete ACL consists of an ACL structure followed by an ordered list of zero or more access-control entries (ACEs).

typedef struct _ACL {
  BYTE AclRevision;
  BYTE Sbz1;
  WORD AclSize;
  WORD AceCount;
  WORD Sbz2;
} ACL;
typedef ACL *PACL;

Members

AclRevision
Specifies the ACL's revision level. This value should be ACL_REVISION. All ACEs in an ACL must be at the same revision level.

Windows 2000: If the ACL contains an object-specific ACE, this value must be ACL_REVISION_DS.

Sbz1
Specifies a zero byte of padding that aligns the AclRevision member on a 16-bit boundary.
AclSize
Specifies the size, in bytes, of the ACL. This value includes both the ACL structure and all the ACEs.
AceCount
Specifies the number of ACEs stored in the ACL.
Sbz2
Specifies two zero bytes of padding that align the ACL structure on a 32-bit boundary.

Remarks

An ACL includes a sequential list of zero or more ACEs. The individual ACEs in an ACL are numbered from 0 to n, where n+1 is the number of ACEs in the ACL. When editing an ACL, an application refers to an ACE within the ACL by its index.

There are two types of ACL: discretionary and system.

A discretionary ACL is controlled by the owner of an object or anyone granted WRITE_DAC access to the object. It specifies the access particular users and groups can have to an object. For example, the owner of a file can use a discretionary ACL to control which users and groups can and cannot have access to the file.

An object may also have system-level security information associated with it, in the form of a system ACL controlled by a system administrator. A system ACL can allow the system administrator to audit any attempts to gain access to an object.

Three ACE structures are currently defined:

ACE structure | Description
ACCESS_ALLOWED_ACE | Grants specified rights to a user or group. This ACE is stored in a discretionary ACL.
ACCESS_DENIED_ACE | Denies specified rights to a user or group. This ACE is stored in a discretionary ACL.
SYSTEM_AUDIT_ACE | Specifies what types of access will cause system-level audits. This ACE is stored in a system ACL.

A fourth ACE structure, SYSTEM_ALARM_ACE, is not currently supported.

The ACL structure is to be treated as though it were opaque and applications are not to attempt to work with its members directly. To ensure that ACLs are semantically correct, applications can use the functions listed in the See Also section to create and manipulate ACLs.

Each ACL and ACE structure begins on a doubleword boundary.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Structures, AddAce, DeleteAce, GetAclInformation, GetSecurityDescriptorDacl, GetSecurityDescriptorSacl, InitializeAcl, IsValidAcl, SetAclInformation, SetSecurityDescriptorDacl, SetSecurityDescriptorSacl


EXPLICIT_ACCESS

The EXPLICIT_ACCESS structure specifies access-control information for a specified trustee. Access control functions, such as SetEntriesInAcl and GetExplicitEntriesFromAcl, use this structure to describe the information in an access-control entry (ACE) of an access-control list (ACL).

typedef struct _EXPLICIT_ACCESS {
  DWORD        grfAccessPermissions;
  ACCESS_MODE  grfAccessMode;
  DWORD        grfInheritance;
  TRUSTEE      Trustee;
} EXPLICIT_ACCESS, *PEXPLICIT_ACCESS;

Members

grfAccessPermissions
A set of bit flags that use the ACCESS_MASK format to specify the access rights that an ACE allows, denies, or audits for the trustee. The functions that use the EXPLICIT_ACCESS structure do not convert, interpret, or validate the bits in this mask.
grfAccessMode
Specifies a value from the ACCESS_MODE enumeration. For a discretionary ACL (DACL), this flag indicates whether the ACL allows or denies the specified access rights. For a system ACL (SACL), this flag indicates whether the ACL generates audit messages for successful attempts to use the specified access rights, or failed attempts, or both. When modifying an existing ACL, you can specify the REVOKE_ACCESS flag to remove any existing ACEs for the specified trustee.
grfInheritance
A set of bit flags that determines whether other containers or objects can inherit the ACE from the primary object to which the ACL is attached. The value of this member corresponds to the inheritance portion (low-order byte) of the AceFlags member of the ACE_HEADER structure. This parameter can be NO_INHERITANCE to indicate that the ACE is not inheritable; or it can be a combination of the following values.
Value | Meaning
CONTAINER_INHERIT_ACE | Other containers that are contained by the primary object inherit the ACE.
INHERIT_ONLY_ACE | The ACE does not apply to the primary object to which the ACL is attached, but objects contained by the primary object inherit the ACE.
NO_PROPAGATE_INHERIT_ACE | The OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE flags are not propagated to an inherited ACE.
OBJECT_INHERIT_ACE | Noncontainer objects contained by the primary object inherit the ACE.
SUB_CONTAINERS_AND_OBJECTS_INHERIT | Both containers and noncontainer objects that are contained by the primary object inherit the ACE. This flag corresponds to the combination of the CONTAINER_INHERIT_ACE and OBJECT_INHERIT_ACE flags.
SUB_CONTAINERS_ONLY_INHERIT | Other containers that are contained by the primary object inherit the ACE. This flag corresponds to the CONTAINER_INHERIT_ACE flag.
SUB_OBJECTS_ONLY_INHERIT | Noncontainer objects contained by the primary object inherit the ACE. This flag corresponds to the OBJECT_INHERIT_ACE flag.

Trustee
A TRUSTEE structure that identifies the user, group, or program (such as a Win32 service) to which the ACE applies.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Accctrl.h.
Unicode: Declared as Unicode and ANSI structures.

See Also

Access Control Overview, Access Control Structures, ACCESS_MODE, ACE, ACE_HEADER, ACL, BuildExplicitAccessWithName, BuildSecurityDescriptor, GetExplicitEntriesFromAcl, LookupSecurityDescriptorParts, SetEntriesInAcl, TRUSTEE


LUID

An LUID is a 64-bit value guaranteed to be unique only on the system on which it was generated. The uniqueness of a locally unique identifier (LUID) is guaranteed only until the system is restarted.

An LUID is not for direct manipulation. Applications are to use functions and structures to manipulate LUID values.

typedef struct _LUID {
  DWORD LowPart;
  LONG HighPart;
} LUID, *PLUID;

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Structures, AllocateLocallyUniqueId, LookupPrivilegeName, LookupPrivilegeValue, PrivilegeCheck, LUID_AND_ATTRIBUTES, PRIVILEGE_SET


LUID_AND_ATTRIBUTES

The LUID_AND_ATTRIBUTES structure represents a locally unique identifier (LUID) and its attributes.

typedef struct _LUID_AND_ATTRIBUTES {
  LUID   Luid;
  DWORD  Attributes;
} LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES;

Members

Luid
Specifies an LUID value.
Attributes
Specifies attributes of the LUID. This value contains up to 32 one-bit flags. Its meaning is dependent on the definition and use of the LUID.

Remarks

An LUID_AND_ATTRIBUTES structure can represent an LUID whose attributes change frequently, such as when it is used to represent privileges in the PRIVILEGE_SET structure. Privileges are represented by LUIDs and have attributes indicating whether they are currently enabled or disabled.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Structures, AllocateLocallyUniqueId, LUID, PRIVILEGE_SET, TOKEN_PRIVILEGES


OBJECTS_AND_NAME

The OBJECTS_AND_NAME structure contains a string that identifies a trustee by name and additional strings that identify the object types of an object-specific ACE.

typedef struct _OBJECTS_AND_NAME {
  DWORD          ObjectsPresent;
  SE_OBJECT_TYPE ObjectType;
  LPTSTR   ObjectTypeName
  LPTSTR   InheritedObjectTypeName;
  LPTSTR   ptstrName;
} OBJECTS_AND_NAME, *POBJECTS_AND_NAME;

Members

ObjectsPresent
Indicates whether the ObjectTypeName and InheritedObjectTypeName members contain strings. This parameter can be a combination of the following values.
Value | Meaning
ACE_OBJECT_TYPE_PRESENT | The ObjectTypeName member contains a string.
ACE_INHERITED_OBJECT_TYPE_PRESENT | The InheritedObjectTypeName member contains a string.

ObjectType
Specifies a value from the SE_OBJECT_TYPE enumeration that indicates the type of object.
ObjectTypeName
Pointer to a null-terminated string that identifies the type of object, property set, or property protected by the ACE. If this ACE is inherited, the GUID identifies the type of object, property set, or property protected by the inherited ACE.

This string must be a valid LDAP display name in the Active Directory schema.

If the ACE_OBJECT_TYPE_PRESENT bit is not set in the ObjectsPresent member, the ObjectTypeName member is ignored, and the ACE protects the object to which the ACL is assigned.

InheritedObjectTypeName
Pointer to a null-terminated string that identifies the type of object that can inherit the ACE.

This string must be a valid LDAP display name in the Active Directory schema.

If the ACE_INHERITED_OBJECT_TYPE_PRESENT bit is not set in the ObjectsPresent member, the InheritedObjectTypeName member is ignored, and all types of child objects can inherit the ACE. Otherwise, only the specified object type can inherit the ACE. In either case, inheritance is also controlled by the inheritance flags in the ACE_HEADER as well as by any protection against inheritance placed on the child objects.

ptstrName
Pointer to a null-terminated string that contains the name of the trustee.

Remarks

The ptstrName member of a TRUSTEE structure can be a pointer to an OBJECTS_AND_NAME structure. This enables functions such as SetEntriesInAcl and GetExplicitEntriesFromAcl to store object-specific ACE information in the Trustee member of an EXPLICIT_ACCESS structure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Accctrl.h.
Unicode: Declared as Unicode and ANSI structures.

See Also

Access Control Overview, Access Control Structures, GetExplicitEntriesFromAcl, OBJECTS_AND_SID, SE_OBJECT_TYPE, SetEntriesInAcl, TRUSTEE


OBJECTS_AND_SID

The OBJECTS_AND_SID structure contains a SID that identifies a trustee and GUIDs that identify the object types of an object-specific ACE.

typedef struct _OBJECTS_AND_SID {
  DWORD   ObjectsPresent;
  GUID    ObjectTypeGuid;
  GUID    InheritedObjectTypeGuid;
  SID    *pSID;
} OBJECTS_AND_SID, *POBJECTS_AND_SID;

Members

ObjectsPresent
Indicates whether the ObjectTypeGuid and InheritedObjectTypeGuid members contain GUIDs. This parameter can be a combination of the following values.
Value | Meaning
ACE_OBJECT_TYPE_PRESENT | The ObjectTypeGuid member contains a GUID.
ACE_INHERITED_OBJECT_TYPE_PRESENT | The InheritedObjectTypeGuid member contains a GUID.

ObjectTypeGuid
A GUID structure that identifies the type of object, property set, or property protected by the ACE. If this ACE is inherited, the GUID identifies the type of object, property set, or property protected by the inherited ACE. This GUID must be a valid schema identifier in the Active Directory schema.

If the ACE_OBJECT_TYPE_PRESENT bit is not set in the ObjectsPresent member, the ObjectTypeGuid member is ignored, and the ACE protects the object to which the ACL is assigned.

InheritedObjectTypeGuid
A GUID structure that identifies the type of object that can inherit the ACE. This GUID must be a valid schema identifier in the Active Directory schema.

If the ACE_INHERITED_OBJECT_TYPE_PRESENT bit is not set in the ObjectsPresent member, the InheritedObjectTypeGuid member is ignored, and all types of child objects can inherit the ACE. Otherwise, only the specified object type can inherit the ACE. In either case, inheritance is also controlled by the inheritance flags in the ACE_HEADER as well as by any protection against inheritance placed on the child objects.

pSID
Pointer to the SID of the trustee to whom the ACE applies.

Remarks

The ptstrName member of a TRUSTEE structure can be a pointer to an OBJECTS_AND_SID structure. This enables functions such as SetEntriesInAcl and GetExplicitEntriesFromAcl to store object-specific ACE information in the Trustee member of an EXPLICIT_ACCESS structure.

When you use this structure in a call to SetEntriesInAcl, ObjectTypeGuid and InheritedObjectTypeGuid must be valid schema identifiers in the Active Directory schema. The system does not verify the GUIDs; they are used as is.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Accctrl.h.
Unicode: Declared as Unicode and ANSI structures.

See Also

Access Control Overview, Access Control Structures, GetExplicitEntriesFromAcl, GUID, OBJECTS_AND_NAME, SetEntriesInAcl, TRUSTEE


SECURITY_ATTRIBUTES

The SECURITY_ATTRIBUTES structure contains the security descriptor for an object and specifies whether the handle retrieved by specifying this structure is inheritable.

typedef struct _SECURITY_ATTRIBUTES {
  DWORD  nLength;
  LPVOID lpSecurityDescriptor;
  BOOL   bInheritHandle;
} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES;

Members

nLength
Specifies the size, in bytes, of this structure. Set this value to the size of the SECURITY_ATTRIBUTES structure.
lpSecurityDescriptor
Pointer to a security descriptor for the object that controls the sharing of it. If NULL is specified for this member, the object is assigned the default security descriptor of the calling process. This is not the same as granting access to everyone by assigning a null DACL. The default security descriptor is based on the default DACL of the access token belonging to the calling process. By default, the default DACL in the access token of a process allows access only to the user represented by the access token. If other users must access the object, you can either create a security descriptor with a null DACL, or add ACEs to the DACL that grants access to a group of users.

Windows 95/98/Me: The lpSecurityDescriptor member of this structure is ignored.

bInheritHandle
Specifies whether the returned handle is inherited when a new process is created. If this member is TRUE, the new process inherits the handle.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.

See Also

Access Control Overview, Access Control Structures, SECURITY_DESCRIPTOR


SECURITY_DESCRIPTOR

The SECURITY_DESCRIPTOR structure contains the security information associated with an object. Applications use this structure to set and query an object's security status.

Applications are not to modify the SECURITY_DESCRIPTOR structure directly. For creating and manipulating a security descriptor, use the functions listed in the See Also section.

typedef struct _SECURITY_DESCRIPTOR {
  BYTE  Revision;
  BYTE  Sbz1;
  SECURITY_DESCRIPTOR_CONTROL Control;
  PSID Owner;
  PSID Group;
  PACL Sacl;
  PACL Dacl;
} SECURITY_DESCRIPTOR, *PISECURITY_DESCRIPTOR;
typedef PVOID PSECURITY_DESCRIPTOR;

Remarks

A security descriptor includes information that specifies the following components of an object's security:

  • An owner (SID)
  • A primary group (SID)
  • A discretionary ACL
  • A system ACL
  • Qualifiers for the preceding items

Security descriptors use access-control lists (ACLs) and security identifiers (SIDs) to specify the information in this list.

A security descriptor can be in absolute or self-relative form. In self-relative form, all members of the structure are located contiguously in memory. In absolute form, the structure only contains pointers to the members.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Structures, GetSecurityDescriptorControl, GetSecurityDescriptorDacl, GetSecurityDescriptorGroup, GetSecurityDescriptorLength, GetSecurityDescriptorOwner, GetSecurityDescriptorRMControl, GetSecurityDescriptorSacl, InitializeSecurityDescriptor, IsValidSecurityDescriptor, SetSecurityDescriptorDacl, SetSecurityDescriptorGroup, SetSecurityDescriptorOwner, SetSecurityDescriptorRMControl, SetSecurityDescriptorSacl


SECURITY_INFORMATION

The SECURITY_INFORMATION structure identifies the object-related security information being set or queried. This security information includes:

  • The owner of an object
  • The primary group of an object
  • The discretionary access-control list (DACL) of an object
  • The system access-control list (SACL) of an object
typedef DWORD SECURITY_INFORMATION, *PSECURITY_INFORMATION;

Each item of security information is designated by a bit flag. The following values specify the bits.

Value | Meaning
DACL_SECURITY_INFORMATION | Indicates the discretionary ACL of the object is being referenced.
GROUP_SECURITY_INFORMATION | Indicates the primary group identifier of the object is being referenced.
OWNER_SECURITY_INFORMATION | Indicates the owner identifier of the object is being referenced.
PROTECTED_DACL_SECURITY_INFORMATION | Windows 2000 or later: Indicates the DACL cannot inherit ACEs.
PROTECTED_SACL_SECURITY_INFORMATION | Windows 2000 or later: Indicates the SACL cannot inherit ACEs.
SACL_SECURITY_INFORMATION | Indicates the system ACL of the object is being referenced.
UNPROTECTED_DACL_SECURITY_INFORMATION | Windows 2000 or later: Indicates the DACL inherits ACEs from the parent object.
UNPROTECTED_SACL_SECURITY_INFORMATION | Windows 2000 or later: Indicates the SACL inherits ACEs from the parent object.

Remarks

New SECURITY_INFORMATION members indicated for Windows 2000 only work with the SetNamedSecurityInfo function. These new members are not returned in the structure returned by other security functions such as GetNamedSecurityInfo or ConvertStringSecurityDescriptorToSecurityDescriptor.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Structures, GetFileSecurity, GetKernelObjectSecurity, GetPrivateObjectSecurity, GetUserObjectSecurity, SetFileSecurity, SetKernelObjectSecurity, SetPrivateObjectSecurity, SetUserObjectSecurity


SID

The security identifier (SID) structure is a variable-length structure used to uniquely identify users or groups.

Applications are not to modify the SID structure directly. To create and manipulate a security identifier, use the functions listed in the See Also section.

typedef struct _SID {
  BYTE  Revision;
  BYTE  SubAuthorityCount;
  SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
  DWORD SubAuthority[ANYSIZE_ARRAY];
} SID;
typedef PVOID PSID;

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Structures, AllocateAndInitializeSid, CopySid, EqualSid, FreeSid, GetLengthSid, GetSidIdentifierAuthority, GetSidLengthRequired, GetSidSubAuthority, GetSidSubAuthorityCount, InitializeSid, IsValidSid, LookupAccountName, LookupAccountSid


SID_AND_ATTRIBUTES

The SID_AND_ATTRIBUTES structure represents a security identifier (SID) and its attributes. SIDs are used to uniquely identify users or groups.

typedef struct _SID_AND_ATTRIBUTES {
  PSID  Sid;
  DWORD Attributes;
} SID_AND_ATTRIBUTES, *PSID_AND_ATTRIBUTES;

Members

Sid
Pointer to a SID structure.
Attributes
Specifies attributes of the SID. This value contains up to 32 one-bit flags. Its meaning depends on the definition and use of the SID.

Remarks

A group is represented by a SID. SIDs have attributes that indicate whether they are currently enabled, disabled, or mandatory, and how they are used. A SID_AND_ATTRIBUTES structure can represent a SID whose attributes change frequently. For example, it is used to represent groups in the TOKEN_GROUPS structure.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Structures, SID, TOKEN_GROUPS, TOKEN_USER


SID_IDENTIFIER_AUTHORITY

The SID_IDENTIFIER_AUTHORITY structure represents the top-level authority of a security identifier (SID).

typedef struct _SID_IDENTIFIER_AUTHORITY {
  BYTE Value[6];
} SID_IDENTIFIER_AUTHORITY, *PSID_IDENTIFIER_AUTHORITY;

Members

Value
An array of six bytes specifying a SID's top-level authority.

Remarks

The identifier authority value identifies the agency that issued the SID. The following identifier authorities are predefined.

Identifier authority | Value
SECURITY_NULL_SID_AUTHORITY | 0
SECURITY_WORLD_SID_AUTHORITY | 1
SECURITY_LOCAL_SID_AUTHORITY | 2
SECURITY_CREATOR_SID_AUTHORITY | 3
SECURITY_NT_AUTHORITY | 5

A SID must contain a top-level authority and at least one relative identifier (RID) value.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Structures, AllocateAndInitializeSid, GetSidIdentifierAuthority, InitializeSid, SID


TOKEN_CONTROL

The TOKEN_CONTROL structure contains information that identifies an access token.

typedef struct _TOKEN_CONTROL {
  LUID TokenId;
  LUID AuthenticationId;
  LUID ModifiedId;
  TOKEN_SOURCE TokenSource;
} TOKEN_CONTROL, *PTOKEN_CONTROL;

Members

TokenId
Specifies a locally unique identifier (LUID) identifying this instance of the token object.
AuthenticationId
Specifies an LUID assigned to the session this token represents. There can be many tokens representing a single logon session.
ModifiedId
Specifies an LUID that changes each time the token is modified. An application can use this value as a test of whether a security context has changed since it was last used.
TokenSource
Specifies a TOKEN_SOURCE structure identifying the agency that issued the token. This information is used in audit logging.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Structures, LUID, TOKEN_DEFAULT_DACL, TOKEN_GROUPS, TOKEN_INFORMATION_CLASS, TOKEN_OWNER, TOKEN_PRIMARY_GROUP, TOKEN_PRIVILEGES, TOKEN_SOURCE, TOKEN_STATISTICS, TOKEN_TYPE, TOKEN_USER


TOKEN_DEFAULT_DACL

The TOKEN_DEFAULT_DACL structure specifies a discretionary access-control list (DACL).

typedef struct _TOKEN_DEFAULT_DACL {
  PACL DefaultDacl;
} TOKEN_DEFAULT_DACL, *PTOKEN_DEFAULT_DACL;

Members

DefaultDacl
Pointer to an ACL structure assigned by default to any objects created by the user represented by the access token.

Remarks

The GetTokenInformation function retrieves the default discretionary ACL for an access token, in the form of a TOKEN_DEFAULT_DACL structure. This structure is also used with the SetTokenInformation function to set the default discretionary ACL.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Structures, ACL, GetTokenInformation, SetTokenInformation, TOKEN_CONTROL, TOKEN_GROUPS, TOKEN_INFORMATION_CLASS, TOKEN_OWNER, TOKEN_PRIMARY_GROUP, TOKEN_PRIVILEGES, TOKEN_SOURCE, TOKEN_STATISTICS, TOKEN_TYPE, TOKEN_USER


TOKEN_GROUPS

The TOKEN_GROUPS structure contains information about the group SIDs in an access token.

typedef struct _TOKEN_GROUPS {
  DWORD GroupCount;
  SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY];
} TOKEN_GROUPS, *PTOKEN_GROUPS;

Members

GroupCount
Specifies the number of groups in the access token.
Groups
Specifies an array of SID_AND_ATTRIBUTES structures containing a set of SIDs and corresponding attributes.

The Attributes members of the SID_AND_ATTRIBUTES structures can have the following attributes.
Value | Meaning
SE_GROUP_ENABLED The SID is enabled for access checks. When the system performs an access check, it checks for access-allowed and access-denied ACEs that apply to the SID.

A SID without this attribute is ignored during an access check unless the SE_GROUP_USE_FOR_DENY_ONLY attribute is set.
SE_GROUP_ENABLED_BY_DEFAULT | The SID is enabled by default.
SE_GROUP_LOGON_ID | The SID is a logon SID that identifies the logon session associated with an access token.
SE_GROUP_MANDATORY | The SID cannot have the SE_GROUP_ENABLED attribute cleared by a call to the AdjustTokenGroups function. However, you can use the CreateRestrictedToken function to convert a mandatory SID to a deny-only SID.
SE_GROUP_OWNER | The SID identifies a group account for which the token's user is the owner of the group; or the SID can be assigned as the owner of the token or objects.
SE_GROUP_RESOURCE | Windows 2000 or later: The SID identifies a domain local group.
SE_GROUP_USE_FOR_DENY_ONLY Windows 2000 or later: The SID is deny-only in a restricted token. When the system performs an access check, it checks for access-denied ACEs that apply to the SID, but ignores access-allowed ACEs for the SID.

If this attribute is set, the SE_GROUP_ENABLED is not set, and the SID cannot be re-enabled.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Structures, AdjustTokenGroups, SID_AND_ATTRIBUTES, TOKEN_CONTROL, TOKEN_DEFAULT_DACL, TOKEN_INFORMATION_CLASS, TOKEN_OWNER, TOKEN_PRIMARY_GROUP, TOKEN_PRIVILEGES, TOKEN_SOURCE, TOKEN_STATISTICS, TOKEN_TYPE, TOKEN_USER


TOKEN_GROUPS_AND_PRIVILEGES

The TOKEN_GROUPS_AND_PRIVILEGES structure contains information about the group SIDs in an access token.

typedef struct _TOKEN_GROUPS_AND_PRIVILEGES {
  ULONG SidCount;
  ULONG SidLength;
  PSID_AND_ATTRIBUTES Sids;
  ULONG RestrictedSidCount;
  ULONG RestrictedSidLength;
  PSID_AND_ATTRIBUTES RestrictedSids;
  ULONG PrivilegeCount;
  ULONG PrivilegeLength;
  PLUID_AND_ATTRIBUTES Privileges;
  LUID AuthenticationId;
} TOKEN_GROUPS_AND_PRIVILEGES, *PTOKEN_GROUPS_AND_PRIVILEGES;

Members

SidCount
Number of SIDs in the access token.
SidLength
Length, in bytes, required to hold all of the user SIDs and the group's account SID.
Sids.
Pointer to an array of SID_AND_ATTRIBUTES structures containing a set of SIDs and corresponding attributes.

The Attributes members of the SID_AND_ATTRIBUTES structures can have the following attributes.
Value | Meaning
SE_GROUP_ENABLED The SID is enabled for access checks. When the system performs an access check, it checks for access-allowed and access-denied ACEs that apply to the SID.

A SID without this attribute is ignored during an access check unless the SE_GROUP_USE_FOR_DENY_ONLY attribute is set.
SE_GROUP_ENABLED_BY_DEFAULT | The SID is enabled by default.
SE_GROUP_LOGON_ID | The SID is a logon SID that identifies the logon session associated with an access token.
SE_GROUP_MANDATORY | The SID cannot have the SE_GROUP_ENABLED attribute cleared by a call to the AdjustTokenGroups function. However, you can use the CreateRestrictedToken function to convert a mandatory SID to a deny-only SID.
SE_GROUP_OWNER | The SID identifies a group account for which the token's user is the owner of the group, or the SID can be assigned as the owner of the token or objects.
SE_GROUP_RESOURCE | Windows 2000 or later: The SID identifies a domain local group.
SE_GROUP_USE_FOR_DENY_ONLY Windows 2000 or later: The SID is deny-only in a restricted token. When the system performs an access check, it checks for access-denied ACEs that apply to the SID, but ignores access-allowed ACEs for the SID.

If this attribute is set, the SE_GROUP_ENABLED is not set, and the SID cannot be re-enabled.

RestrictedSidCount
Number of restricted SIDs.
RestrictedSidLenght
Length, in bytes, required to hold all of the restricted SIDs.
RestrictedSids
Pointer to an array of SID_AND_ATTRIBUTES structures containing a set of restricted SIDs and corresponding attributes.

The Attributes members of the SID_AND_ATTRIBUTES structures can have the same values as the attributes values listed for the SIDs parameter.

PriviledgeCount
Number of privileges.
PrivilegeLenght
Length, in bytes, needed to hold the privilege array.
Privileges
Array of privileges.
AuthenticationId
Locally unique identifier of the authenticator of the token.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Structures, AdjustTokenGroups, SID_AND_ATTRIBUTES, TOKEN_CONTROL, TOKEN_DEFAULT_DACL, TOKEN_INFORMATION_CLASS, TOKEN_OWNER, TOKEN_PRIMARY_GROUP, TOKEN_PRIVILEGES, TOKEN_SOURCE, TOKEN_STATISTICS, TOKEN_TYPE, TOKEN_USER


TOKEN_OWNER

The TOKEN_OWNER structure contains the default owner security identifier (SID) that will be applied to newly created objects.

typedef struct _TOKEN_OWNER {
  PSID Owner;
} TOKEN_OWNER, *PTOKEN_OWNER;

Members

Owner
Pointer to a SID structure representing a user who will become the owner of any objects created by a process using this access token. The security identifier (SID) must be one of the user or group SIDs already in the token.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Structures, GetTokenInformation, SetTokenInformation, SID, TOKEN_CONTROL, TOKEN_DEFAULT_DACL, TOKEN_GROUPS, TOKEN_INFORMATION_CLASS, TOKEN_PRIMARY_GROUP, TOKEN_PRIVILEGES, TOKEN_SOURCE, TOKEN_STATISTICS, TOKEN_TYPE, TOKEN_USER


TOKEN_PRIMARY_GROUP

The TOKEN_PRIMARY_GROUP structure specifies a group security identifier (SID) for an access token.

typedef struct _TOKEN_PRIMARY_GROUP {
  PSID PrimaryGroup;
} TOKEN_PRIMARY_GROUP, *PTOKEN_PRIMARY_GROUP;

Members

PrimaryGroup
Pointer to a SID structure representing a group that will become the primary group of any objects created by a process using this access token. The security identifier (SID) must be one of the group SIDs already in the token.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Structures, GetTokenInformation, SetTokenInformation, SID, TOKEN_CONTROL, TOKEN_DEFAULT_DACL, TOKEN_GROUPS, TOKEN_INFORMATION_CLASS, TOKEN_OWNER, TOKEN_PRIVILEGES, TOKEN_SOURCE, TOKEN_STATISTICS, TOKEN_TYPE, TOKEN_USER


TOKEN_PRIVILEGES

The TOKEN_PRIVILEGES structure contains information about a set of privileges for an access token.

typedef struct _TOKEN_PRIVILEGES {
  DWORD PrivilegeCount;
  LUID_AND_ATTRIBUTES Privileges[];
} TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;

Members

PrivilegeCount
Specifies the number of entries in the Privileges array.
Privileges
Specifies an array of LUID_AND_ATTRIBUTES structures. Each structure contains the LUID and attributes of a privilege. The attributes of a privilege can be a combination of the following values:
Attribute | Description
SE_PRIVILEGE_ENABLED | The privilege is enabled.
SE_PRIVILEGE_ENABLED_BY_DEFAULT | The privilege is enabled by default.
SE_PRIVILEGE_USED_FOR_ACCESS | The privilege was used to gain access to an object or service. This flag is used to identify the relevant privileges in a set passed by a client application that may contain unnecessary privileges.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Structures, AdjustTokenPrivileges, GetTokenInformation, LUID, LUID_AND_ATTRIBUTES, PrivilegeCheck, PrivilegedServiceAuditAlarm, PRIVILEGE_SET, SetTokenInformation, TOKEN_CONTROL, TOKEN_DEFAULT_DACL, TOKEN_GROUPS, TOKEN_INFORMATION_CLASS, TOKEN_OWNER, TOKEN_PRIMARY_GROUP, TOKEN_SOURCE, TOKEN_STATISTICS, TOKEN_TYPE, TOKEN_USER


TOKEN_SOURCE

The TOKEN_SOURCE structure identifies the source of an access token.

typedef struct _TOKEN_SOURCE {
  Char SourceName[8];
  LUID SourceIdentifier;
} TOKEN_SOURCE, *PTOKEN_SOURCE;

Members

SourceName
Specifies an 8-byte character string used to identify the source of an access token. This is used to distinguish between such sources as Session Manager, LAN Manager, and RPC Server. A string, rather than a constant, is used to identify the source so users and developers can make extensions to the system, such as by adding other networks, that act as the source of access tokens.
SourceIdentifier
Specifies a locally unique identifier (LUID) provided by the source component named by the SourceName member. This value aids the source component in relating context blocks, such as session-control structures, to the token. This value is typically, but not necessarily, an LUID.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Structures, GetTokenInformation, LUID, TOKEN_CONTROL, TOKEN_DEFAULT_DACL, TOKEN_GROUPS, TOKEN_INFORMATION_CLASS, TOKEN_OWNER, TOKEN_PRIMARY_GROUP, TOKEN_PRIVILEGES, TOKEN_STATISTICS, TOKEN_TYPE, TOKEN_USER


TOKEN_STATISTICS

The TOKEN_STATISTICS structure contains information about an access token. An application can retrieve this information by calling the GetTokenInformation function.

typedef struct _TOKEN_STATISTICS {
  LUID  TokenId;
  LUID  AuthenticationId;
  LARGE_INTEGER ExpirationTime;
  TOKEN_TYPE    TokenType;
  SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
  DWORD DynamicCharged;
  DWORD DynamicAvailable;
  DWORD GroupCount;
  DWORD PrivilegeCount;
  LUID  ModifiedId;
} TOKEN_STATISTICS, *PTOKEN_STATISTICS;

Members

TokenId
Specifies a locally unique identifier (LUID) that identifies this instance of the token object.
AuthenticationId
Specifies an LUID assigned to the session this token represents. There can be many tokens representing a single logon session.
ExpirationTime
Specifies the time at which this token expires. Expiration times for access tokens are not currently supported.
TokenType
Specifies a TOKEN_TYPE enumerated type indicating whether the token is a primary or impersonation token.
ImpersonationLevel
Specifies a SECURITY_IMPERSONATION_LEVEL enumerated type indicating the impersonation level of the token. This member is valid only if the TokenType is TokenImpersonation.
DynamicCharged
Specifies the amount, in bytes, of memory allocated for storing default protection and a primary group identifier.
DynamicAvailable
Specifies the portion of memory allocated for storing default protection and a primary group identifier not already in use. This value is returned as a count of free bytes.
GroupCount
Specifies the number of supplemental group security identifiers (SIDs) included in the token.
PrivilegeCount
Specifies the number of privileges included in the token.
ModifiedId
Specifies an LUID that changes each time the token is modified. An application can use this value as a test of whether a security context has changed since it was last used.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Structures, GetTokenInformation, LUID, SECURITY_IMPERSONATION_LEVEL, TOKEN_CONTROL, TOKEN_DEFAULT_DACL, TOKEN_GROUPS, TOKEN_INFORMATION_CLASS, TOKEN_OWNER, TOKEN_PRIMARY_GROUP, TOKEN_PRIVILEGES, TOKEN_SOURCE, TOKEN_TYPE, TOKEN_USER


TOKEN_USER

The TOKEN_USER structure identifies the user associated with an access token.

typedef struct _TOKEN_USER {
  SID_AND_ATTRIBUTES User;
} TOKEN_USER, *PTOKEN_USER;

Members

User
Specifies an SID_AND_ATTRIBUTES structure representing the user associated with the access token. There are currently no attributes defined for user security identifiers (SIDs).

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Structures, GetTokenInformation, SID_AND_ATTRIBUTES, TOKEN_CONTROL, TOKEN_DEFAULT_DACL, TOKEN_GROUPS, TOKEN_INFORMATION_CLASS, TOKEN_OWNER, TOKEN_PRIMARY_GROUP, TOKEN_PRIVILEGES, TOKEN_SOURCE, TOKEN_STATISTICS, TOKEN_TYPE


TRUSTEE

The TRUSTEE structure identifies the user account, group account, or logon session to which an ACE applies. The structure can use a name or a security identifier (SID) to identify the trustee.

Access control functions, such as SetEntriesInAcl and GetExplicitEntriesFromAcl, use this structure to identify the logon account associated with the access-control or audit-control information in an EXPLICIT_ACCESS structure.

typedef struct _TRUSTEE {
  PTRUSTEE                    pMultipleTrustee;
  MULTIPLE_TRUSTEE_OPERATION  MultipleTrusteeOperation;
  TRUSTEE_FORM                TrusteeForm;
  TRUSTEE_TYPE                TrusteeType;
  LPTSTR                      ptstrName;
} TRUSTEE, *PTRUSTEE;

Members

pMultipleTrustee
Pointer to a TRUSTEE structure that identifies a server account that can impersonate the user identified by the ptstrName member. This member is not currently supported and must be NULL.
MultipleTrusteeOperation
Specifies a value from the MULTIPLE_TRUSTEE_OPERATION enumeration type. Currently, this member must be NO_MULTIPLE_TRUSTEE.
TrusteeForm
Specifies a value from the TRUSTEE_FORM enumeration type that indicates the type of data pointed to by the ptstrName member.
TrusteeType
Specifies a value from the TRUSTEE_TYPE enumeration type that indicates whether the trustee is a user account, a group account, or the account type is unknown.
ptstrName
Pointer to a buffer that identifies the trustee and optionally contains information about object-specific ACEs. The type of data depends on the value of the TrusteeForm member.
TrusteeForm value | Description
TRUSTEE_IS_NAME | ptstrName is a pointer to a null-terminated string that contains the name of the trustee.
TRUSTEE_IS_OBJECTS_AND_NAME | Windows 2000 or later: ptstrName is a pointer to an OBJECTS_AND_NAME structure that contains the name of the trustee and the names of the object types in an object-specific ACE.
TRUSTEE_IS_OBJECTS_AND_SID | Windows 2000 or later: ptstrName is a pointer to an OBJECTS_AND_SID structure that contains the SID of the trustee and the GUIDs of the object types in an object-specific ACE.
TRUSTEE_IS_SID | ptstrName is a pointer to the SID of the trustee.

Remarks

A trustee name can have any of the following formats:

  • A fully qualified name, such as "g:\remotedir\abc".
  • A Windows NT version 3.x or later domain account, such as "redmond\xyz".
  • One of the predefined group names, such as "EVERYONE" or "GUEST".
  • One of the following special names.
    Name | Meaning
    "CREATOR GROUP" | Indicates the CREATOR_GROUP security identifier. This is a SID used in inheritable ACEs. When a new object is created, the system replaces this SID with the primary group SID of the user who created the object.
    "CREATOR OWNER" | Indicates the CREATOR_OWNER security identifier. This is a SID used in inheritable ACEs. When a new object is created, the system replaces this SID with the SID of the user who created the object.
    "CURRENT_USER" | Indicates the owner of the calling thread or process.

A trustee SID can be any user or group SID. It can also be any of the universal, well-known SIDs. For more information, see Security Identifiers (SIDs).

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Accctrl.h.
Unicode: Declared as Unicode and ANSI structures.

See Also

Access Control Overview, Access Control Structures, ACL, EXPLICIT_ACCESS, GetExplicitEntriesFromAcl, MULTIPLE_TRUSTEE_OPERATION, SetEntriesInAcl, SID, TRUSTEE_FORM, TRUSTEE_TYPE


Access Control Enumeration Types

The following enumeration types are used with security.

ACCESS_MODE
ACL_INFORMATION_CLASS
MULTIPLE_TRUSTEE_OPERATION
SE_OBJECT_TYPE
SID_NAME_USE
TOKEN_INFORMATION_CLASS
TOKEN_TYPE
TRUSTEE_FORM
TRUSTEE_TYPE


ACCESS_MODE

The ACCESS_MODE enumeration type contains values that indicate how the access rights in an EXPLICIT_ACCESS structure apply to the trustee. Functions such as SetEntriesInAcl and GetExplicitEntriesFromAcl use these values to set or retrieve information in an access-control entry (ACE).

typedef enum _ACCESS_MODE {
  NOT_USED_ACCESS = 0,
  GRANT_ACCESS,
  SET_ACCESS,
  DENY_ACCESS,
  REVOKE_ACCESS,
  SET_AUDIT_SUCCESS,
  SET_AUDIT_FAILURE
} ACCESS_MODE;

Enumeration Values

GRANT_ACCESS
An input flag that creates an ACCESS_ALLOWED_ACE. The new ACE combines the specified rights with any existing allowed or denied rights of the trustee.
SET_ACCESS
Indicates an ACCESS_ALLOWED_ACE that allows the specified rights.

On input, this flag discards any existing access-control information for the trustee.

DENY_ACCESS
Indicates an ACCESS_DENIED_ACE that denies the specified rights.

On input, this flag denies the specified rights in addition to any currently denied rights of the trustee. It also modifies or deletes any existing ACCESS_ALLOWED_ACE for the trustee that allows the specified rights.

REVOKE_ACCESS
An input flag that removes all existing ACCESS_DENIED_ACE, ACCESS_ALLOWED_ACE, or SYSTEM_AUDIT_ACE structures for the specified trustee.
SET_AUDIT_SUCCESS
Indicates a SYSTEM_AUDIT_ACE that generates audit messages for successful attempts to use the specified access rights. You can combine this value with SET_AUDIT_FAILURE.

On input, this flag combines the specified rights with any existing audited access rights for the trustee.

SET_AUDIT_FAILURE
Indicates a SYSTEM_AUDIT_ACE that generates audit messages for failed attempts to use the specified access rights. You can combine this value with SET_AUDIT_SUCCESS.

On input, this flag combines the specified rights with any existing audited access rights for the trustee.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Accctrl.h.

See Also

Access Control Overview, Access Control Enumeration Types, ACCESS_DENIED_ACE, ACCESS_ALLOWED_ACE, ACE, EXPLICIT_ACCESS, GetExplicitEntriesFromAcl, SetEntriesInAcl, SYSTEM_AUDIT_ACE


ACL_INFORMATION_CLASS

The ACL_INFORMATION_CLASS enumeration type contains values that specify the type of information being assigned to or retrieved from an access-control list (ACL).

typedef enum _ACL_INFORMATION_CLASS {
  AclRevisionInformation = 1,
  AclSizeInformation
} ACL_INFORMATION_CLASS;

Enumeration Values

AclRevisionInformation
Indicates ACL revision information.
AclSizeInformation
Indicates ACL size information.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Enumeration Types, ACL, ACL_REVISION_INFORMATION, ACL_SIZE_INFORMATION, GetAclInformation, SetAclInformation


MULTIPLE_TRUSTEE_OPERATION

The MULTIPLE_TRUSTEE_OPERATION enumeration type contains values that indicate whether a TRUSTEE structure is an impersonate trustee.

typedef enum _MULTIPLE_TRUSTEE_OPERATION {
  NO_MULTIPLE_TRUSTEE,
  TRUSTEE_IS_IMPERSONATE,
} MULTIPLE_TRUSTEE_OPERATION;

Enumeration Values

NO_MULTIPLE_TRUSTEE
The trustee is not an impersonate trustee.
TRUSTEE_IS_IMPERSONATE
The trustee is an impersonate trustee. The pMultipleTrustee member of the TRUSTEE structure points to a trustee for a server that can impersonate the client trustee.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Accctrl.h.

See Also

Access Control Overview, Access Control Enumeration Types, TRUSTEE


SE_OBJECT_TYPE

The SE_OBJECT_TYPE enumeration type contains values that correspond to the types of Win32 objects that support security. The functions, such as GetSecurityInfo and SetSecurityInfo, that set and retrieve an object's security information, use these values to indicate the type of object.

typedef enum _SE_OBJECT_TYPE {
  SE_UNKNOWN_OBJECT_TYPE = 0,
  SE_FILE_OBJECT,
  SE_SERVICE,
  SE_PRINTER,
  SE_REGISTRY_KEY,
  SE_LMSHARE,
  SE_KERNEL_OBJECT,
  SE_WINDOW_OBJECT,
  SE_DS_OBJECT,
  SE_DS_OBJECT_ALL,
  SE_PROVIDER_DEFINED_OBJECT
  SE_WMIGUID_OBJECT
} SE_OBJECT_TYPE;

Enumeration Values

SE_FILE_OBJECT
Indicates a file or directory. The name string that identifies a file or directory object can be
  • A relative path, such as "abc.dat" or "..\abc.dat"
  • An absolute path, such as "\abc.dat", "c:\dir1\abc.dat", or "g:\remotedir\abc.dat"
  • A UNC name, such as "\\machinename\sharename\abc.dat".
  • A local file system root, such as "\\\\.\\c:". Security set on a file system root does not persist when the system is restarted.
SE_SERVICE
Indicates a Win32 service. A service object can be a local service, such as "servicename"; or a remote service, such as "\\machinename\servicename".
SE_PRINTER
Indicates a printer. A printer object can be a local printer, such as "printername"; or a remote printer, such as "\\machinename\printername".
SE_REGISTRY_KEY
Indicates a registry key. A registry key object can be in the local registry, such as "CLASSES_ROOT\somepath"; or in a remote registry, such as "\\machinename\CLASSES_ROOT\somepath".

The names of registry keys must use the following literal strings to identify the predefined registry keys: "CLASSES_ROOT", "CURRENT_USER", "MACHINE", and "USERS".

SE_LMSHARE
Indicates a network share. A share object can be local, such as "sharename"; or remote, such as "\\machinename\sharename".
SE_KERNEL_OBJECT
Indicates a local kernel object.

The GetSecurityInfo and SetSecurityInfo functions support all types of kernel objects. The GetNamedSecurityInfo and SetNamedSecurityInfo functions work only with the following kernel objects: semaphore, event, mutex, waitable timer, and file mapping.

SE_WINDOW_OBJECT
Indicates a window station or desktop object on the local computer. You cannot use GetNamedSecurityInfo and SetNamedSecurityInfo with these objects because the names of window stations or desktops are not unique.
SE_DS_OBJECT
Windows 2000 or later: Indicates a directory service (DS) object, or a property set or property of a directory service object.

The name string for a DS object can be a UNC name, such as "\\domain.microsoft.com\ou1\ou2\someobject".

The name string can also be in X.500 form, such as "CN=someobject,OU=ou2,OU=ou1,DC=domain,DC=microsoft,DC=com,O=internet".

SE_DS_OBJECT_ALL
Windows 2000 or later: Indicates a directory service object and all of its property sets and properties.
SE_PROVIDER_DEFINED_OBJECT
Windows 2000 or later: Indicates a provider-defined object.
SE_WMIGUID_OBJECT
Windows 2000 or later: Indicates a WMI object.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Accctrl.h.

See Also

Access Control Overview, Access Control Enumeration Types, GetSecurityInfo, GetNamedSecurityInfo, SetSecurityInfo, SetNamedSecurityInfo


SID_NAME_USE

The SID_NAME_USE enumeration type contains values that specify the type of a security identifier (SID).

typedef enum _SID_NAME_USE {
  SidTypeUser = 1,
  SidTypeGroup,
  SidTypeDomain,
  SidTypeAlias,
  SidTypeWellKnownGroup,
  SidTypeDeletedAccount,
  SidTypeInvalid,
  SidTypeUnknown,
  SidTypeComputer
} SID_NAME_USE, *PSID_NAME_USE;

Enumeration Values

SidTypeUser
Indicates a user SID.
SidTypeGroup
Indicates a group SID.
SidTypeDomain
Indicates a domain SID.
SidTypeAlias
Indicates an alias SID.
SidTypeWellKnownGroup
Indicates an SID for a well-known group.
SidTypeDeletedAccount
Indicates an SID for a deleted account.
SidTypeInvalid
Indicates an invalid SID.
SidTypeUnknown
Indicates an unknown SID type.
SidTypeComputer
Indicates a SID for a computer.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Enumeration Types, LookupAccountName, LookupAccountSid


TOKEN_INFORMATION_CLASS

The TOKEN_INFORMATION_CLASS enumeration type contains values that specify the type of information being assigned to or retrieved from an access token.

The GetTokenInformation function uses these enumerator values to indicate the type of token information to retrieve.

typedef enum _TOKEN_INFORMATION_CLASS {
  TokenUser = 1,
  TokenGroups,
  TokenPrivileges,
  TokenOwner,
  TokenPrimaryGroup,
  TokenDefaultDacl,
  TokenSource,
  TokenType,
  TokenImpersonationLevel,
  TokenStatistics,
  TokenRestrictedSids,
  TokenSessionId
} TOKEN_INFORMATION_CLASS;

Enumeration Values

TokenUser
The buffer receives a TOKEN_USER structure containing the token's user account.
TokenGroups
The buffer receives a TOKEN_GROUPS structure containing the group accounts associated with the token.
TokenPrivileges
The buffer receives a TOKEN_PRIVILEGES structure containing the token's privileges.
TokenOwner
The buffer receives a TOKEN_OWNER structure containing the default owner SID for newly created objects.
TokenPrimaryGroup
The buffer receives a TOKEN_PRIMARY_GROUP structure containing the default primary group SID for newly created objects.
TokenDefaultDacl
The buffer receives a TOKEN_DEFAULT_DACL structure containing the default DACL for newly created objects.
TokenSource
The buffer receives a TOKEN_SOURCE structure containing the source of the token. TOKEN_QUERY_SOURCE access is needed to retrieve this information.
TokenType
The buffer receives a TOKEN_TYPE value indicating whether the token is a primary or impersonation token.
TokenImpersonationLevel
The buffer receives a SECURITY_IMPERSONATION_LEVEL value indicating the impersonation level of the token. If the access token is not an impersonation token, the function fails.
TokenStatistics
The buffer receives a TOKEN_STATISTICS structure containing various token statistics.
TokenRestrictedSids
The buffer receives a TOKEN_GROUPS structure containing the list of restricting SIDs in a restricted token.
TokenSessionId
Terminal Services: The buffer receives a DWORD value that indicates the Terminal Services session identifier associated with the token. If the token is associated with the Terminal Server console session, the session identifier is zero. A nonzero session identifier indicates a Terminal Services client session. In a non-Terminal Services environment, the session identifier is zero. If TokenSessionId is set with SetTokenInformation, the application must have the "Act As Part Of the Operating System" privilege and the application must be enabled to set the session ID in a token.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Enumeration Types, GetTokenInformation, SetTokenInformation, TOKEN_CONTROL, TOKEN_DEFAULT_DACL, TOKEN_GROUPS, TOKEN_OWNER, TOKEN_PRIMARY_GROUP, TOKEN_PRIVILEGES, TOKEN_SOURCE, TOKEN_STATISTICS, TOKEN_TYPE, TOKEN_USER


TOKEN_TYPE

The TOKEN_TYPE enumeration type contains values that differentiate between a primary token and an impersonation token.

typedef enum tagTOKEN_TYPE {
  TokenPrimary = 1,
  TokenImpersonation
} TOKEN_TYPE;

Enumeration Values

TokenPrimary
Indicates a primary token.
TokenImpersonation
Indicates an impersonation token.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Access Control Overview, Access Control Enumeration Types, GetTokenInformation, TOKEN_CONTROL, TOKEN_DEFAULT_DACL, TOKEN_GROUPS, TOKEN_INFORMATION_CLASS, TOKEN_OWNER, TOKEN_PRIMARY_GROUP, TOKEN_PRIVILEGES, TOKEN_SOURCE, TOKEN_STATISTICS, TOKEN_USER


TRUSTEE_FORM

The TRUSTEE_FORM enumeration type contains values that indicate the type of data pointed to by the ptstrName member of a TRUSTEE structure.

typedef enum _TRUSTEE_FORM {
  TRUSTEE_IS_SID,
  TRUSTEE_IS_NAME,
  TRUSTEE_BAD_FORM
  TRUSTEE_IS_OBJECTS_AND_SID,
  TRUSTEE_IS_OBJECTS_AND_NAME
} TRUSTEE_FORM;

Enumeration Values

TRUSTEE_IS_SID
The ptstrName member is a pointer to a security identifier (SID) that identifies the trustee.
TRUSTEE_IS_NAME
The ptstrName member is a pointer to null-terminated string that identifies the trustee.
TRUSTEE_BAD_FORM
Indicates an invalid trustee form.
TRUSTEE_IS_OBJECTS_AND_SID
Windows 2000 or later: The ptstrName member is a pointer to an OBJECTS_AND_SID structure that contains the SID of the trustee and the GUIDs of the object types in an object-specific ACE.
TRUSTEE_IS_OBJECTS_AND_NAME
Windows 2000 or later: The ptstrName member is a pointer to an OBJECTS_AND_NAME structure that contains the name of the trustee and the names of the object types in an object-specific ACE.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Accctrl.h.

See Also

Access Control Overview, Access Control Enumeration Types, TRUSTEE


TRUSTEE_TYPE

The TRUSTEE_TYPE enumeration type contains values that indicate the type of trustee identified by a TRUSTEE structure.

typedef enum _TRUSTEE_TYPE {
  TRUSTEE_IS_UNKNOWN,
  TRUSTEE_IS_USER,
  TRUSTEE_IS_GROUP,
  TRUSTEE_IS_DOMAIN,
  TRUSTEE_IS_ALIAS,
  TRUSTEE_IS_WELL_KNOWN_GROUP,
  TRUSTEE_IS_DELETED,
  TRUSTEE_IS_INVALID,
  TRUSTEE_IS_COMPUTER
} TRUSTEE_TYPE;

Enumeration Values

TRUSTEE_IS_UNKNOWN
The trustee type is unknown, but not necessarily invalid.
TRUSTEE_IS_USER
Indicates a user.
TRUSTEE_IS_GROUP
Indicates a group.
TRUSTEE_IS_DOMAIN
Indicates a domain.
TRUSTEE_IS_ALIAS
Indicates an alias.
TRUSTEE_IS_WELL_KNOWN_GROUP
Indicates a well-known group.
TRUSTEE_IS_DELETED
Indicates a deleted account.
TRUSTEE_IS_INVALID
Indicates an invalid trustee type.
TRUSTEE_IS_COMPUTER
Indicates a computer.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Accctrl.h.

See Also

Access Control Overview, Access Control Enumeration Types, TRUSTEE


Windows NT Privileges

The following privilege constants are defined for Windows NT/Windows 2000. These constants are defined as strings in WINNT.H. For example, the SE_AUDIT_NAME constant is defined as "SeAuditPrivilege".

The functions that get and adjust the privileges in an access token use the LUID type to identify privileges. Use the LookupPrivilegeValue function to determine the LUID on the local system that corresponds to a privilege constant. Use the LookupPrivilegeName function to convert a LUID to its corresponding string constant.

Privilege Constant | Description
SE_ASSIGNPRIMARYTOKEN_NAME | Required to assign the primary token of a process. User Right: Replace a process level token.
SE_AUDIT_NAME | Required to generate audit-log entries. Give this privilege to secure servers. User Right: Generate security audits.
SE_BACKUP_NAME | Required to perform backup operations. User Right: Back up files and directories.
SE_CHANGE_NOTIFY_NAME | Required to receive notifications of changes to files or directories. This privilege also causes the system to skip all traversal access checks. It is enabled by default for all users. User Right: Bypass traverse checking.
SE_CREATE_PAGEFILE_NAME | Required to create a paging file. User Right: Create a pagefile.
SE_CREATE_PERMANENT_NAME | Required to create a permanent object. User Right: Create permanent shared objects.
SE_CREATE_TOKEN_NAME | Required to create a primary token. User Right: Create a token object.
SE_DEBUG_NAME | Required to debug a process. User Right: Debug programs.
SE_ENABLE_DELEGATION_NAME | Required to mark user and computer accounts as trusted for delegation.
SE_INC_BASE_PRIORITY_NAME | Required to increase the base priority of a process. User Right: Increase scheduling priority.
SE_INCREASE_QUOTA_NAME | Required to increase the quota assigned to a process. User Right: Increase quotas.
SE_LOAD_DRIVER_NAME | Required to load or unload a device driver. User Right: Load and unload device drivers.
SE_LOCK_MEMORY_NAME | Required to lock physical pages in memory. User Right: Lock pages in memory.
SE_MACHINE_ACCOUNT_NAME | Required to create a machine account. User Right: Add workstations to domain.
SE_PROF_SINGLE_PROCESS_NAME | Required to gather profiling information for a single process. User Right: Profile single process.
SE_REMOTE_SHUTDOWN_NAME | Required to shut down a system using a network request. User Right: Force shutdown from a remote system.
SE_RESTORE_NAME | Required to perform restore operations. This privilege enables you to set any valid user or group SID as the owner of an object. User Right: Restore files and directories.
SE_SECURITY_NAME | Required to perform a number of security-related functions, such as controlling and viewing audit messages. This privilege identifies its holder as a security operator. User Right: Manage auditing and security log.
SE_SHUTDOWN_NAME | Required to shut down a local system. User Right: Shut down the system.
SE_SYNC_AGENT_NAME | Required for a domain controller to use the LDAP directory synchronization services. This privilege enables the holder to read all objects and properties in the directory, regardless of the protection on the objects and properties. By default, it is assigned to the Administrator and LocalSystem accounts on domain controllers. User Right: Synchronize directory service data.
SE_SYSTEM_ENVIRONMENT_NAME | Required to modify the nonvolatile RAM of systems that use this type of memory to store configuration information. User Right: Modify firmware environment values.
SE_SYSTEM_PROFILE_NAME | Required to gather profiling information for the entire system. User Right: Profile system performance.
SE_SYSTEMTIME_NAME | Required to modify the system time. User Right: Change the system time.
SE_TAKE_OWNERSHIP_NAME | Required to take ownership of an object without being granted discretionary access. This privilege allows the owner value to be set only to those values that the holder may legitimately assign as the owner of an object. User Right: Take ownership of files or other objects.
SE_TCB_NAME | This privilege identifies its holder as part of the trusted computer base. Some trusted protected subsystems are granted this privilege. This privilege is required to call the LogonUser function. User Right: Act as part of the operating system.
SE_UNDOCK_NAME | Required to undock a laptop.
SE_UNSOLICITED_INPUT_NAME | Required to read unsolicited input from a terminal device. User Right:


Security Descriptor Definition Language

The security descriptor definition language (SDDL) defines the string format that the ConvertSecurityDescriptorToStringSecurityDescriptor and ConvertStringSecurityDescriptorToSecurityDescriptor functions use to describe a security descriptor as a text string. The language also defines string elements for describing information in the components of a security descriptor. For more information about SDDL, see the following topics:

  • Security Descriptor String Format
  • ACE Strings
  • SID Strings


Security Descriptor String Format

The security descriptor string format is a text format for storing or transporting information in a security descriptor. The ConvertSecurityDescriptorToStringSecurityDescriptor and ConvertStringSecurityDescriptorToSecurityDescriptor functions use this format.

The format is a null-terminated string with tokens to indicate each of the four main components of a security descriptor: owner (O:), primary group (G:), DACL (D:), and SACL (S:).

O:owner_sid
G:group_sid
D:dacl_flags(string_ace1)(string_ace2)... (string_acen)
S:sacl_flags(string_ace1)(string_ace2)... (string_acen)

Fields

owner_sid
A SID string that identifies the object's owner.
group_sid
A SID string that identifies the object's primary group.
dacl_flags
Security descriptor control flags that apply to the DACL. For a description of these control flags, see the SetSecurityDescriptorControl function. The dacl_flags string can be a concatenation of zero or more of the following strings.
Control | Constant in sddl.h | Meaning
"P" | SDDL_PROTECTED | The SE_DACL_PROTECTED flag is set.
"AR" | SDDL_AUTO_INHERIT_REQ | The SE_DACL_AUTO_INHERIT_REQ flag is set.
"AI" | SDDL_AUTO_INHERITED | The SE_DACL_AUTO_INHERITED flag is set.

sacl_flags
Security descriptor control flags that apply to the SACL. The sacl_flags string uses the same control bit strings as the dacl_flags string.
string_ace
A string that describes an ACE in the security descriptor's DACL or SACL. For a description of the ACE string format, see ACE strings. Each ACE string is enclosed in parentheses ( ).

Remarks

Unneeded components can be omitted from the security descriptor string. For example, if the SE_DACL_PRESENT flag is not set in the input security descriptor, ConvertSecurityDescriptorToStringSecurityDescriptor does not include a D: component in the output string. You can also use the SECURITY_INFORMATION bit flags to indicate the components to include in a security descriptor string.

The security descriptor string format does not support NULL ACLs. If you need the null DACL functionality, the DACL must have an explicit ACE that grants the access.

To denote an empty ACL, the security descriptor string includes the D: or S: token with no additional string information.

The security descriptor string stores the security descriptor control bits in different ways. The SE_DACL_PRESENT or SE_SACL_PRESENT bits are indicated by the presence of the D: or S: token in the string. Other bits that apply to the DACL or SACL are stored in dacl_flags and sacl_flags. The SE_OWNER_DEFAULTED, SE_GROUP_DEFAULTED, SE_DACL_DEFAULTED, and SE_SACL_DEFAULTED bits are not stored in a security descriptor string. The SE_SELF_RELATIVE bit is not stored in the string, but ConvertStringSecurityDescriptorToSecurityDescriptor always sets this bit in the output security descriptor.

Examples

The following examples show security descriptor strings and the information in the associated security descriptors.

String 1:

"O:AOG:DAD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)"

Security Descriptor 1:

    Revision:  0x00000001
    Control:   0x0004
        SE_DACL_PRESENT
    Owner: (S-1-5-32-548)
    PrimaryGroup: (S-1-5-21-397955417-626881126-188441444-512)
DACL
    Revision: 0x02
    Size:     0x001c
    AceCount: 0x0001
    Ace[00]
        AceType:       0x00 (ACCESS_ALLOWED_ACE_TYPE)
        AceSize:       0x0014
        InheritFlags:  0x00
        Access Mask:   0x100e003f
                            READ_CONTROL
                            WRITE_DAC
                            WRITE_OWNER
                            GENERIC_ALL
                            Others(0x0000003f)
        Ace Sid      : (S-1-0-0)
SACL
    Not present

String 2:

"O:DAG:DAD:(A;;RPWPCCDCLCRCWOWDSDSW;;;SY)(A;;RPWPCCDCLCRCWOWDSDSW;;;DA)(OA;;CCDC;bf967aba-0de6-11d0-a285-00aa003049e2;;AO)(OA;;CCDC;bf967a9c-0de6-11d0-a285-00aa003049e2;;AO)(OA;;CCDC;6da8a4ff-0e52-11d0-a286-00aa003049e2;;AO)(OA;;CCDC;bf967aa8-0de6-11d0-a285-00aa003049e2;;PO)(A;;RPLCRC;;;AU)S:(AU;SAFA;WDWOSDWPCCDCSW;;;WD)"

Security Descriptor 2:

    Revision:  0x00000001
    Control:   0x0014
        SE_DACL_PRESENT
        SE_SACL_PRESENT
    Owner: (S-1-5-21-397955417-626881126-188441444-512)
    PrimaryGroup: (S-1-5-21-397955417-626881126-188441444-512)
DACL
    Revision: 0x04
    Size:     0x0104
    AceCount: 0x0007
    Ace[00]
        AceType:       0x00 (ACCESS_ALLOWED_ACE_TYPE)
        AceSize:       0x0014
        InheritFlags:  0x00
        Access Mask:   0x000f003f
                            DELETE
                            READ_CONTROL
                            WRITE_DAC
                            WRITE_OWNER
                            Others(0x0000003f)
        Ace Sid:       (S-1-5-18)
    Ace[01]
        AceType:       0x00 (ACCESS_ALLOWED_ACE_TYPE)
        AceSize:       0x0024
        InheritFlags:  0x00
        Access Mask:   0x000f003f
                            DELETE
                            READ_CONTROL
                            WRITE_DAC
                            WRITE_OWNER
                            Others(0x0000003f)
        Ace Sid:       (S-1-5-21-397955417-626881126-188441444-512)
    Ace[02]
        AceType:       0x05 (ACCESS_ALLOWED_OBJECT_ACE_TYPE)
        AceSize:       0x002c
        InheritFlags:  0x00
        Access Mask:   0x00000003
                            Others(0x00000003)
        Flags:         0x00000001, ACE_OBJECT_TYPE_PRESENT
        ObjectType:    GUID_C_USER
        InhObjectType: GUID ptr is NULL
        Ace Sid:       (S-1-5-32-548)
    Ace[03]
        AceType:       0x05 (ACCESS_ALLOWED_OBJECT_ACE_TYPE)
        AceSize:       0x002c
        InheritFlags:  0x00
        Access Mask:   0x00000003
                            Others(0x00000003)
        Flags:         0x00000001, ACE_OBJECT_TYPE_PRESENT
        ObjectType:    GUID_C_GROUP
        InhObjectType: GUID ptr is NULL
        Ace Sid:       (S-1-5-32-548)
    Ace[04]
        AceType:       0x05 (ACCESS_ALLOWED_OBJECT_ACE_TYPE)
        AceSize:       0x002c
        InheritFlags:  0x00
        Access Mask:   0x00000003
                            Others(0x00000003)
        Flags:         0x00000001, ACE_OBJECT_TYPE_PRESENT
        ObjectType:    GUID_C_LOCALGROUP
        InhObjectType: GUID ptr is NULL
        Ace Sid:       (S-1-5-32-548)
    Ace[05]
        AceType:       0x05 (ACCESS_ALLOWED_OBJECT_ACE_TYPE)
        AceSize:       0x002c
        InheritFlags:  0x00
        Access Mask:   0x00000003
                            Others(0x00000003)
        Flags:         0x00000001, ACE_OBJECT_TYPE_PRESENT
        ObjectType:    GUID_C_PRINT_QUEUE
        InhObjectType: GUID ptr is NULL
        Ace Sid:       (S-1-5-32-550)
    Ace[06]
        AceType:       0x00 (ACCESS_ALLOWED_ACE_TYPE)
        AceSize:       0x0014
        InheritFlags:  0x00
        Access Mask:   0x00020014
                            READ_CONTROL
                            Others(0x00000014)
        Ace Sid:       (S-1-5-11)
    SACL
        Revision: 0x02
        Size:     0x001c
        AceCount: 0x0001
        Ace[00]
            AceType:       0x02 (SYSTEM_AUDIT_ACE_TYPE)
            AceSize:       0x0014
            InheritFlags:  0xc0
                SUCCESSFUL_ACCESS_ACE_FLAG
                FAILED_ACCESS_ACE_FLAG
            Access Mask:    0x000d002b
                                DELETE
                                WRITE_DAC
                                WRITE_OWNER
                                Others(0x0000002b)
            Ace Sid:       (S-1-1-0)


ACE Strings

The security descriptor definition language (SDDL) uses ACE strings in the DACL and SACL components of a security descriptor string.

As shown in the Security Descriptor String Format examples, each ACE in a security descriptor string is enclosed in parentheses. The fields of the ACE are in the following order and are separated by semicolons ( ; ).

ace_type;ace_flags;rights;object_guid;inherit_object_guid;account_sid

Fields

ace_type
A string that indicates the value of the AceType member of the ACE_HEADER structure. The ACE type string can be one of the following strings defined in sddl.h.
ACE type string

Constant in sddl.h

AceType value
"A" | SDDL_ACCESS_ALLOWED | ACCESS_ALLOWED_ACE_TYPE
"D" | SDDL_ACCESS_DENIED | ACCESS_DENIED_ACE_TYPE
"OA" | SDDL_OBJECT_ACCESS_ALLOWED | ACCESS_ALLOWED_OBJECT_ACE_TYPE
"OD" | SDDL_OBJECT_ACCESS_DENIED | ACCESS_DENIED_OBJECT_ACE_TYPE
"AU" | SDDL_AUDIT | SYSTEM_AUDIT_ACE_TYPE
"AL" | SDDL_ALARM | SYSTEM_ALARM_ACE_TYPE
"OU" | SDDL_OBJECT_AUDIT | SYSTEM_AUDIT_OBJECT_ACE_TYPE
"OL" | SDDL_OBJECT_ALARM | SYSTEM_ALARM_OBJECT_ACE_TYPE

ace_flags
A string that indicates the value of the AceFlags member of the ACE_HEADER structure. The ACE flags string can be a concatenation of the following strings defined in sddl.h.
ACE flags string

Constant in sddl.h

AceFlag value
"CI" | SDDL_CONTAINER_INHERIT | CONTAINER_INHERIT_ACE
"OI" | SDDL_OBJECT_INHERIT | OBJECT_INHERIT_ACE
"NP" | SDDL_NO_PROPAGATE | NO_PROPAGATE_INHERIT_ACE
"IO" | SDDL_INHERIT_ONLY | INHERIT_ONLY_ACE
"ID" | SDDL_INHERITED | INHERITED_ACE
"SA" | SDDL_AUDIT_SUCCESS | SUCCESSFUL_ACCESS_ACE_FLAG
"FA" | SDDL_AUDIT_FAILURE | FAILED_ACCESS_ACE_FLAG

rights
A string that indicates the access rights controlled by the ACE. This string can be a hexadecimal string representation of the access rights, such as "0x7800003F", or it can be a concatenation of the following strings.
Access rights string

Constant in sddl.h

Access right value
Generic access rights
"GA" | SDDL_GENERIC_ALL | GENERIC_ALL
"GR" | SDDL_GENERIC_READ | GENERIC_READ
"GW" | SDDL_GENERIC_WRITE | GENERIC_WRITE
"GX" | SDDL_GENERIC_EXECUTE | GENERIC_EXECUTE
Standard access rights
"RC" | SDDL_READ_CONTROL | READ_CONTROL
"SD" | SDDL_STANDARD_DELETE | DELETE
"WD" | SDDL_WRITE_DAC | WRITE_DAC
"WO" | SDDL_WRITE_OWNER | WRITE_OWNER
Directory service object access rights
"RP" | SDDL_READ_PROPERTY | ADS_RIGHT_DS_READ_PROP
"WP" | SDDL_WRITE_PROPERTY | ADS_RIGHT_DS_WRITE_PROP
"CC" | SDDL_CREATE_CHILD | ADS_RIGHT_DS_CREATE_CHILD
"DC" | SDDL_DELETE_CHILD | ADS_RIGHT_DS_DELETE_CHILD
"LC" | SDDL_LIST_CHILDREN | ADS_RIGHT_DS_LIST
"SW" | SDDL_SELF_WRITE | ADS_RIGHT_DS_SELF
"LO" | SDDL_LIST_OBJECT | ADS_RIGHT_DS_LIST_OBJECT
"DT" | SDDL_DELETE_TREE | ADS_RIGHT_DS_DELETE_TREE
"CR" | SDDL_CONTROL_ACCESS | ADS_RIGHT_DS_CONTROL_ACCESS
File access rights
"FA" | SDDL_FILE_ALL | FILE_ALL_ACCESS
"FR" | SDDL_FILE_READ | FILE_GENERIC_READ
"FW" | SDDL_FILE_WRITE | FILE_GENERIC_WRITE
"FX" | SDDL_FILE_EXECUTE | FILE_GENERIC_EXECUTE
Registry key access rights
"KA" | SDDL_KEYL_ALL | KEY_ALL_ACCESS
"KR" | SDDL_KEY_READ | KEY_READ
"KW" | SDDL_KEY_WRITE | KEY_WRITE
"KX" | SDDL_KEY_EXECUTE | KEY_EXECUTE

object_guid
A string representation of a GUID that indicates the value of the ObjectType member of an object-specific ACE structure, such as ACCESS_ALLOWED_OBJECT_ACE. The GUID string uses the format returned by the UuidToString function.
inherit_object_guid
A string representation of a GUID that indicates the value of the InheritedObjectType member of an object-specific ACE structure. The GUID string uses the UuidToString format.
account_sid
A SID string that identifies the trustee of the ACE.

Example

The following example shows an ACE string for an access-allowed ACE. It is not an object-specific ACE, so it has no information in the object_guid and inherit_object_guid fields. The ace_flags field is also empty, indicating that none of the ACE flags are set.

(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)

This string describes the following ACE information.

AceType:       0x00 (ACCESS_ALLOWED_ACE_TYPE)
AceFlags:      0x00
Access Mask:   0x100e003f
                    READ_CONTROL
                    WRITE_DAC
                    WRITE_OWNER
                    GENERIC_ALL
                    Other access rights(0x0000003f)
Ace Sid      : (S-1-0-0)

See Also

Security Descriptor String Format, SID Strings


SID Strings

In the security descriptor definition language (SDDL), security descriptor string use SID strings for the following components of a security descriptor:

  • Owner
  • Primary group
  • The trustee in an ACE

A SID string in a security descriptor string can use either the standard string representation of a SID (S-R-I-S-S...) or one of the string constants defined in sddl.h. For more information about the standard SID string notation, see SID Components.

The following SID string constants for well-known SIDs are defined in sddl.h.

SID string | Constant in sddl.h | Account alias
"AO" | SDDL_ACCOUNT_OPERATORS | Account operators
"AU" | SDDL_AUTHENTICATED_USERS | Authenticated users
"BA" | SDDL_BUILTIN_ADMINISTRATORS | Built-in administrators
"BG" | SDDL_BUILTIN_GUESTS | Built-in guests
"BO" | SDDL_BACKUP_OPERATORS | Backup operators
"BU" | SDDL_BUILTIN_USERS | Built-in users
"CA" | SDDL_CERT_SERV_ADMINISTRATORS | Certificate server administrators
"CG" | SDDL_CREATOR_GROUP | Creator group
"CO" | SDDL_CREATOR_OWNER | Creator owner
"DA" | SDDL_DOMAIN_ADMINISTRATORS | Domain administrators
"DC" | SDDL_DOMAIN_COMPUTERS | Domain computers
"DD" | SDDL_DOMAIN_DOMAIN_CONTROLLERS | Domain controllers
"DG" | SDDL_DOMAIN_GUESTS | Domain guests
"DU" | SDDL_DOMAIN_USERS | Domain users
"ED" | SDDL_ENTERPRISE_DOMAIN_CONTROLLERS | Enterprise domain controllers
"IU" | SDDL_INTERACTIVE | Interactively logged-on user
"LA" | SDDL_LOCAL_ADMIN | Local administrator
"LG" | SDDL_LOCAL_GUEST | Local guest
"NU" | SDDL_NETWORK | Network logon user
"PO" | SDDL_PRINTER_OPERATORS | Printer operators
"PS" | SDDL_PERSONAL_SELF | Personal self
"PU" | SDDL_POWER_USERS | Power users
"RC" | SDDL_RESTRICTED_CODE | Restricted code
"RE" | SDDL_REPLICATOR | Replicator
"SA" | SDDL_SCHEMA_ADMINISTRATORS | Schema administrators
"SO" | SDDL_SERVER_OPERATORS | Server operators
"SU" | SDDL_SERVICE | Service logon user
"SY" | SDDL_LOCAL_SYSTEM | Local System
"WD" | SDDL_EVERYONE | World (Everyone)
"RS" | SDDL_RAS_SERVERS | RAS servers group
"EA" | SDDL_ENTERPRISE_ADMINS | Enterprise administrators
"PA" | SDDL_GROUP_POLICY_ADMINS | Group Policy administrators
"RU" | SDDL_ALIAS_PREW2KCOMPACC | Alias to allow previous Windows 2000

Remarks

The ConvertSidToStringSid and ConvertStringSidToSid functions always use the standard SID string notation and do not support SDDL SID string constants.


Access Control Editor

Does your application use security descriptors to control access to securable objects? Do you want users or administrators to be able to view or edit the information in these security descriptors?

The access control editor provides a standard user interface for editing the information in an object's security descriptor. The editor has a basic security property page for simple editing of the ACEs in the object's DACL. It can optionally display additional property pages for more advanced editing, such as changing the object's owner or modifying the object's SACL.

This overview provides the following information about the access control editor:

  • A discussion of the functions and interfaces used to display the access control editor
  • A description of the basic security property page
  • Descriptions of the advanced property pages

For more information about access control, see the Access Control overview.


About the Access Control Editor

The access control editor is a set of property sheets and property pages that enable the user to view and modify the components of an object's security descriptor. The editor consists of two main parts:

  • A basic security property page that provides a simple interface for editing the ACEs in an object's DACL. This page can include an optional Advanced button that displays the advanced security property sheet.
  • An advanced security property sheet with property pages that enable the user to edit the object's SACL, change the object's owner, or perform advanced editing of the object's DACL.

The CreateSecurityPage function creates the basic security property page. You can then use the PropertySheet function or the PSM_ADDPAGE message to add this page to a property sheet.

Alternatively, you can use the EditSecurity function to display a property sheet that contains the basic security property page.

For both CreateSecurityPage and EditSecurity, the caller must pass a pointer to an implementation of the ISecurityInformation interface. The access control editor calls the methods of this interface to retrieve access control information about the object being edited and to pass the user's input back to your application. The ISecurityInformation methods have the following purposes.

  • To initialize the property pages. Your implementation of the GetObjectInformation method passes an SI_OBJECT_INFO structure to the editor. This structure specifies the property pages that you want the editor to display and other information that determines the editing options available to the user.
  • To provide security information about the object being edited. Your GetSecurity implementation passes the object's initial security descriptor to the editor. The GetAccessRights and MapGeneric methods provide information about the object's access rights. The GetInheritTypes method provides information about how the object's ACEs can be inherited by child objects.
  • To pass the user's input back to your application. When the user clicks the Okay or Apply button, the editor calls your SetSecurity method to pass back a security descriptor containing the user's changes.


Basic Security Property Page

The basic security property page is the starting page of the property sheet displayed by the EditSecurity function. You can also use the CreateSecurityPage function to create a basic security property page to insert in your own property sheet.

The following illustration shows a typical basic security property page.

The property page displays a list of the trustees named in the ACEs of the object's DACL. The page also contains a list of the access rights supported by the object. When the user selects a name from the list of trustees, the checkboxes next to each access right indicate the rights that are allowed or denied for that trustee. The user can then click in the checkboxes to modify the trustee's access rights. The user can also add or remove trustees from the list.

The basic security page cannot display complex ACEs, such as object-specific ACEs . It also does not display ACE inheritance information. To enable the user to view or edit such information, you can include an Advanced button on the basic security page. The user can click the Advanced button to display an advanced security property sheet. This property sheet has property pages that enable the user to edit the object's SACL, change the object's owner, or perform advanced editing of the object's DACL. To display the Advanced button, set the SI_ADVANCED flag in the SI_OBJECT_INFO structure returned by your ISecurityInformation::GetObjectInformation implementation.

You can use the pszPageTitle member of the SI_OBJECT_INFO structure to specify the title of the basic security property page. The default title is Security.


Advanced Security Property Sheet

The advanced security property sheet enables the user to perform editing operations that are not available on the basic security page of an access control editor. The property sheet can include the following property pages:

  • A Permissions property page for advanced editing of the object's DACL, such as editing object-specific ACEs or controlling ACE inheritance.
  • An Auditing property page for viewing and editing the object's SACL.
  • An Owner property page for changing the object's owner.

The user can display the advanced security property sheet by clicking the Advanced button on the basic security property page. To display the Advanced button, set the SI_ADVANCED flag in the SI_OBJECT_INFO structure returned by your ISecurityInformation::GetObjectInformation implementation.

The following illustration shows the Permissions property page of a typical advanced security property sheet.


Permissions Property Page

The Permissions property page contains controls for advanced editing of the ACEs in an object's DACL. This page enables the user to view and edit all of the information in the DACL, including information that is not available on the basic security property page. The advanced information includes object-specific ACEs and information about ACE inheritance.

The Permissions property page is always included in the advanced security property sheet displayed when the user clicks the Advanced button on the basic security property page.


Auditing Property Page

The access control editor can include an Auditing property page that enables the user to view and edit the ACEs in an object's SACL. For more information about SACLs, see Access-Control Lists (ACLs).

The Auditing property page is in the advanced security property sheet displayed when the user clicks the Advanced button on the basic security property page. To include the Auditing property page, set the SI_ADVANCED and SI_EDIT_AUDITS flags in the SI_OBJECT_INFO structure returned by your ISecurityInformation::GetObjectInformation implementation.


Owner Property Page

The access control editor can include an Owner property page that enables the user to change an object's owner. For more information about an object's owner, see Owner of a New Object and Taking Object Ownership.

The Owner property page is in the advanced security property sheet displayed when the user clicks the Advanced button on the basic security property page. To include the Owner property page, set the SI_ADVANCED and SI_EDIT_OWNER flags in the SI_OBJECT_INFO structure returned by your ISecurityInformation::GetObjectInformation implementation.


Using the Access Control Editor

The Platform SDK includes the SECUROBJ sample program that shows how to use the access control editor.


Access Control Editor Reference

The following elements are used with the access control editor.

  • Access Control Editor Functions
  • Access Control Editor Interfaces
  • Access Control Editor Structures
  • Access Control Editor Enumeration Types


Access Control Editor Functions

The following functions are used with the access control editor.

Function | Description
CreateSecurityPage | Creates a basic security property page that enables the user to view and edit the access rights allowed or denied by the ACEs in an object's DACL.
EditSecurity | Displays a property sheet that contains a basic security property page.


CreateSecurityPage

The CreateSecurityPage function creates a basic security property page that enables the user to view and edit the access rights allowed or denied by the ACEs in an object's DACL. Use the PropertySheet function or the PSM_ADDPAGE message to add this page to a property sheet.

HPROPSHEETPAGE CreateSecurityPage(
  LPSECURITYINFO psi   // an ISecurityInformation pointer
);

Parameters

psi
[in] Pointer to your implementation of the ISecurityInformation interface. The system calls the interface methods to retrieve information about the object being edited and to return the user's input.

Return Values

If the function succeeds, the return value is a handle to a basic security property page.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

During the property page initialization, the system calls the ISecurityInformation::GetSecurity and ISecurityInformation::SetSecurity methods to determine whether the user has permission to edit the object's security descriptor. The system displays an error message if the user does not have permission.

The basic security property page can include an Advanced button for displaying the advanced security property sheet. This advanced security property sheet can contain three additional property pages that enable the user to view and edit the object's DACL, SACL, and owner.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Aclui.h.
Library: Use Aclui.lib.

See Also

Access Control Editor Overview, Access Control Editor Functions, EditSecurity, ISecurityInformation, PropertySheet, PSM_ADDPAGE


EditSecurity

The EditSecurity function displays a property sheet that contains a basic security property page. This property page enables the user to view and edit the access rights allowed or denied by the ACEs in an object's DACL.

BOOL EditSecurity(
  HWND hwndOwner,       // handle to the owner window
  LPSECURITYINFO psi   // an ISecurityInformation pointer
);

Parameters

hwndOwner
[in] Handle to the window that owns the property sheet. This parameter can be NULL.
psi
[in] Pointer to your implementation of the ISecurityInformation interface. The system calls the interface methods to retrieve information about the object being edited and to return the user's input.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The EditSecurity function calls the CreateSecurityPage function to create a basic security property page.

During the property page initialization, the system calls the ISecurityInformation::GetSecurity and ISecurityInformation::SetSecurity methods to determine whether the user has permission to edit the object's security descriptor. The system displays an error message if the user does not have permission.

The basic security property page can include an Advanced button for displaying the advanced security property sheet. This advanced security property sheet can contain three additional property pages that enable the user to view and edit the object's DACL, SACL, and owner.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Aclui.h.
Library: Use Aclui.lib.

See Also

Access Control Editor Overview, Access Control Editor Functions, CreateSecurityPage, ISecurityInformation


Access Control Editor Interfaces

The following interfaces are used with the access control editor.

Interface | Description
ISecurityInformation | Enables the access control editor to communicate with the caller of the CreateSecurityPage and EditSecurity functions.
ISecurityInformation2 | Enables the access control editor to obtain information from the client not provided by the ISecurityInformation interface.


ISecurityInformation

The ISecurityInformation interface enables the access control editor to communicate with the caller of the CreateSecurityPage and EditSecurity functions. The editor calls the interface methods to retrieve information used to initialize its pages and to determine the editing options available to the user. The editor also calls the interface methods to pass the user's input back to the application.

The LPSECURITYINFO type is a pointer to an ISecurityInformation object.

When to Implement

You must implement the ISecurityInformation interface if you use the CreateSecurityPage or EditSecurity functions.

When to Use

Applications do not call the ISecurityInformation methods. The system calls the interface methods to communicate with application that called CreateSecurityPage or EditSecurity.

Methods in Vtable Order

IUnknown Methods

QueryInterface
AddRef
Release

ISecurityInformation Methods

Method | Description
GetObjectInformation | Requests information used to initialize the access control editor and to determine the editing options available to the user.
GetSecurity | Requests the security descriptor of the object being edited.
SetSecurity | Provides a security descriptor containing the security information specified by the user.
GetAccessRights | Requests information about the access rights supported by the object being edited.
MapGeneric | Requests that the generic access rights in an access mask be mapped to their corresponding standard and specific access rights.
GetInheritTypes | Requests information about how the object's ACEs can be inherited by child objects.
PropertySheetPageCallback | Notifies the application that an access control editor property page is being created or destroyed.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Aclui.h.

See Also

Access Control Editor Overview, Access Control Editor Interfaces, CreateSecurityPage, EditSecurity


ISecurityInformation::GetObjectInformation

The GetObjectInformation method requests information that the access control editor uses to initialize its pages and to determine the editing options available to the user.

HRESULT GetObjectInformation(
  PSI_OBJECT_INFO pObjectInfo
);

Parameters

pObjectInfo
[out] Pointer to an SI_OBJECT_INFO structure. Your implementation must fill this structure to pass information back to the access control editor.

Return Values

Return S_OK if successful.

Return a nonzero error code if an error occurs.

Remarks

The system does not free the string pointers that you return in the SI_OBJECT_INFO structure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Aclui.h.

See Also

Access Control Editor Overview, Access Control Editor Interfaces, SI_OBJECT_INFO


ISecurityInformation::GetSecurity

The GetSecurity method requests a security descriptor for the securable object whose security descriptor is being edited. The access control editor calls this method to retrieve the object's current or default security descriptor.

HRESULT GetSecurity(
  SECURITY_INFORMATION RequestedInformation,
  PSECURITY_DESCRIPTOR *ppSecurityDescriptor,
  BOOL fDefault
);

Parameters

RequestedInformation
[in] A set of SECURITY_INFORMATION bit flags that indicate the parts of the security descriptor being requested. This parameter can be a combination of the following values.
Value | Meaning
OWNER_SECURITY_INFORMATION | If this flag is set, the security descriptor must include the SID of the object's owner.
GROUP_SECURITY_INFORMATION | If this flag is set, the security descriptor must include the SID of the object's primary group.
DACL_SECURITY_INFORMATION | If this flag is set, the security descriptor must include the object's DACL.
SACL_SECURITY_INFORMATION | If this flag is set, the security descriptor must include the object's SACL.

ppSecurityDescriptor
[out] Pointer to a variable that your implementation must set to a pointer to the object's security descriptor. The security descriptor must include the components requested by the RequestedInformation parameter.

The system calls the LocalFree function to free the returned pointer.

fDefault
[in] If this flag is TRUE, ppSecurityDescriptor should return an application-defined default security descriptor for the object. The access control editor uses this default security descriptor to reinitialize the property page.

The access control editor sets this flag to TRUE only if the user clicks the Default button. The Default button is displayed only if you set the SI_RESET flag in the ISecurityInformation::GetObjectInformation method. If no default security descriptor is available, do not set the SI_RESET flag.

If this flag is FALSE, ppSecurityDescriptor should return the object's current security descriptor.

Return Values

Return S_OK if successful.

Return a nonzero error code if an error occurs. Return E_ACCESSDENIED if the user does not have the permission to read the requested security information.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Aclui.h.

See Also

Access Control Editor Overview, Access Control Editor Interfaces, ISecurityInformation::GetObjectInformation, SECURITY_INFORMATION


ISecurityInformation::SetSecurity

The SetSecurity method provides a security descriptor containing the security information the user wants to apply to the securable object. The access control editor calls this method when the user clicks the Okay or Apply buttons.

HRESULT SetSecurity(
  SECURITY_INFORMATION SecurityInformation,
  PSECURITY_DESCRIPTOR pSecurityDescriptor
);

Parameters

SecurityInformation
[in] A set of SECURITY_INFORMATION bit flags that indicate the parts of the security descriptor to set. This parameter can be a combination of the following values.
Value | Meaning
OWNER_SECURITY_INFORMATION | If this flag is set, the security descriptor contains the SID of the object's owner.
GROUP_SECURITY_INFORMATION | If this flag is set, the security descriptor contains the SID of the object's primary group.
DACL_SECURITY_INFORMATION | If this flag is set, the security descriptor contains the object's DACL.
SACL_SECURITY_INFORMATION | If this flag is set, the security descriptor contains the object's SACL.

pSecurityDescriptor
[in] Pointer to a security descriptor containing the new security information. Do not assume the security descriptor is in self-relative form; it may be either absolute or self-relative.

Return Values

Return S_OK if successful.

Return a nonzero error code if an error occurs.

Remarks

To build a complete security descriptor for the object, the application must merge the new security descriptor parts, as defined by the SecurityInformation parameter, into the object's existing security descriptor.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Aclui.h.

See Also

Access Control Editor Overview, Access Control Editor Interfaces, SECURITY_INFORMATION


ISecurityInformation::GetAccessRights

The GetAccessRights method requests information about the access rights that can be controlled for a securable object. The access control editor calls this method to retrieve display strings and other information used to initialize the property pages. For more information, see Access Rights and Access Masks.

HRESULT GetAccessRights(
  const GUID *pguidObjectType,
  DWORD dwFlags,
  PSI_ACCESS *ppAccess,
  ULONG *pcAccesses,
  ULONG *piDefaultAccess
);

Parameters

pguidObjectType
[in] Pointer to a GUID structure that identifies the type of object for which access rights are being requested. If this parameter is NULL or a pointer to GUID_NULL, return the access rights for the object being edited. Otherwise, the GUID identifies a child object type returned by the ISecurityInformation::GetInheritTypes method. The GUID corresponds to the InheritedObjectType member of an object-specific ACE.
dwFlags
[in] A set of bit flags that indicate the property page being initialized. This value is zero if the basic security page is being initialized. Otherwise, it is a combination of the following values.
Value | Meaning
SI_ADVANCED | The advanced security property sheet is being initialized.
SI_EDIT_AUDITS | The advanced security property sheet includes the Audit property page.
SI_EDIT_PROPERTIES | The advanced security property sheet enables editing of ACEs that apply to the object's properties and property sets.

ppAccess
[out] Pointer to a variable that you should set to a pointer to an array of SI_ACCESS structures. The array should include one entry for each access right. You can specify access rights that apply to the object itself, as well as object-specific access rights that apply only to a property set or property on the object.
pcAccesses
[out] Pointer to a variable that you should set to indicate the number of entries in the ppAccess array.
piDefaultAccess
[out] Pointer to a variable that you should set to indicate the zero-based index of the array entry that contains the default access rights. The access control editor uses this entry as the initial access rights in a new ACE.

Return Values

Return S_OK if successful.

Return a nonzero error code if an error occurs.

Remarks

The GetAccessRights method is called each time a property page is initialized.

The access control editor does not free the pointer returned in *ppAccess.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Aclui.h.

See Also

Access Control Editor Overview, Access Control Editor Interfaces, CreateSecurityPage, EditSecurity, GUID, ISecurityInformation::GetInheritTypes, SI_ACCESS


ISecurityInformation::MapGeneric

The MapGeneric method requests that the generic access rights in an access mask be mapped to their corresponding standard and specific access rights. For more information about generic, standard, and specific access rights, see Access Rights and Access Masks.

HRESULT MapGeneric(
  const GUID *pguidObjectType,
  UCHAR *pAceFlags,
  ACCESS_MASK *pMask
);

Parameters

pguidObjectType
[in] Pointer to a GUID structure that identifies the type of object to which the access mask applies. If this member is NULL or a pointer to GUID_NULL, the access mask applies to the object itself.
pAceFlags
[in] Pointer to the AceFlags member of the ACE_HEADER structure from the ACE whose access mask is being mapped.
pMask
[in] Pointer to an access mask containing the generic access rights to map. Your implementation should map the generic access rights to the corresponding standard and specific access rights for the specified object type.

Return Values

Return S_OK if successful.

Return a nonzero error code if an error occurs.

Remarks

Your MapGeneric implementation can call the MapGenericMask function to map the generic access rights in the access mask.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Aclui.h.

See Also

Access Control Editor Overview, Access Control Editor Interfaces, ACE_HEADER, CreateSecurityPage, EditSecurity, GUID, MapGenericMask


ISecurityInformation::GetInheritTypes

The GetInheritTypes method requests information about how ACEs can be inherited by child objects. For more information, see ACE Inheritance.

HRESULT GetInheritTypes(
  PSI_INHERIT_TYPE *ppInheritTypes,
  ULONG *pcInheritTypes
);

Parameters

ppInheritTypes
[out] Pointer to a variable you should set to a pointer to an array of SI_INHERIT_TYPE structures. The array should include one entry for each combination of inheritance flags and child object type that you support.
pcInheritTypes
[out] Pointer to a variable that you should set to indicate the number of entries in the ppInheritTypes array.

Return Values

Return S_OK if successful.

Return a nonzero error code if an error occurs.

Remarks

The access control editor does not free the pointer returned in *ppInheritTypes.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Aclui.h.

See Also

Access Control Editor Overview, Access Control Editor Interfaces, CreateSecurityPage, EditSecurity, SI_INHERIT_TYPE


ISecurityInformation::PropertySheetPageCallback

The PropertySheetPageCallback method notifies an EditSecurity or CreateSecurityPage caller that an access control editor property page is being created or destroyed.

HRESULT PropertySheetPageCallback(
  HWND hwnd,
  UINT uMsg,
  SI_PAGE_TYPE uPage
);

Parameters

hwnd
[in] If uMsg is PSPCB_SI_INITDIALOG, hwnd is a handle to the property page dialog window. Otherwise, hwnd is NULL.
uMsg
[in] Identifies the message being received. This parameter is one of the following values.
Value | Meaning
PSPCB_CREATE | Indicates that a property page is being created.
PSPCB_RELEASE | Indicates that a property page is being destroyed.
PSPCB_SI_INITDIALOG | Indicates that a property page is being initialized.

uPage
[in] A value from the SI_PAGE_TYPE enumeration type that indicates the type of access control editor property page being created or destroyed.

Return Values

Return S_OK if successful.

Return a nonzero error code if an error occurs.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Aclui.h.

See Also

Access Control Editor Overview, Access Control Editor Interfaces, CreateSecurityPage, EditSecurity, SI_PAGE_TYPE


ISecurityInformation2

The ISecurityInformation2 interface enables the access control editor to obtain information from the client not provided by the ISecurityInformation interface. The client does not need to implement ISecurityInformation2 unless the default behavior of the access control editor is unsuitable for the client.

When to Implement

You must implement the ISecurityInformation2 interface if you intend your access control editor client to provide information to the server on ACE ordering in a DACL or the common names of a list of SIDs.

When to Use

Applications do not call the ISecurityInformation2 methods. The system calls the interface methods to communicate with the client.

Methods

Method | Description
IsDaclCanonical | Checks the specified DACL for canonical ordering of the ACEs contained within it.
LookupSids | Retrieves the common names corresponding to the specified SIDs.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Aclui.h.

See Also

Access Control Editor Overview, Access Control Editor Interfaces


ISecurityInformation2::IsDaclCanonical

The IsDaclCanonical method determines whether the ACEs contained in the specified DACL structure are ordered according to the definition of DACL ordering implemented by the client

BOOL IsDaclCanonical(
  PACL pDacl
);

Parameters

pDacl
[in] Pointer to a discretionary ACL structure initialized by InitializeAcl.

Return Values

Returns TRUE if the ACEs contained in the specified DACL structure are ordered according to the definition of DACL ordering implemented by the client. Returns FALSE if the ACEs are misordered.

Remarks

If the return value of this method is FALSE, the access control editor will display a message box stating that the DACL is incorrectly ordered. If this method is not provided and the editor requires this information, the editor will check the DACL for Windows NT canonical ordering defined in Order of ACEs in a DACL.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Aclui.h.

See Also

Access Control Editor Overview, Access Control Editor Interfaces, ACL, InitializeAcl


ISecurityInformation2::LookupSids

The LookupSids method returns the common names corresponding to each of the elements in the specified list of SIDs.

HRESULT LookupSids(
  ULONG cSids,
  PSID *rgpSids,
  LPDATAOBJECT *pSidNames
);

Parameters

cSids
[in] The number of SID structures pointed to by rgpSids.
rgpSids
[in] Pointer to a linked list of SID structures.
pSidNames
[out] Pointer to a returned data transfer object that contains the common names of the SIDs and, optionally, the user principal name (UPN) of the SIDs, in rgpSids. The data transfer object is a SID_INFO structure.

Return Values

Returns S_OK if successful.

Returns a nonzero error code if an error occurs.

Remarks

Your implementation of LookupSids can return E_NOTIMPL if the access control editor is to determine the common names corresponding to the specified SIDs. However, if the access control editor receives any return code other than S_OK, the editor determines this information.

The client must return the common names through the data object using the following format.

// HGLOBAL containing SID_INFO_LIST returned by ISecurityInformation2::LookupSids
#define CFSTR_ACLUI_SID_INFO_LIST   TEXT("CFSTR_ACLUI_SID_INFO_LIST")

// Data structures corresponding to CFSTR_ACLUI_SID_INFO_LIST
typedef struct _SID_INFO
{
    PSID    pSid;
    PWSTR   pwzCommonName;
    PWSTR   pwzClass;       // Used for selecting icon, e.g. "User" or "Group"
    PWSTR   pwzUPN;         // Optional pointer to a user principal
                            // name
} SID_INFO, *PSID_INFO;

typedef struct _SID_INFO_LIST
{
    ULONG       cItems;
    SID_INFO    aSidInfo[ANYSIZE_ARRAY];
} SID_INFO_LIST, *PSID_INFO_LIST;

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Aclui.h.

See Also

Access Control Editor Overview, Access Control Editor Interfaces, SID_INFO, SID_INFO_LIST, SID


Access Control Editor Structures

The following structures are used with the access control editor.

SI_ACCESS
SI_INHERIT_TYPE
SI_OBJECT_INFO
SID_INFO
SID_INFO_LIST


SI_ACCESS

The SI_ACCESS structure contains information about an access right or default access mask for a securable object. The ISecurityInformation::GetAccessRights method uses this structure to specify information that the access control editor uses to initialize its property pages.

typedef struct _SI_ACCESS {
  const GUID *pguid;
  ACCESS_MASK mask;
  LPCWSTR     pszName;
  DWORD       dwFlags;
} SI_ACCESS, *PSI_ACCESS;

Members

pguid
Pointer to a GUID structure that identifies the type of object to which the access right or default access mask applies. The GUID can identify a property set or property on the object, or a type of child object that can be contained by the object.

If this member points to GUID_NULL, the access right applies to the object itself.

mask
A bit mask that specifies the access right described by this structure. The mask can contain any combination of standard and specific rights, but should not contain generic rights such as GENERIC_ALL.
pszName
Pointer to a null-terminated Unicode string containing a display string that describes the access right.

Alternatively, pszName can be a string resource identifier returned by the MAKEINTRESOURCE macro. Use the ISecurityInformation::GetObjectInformation method to identify the module that contains the string resource.

dwFlags
A set of bit flags that indicate where the access right is displayed. This member can be a combination of the following.
Value | Meaning
SI_ACCESS_SPECIFIC | If this flag is set, the access right is displayed on the advanced security pages.
SI_ACCESS_GENERAL | If this flag is set, the access right is displayed on the basic security page.
SI_ACCESS_CONTAINER | Indicates an access right that applies only to containers. If this flag is set, the access right is displayed on the basic security page only if the ISecurityInformation::GetObjectInformation method specifies the SI_CONTAINER flag.
SI_ACCESS_PROPERTY | Indicates a property-specific access right. Used with SI_EDIT_PROPERTIES.

This member can also specify a combination of the following flags to indicate whether other containers or objects can inherit the access right.
Value | Meaning
CONTAINER_INHERIT_ACE | Other containers that are contained by the primary object inherit the entry.
INHERIT_ONLY_ACE | The ACE does not apply to the primary object to which the ACL is attached, but objects contained by the primary object inherit the entry.
OBJECT_INHERIT_ACE | Noncontainer objects contained by the primary object inherit the entry.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Aclui.h.

See Also

Access Control Editor Overview, Access Control Editor Structures, GUID, ISecurityInformation::GetAccessRights, ISecurityInformation::GetObjectInformation, MAKEINTRESOURCE


SI_INHERIT_TYPE

The SI_INHERIT_TYPE structure contains information about how ACEs can be inherited by child objects. The ISecurityInformation::GetInheritTypes method uses this structure to specify display strings that the access control editor uses to initialize its property pages.

typedef struct _SI_INHERIT_TYPE {
  const GUID *pguid;
  ULONG       dwFlags;
  LPCWSTR     pszName;
} SI_INHERIT_TYPE, *PSI_INHERIT_TYPE;

Members

pguid
Pointer to a GUID structure that identifies the type of child object. This member can be a pointer to GUID_NULL. The GUID corresponds to the InheritedObjectType member of an object-specific ACE.
dwFlags
A set of inheritance flags that indicate the types of ACEs that can be inherited by the pguid object type. These flags correspond to the AceFlags member of an ACE_HEADER structure. This member can be a combination of the following values.
Value | Meaning
CONTAINER_INHERIT_ACE | The specified object type can inherit ACEs that have the CONTAINER_INHERIT_ACE flag set.
INHERIT_ONLY_ACE | The specified object type can inherit ACEs that have the INHERIT_ONLY_ACE flag set.
OBJECT_INHERIT_ACE | The specified object type can inherit ACEs that have the OBJECT_INHERIT_ACE flag set.

pszName
Pointer to a null-terminated Unicode string containing a display string that describes the child object.

Alternatively, pszName can be a string resource identifier returned by the MAKEINTRESOURCE macro. Use the ISecurityInformation::GetObjectInformation method to identify the module that contains the string resource.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Aclui.h.

See Also

Access Control Editor Overview, Access Control Editor Structures, ACE_HEADER, ISecurityInformation::GetInheritTypes, ISecurityInformation::GetObjectInformation, MAKEINTRESOURCE


SI_OBJECT_INFO

The SI_OBJECT_INFO structure is used by the ISecurityInformation::GetObjectInformation method to specify information used to initialize the access control editor.

typedef struct _SI_OBJECT_INFO {
  DWORD       dwFlags;
  HINSTANCE   hInstance;
  LPWSTR      pszServerName;
  LPWSTR      pszObjectName;
  LPWSTR      pszPageTitle;
  GUID        guidObjectType;
} SI_OBJECT_INFO, *PSI_OBJECT_INFO;

Members

dwFlags
A set of bit flags that determine the editing options available to the user. This member can be a combination of the following values.
Value Meaning
SI_ADVANCED
 If this flag is set, the Advanced button is displayed on the basic security property page. If the user clicks this button, the system displays an advanced security property sheet that enables advanced editing of the object's DACL.

Combine this flag with the SI_EDIT_AUDITS, SI_EDIT_OWNER, and SI_EDIT_PROPERTIES flags to enable editing of the object's SACL, owner, and object-specific ACEs.

SI_CONTAINER
 Indicates that the object is a container. If this flag is set, the access control editor enables the controls relevant to the inheritance of permissions onto child objects.
SI_EDIT_ALL
Combines the SI_EDIT_PERMS,

SI_EDIT_OWNER, and SI_EDIT_AUDITS flags.
SI_EDIT_AUDITS
 If this flag is set and the user clicks the Advanced button, the system displays an advanced security property sheet that includes an Auditing property page for editing the object's SACL. To display the Advanced button, set the SI_ADVANCED flag.
SI_EDIT_OWNER
 If this flag is set and the user clicks the Advanced button, the system displays an advanced security property sheet that includes an Owner property page for changing the object's owner. To display the Advanced button, set the SI_ADVANCED flag.
SI_EDIT_PERMS
 This is the default value. The basic security property page always displays the controls for basic editing of the object's DACL. To disable these controls, set the SI_READONLY flag.
SI_EDIT_PROPERTIES
 If this flag is set, the system enables controls for editing ACEs that apply to the object's property sets and properties. These controls are available only on the property sheet displayed when the user clicks the Advanced button.
SI_NO_ACL_PROTECT
 If this flag is set, the access control editor hides the check box that allows inheritable ACEs to propagate from the parent object to this object. If this flag is not set, the check box is visible.

The check box is clear if the SE_DACL_PROTECTED flag is set in the object's security descriptor. In this case, the object's DACL is protected from being modified by inheritable ACEs.

If the user clears the check box, any inherited ACEs in the security descriptor are deleted or converted to noninherited ACEs. Before proceeding with this conversion, the system displays a warning message box to confirm the change.
SI_NO_TREE_APPLY
 If this flag is set, the access control editor hides the check box that controls the NO_PROPAGATE_INHERIT_ACE flag. This flag is relevant only when the SI_ADVANCED flag is also set.
SI_OBJECT_GUID
 When set, indicates that the guidObjectType member of the SI_OBJECT_INFO structure is valid. This is set in comparisons with object-specific ACEs in determining whether the ACE applies to the current object.
SI_OWNER_READONLY
 If this flag is set, the user cannot change the owner of the object. Set this flag if SI_EDIT_OWNER is set but the user does not have permission to change the owner.
SI_OWNER_RECURSE
 Combine this flag with SI_CONTAINER to display a check box on the owner page that indicates whether the user intends the new owner to be applied to all child objects as well as the current object. The access control editor does not perform the recursion, but it should be performed by the application in ISecurityInformation::SetSecurity.
SI_PAGE_TITLE
 If this flag is set, the pszPageTitle member is used as the title of the basic security property page. Otherwise, a default title is used.
SI_READONLY
 If this flag is set, the editor displays the object's security information, but the controls for editing the information are disabled.
SI_RESET
 If this flag is set, the Default button is displayed. If the user clicks this button, the access control editor calls the ISecurityInformation::GetSecurity method to retrieve an application-defined default security descriptor. The access control editor uses this security descriptor to reinitialize the property sheet, and the user is allowed to apply the change or cancel.
SI_RESET_DACL_TREE
 When set, this flag displays the Reset permissions on all child objects and enable propagation of inheritable permissions check box in the Permissions page of the Access Control Settings window. If this check box is selected when the Apply button is clicked, a bitwise OR operation is performed on the SecurityInformation parameter of ISecurityInformation::SetSecurity with SI_RESET_DACL_TREE. This function does not reset the permissions and enable propagation of inheritable permissions; the implementation of ISecurityInformation must do this.
SI_RESET_SACL_TREE
 When set, this flag displays the Reset auditing entries on all child objects and enable propagation of inheritable auditing entries check box in the Auditing page of the Access Control Settings window. If this check box is selected when the Apply button is clicked, a bitwise OR operation is performed on the SecurityInformation parameter of ISecurityInformation::SetSecurity with SI_RESET_SACL_TREE. This function does not reset the permissions and enable propagation of inheritable permissions; the implementation of ISecurityInformation must do this.
SI_SERVER_IS_DC
 Set this flag if the pszServerName computer is known to be a domain controller. If this flag is set, the domain name is included in the scope list of the Add Users and Groups dialog box. Otherwise, the pszServerName computer is used to determine the scope list of the dialog box.

hInstance
Identifies a module that contains string resources to be used in the property sheet. The ISecurityInformation::GetAccessRights and ISecurityInformation::GetInheritTypes methods can specify string resource identifiers for display names.
pszServerName
Pointer to a null-terminated, Unicode string that names the computer on which to look up account names and SIDs. This value can be NULL to specify the local computer. The access control editor does not free this pointer.
pszObjectName
Pointer to a null-terminated, Unicode string that names the object being edited. This name appears in the title of the advanced security property sheet and any error message boxes displayed by the access control editor. The access control editor does not free this pointer.
pszPageTitle
Pointer to a null-terminated, Unicode string used as the title of the basic security property page. This member is ignored unless the SI_PAGE_TITLE flag is set in dwFlags. If the page title is not provided, a default title is used. The access control editor does not free this pointer.
guidObjectType
A GUID for the object. This member is ignored unless the SI_OBJECT_GUID flag is set in dwFlags.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Aclui.h.

See Also

Access Control Editor Overview, Access Control Editor Structures, ISecurityInformation::GetAccessRights, ISecurityInformation::GetObjectInformation, ISecurityInformation::SetSecurity


SID_INFO

The SID_INFO structure contains the list of common names corresponding to the SID structures returned by ISecurityInformation2::LookupSids. It is a member of the SID_INFO_LIST structure.

typedef struct _SID_INFO {
  PSID pSid;
  PWSTR pwzCommonName;
  PWSTR pwzClass;
  PWSTR pwzUPN;
} SID_INFO, *PSID_INFO;

Members

pSid
Pointer to a SID structure that identifies one of the SIDs passed into ISecurityInformation2::LookupSids.
pwzCommonName
Pointer to a string containing the common name corresponding to the SID specified in pSid.
pwzClass
Pointer to a string describing the SID as either a user or a group. The possible values of this parameter are "User", "Group", or "Computer".
pwzUPN
Pointer to the user principal name (UPN) corresponding to the SID specified in pSid. If a UPN has not been designated for the SID, the value of this parameter is NULL.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Aclui.h.

See Also

Access Control Editor Overview, Access Control Editor Structures, SID, ISecurityInformation2::LookupSids


SID_INFO_LIST

The SID_INFO_LIST structure contains the list of SID_INFO structures returned by ISecurityInformation2::LookupSids.

typedef struct _SID_INFO_LIST {
  ULONG cItems;
  SID_INFO aSidInfo[ANYSIZE_ARRAY];
} SID_INFO_LIST, *PSID_INFO_LIST;

Members

cItems
The number of SID_INFO structures contained in the aSidInfo member.
aSidInfo
Pointer to a list of SID_INFO structures that is returned by the ISecurityInformation2::LookupSids method.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Aclui.h.

See Also

Access Control Editor Overview, Access Control Editor Structures, SID_INFO, ISecurityInformation2::LookupSids


Access Control Editor Enumeration Types

The following enumeration type is used with the access control editor.

SI_PAGE_TYPE


SI_PAGE_TYPE

The SI_PAGE_TYPE enumeration type contains values that indicate types of property pages in an access control editor property sheet.

typedef enum _SI_PAGE_TYPE
{
  SI_PAGE_PERM=0,
  SI_PAGE_ADVPERM,
  SI_PAGE_AUDIT,
  SI_PAGE_OWNER,
} SI_PAGE_TYPE;

Enumeration Values

SI_PAGE_PERM
Indicates the basic security property page for editing the object's DACL.
SI_PAGE_ADVPERM
Indicates the Permissions property page for advanced editing of the object's DACL, such as editing object-specific ACEs.
SI_PAGE_AUDIT
Indicates the Auditing property page for editing the object's SACL.
SI_PAGE_OWNER
Indicates the Owner property page for editing the object's owner.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Aclui.h.

See Also

Access Control Editor Overview, Access Control Editor Enumeration Types, ISecurityInformation::PropertySheetPageCallback


Client/Server Access Control

In the client/server model, clients connect to a server to access the server's functionality and data. A protected server controls access to its functionality and data based on the identity and privileges of its clients.

Microsoft® Windows NT®/Windows® 2000 provides a set of security functions that a protected server can use for access control. These functions extend the Windows NT/Windows 2000 access-control model to control access to private objects and to server functionality.

  • About Client/Server Access Control
  • Using Client/Server Access Control
  • Client/Server Access Control Reference


About Client/Server Access Control

A server application provides services to clients. For example, a server could perform the following services on behalf of a client:

  • Save and retrieve information from a private database
  • Access network resources
  • Start processes in the client's security context on the server's computer

A protected server controls access to its services. Windows NT/Windows 2000 provides security support that enables a server to do the following:

  • Impersonate a client's security context, which causes the system to perform most access and privilege checks against the client's access token rather than the server's
  • Log a client on to the server's computer
  • Connect to network resources using the client's security context
  • Create security descriptors to protect private objects
  • Determine whether a security descriptor allows access to a client
  • Determine whether a set of privileges are enabled in a client's token
  • Generate audit messages in the security event log to record attempts by a client to access objects or use privileges


The Client's Security Context

Like all processes, a protected server has a primary access token that describes its security context. When a client connects to a protected server, the server may want to perform actions using the client's security context instead of the server's security context. For example, when a client in a dynamic data exchange (DDE) conversation requests information from a DDE server, the server needs to verify that the client is allowed access to the information.

There are two ways that a server can act in the client's security context:

  • A thread of the server process can impersonate the client. In this case, the server's thread has an impersonation access token that identifies the client, the client's groups, and the client's privileges. For more information, see Client Impersonation.
  • The server can get the client's credentials and log the client on to the server's computer. This creates a new logon session and produces a primary access token for the client. The server can then use the client's access token to impersonate the client or to start a new process that runs in the security context of the client. For more information, see Client Logon Sessions.

In most cases, impersonating the client is sufficient. Impersonation enables the server to check the client's access to securable objects, check the client's privileges, and generate audit log entries that identify the client. Typically, a server needs to start a client logon session only if it needs to use the client's security context to access network resources.


Client Impersonation

Impersonation is the ability of a thread to execute in a security context different from that of the process that owns the thread. Typically, a thread in a server application impersonates a client. This allows the server thread to act on behalf of that client to access objects on the server or validate access to the client's own objects.

The Microsoft® Win32® API provides the following functions that a thread can use to begin an impersonation:

  • A DDE server application can call the DdeImpersonateClient function to impersonate a client.
  • A named-pipe server can call the ImpersonateNamedPipeClient function.
  • You can call the ImpersonateLoggedOnUser function to impersonate the security context of a logged-on user's access token.
  • The ImpersonateSelf function enables a thread to generate a copy of its own access token. This is useful when an application needs to change the security context of a single thread. For example, sometimes only one thread of a process needs to enable a privilege.
  • You can call the SetThreadToken function to cause the target thread to run in the security context of a specified impersonation token.
  • A Microsoft Remote Procedure Call (RPC) server application can call the RpcImpersonateClient function to impersonate a client.
  • A security package or application server can call the ImpersonateSecurityContext function to impersonate a client.

For most of these impersonations, the impersonating thread can revert to its own security context by calling the RevertToSelf function. The exception is the RPC impersonation, in which the RPC server application calls RpcRevertToSelf or RpcRevertToSelfEx to revert to its own security context.


Impersonation Levels

The SECURITY_IMPERSONATION_LEVEL enumeration defines four impersonation levels that determine the operations a server can perform in the client's context.

Impersonation level | Description
SecurityAnonymous | The server cannot impersonate or identify the client.
SecurityIdentification | The server can get the identity and privileges of the client, but cannot impersonate the client.
SecurityImpersonation | The server can impersonate the client's security context on the local system.
SecurityDelegation | The server can impersonate the client's security context on remote systems.

The client of a named pipe, RPC, or DDE connection can control the impersonation level. For example, a named pipe client can call the CreateFile function to open a handle to a named pipe and specify the server's impersonation level.

Windows 2000 or later: When the named pipe, RPC, or DDE connection is remote, the flags passed to CreateFile to set the impersonation level are ignored. In this case, the impersonation level of the client is determined by the impersonation levels enabled by the server, which is set by a flag on the server's account in the directory service. For example, if the server is enabled for delegation, the client's impersonation level will also be set to delegation even if the flags passed to CreateFile specify the identification impersonation level.

Windows NT: When the named pipe, RPC, or DDE connection is remote, the flags passed to CreateFile to set the impersonation level are ignored as they are in Windows 2000. However, the impersonation level of the client is always set to the maximum impersonation level. This is SecurityImpersonation under Windows NT.

DDE clients use the DdeSetQualityOfService function with the SECURITY_QUALITY_OF_SERVICE structure to specify the impersonation level. The SecurityImpersonation level is the default for named pipe, RPC, and DDE servers. The ImpersonateSelf, DuplicateToken, and DuplicateTokenEx functions allow the caller to specify an impersonation level. Use the GetTokenInformation function to retrieve the impersonation level of an access token.

At the SecurityImpersonation level, most of the thread's actions occur in the security context of the thread's impersonation token rather than in the primary token of the process that owns the thread. For example, if an impersonating thread opens a securable object, the system uses the impersonation token to check the thread's access. Similarly, if an impersonating thread creates a new object, for example by calling the CreateFile function, the owner of the new object is the default owner from the client's access token.

However, the system uses the primary token of the process rather than the impersonation token of the calling thread in the following situations:

  • If an impersonating thread calls the CreateProcess function, the new process always inherits the primary token of the process.
  • For Win32 functions that require the SE_TCB_NAME privilege, such as the LogonUser function, the system always checks for the privilege in the primary token of the process.
  • For Win32 functions that require the SE_AUDIT_NAME privilege, such as the ObjectOpenAuditAlarm function, the system always checks for the privilege in the primary token of the process.
  • In a call to the OpenThreadToken function, a thread can specify whether the function uses the impersonation token or the primary token to determine whether to grant the requested access.


Impersonation Tokens

An impersonating thread has two access tokens:

  • A primary access token that describes the security context of the server. To get a handle to this token, call the OpenProcessToken function.
  • An impersonation access token that describes the security context of the client being impersonated. To get a handle to this token, call the OpenThreadToken function.

A server can use the impersonation token in the following functions:

  • In the AccessCheck, AccessCheckByType, and AccessCheckByTypeResultList functions to determine whether a security descriptor allows the client a set of access rights.
  • In the AdjustTokenPrivileges function to enable or disable the client's privileges.
  • In the PrivilegeCheck function to determine whether a set of privileges are enabled in the client's token.
  • In functions that generate entries in the security event log, such as ObjectOpenAuditAlarm or PrivilegedServiceAuditAlarm. These functions use an impersonation token to get information about the client for the log entry.


Client Logon Sessions

A server with the SE_TCB_NAME privilege, such as a Win32 service running in the LocalSystem account, can call the LogonUser function to authenticate a client on the computer that the server is running on. The LogonUser function starts a new logon session and returns a primary access token that contains the client's security information. You can use this primary token in calling the ImpersonateLoggedOnUser function to impersonate the client or in calling the CreateProcessAsUser function to create a process that runs in the security context of the client.

The advantage of authenticating the client in this way is that the server impersonating the authenticated client, or a process created in the context of the authenticated client, can connect to remote network resources as the client. If this authentication is not done, the server can connect to network resources only if it has acquired the client's account name and password to pass to the WNetAddConnection2 function.

The disadvantage of authenticating the client in this way is that the server must have acquired the client's credentials (domain name, user name, and password). If a remote client supplies these credentials to the server, it is the responsibility of the client and server to ensure that the credentials are transmitted in a secure manner.


Processes in the Client's Security Context

A server application can call the CreateProcessAsUser function to create a new process that runs in a client's security context. When called with a client's access token, CreateProcessAsUser requires the SE_ASSIGNPRIMARYTOKEN_NAME and SE_INCREASE_QUOTA_NAME privileges, which are held by Win32 services running in the LocalSystem account.

The CreateProcessAsUser function also requires a primary access token. A server can get a primary access token for a client either by starting a logon session for the client, or by impersonating the client and duplicating the impersonation token.

To create a client process by logging on the client

  1. Use the client's credentials in a call to the LogonUser function to log the client on to the local computer. LogonUser produces a primary token for the client's logon session.
  2. If the server needs to use the client's security context to get access to the executable file for the client process, it can use the primary token in a call to the ImpersonateLoggedOnUser function.
  3. Use the primary token in a call to the CreateProcessAsUser function to create a process in the client's security context.

To create a client process by impersonating the client

Note A process created by this technique may not be able to access network resources unless it has the client's credentials.

  1. Use an impersonation function, such as ImpersonateNamedPipeClient, to start the impersonation.
  2. Call the OpenThreadToken function to get an impersonation token that has the security context of the client.
  3. Call the DuplicateTokenEx function to convert the impersonation token into a primary token.
  4. Use the primary token in a call to the CreateProcessAsUser function to create a process in the client's security context.

By default, CreateProcessAsUser creates the client process on a noninteractive window station and desktop. To create an interactive process, the server must first set the discretionary access-control lists (DACLs) of the interactive window station and desktop to ensure that the client is allowed access to them. The preferred way to do this is to log the client on, get the security identifier (SID) of the client's logon session, and use that SID in access-allowed ACEs on both the interactive window station and desktop. The server can then call CreateProcessAsUser, specifying the interactive window station and desktop, "winsta0\default". For sample code that shows this procedure, see Starting an Interactive Client Process.


Client Access to Network Resources

A server can use the following strategies to access network resources:

  • If the server has the account name and password of a client, it can call WNetAddConnection2 with the client's credentials to map a local drive letter to a network share.
  • After calling LogonUser with client credentials, the server can call the CreateProcessAsUser function to create a process for the client. This new client process can access network resources using the client's security context. For example, the process can call the CreateFile function to open a file on a remote computer. The system uses the client's primary token to check access attempts by the client process.
  • A server can call WNetAddConnection2 with null credentials to establish either a connection to a network resource with server access or a default connection. If the server is running as the LocalSystem account, it authenticates to the network resource under the security context of the domain server if the remote machine is running Windows 2000. Otherwise, it authenticates as the anonymous account. If the server is running under a service account, it authenticates as that account. For more information, see The LocalSystem Account.


Access Control for Private Objects

Just as the system uses security descriptors to control access to securable objects, a server can use security descriptors to control access to its private objects. For more information about the Windows NT/Windows 2000 security model, see Access Control Model.

A protected server can create a security descriptor with a DACL that specifies the types of access allowed for various trustees. In a simple case, the server could create a single security descriptor to control access to all of the server's data and functionality. For a finer granularity of protection, the server could create security descriptors for each of its private objects, or for different types of functionality.

For example, when a client asks the server to create a new object in a database, the server could create a security descriptor for the new private object. The server could then store the security descriptor with the private object in the database. When a client tries to access the object, the server retrieves the security descriptor to check the client's access rights. It is important to note that there is nothing in a security descriptor that associates it with the object or functionality it is protecting. Instead, it is up to the protected server to maintain the association.

Access to the private object can also be audited. Refer to Auditing Access to Private Objects for a description of this.


Security Descriptors for Private Objects

To create a security descriptor, a protected server can use the same procedure that an application would use to create a security descriptor for a securable object. For sample code, see Creating a Security Descriptor for a New Object. Alternatively, a protected server application can call the BuildSecurityDescriptor function to do this. If a pointer to an existing self-relative security descriptor is supplied to BuildSecurityDescriptor, it will build the new security descriptor with information taken from that security descriptor merged with new access control information passed as parameters in the function call. The owner and group are optionally specified by TRUSTEE structures passed to the function. The security descriptor created by BuildSecurityDescriptor is in self-relative format. For an example of how to use BuildSecurityDescriptor, refer to the Manipulating Security Descriptors and SIDs example.

In addition, the Win32 API provides a set of functions for merging client security information with information inherited from the security descriptor for a parent object or from a default security descriptor. The CreatePrivateObjectSecurity, GetPrivateObjectSecurity, SetPrivateObjectSecurity, and DestroyPrivateObjectSecurity functions provide the ability to retrieve default information from an access token, support inheritance, and manipulate specific parts of the security descriptor. This can be useful when a client creates a private object in a hierarchy of secured objects. For example, you could use the CreatePrivateObjectSecurity function to create a security descriptor that contained ACEs specified by the client, ACEs inherited from a parent object, and the default owner from the creating client's access token. While BuildSecurityDescriptor creates security descriptors either from access control information passed into the function call or from an existing security descriptor, CreatePrivateObjectSecurity creates a security descriptor solely from the information in existing security descriptors.

The LookupSecurityDescriptorParts function obtains security descriptor information from an existing self-relative security descriptor. This information includes the owner and group specification, the number of ACEs in the SACL or DACL, and the list of ACEs in the SACL or DACL.


Checking Access to Private Objects

A protected server application must check a client's access rights before allowing the client to access a protected private object. To do this, the server passes an impersonation token, a security descriptor, and a set of requested access rights to the AccessCheck function. The ACEs in the security descriptor's DACL specify the access rights allowed or denied to various trustees. AccessCheck compares the trustee in each ACE to the trustees identified in the impersonation token. For a description of the algorithm used to grant or deny access, see How DACLs Control Access to an Object.

The AccessCheckAndAuditAlarm function performs a similar access check. In addition, it generates audit records in the security event log depending on the SACL in the security descriptor.

The AccessCheckByType and AccessCheckByTypeAndAuditAlarm functions are similar to AccessCheck and AccessCheckAndAuditAlarm except that they allow you to check access to the subobjects of an object, such as property sets or properties. The AccessCheckByTypeResultList and AccessCheckByTypeResultListAndAuditAlarm functions are also similar to AccessCheck except that they provide the access check results for each subobject in a hierarchy of the object's properties and property sets. These functions use the OBJECT_TYPE_LIST structure to describe the hierarchy of objects for which access is checked. The functions that generate an audit message use the AUDIT_EVENT_TYPE enumeration type to indicate whether the object being checked is a directory service object. For more information about the hierarchy of an object and its subobjects, see ACEs to Control Access to an Object's Properties.

The requested access rights passed to the AccessCheck and AccessCheckAndAuditAlarm functions must not include any generic access rights. The server can use the MapGenericMask function to convert any generic access rights to the corresponding specific and standard rights according to the mapping specified in the GENERIC_MAPPING structure.

The AreAllAccessesGranted and AreAnyAccessesGranted functions compare a requested access mask with a granted access mask.

For sample code that uses the AccessCheck function, see Checking Client Access.

The ConvertToAutoInheritPrivateObjectSecurity function creates and returns a security descriptor in a format that allows the automatic propagation of inheritable ACEs. This security descriptor contains all of the ACEs, inherited and noninherited, in the current security descriptor and is in self-relative format. The ConvertToAutoInheritPrivateObjectSecurity function determines whether the ACEs are inherited or noninherited by comparing all of the ACEs in the current security descriptor with all of the ACEs in its parent security descriptor. There may not be a one-to-one correspondence between the two groups of ACEs. For instance, an ACE that allows read/write access can be equivalent to two ACEs: an ACE that allows read access and an ACE that allows write access. A parent security descriptor may not be supplied when the current security descriptor is the parent.


Auditing Access To Private Objects

A protected server can use the following functions to generate audit reports in the security event log.

Function | Description
AccessCheckAndAuditAlarm | Same as the AccessCheck function except that it can generate audit messages for failed or successful access attempts.
AccessCheckByTypeAndAuditAlarm | Same as the AccessCheckByType function except that it can generate audit messages for failed or successful access attempts.
AccessCheckByTypeResultListAndAuditAlarm | Same as the AccessCheckByTypeResultList function except that it can generate audit messages for failed or successful access attempts.
AccessCheckByTypeResultListAndAuditAlarmByHandle | Same as the AccessCheckByTypeResultListAndAuditAlarm function except that it allows the calling thread to perform the access check before impersonating the client.
ObjectCloseAuditAlarm | Generates an audit message to indicate that a client tried to close a private object.
ObjectDeleteAuditAlarm | Generates an audit message to indicate that a client tried to delete a private object.
ObjectOpenAuditAlarm | Generates an audit message to indicate that a client tried to open or create a private object.
ObjectPrivilegeAuditAlarm | Generates an audit message to indicate that a client tried to use a specified set of privileges in conjunction with an attempt to access a private object.
PrivilegedServiceAuditAlarm | Generates an audit message to indicate that a client tried to use a specified set of privileges.


Access Control Using and the Authz Framework.

[This is preliminary documentation and subject to change.]

Windows Whistler edition introduces the Authz API, a faster, more flexible set of functions, for resource manager (RM) applications. These functions allow greater flexibility in deciding who has access to the resources (data and other objects) that an RM owns and maintains.

Authz functions and their related structures permit an RM to implement business-rule style access policy and dynamic group and role membership evaluation. Representing a caller's authorization attributes with user-mode security contexts, rather than kernel-level NT access tokens, improves the performance of access checking by avoiding kernel transitions. An RM that performs multiple access checks for the same caller and the same accessed object or security descriptor can further improve performance by caching and re-using the access check evaluation. The Authz API also supports optional system Security Log auditing.

Since the RM owns the objects being protected, the mechanisms used to protect these objects can be customized at an RM's discretion without compromising system security. The Authz API supplements the older Windows NT and Windows 2000 access control API functions, that support only Windows NT security descriptors with static policy expressiveness.


Using Client/Server Access Control

Following are some common tasks for the Win32 client/server access-control functions and structures:

  • Getting the Logon SID
  • Starting an Interactive Client Process
  • Checking Client Access


Getting the Logon SID

A logon security identifier (SID) identifies the logon session associated with an access token. A typical use of a logon SID is in an ACE that allows access for the duration of a client's logon session. For example, a Win32 service can use the LogonUser function to start a new logon session. The LogonUser function returns an access token from which the service can extract the logon SID. The service can then use the SID in an ACE that allows the client's logon session to access the interactive window station and desktop.

The following example gets the logon SID from an access token. It uses the GetTokenInformation function to fill a TOKEN_GROUPS buffer with an array of the group SIDs from an access token. This array includes the logon SID, which is identified by the SE_GROUP_LOGON_ID attribute. The example function allocates a buffer for the logon SID; it is the caller's responsibility to free the buffer.

BOOL GetLogonSID (HANDLE hToken, PSID *ppsid)
{
   BOOL bSuccess = FALSE;
   DWORD dwIndex;
   DWORD dwLength = 0;
   PTOKEN_GROUPS ptg = NULL;

// Get required buffer size and allocate the TOKEN_GROUPS buffer.

   if (!GetTokenInformation(
         hToken,         // handle to the access token
         TokenGroups,    // get information about the token's groups
         (LPVOID) ptg,   // pointer to TOKEN_GROUPS buffer
         0,              // size of buffer
         &dwLength       // receives required buffer size
      ))
   {
      if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
         goto Cleanup;

      ptg = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(),
         HEAP_ZERO_MEMORY, dwLength);

      if (ptg == NULL)
         goto Cleanup;
   }

// Get the token group information from the access token.

   if (!GetTokenInformation(
         hToken,         // handle to the access token
         TokenGroups,    // get information about the token's groups
         (LPVOID) ptg,   // pointer to TOKEN_GROUPS buffer
         dwLength,       // size of buffer
         &dwLength       // receives required buffer size
         ))
   {
      goto Cleanup;
   }

// Loop through the groups to find the logon SID.

   for (dwIndex = 0; dwIndex < ptg->GroupCount; dwIndex++)
      if ((ptg->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID)
             ==  SE_GROUP_LOGON_ID)
      {
      // Found the logon SID; make a copy of it.

         dwLength = GetLengthSid(ptg->Groups[dwIndex].Sid);
         *ppsid = (PSID) HeapAlloc(GetProcessHeap(),
                     HEAP_ZERO_MEMORY, dwLength);
         if (*ppsid == NULL)
             goto Cleanup;
         if (!CopySid(dwLength, *ppsid, ptg->Groups[dwIndex].Sid))
         {
             HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid);
             goto Cleanup;
         }
         break;
      }

   bSuccess = TRUE;

Cleanup:

// Free the buffer for the token groups.

   if (ptg != NULL)
      HeapFree(GetProcessHeap(), 0, (LPVOID)ptg);

   return bSuccess;
}

The following function frees the buffer allocated by the GetLogonSID example function.

VOID FreeLogonSID (PSID *ppsid)
{
    HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid);
}


Starting an Interactive Client Process

The following example uses the LogonUser function to start a new logon session for a client. The example gets the logon SID from the client's access token, and uses it to add access-control entries (ACEs) to the DACLs of the interactive window station and desktop. The ACEs allow the client access to the interactive desktop for the duration of the logon session. Next, the example calls the ImpersonateLoggedOnUser function to ensure that it has access to the client's executable file. A call to the CreateProcessAsUser function creates the client's process, specifying that it run in the interactive desktop. Before the function returns, it calls the RevertToSelf function to end the caller's impersonation of the client.

This sample calls the GetLogonSID and FreeLogonSID sample functions described in Getting the Logon SID.

#define DESKTOP_ALL (DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW | \ DESKTOP_CREATEMENU | DESKTOP_HOOKCONTROL | \ DESKTOP_JOURNALRECORD | DESKTOP_JOURNALPLAYBACK | \ DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | \ DESKTOP_SWITCHDESKTOP | STANDARD_RIGHTS_REQUIRED)

#define WINSTA_ALL (WINSTA_ENUMDESKTOPS | WINSTA_READATTRIBUTES |  \WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | \ WINSTA_WRITEATTRIBUTES | WINSTA_ACCESSGLOBALATOMS | \ WINSTA_EXITWINDOWS | WINSTA_ENUMERATE | \ WINSTA_READSCREEN | \ STANDARD_RIGHTS_REQUIRED)

#define GENERIC_ACCESS (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL)

BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid);

BOOL AddAceToDesktop(HDESK hdesk, PSID psid);

BOOL StartInteractiveClientProcess (
    LPTSTR lpszUsername,    // client to log on
    LPTSTR lpszDomain,      // domain of client's account
    LPTSTR lpszPassword,    // client's password
    LPTSTR lpCommandLine    // command line to execute
)
{
   HANDLE      hToken;
   HDESK       hdesk = NULL;
   HWINSTA     hwinsta = NULL, hwinstaSave = NULL;
   PROCESS_INFORMATION pi;
   PSID pSid = NULL;
   STARTUPINFO si;
   BOOL bResult = FALSE;

// Log the client on to the local computer.

   if (!LogonUser(
           lpszUsername,
           lpszDomain,
           lpszPassword,
           LOGON32_LOGON_INTERACTIVE,
           LOGON32_PROVIDER_DEFAULT,
           &hToken) )
   {
      goto Cleanup;
   }

// Save a handle to the caller's current window station.

   if ( (hwinstaSave = GetProcessWindowStation() ) == NULL)
      goto Cleanup;

// Get a handle to the interactive window station.

   hwinsta = OpenWindowStation(
       "winsta0",                   // the interactive window station
       FALSE,                       // handle is not inheritable
       READ_CONTROL | WRITE_DAC);   // rights to read/write the DACL

   if (hwinsta == NULL)
      goto Cleanup;

// To get the correct default desktop, set the caller's
// window station to the interactive window station.

   if (!SetProcessWindowStation(hwinsta))
      goto Cleanup;

// Get a handle to the interactive desktop.

   hdesk = OpenDesktop(
      "default",     // the interactive window station
      0,             // no interaction with other desktop processes
      FALSE,         // handle is not inheritable
      READ_CONTROL | // request the rights to read and write the DACL
      WRITE_DAC |
      DESKTOP_WRITEOBJECTS |
      DESKTOP_READOBJECTS);

// Restore the caller's window station.

   if (!SetProcessWindowStation(hwinstaSave))
      goto Cleanup;

   if (hdesk == NULL)
      goto Cleanup;

// Get the SID for the client's logon session.

   if (!GetLogonSID(hToken, &pSid))
      goto Cleanup;

// Allow logon SID full access to interactive window station.

   if (! AddAceToWindowStation(hwinsta, pSid) )
      goto Cleanup;

// Allow logon SID full access to interactive desktop.

   if (! AddAceToDesktop(hdesk, pSid) )
      goto Cleanup;

// Impersonate client to ensure access to executable file.

   if (! ImpersonateLoggedOnUser(hToken) )
      goto Cleanup;

// Initialize the STARTUPINFO structure.
// Specify that the process runs in the interactive desktop.

   ZeroMemory(&si, sizeof(STARTUPINFO));
   si.cb= sizeof(STARTUPINFO);
   si.lpDesktop = TEXT("winsta0\\default");

// Launch the process in the client's logon session.

   bResult = CreateProcessAsUser(
      hToken,            // client's access token
      NULL,              // file to execute
      lpCommandLine,     // command line
      NULL,              // pointer to process SECURITY_ATTRIBUTES
      NULL,              // pointer to thread SECURITY_ATTRIBUTES
      FALSE,             // handles are not inheritable
      NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,   // creation flags
      NULL,              // pointer to new environment block
      NULL,              // name of current directory
      &si,               // pointer to STARTUPINFO structure
      &pi                // receives information about new process
   );

// End impersonation of client.

   RevertToSelf();

   if (bResult && pi.hProcess != INVALID_HANDLE_VALUE)
   {
      WaitForSingleObject(pi.hProcess, INFINITE);
      CloseHandle(pi.hProcess);
   }

   if (pi.hThread != INVALID_HANDLE_VALUE)
      CloseHandle(pi.hThread);

Cleanup:

   if (hwinstaSave != NULL)
      SetProcessWindowStation (hwinstaSave);

// Free the buffer for the logon SID.

   if (pSid)
      FreeLogonSID(&pSid);

// Close the handles to the interactive window station and desktop.

   if (hwinsta)
      CloseWindowStation(hwinsta);

   if (hdesk)
      CloseDesktop(hdesk);

// Close the handle to the client's access token.

   if (hToken != INVALID_HANDLE_VALUE)
      CloseHandle(hToken);

   return bResult;
}

BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid)
{
   ACCESS_ALLOWED_ACE   *pace;
   ACL_SIZE_INFORMATION aclSizeInfo;
   BOOL                 bDaclExist;
   BOOL                 bDaclPresent;
   BOOL                 bSuccess = FALSE;
   DWORD                dwNewAclSize;
   DWORD                dwSidSize = 0;
   DWORD                dwSdSizeNeeded;
   PACL                 pacl;
   PACL                 pNewAcl;
   PSECURITY_DESCRIPTOR psd = NULL;
   PSECURITY_DESCRIPTOR psdNew = NULL;
   PVOID                pTempAce;
   SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
   unsigned int         i;

   __try
   {
      // Obtain the DACL for the window station.

      if (!GetUserObjectSecurity(
             hwinsta,
             &si,
             psd,
             dwSidSize,
             &dwSdSizeNeeded)
      )
      if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
      {
         psd = (PSECURITY_DESCRIPTOR)HeapAlloc(
               GetProcessHeap(),
               HEAP_ZERO_MEMORY,
               dwSdSizeNeeded);

         if (psd == NULL)
            __leave;

         psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(
               GetProcessHeap(),
               HEAP_ZERO_MEMORY,
               dwSdSizeNeeded);

         if (psdNew == NULL)
            __leave;

         dwSidSize = dwSdSizeNeeded;

         if (!GetUserObjectSecurity(
               hwinsta,
               &si,
               psd,
               dwSidSize,
               &dwSdSizeNeeded)
         )
            __leave;
      }
      else
         __leave;

      // Create a new DACL.

      if (!InitializeSecurityDescriptor(
            psdNew,
            SECURITY_DESCRIPTOR_REVISION)
      )
         __leave;

      // Get the DACL from the security descriptor.

      if (!GetSecurityDescriptorDacl(
            psd,
            &bDaclPresent,
            &pacl,
            &bDaclExist)
      )
         __leave;

      // Initialize the ACL.

      ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
      aclSizeInfo.AclBytesInUse = sizeof(ACL);

      // Call only if the DACL is not NULL.

      if (pacl != NULL)
      {
         // get the file ACL size info
         if (!GetAclInformation(
               pacl,
               (LPVOID)&aclSizeInfo,
               sizeof(ACL_SIZE_INFORMATION),
               AclSizeInformation)
         )
            __leave;
      }

      // Compute the size of the new ACL.

      dwNewAclSize = aclSizeInfo.AclBytesInUse + (2*sizeof(ACCESS_ALLOWED_ACE)) +
(2*GetLengthSid(psid)) - (2*sizeof(DWORD));

      // Allocate memory for the new ACL.

      pNewAcl = (PACL)HeapAlloc(
            GetProcessHeap(),
            HEAP_ZERO_MEMORY,
            dwNewAclSize);

      if (pNewAcl == NULL)
         __leave;

      // Initialize the new DACL.

      if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))
         __leave;

      // If DACL is present, copy it to a new DACL.

      if (bDaclPresent)
      {
         // Copy the ACEs to the new ACL.
         if (aclSizeInfo.AceCount)
         {
            for (i=0; i < aclSizeInfo.AceCount; i++)
            {
               // Get an ACE.
               if (!GetAce(pacl, i, &pTempAce))
                  __leave;

               // Add the ACE to the new ACL.
               if (!AddAce(
                     pNewAcl,
                     ACL_REVISION,
                     MAXDWORD,
                     pTempAce,
                    ((PACE_HEADER)pTempAce)->AceSize)
               )
                  __leave;
            }
         }
      }

      // Add the first ACE to the window station.

      pace = (ACCESS_ALLOWED_ACE *)HeapAlloc(
            GetProcessHeap(),
            HEAP_ZERO_MEMORY,
            sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) -
                  sizeof(DWORD));

      if (pace == NULL)
         __leave;

      pace->Header.AceType  = ACCESS_ALLOWED_ACE_TYPE;
      pace->Header.AceFlags = CONTAINER_INHERIT_ACE |
                   INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE;
      pace->Header.AceSize  = sizeof(ACCESS_ALLOWED_ACE) +
                   GetLengthSid(psid) - sizeof(DWORD);
      pace->Mask            = GENERIC_ACCESS;

      if (!CopySid(GetLengthSid(psid), &pace->SidStart, psid))
         __leave;

      if (!AddAce(
            pNewAcl,
            ACL_REVISION,
            MAXDWORD,
            (LPVOID)pace,
            pace->Header.AceSize)
      )
         __leave;

      // Add the second ACE to the window station.

      pace->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE;
      pace->Mask            = WINSTA_ALL;

      if (!AddAce(
            pNewAcl,
            ACL_REVISION,
            MAXDWORD,
            (LPVOID)pace,
            pace->Header.AceSize)
      )
         __leave;

      // Set a new DACL for the security descriptor.

      if (!SetSecurityDescriptorDacl(
            psdNew,
            TRUE,
            pNewAcl,
            FALSE)
      )
         __leave;

      // Set the new security descriptor for the window station.

      if (!SetUserObjectSecurity(hwinsta, &si, psdNew))
         __leave;

      // Indicate success.

      bSuccess = TRUE;
   }
   __finally
   {
      // Free the allocated buffers.

      if (pace != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)pace);

      if (pNewAcl != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);

      if (psd != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)psd);

      if (psdNew != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew);
   }

   return bSuccess;

}

BOOL AddAceToDesktop(HDESK hdesk, PSID psid)
{
   ACL_SIZE_INFORMATION aclSizeInfo;
   BOOL                 bDaclExist;
   BOOL                 bDaclPresent;
   BOOL                 bSuccess = FALSE;
   DWORD                dwNewAclSize;
   DWORD                dwSidSize = 0;
   DWORD                dwSdSizeNeeded;
   PACL                 pacl;
   PACL                 pNewAcl;
   PSECURITY_DESCRIPTOR psd = NULL;
   PSECURITY_DESCRIPTOR psdNew = NULL;
   PVOID                pTempAce;
   SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
   unsigned int         i;

   __try
   {
      // Obtain the security descriptor for the desktop object.

      if (!GetUserObjectSecurity(
            hdesk,
            &si,
            psd,
            dwSidSize,
            &dwSdSizeNeeded))
      {
         if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
         {
            psd = (PSECURITY_DESCRIPTOR)HeapAlloc(
                  GetProcessHeap(),
                  HEAP_ZERO_MEMORY,
                  dwSdSizeNeeded );

            if (psd == NULL)
               __leave;

            psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(
                  GetProcessHeap(),
                  HEAP_ZERO_MEMORY,
                  dwSdSizeNeeded);

            if (psdNew == NULL)
               __leave;

            dwSidSize = dwSdSizeNeeded;

            if (!GetUserObjectSecurity(
                  hdesk,
                  &si,
                  psd,
                  dwSidSize,
                  &dwSdSizeNeeded)
            )
               __leave;
         }
         else
            __leave;
      }

      // Create a new security descriptor.

      if (!InitializeSecurityDescriptor(
            psdNew,
            SECURITY_DESCRIPTOR_REVISION)
      )
         __leave;

      // Obtain the DACL from the security descriptor.

      if (!GetSecurityDescriptorDacl(
            psd,
            &bDaclPresent,
            &pacl,
            &bDaclExist)
      )
         __leave;

      // Initialize.

      ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
      aclSizeInfo.AclBytesInUse = sizeof(ACL);

      // Call only if NULL DACL.

      if (pacl != NULL)
      {
         // Determine the size of the ACL information.

         if (!GetAclInformation(
               pacl,
               (LPVOID)&aclSizeInfo,
               sizeof(ACL_SIZE_INFORMATION),
               AclSizeInformation)
         )
            __leave;
      }

      // Compute the size of the new ACL.

      dwNewAclSize = aclSizeInfo.AclBytesInUse +
            sizeof(ACCESS_ALLOWED_ACE) +
            GetLengthSid(psid) - sizeof(DWORD);

      // Allocate buffer for the new ACL.

      pNewAcl = (PACL)HeapAlloc(
            GetProcessHeap(),
            HEAP_ZERO_MEMORY,
            dwNewAclSize);

      if (pNewAcl == NULL)
         __leave;

      // Initialize the new ACL.

      if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))
         __leave;

      // If DACL is present, copy it to a new DACL.

      if (bDaclPresent)
      {
         // Copy the ACEs to the new ACL.
         if (aclSizeInfo.AceCount)
         {
            for (i=0; i < aclSizeInfo.AceCount; i++)
            {
               // Get an ACE.
               if (!GetAce(pacl, i, &pTempAce))
                  __leave;

               // Add the ACE to the new ACL.
               if (!AddAce(
                  pNewAcl,
                  ACL_REVISION,
                  MAXDWORD,
                  pTempAce,
                  ((PACE_HEADER)pTempAce)->AceSize)
               )
                  __leave;
            }
         }
      }

      // Add ACE to the DACL.

      if (!AddAccessAllowedAce(
            pNewAcl,
            ACL_REVISION,
            DESKTOP_ALL,
            psid)
      )
         __leave;

      // Set new DACL to the new security descriptor.

      if (!SetSecurityDescriptorDacl(
            psdNew,
            TRUE,
            pNewAcl,
            FALSE)
      )
         __leave;

      // Set the new security descriptor for the desktop object.

      if (!SetUserObjectSecurity(hdesk, &si, psdNew))
         __leave;

      // Indicate success.

      bSuccess = TRUE;
   }
   __finally
   {
      // Free buffers.

      if (pNewAcl != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);

      if (psd != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)psd);

      if (psdNew != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew);
   }

   return bSuccess;
}


Checking Client Access

The following example shows how a server could check the access rights that a security descriptor allows for a client. The example uses the ImpersonateNamedPipeClient function; however, it would work the same using any of the other impersonation functions. After impersonating the client, the example calls the OpenThreadToken function to get the impersonation token. Then, it calls the MapGenericMask function to convert any generic access rights to the corresponding specific and standard rights according to the mapping specified in the GENERIC_MAPPING structure.

The AccessCheck function checks the requested access rights against the rights allowed for the client in the DACL of the security descriptor. To check access and generate an entry in the security event log, use the AccessCheckAndAuditAlarm function.

BOOL ImpersonateAndCheckAccess(
  HANDLE hNamedPipe,               // handle of pipe to impersonate
  PSECURITY_DESCRIPTOR pSD,        // security descriptor to check
  DWORD dwAccessDesired,           // access rights to check
  PGENERIC_MAPPING pGeneric,       // generic mapping for object
  PDWORD pdwAccessAllowed          // returns allowed access rights
)
{
   HANDLE hToken;
   PRIVILEGE_SET PrivilegeSet;
   DWORD dwPrivSetSize = sizeof( PRIVILEGE_SET );
   BOOL fAccessGranted=FALSE;

// Impersonate the client.

   if (! ImpersonateNamedPipeClient(hNamedPipe) )
      return FALSE;

// Get an impersonation token with the client's security context.

   if (! OpenThreadToken( GetCurrentThread(), TOKEN_ALL_ACCESS,
         TRUE, &hToken ))
   {
      goto Cleanup;
   }

// Use the GENERIC_MAPPING structure to convert any
// generic access rights to object-specific access rights.

   MapGenericMask( &dwAccessDesired, pGeneric );

// Check the client's access rights.

   if( !AccessCheck(
      pSD,                 // security descriptor to check
      hToken,              // impersonation token
      dwAccessDesired,     // requested access rights
      pGeneric,            // pointer to GENERIC_MAPPING
      &PrivilegeSet,       // receives privileges used in check
      &dwPrivSetSize,      // size of PrivilegeSet buffer
      pdwAccessAllowed,    // receives mask of allowed access rights
      &fAccessGranted ))   // receives results of access check
   {
      goto Cleanup;
   }

Cleanup:

   RevertToSelf();

   if (hToken != INVALID_HANDLE_VALUE)
      CloseHandle(hToken);

   return fAccessGranted;
}


Client/Server Access Control Reference

The following elements are used with client/server access control:

  • Client/Server Access Control Functions
  • Client/Server Access Control Structures
  • Client/Server Access Control Enumeration Types


Client/Server Access Control Functions

The following functions are used by servers to impersonate clients.

Function | History
CreateProcessAsUser | Windows NT 3.51 and later
CreateProcessWithLogonW | Windows 2000
ImpersonateLoggedOnUser | Windows NT 3.51 and later
ImpersonateNamedPipeClient | Windows NT 3.1 and later
ImpersonateSelf | Windows NT 3.1 and later
LogonUser | Windows NT 3.51 and later
RevertToSelf | Windows NT 3.1 and later

The following functions are used by servers to check and set the security descriptors on private objects.

Function | History
AccessCheck | Windows NT 3.1 and later
AccessCheckAndAuditAlarm | Windows NT 3.1 and later
AccessCheckByType | Windows 2000
AccessCheckByTypeAndAuditAlarm | Windows 2000
AccessCheckByTypeResultList | Windows 2000
AccessCheckByTypeResultListAndAuditAlarm | Windows 2000
AccessCheckByTypeResultListAndAuditAlarmByHandle | Windows 2000
AreAllAccessesGranted | Windows NT 3.1 and later
AreAnyAccessesGranted | Windows NT 3.1 and later
BuildSecurityDescriptor | Windows NT 4.0 and later
ConvertToAutoInheritPrivateObjectSecurity | Windows 2000
CreatePrivateObjectSecurity | Windows NT 3.1 and later
CreatePrivateObjectSecurityEx | Windows 2000
CreatePrivateObjectSecurityWithMultipleInheritance | Whistler Beta 2
DestroyPrivateObjectSecurity | Windows NT 3.1 and later
GetPrivateObjectSecurity | Windows NT 3.1 and later
LookupSecurityDescriptorParts | Windows NT 4.0 and later
MapGenericMask | Windows NT 3.1 and later
PrivilegeCheck | Windows NT 3.1 and later
SetPrivateObjectSecurity | Windows NT 3.1 and later
SetPrivateObjectSecurityEx | Windows 2000

The following functions are used by servers to generate audit messages in the security event log.

Function | History
ObjectCloseAuditAlarm | Windows NT 3.1 and later
ObjectDeleteAuditAlarm | Windows NT 3.1 and later
ObjectOpenAuditAlarm | Windows NT 3.1 and later
ObjectPrivilegeAuditAlarm | Windows NT 3.1 and later
PrivilegedServiceAuditAlarm | Windows NT 3.1 and later

The following functions are used with the Authorization Framework.

Function | History
AuthzInitializeResourceManager | Windows 2000 Whistler
AuthzInitializeContextFromToken | Windows 2000 Whistler
AuthzInitializeContextFromSid | Windows 2000 Whistler
AuthzAccessCheck | Windows 2000 Whistler
AuthzInitializeContentxFromAuthzContext | Windows 2000 Whistler
AuthzCachedAccessCheck | Windows 2000 Whistler
AuthzAddSidsToContext | Windows 2000 Whistler
AuthzFreeHandle | Windows 2000 Whistler
AuthzFreeContext | Windows 2000 Whistler
AuthzFreeResourceManager | Windows 2000 Whistler
AuthzGetContextInformation | Windows 2000 Whistler
AuthzGetInformationFromResourceManager | Windows 2000 Whistler
AuthzGetInformationFromRMAuditInfo | Windows 2000 Whistler
AuthzModifyRMAuditInfo | Windows 2000 Whistler
AuthzFreeRMAuditInfo | Windows 2000 Whistler
AuthzInitializeAuditEvent | Windows 2000 Whistler
AuthzFreeAuditEvent | Windows 2000 Whistler
AuthzInitializeAuditInfo | Windows 2000 Whistler
AuthzFreeAuditInfo | Windows 2000 Whistler
AuthzOpenObjectAuditAlarm | Windows 2000 Whistler


AccessCheck

The AccessCheck function determines whether a security descriptor grants a specified set of access rights to the client identified by an access token. Typically, server applications use this function to check access to a private object.

BOOL AccessCheck(
  PSECURITY_DESCRIPTOR pSecurityDescriptor, // SD
  HANDLE ClientToken,                       // handle to client access token
  DWORD DesiredAccess,                      // requested access rights
  PGENERIC_MAPPING GenericMapping,          // mapping
  PPRIVILEGE_SET PrivilegeSet,              // privileges
  LPDWORD PrivilegeSetLength,               // size of privileges buffer
  LPDWORD GrantedAccess,                    // granted access rights
  LPBOOL AccessStatus                       // result of access check
);

Parameters

pSecurityDescriptor
[in] Pointer to a SECURITY_DESCRIPTOR structure against which access is checked.
ClientToken
[in] Handle to an impersonation token that represents the client attempting to gain access. The handle must have TOKEN_QUERY access to the token; otherwise, the function fails with ERROR_ACCESS_DENIED.
DesiredAccess
[in] Access mask that specifies the access rights to check. This mask must have been mapped by the MapGenericMask function to contain no generic access rights.

If this parameter is MAXIMUM_ALLOWED, the function sets the GrantedAccess access mask to indicate the maximum access rights the security descriptor allows the client.

GenericMapping
[in] Pointer to the GENERIC_MAPPING structure associated with the object for which access is being checked.
PrivilegeSet
[out] Pointer to a PRIVILEGE_SET structure that receives the privileges used to perform the access validation. If no privileges were used, the function sets the PrivilegeCount member to zero.
PrivilegeSetLength
[in] Specifies the size, in bytes, of the buffer pointed to by the PrivilegeSet parameter.
GrantedAccess
[out] Pointer to an access mask that receives the granted access rights. If AccessStatus is set to FALSE, the function sets the access mask to zero. If the function fails, it does not set the access mask.
AccessStatus
[out] Pointer to a variable that receives the results of the access check. If the security descriptor allows the requested access rights to the client identified by the access token, AccessStatus is set to TRUE. Otherwise, AccessStatus is set to FALSE, and you can call GetLastError to get extended error information.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The AccessCheck function compares the specified security descriptor with the specified access token and indicates, in the AccessStatus parameter, whether access is granted or denied. If access is granted, the requested access mask becomes the object's granted access mask.

If the security descriptor's DACL is NULL, the AccessStatus parameter returns TRUE indicating that the client has the requested access.

AccessCheck fails with ERROR_INVALID_SECURITY_DESCR if the security descriptor does not contain owner and group SIDs.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheckAndAuditAlarm, AreAllAccessesGranted, AreAnyAccessesGranted, GENERIC_MAPPING, MakeAbsoluteSD, MapGenericMask, PrivilegeCheck, PRIVILEGE_SET, SECURITY_DESCRIPTOR


AccessCheckAndAuditAlarm

The AccessCheckAndAuditAlarm function determines whether a security descriptor grants a specified set of access rights to the client being impersonated by the calling thread. If the security descriptor has a SACL with ACEs that apply to the client, the function generates any necessary audit messages in the security event log.

Alarms are not currently supported.

BOOL AccessCheckAndAuditAlarm(
  LPCTSTR SubsystemName,                   // subsystem name
  LPVOID HandleId,                         // handle to object
  LPTSTR ObjectTypeName,                   // type of object
  LPTSTR ObjectName,                       // name of object
  PSECURITY_DESCRIPTOR SecurityDescriptor, // SD
  DWORD DesiredAccess,                     // requested access rights
  PGENERIC_MAPPING GenericMapping,         // mapping
  BOOL ObjectCreation,                     // creation status
  LPDWORD GrantedAccess,                   // granted access rights
  LPBOOL AccessStatus,                     // result of access check
  LPBOOL pfGenerateOnClose                 // audit generation option
);

Parameters

SubsystemName
[in] Pointer to a null-terminated string specifying the name of the subsystem calling the function. This string appears in any audit message that the function generates.
HandleId
[in] Pointer to a unique value representing the client's handle to the object. If the access is denied, the system ignores this value.
ObjectTypeName
[in] Pointer to a null-terminated string specifying the type of object being created or accessed. This string appears in any audit message that the function generates.
ObjectName
[in] Pointer to a null-terminated string specifying the name of the object being created or accessed. This string appears in any audit message that the function generates.
SecurityDescriptor
[in] Pointer to the SECURITY_DESCRIPTOR structure against which access is checked.
DesiredAccess
[in] Access mask that specifies the access rights to check. This mask must have been mapped by the MapGenericMask function to contain no generic access rights.

If this parameter is MAXIMUM_ALLOWED, the function sets the GrantedAccess access mask to indicate the maximum access rights the security descriptor allows the client.

GenericMapping
[in] Pointer to the GENERIC_MAPPING structure associated with the object for which access is being checked.
ObjectCreation
[in] Specifies a flag that determines whether the calling application will create a new object when access is granted. A value of TRUE indicates the application will create a new object. A value of FALSE indicates the application will open an existing object.
GrantedAccess
[out] Pointer to an access mask that receives the granted access rights. If AccessStatus is set to FALSE, the function sets the access mask to zero. If the function fails, it does not set the access mask.
AccessStatus
[out] Pointer to a variable that receives the results of the access check. If the security descriptor allows the requested access rights to the client, AccessStatus is set to TRUE. Otherwise, AccessStatus is set to FALSE.
pfGenerateOnClose
[out] Pointer to a flag set by the audit-generation routine when the function returns. Pass this flag to the ObjectCloseAuditAlarm function when the object handle is closed.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The AccessCheckAndAuditAlarm function requires the calling process to have the SE_AUDIT_NAME privilege enabled. The test for this privilege is performed against the primary token of the calling process, not the impersonation token of the thread.

The AccessCheckAndAuditAlarm function fails if the calling thread is not impersonating a client.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheck, GENERIC_MAPPING, MakeAbsoluteSD, MapGenericMask, ObjectCloseAuditAlarm, ObjectOpenAuditAlarm, ObjectPrivilegeAuditAlarm, PrivilegeCheck, PrivilegedServiceAuditAlarm, SECURITY_DESCRIPTOR


AccessCheckByType

The AccessCheckByType function determines whether a security descriptor grants a specified set of access rights to the client identified by an access token. The function can check the client's access to a hierarchy of objects, such as an object, its property sets, and properties. The function grants or denies access to the hierarchy as a whole. Typically, server applications use this function to check access to a private object.

BOOL AccessCheckByType(
  PSECURITY_DESCRIPTOR pSecurityDescriptor, // SD
  PSID PrincipalSelfSid,                    // object SID
  HANDLE ClientToken,                       // handle to client access token
  DWORD DesiredAccess,                      // requested access rights
  POBJECT_TYPE_LIST ObjectTypeList,         // array of object types
  DWORD ObjectTypeListLength,               // number of object types
  PGENERIC_MAPPING GenericMapping,          // mapping
  PPRIVILEGE_SET PrivilegeSet,              // privileges
  LPDWORD PrivilegeSetLength,               // size of privileges buffer
  LPDWORD GrantedAccess,                    // granted access rights
  LPBOOL AccessStatus                       // results of access check
);

Parameters

pSecurityDescriptor
[in] Pointer to a SECURITY_DESCRIPTOR structure against which access is checked.
PrincipalSelfSid
[in] Pointer to a SID. If the security descriptor is associated with an object that represents a principal (for example, a user object), the PrincipalSelfSid parameter should be the SID of the object. When evaluating access, this SID logically replaces the SID in any ACE containing the well-known PRINCIPAL_SELF SID (S-1-5-10).

This parameter should be NULL if the protected object does not represent a principal.

ClientToken
[in] Handle to an impersonation token that represents the client attempting to gain access. The handle must have TOKEN_QUERY access to the token; otherwise, the function fails with ERROR_ACCESS_DENIED.
DesiredAccess
[in] Access mask that specifies the access rights to check. This mask must have been mapped by the MapGenericMask function to contain no generic access rights.

If this parameter is MAXIMUM_ALLOWED, the function sets the GrantedAccess access mask to indicate the maximum access rights the security descriptor allows the client.

ObjectTypeList
[out] Pointer to an array of OBJECT_TYPE_LIST structures that identify the hierarchy of object types for which to check access. Each element in the array specifies a GUID that identifies the object type and a value indicating the level of the object type in the hierarchy of object types. The array should not have two elements with the same GUID.

The array must have at least one element. The first element in the array must be at level zero and identify the object itself. The array can have only one level zero element. The second element is a subobject, such as a property set, at level 1. Following each level 1 entry are subordinate entries for the level 2 through 4 subobjects. Thus, the levels for the elements in the array might be {0, 1, 2, 2, 1, 2, 3}. If the object type list is out of order, AccessCheckByType fails and GetLastError returns ERROR_INVALID_PARAMETER.

If ObjectTypeList is NULL, AccessCheckByType is the same as the AccessCheck function.

ObjectTypeListLength
[in] Specifies the number of elements in the ObjectTypeList array.
GenericMapping
[out] Pointer to the GENERIC_MAPPING structure associated with the object for which access is being checked.
PrivilegeSet
[out] Pointer to a PRIVILEGE_SET structure that receives the privileges used to perform the access validation. If no privileges were used, the function sets the PrivilegeCount member to zero.
PrivilegeSetLength
[out] Specifies the size, in bytes, of the buffer pointed to by the PrivilegeSet parameter.
GrantedAccess
[out] Pointer to an access mask that receives the granted access rights. If AccessStatus is set to FALSE, the function sets the access mask to zero. If the function fails, it does not set the access mask.
AccessStatus
[out] Pointer to a variable that receives the results of the access check. If the security descriptor allows the requested access rights to the client identified by the access token, AccessStatus is set to TRUE. Otherwise, AccessStatus is set to FALSE, and you can call GetLastError to get extended error information.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The AccessCheckByType function compares the specified security descriptor with the specified access token and indicates, in the AccessStatus parameter, whether access is granted or denied.

The ObjectTypeList array does not necessarily represent the entire defined object. Rather, it represents that subset of the object for which to check access. For instance, to check access to two properties in a property set, specify an object type list with four elements: the object itself at level zero, the property set at level 1, and the two properties at level 2.

The AccessCheckByType function evaluates ACEs that apply to the object itself and object-specific ACEs for the object types listed in the ObjectTypeList array. The function ignores object-specific ACEs for object types not listed in the ObjectTypeList array. Thus, the results returned in the AccessStatus parameter indicate the access allowed to the subset of the object defined by the ObjectTypeList parameter, not to the entire object.

For more information about how a hierarchy of ACEs controls access to an object and its subobjects, see ACEs to Control Access to an Object's Properties.

If the security descriptor's DACL is NULL, the AccessStatus parameter returns TRUE, indicating that the client has the requested access.

If the security descriptor does not contain owner and group SIDs, AccessCheckByType fails with ERROR_INVALID_SECURITY_DESCR.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheck, AccessCheckAndAuditAlarm, AccessCheckByTypeAndAuditAlarm, AccessCheckByTypeResultList, AccessCheckByTypeResultListAndAuditAlarm, GENERIC_MAPPING, MakeAbsoluteSD, MapGenericMask, PRIVILEGE_SET, SECURITY_DESCRIPTOR


AccessCheckByTypeAndAuditAlarm

The AccessCheckByTypeAndAuditAlarm function determines whether a security descriptor grants a specified set of access rights to the client being impersonated by the calling thread. The function can check the client's access to a hierarchy of objects, such as an object, its property sets, and properties. The function grants or denies access to the hierarchy as a whole. If the security descriptor has a SACL with ACEs that apply to the client, the function generates any necessary audit messages in the security event log.

Alarms are not currently supported.

BOOL AccessCheckByTypeAndAuditAlarm(
  LPCTSTR SubsystemName,                    // subsystem name
  LPVOID HandleId,                          // object's handle identifier
  LPCTSTR ObjectTypeName,                   // object type
  LPCTSTR ObjectName,                       // object name
  PSECURITY_DESCRIPTOR pSecurityDescriptor, // SD
  PSID PrincipalSelfSid,                    // SID
  DWORD DesiredAccess,                      // requested access rights
  AUDIT_EVENT_TYPE AuditType,               // audit type
  DWORD Flags,                              // access check options
  POBJECT_TYPE_LIST ObjectTypeList,         // array of object types
  DWORD ObjectTypeListLength,               // number of object types
  PGENERIC_MAPPING GenericMapping,          // mapping
  BOOL ObjectCreation,                      // creation status
  LPDWORD GrantedAccess,                    // granted access rights
  LPBOOL AccessStatus                       // result of access check
  LPBOOL pfGenerateOnClose                  // audit generation
);

Parameters

SubsystemName
[in] Pointer to a null-terminated string specifying the name of the subsystem calling the function. This string appears in any audit message that the function generates.
HandleId
[in] Pointer to a unique value representing the client's handle to the object. If the access is denied, the system ignores this value.
ObjectTypeName
[in] Pointer to a null-terminated string specifying the type of object being created or accessed. This string appears in any audit message that the function generates.
ObjectName
[in] Pointer to a null-terminated string specifying the name of the object being created or accessed. This string appears in any audit message that the function generates.
pSecurityDescriptor
[in] Pointer to a SECURITY_DESCRIPTOR structure against which access is checked.
PrincipalSelfSid
[in] Pointer to a SID. If the security descriptor is associated with an object that represents a principal (for example, a user object), the PrincipalSelfSid parameter should be the SID of the object. When evaluating access, this SID logically replaces the SID in any ACE containing the well-known PRINCIPAL_SELF SID (S-1-5-10).

This parameter should be NULL if the protected object does not represent a principal.

DesiredAccess
[in] Access mask that specifies the access rights to check. This mask must have been mapped by the MapGenericMask function to contain no generic access rights.

If this parameter is MAXIMUM_ALLOWED, the function sets the GrantedAccess access mask to indicate the maximum access rights the security descriptor allows the client.

AuditType
[in] Specifies the type of audit to be generated. This can be one of the values from the AUDIT_EVENT_TYPE enumeration type.
Flags
[in] Flag that controls the function's behavior if the calling process does not have the SE_AUDIT_NAME privilege enabled. If the AUDIT_ALLOW_NO_PRIVILEGE flag is set, the function performs the access check without generating audit messages when the privilege is not enabled. If this parameter is zero, the function fails if the privilege is not enabled.
ObjectTypeList
[in] Pointer to an array of OBJECT_TYPE_LIST structures that identify the hierarchy of object types for which to check access. Each element in the array specifies a GUID that identifies the object type and a value indicating the level of the object type in the hierarchy of object types. The array should not have two elements with the same GUID.

The array must have at least one element. The first element in the array must be at level zero and identify the object itself. The array can have only one level zero element. The second element is a subobject, such as a property set, at level 1. Following each level 1 entry are subordinate entries for the level 2 through 4 subobjects. Thus, the levels for the elements in the array might be {0, 1, 2, 2, 1, 2, 3}. If the object type list is out of order, AccessCheckByTypeAndAuditAlarm fails and GetLastError returns ERROR_INVALID_PARAMETER.

ObjectTypeListLength
[in] Specifies the number of elements in the ObjectTypeList array.
GenericMapping
[in] Pointer to the GENERIC_MAPPING structure associated with the object for which access is being checked.
ObjectCreation
[in] Specifies a flag that determines whether the calling application will create a new object when access is granted. A value of TRUE indicates the application will create a new object. A value of FALSE indicates the application will open an existing object.
GrantedAccess
[out] Pointer to an access mask that receives the granted access rights. If AccessStatus is set to FALSE, the function sets the access mask to zero. If the function fails, it does not set the access mask.
AccessStatus
[out] Pointer to a variable that receives the results of the access check. If the security descriptor allows the requested access rights to the client, AccessStatus is set to TRUE. Otherwise, AccessStatus is set to FALSE and you can call GetLastError to get extended error information.
pfGenerateOnClose
[out] Pointer to a flag set by the audit-generation routine when the function returns. Pass this flag to the ObjectCloseAuditAlarm function when the object handle is closed.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If the PrincipalSelfSid and ObjectTypeList parameters are NULL, the AuditType parameter is AuditEventObjectAccess, and the Flags parameter is zero, AccessCheckByTypeAndAuditAlarm performs in the same way as the AccessCheckAndAuditAlarm function.

The ObjectTypeList array does not necessarily represent the entire defined object. Rather, it represents that subset of the object for which to check access. For instance, to check access to two properties in a property set, specify an object type list with four elements: the object itself at level zero, the property set at level 1, and the two properties at level 2.

AccessCheckByTypeAndAuditAlarm evaluates ACEs that apply to the object itself and object-specific ACEs for the object types listed in the ObjectTypeList array. The function ignores object-specific ACEs for object types not listed in the ObjectTypeList array. Thus, the results returned in the AccessStatus parameter indicate the access allowed to the subset of the object defined by the ObjectTypeList parameter, not to the entire object.

For more information about how a hierarchy of ACEs controls access to an object and its subobjects, see ACEs to Control Access to an Object's Properties.

To generate audit messages in the security event log, the calling process must have the SE_AUDIT_NAME privilege enabled. The system checks for this privilege in the primary token of the calling process, not the impersonation token of the thread. If the Flags parameter includes the AUDIT_ALLOW_NO_PRIVILEGE flag, the function performs the access check without generating audit messages when the privilege is not enabled.

The AccessCheckByTypeAndAuditAlarm function fails if the calling thread is not impersonating a client.

If the security descriptor does not contain owner and group SIDs, AccessCheckByTypeAndAuditAlarm fails with ERROR_INVALID_SECURITY_DESCR.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows 2000.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheck, AccessCheckAndAuditAlarm, AccessCheckByType, AccessCheckByTypeResultList, AccessCheckByTypeResultListAndAuditAlarm, GENERIC_MAPPING, MakeAbsoluteSD, MapGenericMask, PRIVILEGE_SET, SECURITY_DESCRIPTOR


AccessCheckByTypeResultList

The AccessCheckByTypeResultList function determines whether a security descriptor grants a specified set of access rights to the client identified by an access token. The function can check the client's access to a hierarchy of objects, such as an object, its property sets, and properties. The function reports the access rights granted or denied to each object type in the hierarchy. Typically, server applications use this function to check access to a private object.

BOOL AccessCheckByTypeResultList(
  PSECURITY_DESCRIPTOR pSecurityDescriptor, // SD
  PSID PrincipalSelfSid,                    // object SID
  HANDLE ClientToken,                       // handle to client access token
  DWORD DesiredAccess,                      // requested access rights
  POBJECT_TYPE_LIST ObjectTypeList,         // array of object types
  DWORD ObjectTypeListLength,               // number of object types
  PGENERIC_MAPPING GenericMapping,          // mapping
  PPRIVILEGE_SET PrivilegeSet,              // privileges used
  LPDWORD PrivilegeSetLength,               // size of privilege-set buffer
  LPDWORD GrantedAccessList,                // array of granted rights
  LPDWORD AccessStatusList                  // array of results
);

Parameters

pSecurityDescriptor
[in] Pointer to a SECURITY_DESCRIPTOR structure against which access is checked.
PrincipalSelfSid
[in] Pointer to a SID. If the security descriptor is associated with an object that represents a principal (for example, a user object), the PrincipalSelfSid parameter should be the SID of the object. When evaluating access, this SID logically replaces the SID in any ACE containing the well-known PRINCIPAL_SELF SID (S-1-5-10).

This parameter should be NULL if the protected object does not represent a principal.

ClientToken
[in] Handle to an impersonation token that represents the client attempting to gain access. The handle must have TOKEN_QUERY access to the token; otherwise, the function fails with ERROR_ACCESS_DENIED.
DesiredAccess
[in] Access mask that specifies the access rights to check. This mask must have been mapped by the MapGenericMask function to contain no generic access rights.

If this parameter is MAXIMUM_ALLOWED, the function sets the access masks in the GrantedAccess array to indicate the client's maximum access rights to each element in the object type list.

ObjectTypeList
[out] Pointer to an array of OBJECT_TYPE_LIST structures that identify the hierarchy of object types for which to check access. Each element in the array specifies a GUID that identifies the object type and a value indicating the level of the object type in the hierarchy of object types. The array should not have two elements with the same GUID.

The array must have at least one element. The first element in the array must be at level zero and identify the object itself. The array can have only one level zero element. The second element is a subobject, such as a property set, at level 1. Following each level 1 entry are subordinate entries for the level 2 through 4 subobjects. Thus, the levels for the elements in the array might be {0, 1, 2, 2, 1, 2, 3}. If the object type list is out of order, AccessCheckByTypeResultList fails and GetLastError returns ERROR_INVALID_PARAMETER.

ObjectTypeListLength
[in] Specifies the number of elements in the ObjectTypeList array. This is also the number of elements in the arrays pointed to by the GrantedAccessList and AccessStatusList parameters.
GenericMapping
[out] Pointer to the GENERIC_MAPPING structure associated with the object for which access is being checked.
PrivilegeSet
[out] Pointer to a PRIVILEGE_SET structure that receives the privileges used to perform the access validation. If no privileges were used, the function sets the PrivilegeCount member to zero.
PrivilegeSetLength
[out] Specifies the size, in bytes, of the buffer pointed to by the PrivilegeSet parameter.
GrantedAccessList
[out] Pointer to an array of access masks. The function sets each access mask to indicate the access rights granted to the corresponding element in the object type list. If the function fails, it does not set the access masks.
AccessStatusList
[out] Pointer to an array of status codes for the corresponding elements in the object type list. The function sets an element to zero to indicate success or a nonzero value to indicate the specific error during the access check. If the function fails, it does not set any of the elements in the array.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The AccessCheckByTypeResultList function compares the specified security descriptor with the specified access token and indicates, in the AccessStatusList parameter, whether access is granted or denied for each of the elements in the object types list.

The ObjectTypeList array does not necessarily represent the entire defined object. Rather, it represents that subset of the object for which to check access. For instance, to check access to two properties in a property set, specify an object type list with four elements: the object itself at level zero, the property set at level 1, and the two properties at level 2.

The AccessCheckByTypeResultList function evaluates ACEs that apply to the object itself and object-specific ACEs for the object types listed in the ObjectTypeList array. The function ignores object-specific ACEs for object types not listed in the ObjectTypeList array. Thus, the results returned for element zero in the AccessStatusList parameter indicate the access allowed to the subset of the object defined by the ObjectTypeList parameter, not to the entire object.

For more information about how a hierarchy of ACEs controls access to an object and its subobjects, see ACEs to Control Access to an Object's Properties.

If the security descriptor's DACL is NULL, the function grants the requested access to all of the elements in the object type list.

If the security descriptor does not contain owner and group SIDs, AccessCheckByTypeResultList fails with ERROR_INVALID_SECURITY_DESCR.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheck, AccessCheckAndAuditAlarm, AccessCheckByType, AccessCheckByTypeAndAuditAlarm, AccessCheckByTypeResultListAndAuditAlarm, GENERIC_MAPPING, MakeAbsoluteSD, MapGenericMask, PRIVILEGE_SET, SECURITY_DESCRIPTOR


AccessCheckByTypeResultListAndAuditAlarm

The AccessCheckByTypeResultListAndAuditAlarm function determines whether a security descriptor grants a specified set of access rights to the client being impersonated by the calling thread. The function can check access to a hierarchy of objects, such as an object, its property sets, and properties. The function reports the access rights granted or denied to each object type in the hierarchy. If the security descriptor has a SACL with ACEs that apply to the client, the function generates any necessary audit messages in the security event log. Alarms are not currently supported.

BOOL AccessCheckByTypeResultListAndAuditAlarm(
  LPCTSTR SubsystemName,                    // subsystem name
  LPVOID HandleId,                          // object's handle identifier
  LPCTSTR ObjectTypeName,                   // object type
  LPCTSTR ObjectName,                       // object name
  PSECURITY_DESCRIPTOR pSecurityDescriptor, // SD
  PSID PrincipalSelfSid,                    // SID
  DWORD DesiredAccess,                      // requested access rights
  AUDIT_EVENT_TYPE AuditType,               // type of audit
  DWORD Flags,                              // access check options
  POBJECT_TYPE_LIST ObjectTypeList,         // array of object types
  DWORD ObjectTypeListLength,               // number of object types
  PGENERIC_MAPPING GenericMapping,          // mapping
  BOOL ObjectCreation,                      // creation status
  LPDWORD GrantedAccess,                    // granted rights
  LPDWORD AccessStatusList                  // array of results
  LPBOOL pfGenerateOnClose                  // audit generation
);

Parameters

SubsystemName
[in] Pointer to a null-terminated string specifying the name of the subsystem calling the function. This string appears in any audit message that the function generates.
HandleId
[in] Pointer to a unique value representing the client's handle to the object. If the access is denied, the system ignores this value.
ObjectTypeName
[in] Pointer to a null-terminated string specifying the type of object being created or accessed. This string appears in any audit message that the function generates.
ObjectName
[in] Pointer to a null-terminated string specifying the name of the object being created or accessed. This string appears in any audit message that the function generates.
pSecurityDescriptor
[in] Pointer to a SECURITY_DESCRIPTOR structure against which access is checked.
PrincipalSelfSid
[in] Pointer to a SID. If the security descriptor is associated with an object that represents a principal (for example, a user object), the PrincipalSelfSid parameter should be the SID of the object. When evaluating access, this SID logically replaces the SID in any ACE containing the well-known PRINCIPAL_SELF SID (S-1-5-10).

This parameter should be NULL if the protected object does not represent a principal.

DesiredAccess
[in] Access mask that specifies the access rights to check. This mask must have been mapped by the MapGenericMask function so that it contains no generic access rights.

If this parameter is MAXIMUM_ALLOWED, the function sets the access mask in GrantedAccess to indicate the maximum access rights the security descriptor allows the client.

AuditType
[in] Specifies the type of audit to be generated. This can be one of the values from the AUDIT_EVENT_TYPE enumeration type.
Flags
[in] Flag that controls the function's behavior if the calling process does not have the SE_AUDIT_NAME privilege enabled. If the AUDIT_ALLOW_NO_PRIVILEGE flag is set, the function performs the access check without generating audit messages when the privilege is not enabled. If this parameter is zero, the function fails if the privilege is not enabled.
ObjectTypeList
[in] Pointer to an array of OBJECT_TYPE_LIST structures that identify the hierarchy of object types for which to check access. Each element in the array specifies a GUID that identifies the object type and a value indicating the level of the object type in the hierarchy of object types. The array should not have two elements with the same GUID.

The array must have at least one element. The first element in the array must be at level zero and identify the object itself. The array can have only one level zero element. The second element is a subobject, such as a property set, at level 1. Following each level 1 entry are subordinate entries for the level 2 through 4 subobjects. Thus, the levels for the elements in the array might be {0, 1, 2, 2, 1, 2, 3}. If the object type list is out of order, AccessCheckByTypeResultListAndAuditAlarm fails, and GetLastError returns ERROR_INVALID_PARAMETER.

ObjectTypeListLength
[in] Specifies the number of elements in the ObjectTypeList array.
GenericMapping
[in] Pointer to the GENERIC_MAPPING structure associated with the object for which access is being checked.
ObjectCreation
[in] Specifies a flag that determines whether the calling application will create a new object when access is granted. A value of TRUE indicates the application will create a new object. A value of FALSE indicates the application will open an existing object.
GrantedAccess
[out] Pointer to an access mask that receives the granted access rights. If AccessStatus is set to FALSE, the function sets the access mask to zero. If the function fails, it does not set the access mask.
AccessStatusList
[out] Pointer to an array of status codes for the corresponding elements in the object type list. The function sets an element to zero to indicate success or to a nonzero value to indicate the specific error during the access check. If the function fails, it does not set any of the elements in the array.
pfGenerateOnClose
[out] Pointer to a flag set by the audit-generation routine when the function returns. Pass this flag to the ObjectCloseAuditAlarm function when the object handle is closed.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The AccessCheckByTypeResultListAndAuditAlarm function is a combination of the AccessCheckByTypeResultList and AccessCheckAndAuditAlarm functions.

The ObjectTypeList array does not necessarily represent the entire defined object. Rather, it represents that subset of the object for which to check access. For instance, to check access to two properties in a property set, specify an object type list with four elements: the object itself at level zero, the property set at level 1, and the two properties at level 2.

The AccessCheckByTypeResultListAndAuditAlarm function evaluates ACEs that apply to the object itself and object-specific ACEs for the object types listed in the ObjectTypeList array. The function ignores object-specific ACEs for object types not listed in the ObjectTypeList array.

For more information about how a hierarchy of ACEs controls access to an object and its subobjects, see ACEs to Control Access to an Object's Properties.

To generate audit messages in the security event log, the calling process must have the SE_AUDIT_NAME privilege enabled. The system checks for this privilege in the primary token of the calling process, not the impersonation token of the thread. If the Flags parameter includes the AUDIT_ALLOW_NO_PRIVILEGE flag, the function performs the access check without generating audit messages when the privilege is not enabled.

The AccessCheckByTypeResultListAndAuditAlarm function fails if the calling thread is not impersonating a client.

If the security descriptor does not contain owner and group SIDs, AccessCheckByTypeResultListAndAuditAlarm fails with ERROR_INVALID_SECURITY_DESCR.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows 2000.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheck, AccessCheckAndAuditAlarm, AccessCheckByType, AccessCheckByTypeResultList, GENERIC_MAPPING, MakeAbsoluteSD, MapGenericMask, PRIVILEGE_SET, SECURITY_DESCRIPTOR


AccessCheckByTypeResultListAndAuditAlarmByHandle

The AccessCheckByTypeResultListAndAuditAlarmByHandle function determines whether a security descriptor grants a specified set of access rights to the client that the calling thread is impersonating. The difference between this function and AccessCheckByTypeResultListAndAuditAlarm is that this function allows the calling thread to perform the access check before impersonating the client.

The function can check access to a hierarchy of objects, such as an object, its property sets, and properties. The function reports the access rights granted or denied to each object type in the hierarchy. If the security descriptor has a SACL with ACEs that apply to the client, the function generates any necessary audit messages in the security event log. Alarms are not currently supported.

BOOL AccessCheckByTypeResultListAndAuditAlarmByHandle(
  LPCTSTR SubsystemName,                    // subsystem name
  LPVOID HandleId,                          // object's handle identifier
  HANDLE ClientToken                        // token object handle
  LPCTSTR ObjectTypeName,                   // object type
  LPCTSTR ObjectName,                       // object name
  PSECURITY_DESCRIPTOR pSecurityDescriptor, // SD
  PSID PrincipalSelfSid,                    // SID
  DWORD DesiredAccess,                      // requested access rights
  AUDIT_EVENT_TYPE AuditType,               // type of audit
  DWORD Flags,                              // access check options
  POBJECT_TYPE_LIST ObjectTypeList,         // array of object types
  DWORD ObjectTypeListLength,               // number of object types
  PGENERIC_MAPPING GenericMapping,          // mapping
  BOOL ObjectCreation,                      // creation status
  LPDWORD GrantedAccess,                    // granted rights
  LPDWORD AccessStatusList                  // array of results
  LPBOOL pfGenerateOnClose                  // audit generation
);

Parameters

SubsystemName
[in] Pointer to a null-terminated string specifying the name of the subsystem calling the function. This string appears in any audit message that the function generates.
HandleId
[in] Pointer to a unique value representing the client's handle to the object. If the access is denied, the system ignores this value.
ClientToken
[in] A handle to a token object representing the client that requested the operation. This handle must be obtained through a communication session layer, such as a local named pipe, to prevent possible security policy violations. The caller must have TOKEN_QUERY access for the specified token.
ObjectTypeName
[in] Pointer to a null-terminated string specifying the type of object being created or accessed. This string appears in any audit message that the function generates.
ObjectName
[in] Pointer to a null-terminated string specifying the name of the object being created or accessed. This string appears in any audit message that the function generates.
pSecurityDescriptor
[in] Pointer to a SECURITY_DESCRIPTOR structure against which access is checked.
PrincipalSelfSid
[in] Pointer to a SID. If the security descriptor is associated with an object that represents a principal (for example, a user object), the PrincipalSelfSid parameter should be the SID of the object. When evaluating access, this SID logically replaces the SID in any ACE containing the well-known PRINCIPAL_SELF SID (S-1-5-10).

This parameter should be NULL if the protected object does not represent a principal.

DesiredAccess
[in] Access mask that specifies the access rights to check. This mask must have been mapped by the MapGenericMask function so that it contains no generic access rights.

If this parameter is MAXIMUM_ALLOWED, the function sets the access mask in GrantedAccess to indicate the maximum access rights the security descriptor allows the client.

AuditType
[in] Specifies the type of audit to be generated. This can be one of the values from the AUDIT_EVENT_TYPE enumeration type.
Flags
[in] Flag that controls the function's behavior if the calling process does not have the SE_AUDIT_NAME privilege enabled. If the AUDIT_ALLOW_NO_PRIVILEGE flag is set, the function performs the access check without generating audit messages when the privilege is not enabled. If this parameter is zero, the function fails if the privilege is not enabled.
ObjectTypeList
[in] Pointer to an array of OBJECT_TYPE_LIST structures that identify the hierarchy of object types for which to check access. Each element in the array specifies a GUID that identifies the object type and a value indicating the level of the object type in the hierarchy of object types. The array should not have two elements with the same GUID.

The array must have at least one element. The first element in the array must be at level zero and identify the object itself. The array can have only one level zero element. The second element is a subobject, such as a property set, at level 1. Following each level 1 entry are subordinate entries for the level 2 through 4 subobjects. Thus, the levels for the elements in the array might be {0, 1, 2, 2, 1, 2, 3}. If the object type list is out of order, AccessCheckByTypeResultListAndAuditAlarmByHandle fails, and GetLastError returns ERROR_INVALID_PARAMETER.

ObjectTypeListLength
[in] Specifies the number of elements in the ObjectTypeList array.
GenericMapping
[in] Pointer to the GENERIC_MAPPING structure associated with the object for which access is being checked.
ObjectCreation
[in] Specifies a flag that determines whether the calling application will create a new object when access is granted. A value of TRUE indicates the application will create a new object. A value of FALSE indicates the application will open an existing object.
GrantedAccess
[out] Pointer to an access mask that receives the granted access rights. If AccessStatus is set to FALSE, the function sets the access mask to zero. If the function fails, it does not set the access mask.
AccessStatusList
[out] Pointer to an array of status codes for the corresponding elements in the object type list. The function sets an element to zero to indicate success or to a nonzero value to indicate the specific error during the access check. If the function fails, it does not set any of the elements in the array.
pfGenerateOnClose
[out] Pointer to a flag set by the audit-generation routine when the function returns. Pass this flag to the ObjectCloseAuditAlarm function when the object handle is closed.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

Like AccessCheckByTypeResultListAndAuditAlarm, the AccessCheckByTypeResultListAndAuditAlarmByHandle function is a combination of the AccessCheckByTypeResultList and AccessCheckAndAuditAlarm functions. However, AccessCheckByTypeResultListAndAuditAlarmByHandle also requires a client token handle to provide security information on the client.

The ObjectTypeList array does not necessarily represent the entire defined object. Rather, it represents that subset of the object for which to check access. For instance, to check access to two properties in a property set, specify an object type list with four elements: the object itself at level zero, the property set at level 1, and the two properties at level 2.

The AccessCheckByTypeResultListAndAuditAlarmByHandle function evaluates ACEs that apply to the object itself and object-specific ACEs for the object types listed in the ObjectTypeList array. The function ignores object-specific ACEs for object types not listed in the ObjectTypeList array.

For more information about how a hierarchy of ACEs controls access to an object and its subobjects, see ACEs to Control Access to an Object's Properties.

To generate audit messages in the security event log, the calling process must have the SE_AUDIT_NAME privilege enabled. The system checks for this privilege in the primary token of the calling process, not the impersonation token of the thread. If the Flags parameter includes the AUDIT_ALLOW_NO_PRIVILEGE flag, the function performs the access check without generating audit messages when the privilege is not enabled.

The AccessCheckByTypeResultListAndAuditAlarmByHandle function fails if the calling thread is not impersonating a client.

If the security descriptor does not contain owner and group SIDs, AccessCheckByTypeResultListAndAuditAlarmByHandle fails with ERROR_INVALID_SECURITY_DESCR.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows 2000.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheck, AccessCheckAndAuditAlarm, AccessCheckByType, AccessCheckByTypeResultList, AccessCheckByTypeResultListAndAuditAlarm, GENERIC_MAPPING, MakeAbsoluteSD, MapGenericMask, PRIVILEGE_SET, SECURITY_DESCRIPTOR


AreAllAccessesGranted

The AreAllAccessesGranted function checks whether a set of requested access rights has been granted. The access rights are represented as bit flags in an access mask.

BOOL AreAllAccessesGranted(
  DWORD GrantedAccess,  // granted access rights
  DWORD DesiredAccess   // requested access rights
);

Parameters

GrantedAccess
[in] An access mask that specifies the access rights that have been granted.
DesiredAccess
[in] An access mask that specifies the access rights that have been requested. This mask must have been mapped from generic to specific and standard access rights, usually by calling the MapGenericMask function.

Return Values

If all requested access rights have been granted, the return value is nonzero.

If not all requested access rights have been granted, the return value is zero.

Remarks

The AreAllAccessesGranted function is commonly used by a server application to check the access rights of a client attempting to gain access to an object. When the bits set in the DesiredAccess parameter match the bits set in the GrantedAccess parameter, all requested rights have been granted.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheck, AreAnyAccessesGranted, MapGenericMask


AreAnyAccessesGranted

The AreAnyAccessesGranted function tests whether any of a set of requested access rights has been granted. The access rights are represented as bit flags in an access mask.

BOOL AreAnyAccessesGranted(
  DWORD GrantedAccess,  // granted access rights
  DWORD DesiredAccess   // access rights requested
);

Parameters

GrantedAccess
[in] Specifies the granted access mask.
DesiredAccess
[in] Specifies the access mask to be requested. This mask must have been mapped from generic to specific and standard access rights, usually by calling the MapGenericMask function.

Return Values

If any of the requested access rights have been granted, the return value is nonzero.

If none of the requested access rights have been granted, the return value is zero.

Remarks

The AreAnyAccessesGranted function is often used by a server application to check the access rights of a client attempting to gain access to an object. When any of the bits set in the DesiredAccess parameter match the bits set in the GrantedAccess parameter, at least one of the requested access rights has been granted.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheck, AreAllAccessesGranted, MapGenericMask


AuthzInitializeResourceManager

[This is preliminary documentation and subject to change.]

The AuthzInitializeResourceManager function allocates and initializes a resource manager structure.

BOOL WINAPI AuthzInitializeResourceManager(
  PFN_AUTHZ_ACCESS_CHECK pfnAccessCheck,
  PFN_AUTHZ_COMPUTE_DYNAMIC_GROUPS pfnComputeDynamicGroups,
  PFN_AUTHZ_FREE_DYNAMIC_GROUPS pfnFreeDynamicGroups,
  AUTHZ_RM_AUDIT_INFO StaticAuditInfo,
  DWORD AuthzFlags,
  PAUTHZ_RESOURCE_MANAGER_HANDLE pAuthzResourceManager
);

Parameters

pfnAccessCheck
[in] Pointer to a dynamic access check callback function that the resource manager (RM) calls each time it encounters a CALLBACK ACE during ACL evaluation in AuthzAccessCheck or AuthzCachedAccessCheck.
pfnComputeDynamicGroups
[in] Pointer to the compute dynamic groups callback function invoked by the resource manager during initialization of an AuthzClientContext handle.
pfnFreeDynamicGroups
[in] Pointer to the free dynamic groups callback function invoked by the resource manager to free SID attribute arrays allocated by the compute dynamic groups callback.
StaticAuditInfo
[in] Handle to the static information about the resource manager to be used by the auditing routines.
AuthzFlags
[in] Reserved for future use.
pAuthzResourceManager
[out] Pointer to the returned resource manager handle. The returned handle must be freed using AuthzFreeResourceManager.

Return Values

Returns nonzero (TRUE ) if successful or zero (FALSE ) if it fails. GetLastError returns an error code indicating the reason for a failure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


AuthzInitializeContextFromToken

[This is preliminary documentation and subject to change.]

The AuthzInitializeContextFromToken function initializes an authorization context from the handle to the kernel token. The kernel token must have been opened for TOKEN_QUERY.

BOOL WINAPI AuthzInitializeContextFromToken(
  HANDLE TokenHandle,
  AUTHZ_RESOURCE_MANAGER_HANDLE AuthzResourceManager,
  PLARGE_INTEGER pExpirationTime,
  LUID Identifier,
  DWORD Flags,
  PVOID DynamicGroupArgs,
  PAUTHZ_CLIENT_CONTEXT_HANDLE pAuthzClientContext
);

Parameters

TokenHandle
[in] Handle to the client token used to initialize the pAuthzClientContext parameter. The token must have been opened with TOKEN_QUERY access.
AuthzResourceManager
[in] Handle of the resource manager that created this client context. This handle is stored in the client context structure.
pExpirationTime
[in] Expiration date and time of the token. If no value is passed, the token never expires. Expiration time is not currently enforced.
Identifier
[in] Identifier that is specific to the resource manager. This parameter is not currently used.
Flags
[in] Reserved for future use.
DynamicGroupArgs
[in] Pointer to arguments to be passed to the callback function that computes dynamic groups.
pAuthzClientContext
[out] Pointer to the AuthzClientContext handle returned.

Return Values

Returns nonzero (TRUE ) if successful or zero (FALSE ) if it fails. GetLastError returns an error code indicating the reason for a failure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


AuthzInitializeContextFromSid

[This is preliminary documentation and subject to change.]

The AuthzInitializeContextFromSid function creates a user-mode client context from a user SID. Domain SIDs retrieve token groups attributes from the Active Directory. Local computer groups are computed on the server name specified. Resource managers can dynamically group contexts using the callback mechanism.

BOOL WINAPI AuthzInitializeContextFromSid(
  PSID UserSid,
  PWSTR ServerName,
  AUTHZ_RESOURCE_MANAGER_HANDLE AuthzResourceManager,
  PLARGE_INTEGER pExpirationTime,
  LUID Identifier,
  DWORD Flags,
  PVOID DynamicGroupArgs,
  PAUTHZ_CLIENT_CONTEXT_HANDLE pAuthzClientContext
);

Parameters

UserSid
[in] SID of the user for whom a client context will be created.
ServerName
[in] Name of the server on which local groups should be computed. A NULL server name defaults to the local computer.
AuthzResourceManager
[in] Handle of the resource manager creating this client context. This handle is stored in the client context structure.
pExpirationTime
[in] Expiration date and time of the token. If no value is passed, the token never expires. Expiration time is not currently enforced.
Identifier
[in] Specific identifier of the resource manager. This parameter is not currently used.
Flags
[in] Set to AUTHZ_SKIP_LOCAL_GROUPS to block computing local groups.
DynamicGroupArgs
[in] Pointer to arguments to be passed to the callback function that computes dynamic groups.
pAuthzClientContext
[out] Pointer to the AuthzClientContext handle returned. The returned handle must be freed using AuthzFreeContext.

Return Values

Returns nonzero (TRUE ) if successful or zero (FALSE ) if it fails. GetLastError returns an error code indicating the reason for a failure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


AuthzAccessCheck

[This is preliminary documentation and subject to change.]

The AuthzAccessCheck function determines which access bits can be granted to a client for a given set of security descriptors. The pReply structure returns an array of granted access masks and error status. Optionally, access masks that will always be granted can be cached and a handle to cached values is returned.

BOOL WINAPI AuthzAccessCheck(
  AUTHZ_CLIENT_CONTEXT_HANDLE AuthzClientContext,
  PAUTHZ_ACCESS_REQUEST pRequest,
  AUTHZ_AUDIT_INFO_HANDLE AuditInfo,
  PSECURITY_DESCRIPTOR pSecurityDescriptor,
  PSECURITY_DESCRIPTOR *OptionalSecurityDescriptorArray,
  DWORD OptionalSecurityDescriptorCount,
  PAUTHZ_ACCESS_REPLY pReply,
  PAUTHZ_HANDLE pAuthzHandle
);

Parameters

AuthzClientContext
[in] Handle of an AUTHZ_CLIENT_CONTEXT_HANDLE structure representing the client.
pRequest
[in] Access request specifying the desired access mask, principal self SID, and the object type list structure if it exists.
AuditInfo
[in] Structure containing object specific audit information. A non-NULL value of this parameter automatically requests an audit. Static audit information is read from the resource manager structure.
pSecurityDescriptor
[in] Pointer to a SECUIRITY_DESCIRPTOR structure to be used for access checks. The owner SID for the object is picked from this SID. A NULL DACL in this security descriptor represents a NULL DACL for the entire object. A NULL SACL in this security descriptor is treated the same way as an empty SACL.
OptionalSecurityDescriptorArray
[in] Optionally specified array of SECURITY_DESCIRPTOR structures. NULL ACLs in these security descriptors are treated as empty ACLS and the ACL for the entire object is the logical concatenation of all of the ACLs.
OptionalSecurityDescriptorCount
[in, out] Number of optional security descriptors not including the primary security descriptor.
pReply
[out] Pointer to an AUTHZ_ACCESS_REPLY handle containing the results of access check. The results are returned as an array of GrantedAccessMask Error pairs. The number of pairs returned in supplied by the caller in pReply->ResultListLength.

The Error member of the AUTHZ_ACCESS_REPLY structure is expected to return the array elements shown in the following table.
Error | Meaning
ERROR_SUCCESS | All the access bits, not including MAXIMUM_ALLOWED, are granted and the GrantedAccessMask is not zero.
ERROR_PRIVILEGE_NOT_HELD | DesiredAccess includes ACCESS_SYSTEM_SECURITY and the client does not have SeSecurityPrivilege.
ERROR_ACCESS_DENIED Contains each of the following:
  • Any of the bits requested is not granted.
  • MaximumAllowed bit is on and granted access is zero.
  • DesiredAccess is 0.

pAuthzHandle
Pointer to return a handle to the cached results of access check. A non-NULL value requests that the results of this access check call be cached. This results in a MAXIMUM_ALLOWED check.

Return Values

Returns nonzero (TRUE ) if successful or zero (FALSE ) if it fails. GetLastError returns an error code indicating the reason for a failure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


AuthzInitializeContentxFromAuthzContext

[This is preliminary documentation and subject to change.]

The AuthzInitializeContentxFromAuthzContext function performs a fast access check based on a cached handle that holds the static granted bits evaluated at the time of a previously made AuthzAccessCheck call. The pReply structure returns an array of granted access masks and error statuses. Use of this function assumes that the client context pointer is stored in the AuthzHandle. The structure of the client context must be exactly the same as it was at the time the AuthzHandle was created. This restriction is for the following fields: Sids, RestrictedSids, and Privileges.

Pointers to the primary security descriptor and the optional security descriptor array are stored in the AuthzHandle at the handle's creation. These must still be valid.

AUTHZAPI BOOL WINAPI AuthzCachedAccessCheck(
  AUTHZ_HANDLE AuthzHandle,
  PAUTHZ_ACCESS_REQUEST pRequest,
  AUTHZ_AUDIT_INFO AuditInfo,
  PAUTHZ_ACCESS_REPLY pReply
);

Parameters

AuthzHandle
[in] Handle of the cached access check results.
pRequest
[in] Access request specifying the desired access mask, principal self SID, and the object type list structure if it exists.
AuditInfo
[in] Optional structure containing object-specific audit information. A non-NULL value of this parameter automatically requests an audit. Static audit information is read from the resource manager structure.
pReply
[in, out] Pointer to an AUTHZ_ACCESS_REPLY handle containing the results of access check. The results are returned as an array of GrantedAccessMask error pairs. The number of pairs returned is supplied by the caller in pReply->ResultListLength.

The Error member of the AUTHZ_ACCESS_REPLY structure is expected to return the array elements shown in the following table.
Error | Meaning
ERROR_SUCCESS | All the access bits, not including MAXIMUM_ALLOWED, are granted and the GrantedAccessMask is not zero.
ERROR_PRIVILEGE_NOT_HELD | DesiredAccess includes ACCESS_SYSTEM_SECURITY and the client does not have SeSecurityPrivilege.
ERROR_ACCESS_DENIED Contains each of the following:
  • Any of the bits requested is not granted.
  • MaximumAllowed bit is on and granted access is zero.
  • DesiredAccess is 0.

Return Values

Returns nonzero (TRUE ) if successful or zero (FALSE ) if it fails. GetLastError returns an error code indicating the reason for a failure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


AuthzCachedAccessCheck

[This is preliminary documentation and subject to change.]

The AuthzCachedAccessCheck function performs a fast access check based on a cached handle containing the static granted bits from a previous AuthzAccessCheck call. The pReply parameter returns an array of granted access masks and error status.

BOOL WINAPI AuthzCachedAccessCheck(
  AUTHZ_HANDLE AuthzHandle,
  PAUTHZ_ACCESS_REQUEST_HANDLE pRequest,
  AUTHZ_AUDIT_INFO_HANDLE AuditInfo,
  PAUTHZ_ACCESS_REPLY pReply
);

Parameters

AuthzHandle
[in] Handle of the cached access check results.
pRequest
[in] Access request handle specifying the desired access mask, principal self SID, and the object type list structure (if any).
AuditInfo
[in] Handle of the object-specific audit information. A non-NULL value of this parameter requests an audit. Static audit information for the Resource Manager, set with the StaticAuditInfo parameter of the AuthzInitializeResourceManager function, will be included in the generated audit.
pReply
[out] Pointer to an AUTHZ_ACCESS_REPLY handle that returns the results of access check as an array of GrantedAccessMask/ ErrorValue pairs. The number of pairs returned in supplied by the caller in pReply->ResultListLength.

Expected values of the Error members of array elements returned are shown in the following table.
Error | Meaning
ERROR_SUCCESS | All the access bits, not including MAXIMUM_ALLOWED, are granted and GrantedAccessMask is not zero.
ERROR_PRIVILEGE_NOT_HELD | DesiredAccess includes ACCESS_SYSTEM_SECURITY and the client does not have SeSecurityPrivilege.
ERROR_ACCESS_DENIED Contains each of the following:
  • Any of the bits requested is not granted.
  • MaximumAllowed bit is on and granted access is zero.
  • DesiredAccess is 0.

Remarks

The client context pointer is stored in the AuthzHandle parameter. The structure of the client context must be exactly the same as it was at the time AuthzHandle was created. This restriction is for the following fields:

  • SIDs
  • RestrictedSids
  • Privileges.

Pointers to the primary security descriptor and the optional security descriptor array are stored in AuthzHandle at the time of handle creation. These pointers must still be valid.

Return Values

Returns nonzero (TRUE ) if successful or zero (FALSE ) if it fails. GetLastError returns an error code indicating the reason for a failure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


AuthzAddSidsToContext

[This is preliminary documentation and subject to change.]

The AuthzAddSidsToContext function creates a copy of an already existing context and appends a given set of SIDs and restricted SIDs.

BOOL WINAPI AuthzAddSidsToContext(
  AUTHZ_CLIENT_CONTEXT_HANDLE OrigClientContext,
  PLARGE_INTEGER pExpirationTime,
  LUID Identifier,
  DWORD Flags,
  PSID_AND_ATTRIBUTES Sids,
  DWORD SidCount,
  PSID_AND_ATTRIBUTES RestrictedSids,
  DWORD RestrictedSidCount,
  PAUTHZ_CLIENT_CONTEXT_HANDLE pNewClientContext
);

Parameters

OrigClientContext
[in] AUTHZ_CLIENT_CONTEXT_HANDLE structure to be copied as the basis for NewClientContext.
pExpirationTime
[in] Expiration date and time of the token. If no value is passed, the token never expires. Expiration time is not currently enforced.
Identifier
[in] Resource manager specific identifier. This parameter is not currently used.
Flags
[in] No flags are currently used.
Sids
[in] Pointer to a SID_AND_ATTRIBUTES structure containing the SIDs and attributes to be added to the unrestricted part of the client context.
SidCount
[in] Number of SIDs to be added
RestrictedSids
[in] Pointer to a SID_AND_ATTRIBUTES structure containing the SIDs and attributes to be added to the restricted part of the client context.
RestrictedSidCount
[in] Number of restricted SIDs to be added.
pNewClientContext
[out] Pointer to the created AUTHZ_CLIENT_CONTEXT_HANDLE structure containing input values for expiration time, identifier, flags, additional SIDs and restricted SIDs.

Return Values

Returns nonzero (TRUE ) if successful or zero (FALSE ) if it fails. GetLastError returns an error code indicating the reason for a failure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


AuthzFreeHandle

[This is preliminary documentation and subject to change.]

The AuthzFreeHandle function finds and deletes a handle from the handle list.

BOOL WINAPI AuthzFreeHandle(
  AUTHZ_HANDLE AuthzHandle
);

Parameters

AuthzHandle
[in] Handle to be freed.

Return Values

Returns nonzero (TRUE ) if successful or zero (FALSE ) if it fails. GetLastError returns an error code indicating the reason for a failure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


AuthzFreeContext

[This is preliminary documentation and subject to change.]

The AuthzFreeContext function frees all structures and memory associated with the client context. The list of handles for a client is freed in this call.

BOOL WINAPI AuthzFreeContext(
  AUTHZ_CLIENT_CONTEXT_HANDLE AuthzClientContext
);

Parameters

AuthzClientContext
[in] AUTHZ_CLIENT_CONTEXT_HANDLE structure to be freed.

Return Values

Returns nonzero (TRUE ) if successful or zero (FALSE ) if it fails. GetLastError returns an error code indicating the reason for a failure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


AuthzFreeResourceManager

[This is preliminary documentation and subject to change.]

The AuthzFreeResourceManager function frees a resource manager object.

BOOL AuthzFreeResourceManager(
  AUTHZ_RESOURCE_MANAGER_HANDLE AuthzResourceManager
);

Parameters

AuthzResourceManager
[in] AUTHZ_RESOURCE_MANAGER_HANDLE to be freed.

Return Values

Returns nonzero (TRUE ) if successful or zero (FALSE ) if it fails. GetLastError returns an error code indicating the reason for a failure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


AuthzGetContextInformation

[This is preliminary documentation and subject to change.]

The AuthzGetContextInformation function retrieves information about the client context in a buffer supplied by the caller and the size of the buffer required to hold the requested information.

BOOL AuthzGetContextInformation(
  AUTHZ_CLIENT_CONTEXT_HANDLE AuthzClientContext,
  AUTHZ_CONTEXT_INFORMATION_CLASS InfoClass,
  PVOID Buffer,
  DWORD BufferSize,
  PDWORD pSizeRequired
);

Parameters

AuthzClientContext
[in] AUTHZ_CLIENT_CONTEXT_HANDLE structure from which requested information is retrieved.
InfoClass
[in] Type of information to be returned. The caller can request the following.
Information requested | InfoClass value passed | Type of structure returned in the Buffer parameter.
User SID | AuthzContextInfoUserSid | TOKEN_USER
Group SIDs and their attributes | AuthzContextInfoGroupsSids | TOKEN_GROUPS
Restricted SIDs and their attributes | AuthzContextInfoRestrictedSids | TOKEN_GROUPS
Privileges | AuthzContextInfoPrivileges | TOKEN_PRIVILEGES
Expiration time | AuthzContextInfoxpirationTime | LARGE_INTEGER
Server Context one level higher | AuthzContextInfoServerContext | PAUTHZ_CLIENT_CONTEXT_HANDLE
Client Context Identifier | AuthzContextInfoGroupsIdentifier | LUID

Buffer
[in, out] Pointer to a buffer to hold the information requested. The structure returned depends on the information class requested. Can be NULL to retrieve the number of bytes that must be allocated.
BufferSize
[in] Size of the supplied buffer.
pSizeRequired
[out] Size of the buffer needed to hold the results.

Return Values

Returns nonzero (TRUE ) if successful or zero (FALSE ) if it fails. GetLastError returns an error code indicating the reason for a failure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


AuthzGetInformationFromResourceManager

[This is preliminary documentation and subject to change.]

The AuthzGetInformationFromResourceManager function queries information in the AUTHZ_RESOURCE_MANAGER_HANDLE hResourceManager.

BOOL AuthzGetInformationFromResourceManager(
  AUTHZ_RESOURCE_MANAGER_HANDLE hResourceManager,
  AUTHZ_CONTEXT_INFORMATION_CLASS InfoClass,
  PVOID Buffer,
  DWORD BufferSize,
  PDWORD pSizeRequired
);

Parameters

hResourceManager
[in] AUTHZ_CLIENT_CONTEXT_HANDLE structure from which requested information is retrieved.
InfoClass
[in] Type of information to be returned. Valid values are shown in the following table:
InfoClass value passed | Information returned | Returned type
AuthzRMInfoFlags | Resource Manager flags | DWORD
AuthzRMInfoAccessCheck | Address of registered AccessCheck callback | PFN_AUTHZ_ACCESS_CHECK
AuthzRMInfoComputeDynamicGroups | PFN_AUTHZ_COMPUTE_DYNAMIC_GROUPS
AuthzRMInfoFreeDynamicGroups | PFN_AUTHZ_FREE_DYNAMIC_GROUPS
AuthzRMInfoRMAuditInfo | Address of associated hRMAuditInfo | AUTHZ_RM_AUDIT_INFO_HANDLE

Buffer
[in, out] Pointer to a buffer to hold the information requested. The structure returned depends on the information class requested. Can be NULL to retrieve the number of bytes that must be allocated.
BufferSize
[in] Size of the supplied buffer.
pSizeRequired
[out] Size of the buffer needed to hold the results.

Return Values

Returns nonzero (TRUE ) if successful or zero (FALSE ) if it fails. GetLastError returns an error code indicating the reason for a failure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


AuthzGetInformationFromAuditInfo

[This is preliminary documentation and subject to change.]

The AuthzGetInformationFromAuditInfo function queries information in the AUTHZ_AUDIT_INFO_HANDLE, hAuditInfo.

BOOL AuthzGetInformationFromAuditInfo(
  AUTHZ_AUDIT_INFO_HANDLE hAuditInfo,
  AUTHZ_AUDIT_INFO_INFORMATION_CLASS InfoClass,
  PVOID Buffer,
  DWORD BufferSize,
  PDWORD pSizeRequired
);

Parameters

hAuditInfo
[in] AUTHZ_AUDIT_INFO_HANDLE structure from which requested information is retrieved.
InfoClass
[in] Type of information to be returned. The caller can request the following.
InfoClass value passed | Information returned | Returned type
AuthzAuditInfoFlags | Flags set for the handle | DWORD
AuthzAuditInfoEvent | Copy of the AUDIT_EVENT_INFO associated with the handle. | AUDIT_EVENT_INFO
AuthzAuditInfoAuditParams | Copy of the AUDIT_PARAMS associated with the handle. | AUDIT_PARAMS
AuthzAuditInfoTimeout | The timeout value of the handle. | DWORD
AuthzAuditInfoOperationType | The operation type. | PCWSTR
AuthzAuditInfoObjectName | The object name. | PCWSTR
AuthzAuditInfoAdditionalInfo | Additional info field. | PCWSTR

Buffer
[in, out] Pointer to a buffer to hold the information requested. The structure returned depends on the information class requested. Can be NULL to retrieve the number of bytes that must be allocated.
BufferSize
[in] Size of the supplied buffer.
pSizeRequired
[out] Size of the buffer needed to hold the results.

Return Values

Returns nonzero (TRUE ) if successful or zero (FALSE ) if it fails. GetLastError returns an error code indicating the reason for a failure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


AuthzGetInformationFromRMAuditInfo

[This is preliminary documentation and subject to change.]

The AuthzGetInformationFromRMAuditInfo function queries information in the AUTHZ_RM_AUDIT_INFO_HANDLE, hRMAuditInfo.

BOOL AuthzGetInformationFromRMAuditInfo(
  AUTHZ_RM_AUDIT_INFO_HANDLE hRMAuditInfo,
  AUTHZ_RM_AUDIT_INFO_INFORMATION_CLASS InfoClass,
  PVOID Buffer,
  DWORD BufferSize,
  PDWORD pSizeRequired
);

Parameters

hRMAuditInfo
[in] AUTHZ_RM_AUDIT_INFO_HANDLE structure from which requested information is retrieved.
InfoClass
[in] Type of information to be returned. The caller can request the following.
Information requested | InfoClass value passed | Type of structure returned in the Buffer parameter.
Flags set for the handle | AuthzRMAuditInfoFlags | DWORD
High water mark for the audit queue | AuthzRMAuditInfoQueueSizeHigh | DWORD
Low water mark for the audit queue | AuthzRMAuditInfoQueueSizeLow | DWORD
Resource Manager name | AuthzRMAuditInfoName | PWCSTR

Buffer
[in, out] Pointer to a buffer to hold the information requested. The structure returned depends on the information class requested. Can be NULL to retrieve the number of bytes that must be allocated.
BufferSize
[in] Size of the supplied buffer.
pSizeRequired
[out] Size of the buffer needed to hold the results.

Return Values

Returns nonzero (TRUE ) if successful or zero (FALSE ) if it fails. GetLastError returns an error code indicating the reason for a failure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


AuthzModifyRMAuditInfo

[This is preliminary documentation and subject to change.]

The AuthzModifyRMAuditInfo function allows the Resource Manager (RM) to modify specific audit control information.

BOOL AuthzModifyRMAuditInfo(
  AUTHZ_RESOURCE_MANAGER_HANDLE hResourceManager,
  DWORD dwFlags,
  DWORD dwRmFlags,
  DWORD dwAuditQueueSizeHigh,
  DWORD dwAuditQueueSizeLow,
  PCWSTR szResourceManagerName,
  DWORD dwThreadPriority
);

Parameters

hResourceManager
[in, out] Handle of the Resource Manager.
dwFlags
[in] Flags specifying which fields of the RM are to be reinitialized. Valid flags are:
  • AUTHZ_RM_AUDIT_INFO_FLAGS
  • AUTHZ_RM_AUDIT_INFO_HIGH
  • AUTHZ_RM_AUDIT_INFO_LOW
  • AUTHZ_RM_AUDIT_INFO_NAME
  • AUTHZ_RM_AUDIT_THREAD_PRIORITY
dwRmFlags
[in] Flags to control audit behavior of the Resource Manager. Currently, the only valid flag is AUTHZ_MONITOR_AUDIT_QUEUE_SIZE. If this flag is set, the size of the audit queue is checked and not allowed to grow without limit. This parameter may be set to zero.
dwAuditQueueSizeHigh
[in] Maximum length of the audit queue. This parameter may be set to zero if a maximum queue length is not set.
dwAuditQueueSizeLow
[in] Minimum length of the audit queue. This parameter may be set to zero if a minimum queue length is not set.
szResourceManagerName
[in] Name of the resource manager. This parameter may be NULL.
dwThreadPriority
[in] Changes the priority of the audit queue thread. Valid values are described in the SetThreadPriority documentation. A resource manager (RM) can change the priority of the thread if, for example, the maximum queue length is being reached too frequently and the RM does not want to allow the queue to grow beyond its current size. This parameter may be set to zero if a thread priority is not being set.

Return Values

Returns nonzero (TRUE ) if successful or zero (FALSE ) if it fails. GetLastError returns an error code indicating the reason for a failure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


AuthzFreeRMAuditInfo

[This is preliminary documentation and subject to change.]

The AuthzFreeRMAuditInfo function frees resources allocated by a prior call to AuthzInitializeRMAuditInfo.

BOOL AuthzFreeRMAuditInfo(
  AUTHZ_RM_AUDIT_INFO_HANDLE hRMAuditInfo
);

Parameters

hRMAuditInfo
[in] Handle of Resource Manager (RM) of specific audit information to be freed.

Return Values

Returns nonzero (TRUE ) if successful or zero (FALSE ) if it fails. GetLastError returns an error code indicating the reason for a failure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


AuthzInitializeAuditEvent

[This is preliminary documentation and subject to change.]

The AuthzInitializeAuditEvent function Initializes an AUDIT_EVENT_INFO structure for use by the AuthzInitializeAuditInfo function.

BOOL AuthzInitializeAuditEvent(
  PAUDIT_EVENT_INFO *ppAuditEventInfo,
  DWORD dwFlags,
  USHORT CategoryID,
  USHORT AuditID,
  USHORT ParameterCount
);

Parameters

ppAuditEventInfo
[out] Pointer to pointer to receive memory allocated for the AUDIT_EVENT_INFO structure.
dwFlags
[in] Flags that control behavior of a function. Currently, the only flag defined is AUTHZ_INIT_GENERIC_AUDIT_EVENT. If this flag is set, the AUDIT_EVENT_INFO structure is initialized for generic object-access audits.
CategoryID
[in] Category ID of the audit. Can be set to zero.
AuditID
[in] ID of the audit in msaudite. Can be set to zero.
ParameterCount
[in] Number of fields in the audit. Can be set to zero.

Return Values

Returns nonzero (TRUE ) if successful or zero (FALSE ) if it fails. GetLastError returns an error code indicating the reason for a failure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


AuthzFreeAuditEvent

[This is preliminary documentation and subject to change.]

The AuthzFreeAuditEvent function frees the AUDIT_EVENT_INFO structure allocated in the AuthzInitializeAuditEvent function.

BOOL AuthzFreeAuditEvent(
  IN PAUDIT_EVENT_INFO pAuditEventInfo
);

Parameters

pAuditEventInfo
Pointer to the AUDIT_EVENT_INFO structure to free.

Return Values

Returns nonzero (TRUE ) if successful or zero (FALSE ) if it fails. GetLastError returns an error code indicating the reason for a failure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


AuthzInitializeAuditInfo

[This is preliminary documentation and subject to change.]

The AuthzInitializeAuditInfo function stores audit information specific to an access check call and returns a handle to this information. Call the AuthzFreeAuditInfo function to free resources allocated by this function.

AUTHZAPI BOOL AuthzInitializeAuditInfo(
  PAUTHZ_AUDIT_INFO_HANDLE phAuditInfo,
  DWORD dwFlags,
  PAUDIT_EVENT_INFO pAuditEvent,
  PAUDIT_PARAMS pAuditParams,
  DWORD dwTimeOut,
  PCWSTR szOperationType,
  PCWSTR szObjectType,
  PCWSTR szObjectName,
  PCWSTR szAdditionalInfo
);

Parameters

phAuditInfo
[out] Pointer to the returned handle.
dwFlags
[in] Flags that control audit generation. A combination of the following can be set:
Flag | Description
AUTHZ_NO_SUCCESS_AUDIT | Do not generate audit if access check succeeds.
AUTHZ_NO_FAILURE_AUDIT | Do not generate audit if access check fails.

pAuditEvent
[in] Pointer to an AUDIT_EVENT_INFO structure. Members of this structure should be set as below for generic object-access audits:
AuditEventInfo.Version                 = AUDIT_TYPE_LEGACY
AuditEventInfo.u.Legacy.CategoryId     = SE_CATEGID_OBJECT_ACCESS
AuditEventInfo.u.Legacy.AuditId        = SE_AUDITID_OBJECT_OPERATION
AuditEventInfo.u.Legacy.ParameterCount = 11

Other audit types should be created by resource managers in msaudite.mc.

pAuditParams
[in] Currently must be set to NULL.
dwTimeOut
[in] Maximum milliseconds a thread attempting to generate an audit with this handle waits for access to the queue. Use INFINITE to specify an unlimited timeout.
szOperationType
[in] String naming the type of operation, such as "Open" or "Modify," that will be audited.
szObjectType
[in] String naming the type of the object accessed, such as "File" or "MyObject," that will be audited.
szObjectName
[in] String naming the object that will be audited.
szAdditionalInfo
[in] Optional string to go into the "Additional Information" field of the SE_AUDITID_OBJECT_OPERATION event.

Return Values

Returns nonzero (TRUE ) if successful or zero (FALSE ) if it fails. GetLastError returns an error code indicating the reason for a failure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


AuthzFreeAuditInfo

[This is preliminary documentation and subject to change.]

The AuthzFreeAuditInfo function frees resources allocated for the passed handle.

AUTHZAPI VOID AuthzFreeAuditInfo(
  IN AUTHZ_AUDIT_INFO_HANDLE hAuditInfo
  IN AUTHZ_RESOURCE_MANAGER_HANDLE hRM
);

Parameters

hAuditInfo
[in] Handle of the resources to be freed.
hRM
[in] Handle of the Resource Manager. The Authz audit queue is emptied of references to the hAuditInfo before the hAuditInfo and the corresponding LSA context are freed.

Return Values

This function does not return a value.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


AuthzOpenObjectAuditAlarm

[This is preliminary documentation and subject to change.]

The AuthzOpenObjectAuditAlarm function examines the SACL in the passed security descriptors and generates any appropriate audits.

BOOL AuthzOpenObjectAuditAlarm(
  AUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClientContext,
  PAUTHZ_ACCESS_REQUEST pRequest,
  AUTHZ_AUDIT_INFO_HANDLE hAuditInfo,
  PSECURITY_DESCRIPTOR pSecurityDescriptor,
  PSECURITY_DESCRIPTOR *OptionalSecurityDescriptorArray,
  DWORD OptionalSecurityDescriptorCount,
  PAUTHZ_ACCESS_REPLY pReply
);

Parameters

hAuthzClientContext
[in] Client context to perform the SACL evaluation against.
pRequest
[in] Pointer to the requested structure.
hAuditInfo
[in] Handle to the audit that may be generated.
pSecurityDescriptor
[in] Pointer to a security descriptor.
OptionalSecurityDescriptorArray
[in] Optional array of security descriptors.
OptionalSecurityDescriptorCount
[in] Size of optional security descriptor array.
pReply
[in] Pointer to the reply structure.

Return Values

Returns nonzero (TRUE ) if successful or zero (FALSE ) if it fails. GetLastError returns an error code indicating the reason for a failure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


BuildSecurityDescriptor

The BuildSecurityDescriptor function allocates and initializes a new security descriptor. A security descriptor is an opaque structure that contains the security information associated with an object. The function can initialize the new security descriptor by merging specified security information with the information in an existing security descriptor. If you don't specify an existing security descriptor, the function initializes a new security descriptor based on the specified security information.

BuildSecurityDescriptor creates a self-relative security descriptor, which means that the security descriptor stores a SECURITY_DESCRIPTOR structure and associated security information in a contiguous block of memory. The self-relative format makes the security descriptor suitable for storing in a stream.

DWORD BuildSecurityDescriptor(
  PTRUSTEE pOwner,                       // owner for new SD
  PTRUSTEE pGroup,                       // group for new SD
  ULONG cCountOfAccessEntries,           // count of access-control entries
  PEXPLICIT_ACCESS pListOfAccessEntries, // access-control entries
  ULONG cCountOfAuditEntries,            // count of audit-control entries
  PEXPLICIT_ACCESS pListOfAuditEntries,  // audit-control entries
  PSECURITY_DESCRIPTOR pOldSD,           // existing SD
  PULONG pSizeNewSD,                     // size of new SD
  PSECURITY_DESCRIPTOR * pNewSD          // new SD
);

Parameters

pOwner
[in] Pointer to a TRUSTEE structure that identifies the owner for the new security descriptor. If the structure uses the TRUSTEE_IS_NAME form, BuildSecurityDescriptor looks up the SID associated with the specified trustee name.

If this parameter is NULL, the function uses the owner SID from the original security descriptor pointed to by pOldSD. If pOldSD is NULL, or if the owner SID in pOldSD is NULL, the owner SID is NULL in the new security descriptor.

pGroup
[in] Pointer to a TRUSTEE structure that identifies the primary group SID for the new security descriptor. If the structure uses the TRUSTEE_IS_NAME form, BuildSecurityDescriptor looks up the SID associated with the specified trustee name.

If this parameter is NULL, the function uses the group SID from the original security descriptor pointed to by pOldSD. If pOldSD is NULL, or if the group SID in pOldSD is NULL, the group SID is NULL in the new security descriptor.

cCountOfAccessEntries
[in] Specifies the number of EXPLICIT_ACCESS structures in the pListOfAccessEntries array.
pListOfAccessEntries
[in] Pointer to an array of EXPLICIT_ACCESS structures that describe access control information for the DACL of the new security descriptor. The function creates the new DACL by merging the information in the array with the DACL in pOldSD, if any. If pOldSD is NULL, or if the DACL in pOldSD is NULL, the function creates a new DACL based solely on the information in the array. For a description of the rules for creating an ACL from an array of EXPLICIT_ACCESS structures, see the SetEntriesInAcl function.

If pListOfAccessEntries is NULL, the new security descriptor gets the DACL from pOldSD. In this case, if pOldSD is NULL, or if the DACL in pOldSD is NULL, the new DACL is NULL.

cCountOfAuditEntries
[in] Specifies the number of EXPLICIT_ACCESS structures in the pListOfAuditEntries array.
pListOfAuditEntries
[in] Pointer to an array of EXPLICIT_ACCESS structures that describe audit control information for the SACL of the new security descriptor. The function creates the new SACL by merging the information in the array with the SACL in pOldSD, if any. If pOldSD is NULL, or the SACL in pOldSD is NULL, the function creates a new SACL based solely on the information in the array.

If pListOfAuditEntries is NULL, the new security descriptor gets the SACL from pOldSD. In this case, if pOldSD is NULL, or the SACL in pOldSD is NULL, the new SACL is NULL.

pOldSD
[in] Pointer to an existing self-relative SECURITY_DESCRIPTOR structure and its associated security information. The function builds the new security descriptor by merging the specified owner, group, access-control, and audit-control information with the information in this security descriptor. This parameter can be NULL.
pSizeNewSD
[in] Pointer to a variable that receives the size, in bytes, of the security descriptor.
pNewSD
[in] Pointer to a variable that receives a pointer to the new security descriptor. The function allocates memory for the new security descriptor. You must call the LocalFree function to free the returned buffer.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H.

Remarks

The BuildSecurityDescriptor function is intended for trusted servers that implement or expose security on their own objects. The function uses self-relative security descriptors suitable for serializing into a stream and storing to disk, as a trusted server might require.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Aclapi.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, ACL, EXPLICIT_ACCESS, LocalFree, SECURITY_DESCRIPTOR, SetEntriesInAcl, SID, TRUSTEE


ConvertToAutoInheritPrivateObjectSecurity

The ConvertToAutoInheritPrivateObjectSecurity function converts a security descriptor and its ACLs to a format that supports automatic propagation of inheritable ACEs.

BOOL ConvertToAutoInheritPrivateObjectSecurity(
  PSECURITY_DESCRIPTOR ParentDescriptor,          // SD of parent
  PSECURITY_DESCRIPTOR CurrentSecurityDescriptor, // object SD
  PSECURITY_DESCRIPTOR *NewSecurityDescriptor,    // new SD
  GUID *ObjectType,                               // object type
  BOOLEAN IsDirectoryObject,                      // container status
  PGENERIC_MAPPING GenericMapping                 // mapping
);

Parameters

ParentDescriptor
[in] Pointer to the security descriptor for the parent container of the object. If there is no parent container, this parameter is NULL.
CurrentSecurityDescriptor
[in] Pointer to the current security descriptor of the object.
NewSecurityDescriptor
[out] Pointer to a variable that receives a pointer to the newly allocated self-relative security descriptor. It is the caller's responsibility to call the DestroyPrivateObjectSecurity function to free this security descriptor.
ObjectType
[in] Pointer to a GUID structure that identifies the type of object associated with CurrentSecurityDescriptor. Set ObjectType to NULL if the object does not have a GUID.
IsDirectoryObject
[in] Specifies whether the new object can contain other objects. A value of TRUE indicates that the new object is a container. A value of FALSE indicates that the new object is not a container.
GenericMapping
[in] Pointer to a GENERIC_MAPPING structure that specifies the mapping from each generic right to specific rights for the object.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The ConvertToAutoInheritPrivateObjectSecurity function attempts to determine whether the ACEs in the DACL and SACL of the current security descriptor were inherited from the parent security descriptor. The function passes the ParentDescriptor parameter to the CreatePrivateObjectSecurityEx function to get ACLs that contain only inherited ACEs. Then it compares these ACEs to the ACEs in the original security descriptor to determine which of the original ACEs were inherited. The ACEs do not need to match one-to-one. For instance, an ACE that allows read and write access to a trustee can be equivalent to two ACEs: an ACE that allows read access and an ACE that allows write access.

Any ACEs in the original security descriptor that are equivalent to the ACEs inherited from the parent security descriptor are marked with the INHERITED_ACE flag and added to the new security descriptor. All other ACEs in the original security descriptor are added to the new security descriptor as noninherited ACEs.

If the original DACL does not have any inherited ACEs, the function sets the SE_DACL_PROTECTED flag in the control bits of the new security descriptor. Similarly, the SE_SACL_PROTECTED flag is set if none of the ACEs in the SACL is inherited.

For DACLs that have inherited ACEs, the function reorders the ACEs into two groups. The first group has ACEs that were directly applied to the object. The second group has inherited ACEs. This ordering ensures that noninherited ACEs have precedence over inherited ACEs. For more information, see Order of ACEs in a DACL.

The function sets the SE_DACL_AUTO_INHERITED and SE_SACL_AUTO_INHERITED flags in the control bits of the new security descriptor.

The function does not change the ordering of access-allowed ACEs in relation to access-denied ACEs in the DACL, because to do so would change the semantics of the resulting security descriptor. If the function cannot convert the DACL without changing the semantics, it leaves the DACL unchanged and sets the SE_DACL_PROTECTED flag.

The new security descriptor has the same owner and primary group as the original security descriptor.

The new security descriptor is equivalent to the original security descriptor, so the caller needs no access rights or privileges to update the security descriptor to the new format.

This function works with ACL_REVISION and ACL_REVISION_DS ACLs.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, CreatePrivateObjectSecurityEx, GENERIC_MAPPING


CreatePrivateObjectSecurity

The CreatePrivateObjectSecurity function allocates and initializes a self-relative security descriptor for a new private object. A protected server calls this function when it creates a new private object.

To specify the object type GUID of the new object or control how ACEs are inherited, use the CreatePrivateObjectSecurityEx function.

BOOL CreatePrivateObjectSecurity(
  PSECURITY_DESCRIPTOR ParentDescriptor,  // parent directory SD
  PSECURITY_DESCRIPTOR CreatorDescriptor, // creator SD
  PSECURITY_DESCRIPTOR *NewDescriptor,    // new SD
  BOOL IsDirectoryObject,                 // container
  HANDLE Token,                           // handle to access token
  PGENERIC_MAPPING GenericMapping         // mapping
);

Parameters

ParentDescriptor
[in] Pointer to the security descriptor for the parent directory in which a new object is being created. If there is no parent directory, this parameter can be NULL.
CreatorDescriptor
[in] Pointer to a security descriptor provided by the creator of the object. If the object's creator does not explicitly pass security information for the new object, this parameter is intended to be NULL.
NewDescriptor
[out] Pointer to a variable that receives a pointer to the newly allocated self-relative security descriptor. The caller must call the DestroyPrivateObjectSecurity function to free this security descriptor.
IsDirectoryObject
[in] Specifies whether the new object is a container. A value of TRUE indicates the object contains other objects, such as a directory.
Token
[in] Handle to the access token for the client process on whose behalf the object is being created. If this is an impersonation token, it must be at SecurityIdentification level or higher. For a full description of the SecurityIdentification impersonation level, see the SECURITY_IMPERSONATION_LEVEL enumerated type.

A client token is used to retrieve default security information for the new object, such as its default owner, primary group, and discretionary access-control list. The token must be open for TOKEN_QUERY access.

GenericMapping
[in] Pointer to a GENERIC_MAPPING structure that specifies the mapping from each generic right to specific rights for the object.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If a system access-control list, or SACL, is specified in the SECURITY_DESCRIPTOR specified by the CreatorDescriptor parameter, the Token parameter must have the SE_SECURITY_NAME privilege enabled. The CreatePrivateObjectSecurity function checks this privilege and may generate audits during the process.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, CreatePrivateObjectSecurityEx, DestroyPrivateObjectSecurity, GENERIC_MAPPING, GetPrivateObjectSecurity, GetTokenInformation, OpenProcessToken, SECURITY_DESCRIPTOR, SECURITY_IMPERSONATION_LEVEL, SetPrivateObjectSecurity


CreatePrivateObjectSecurityEx

The CreatePrivateObjectSecurityEx function allocates and initializes a self-relative security descriptor for a new private object created by the resource manager calling this function.

BOOL CreatePrivateObjectSecurityEx(
  PSECURITY_DESCRIPTOR ParentDescriptor,  // parent object SD
  PSECURITY_DESCRIPTOR CreatorDescriptor, // SD of object
  PSECURITY_DESCRIPTOR *NewDescriptor,    // new SD
  GUID *ObjectType,                       // object type
  BOOL IsContainerObject,                 // container status
  ULONG AutoInheritFlags,                 // inheritance options
  HANDLE Token,                           // handle to access token
  PGENERIC_MAPPING GenericMapping         // mapping options
);

Parameters

ParentDescriptor
[in] Pointer to the security descriptor for the parent container of the object. If there is no parent container, this parameter is NULL.
CreatorDescriptor
[in] Pointer to a security descriptor provided by the creator of the object. If the object's creator does not explicitly pass security information for the new object, this parameter can be NULL. Alternatively, this parameter can point to a default security descriptor.
NewDescriptor
[out] Pointer to a variable that receives a pointer to the newly allocated self-relative security descriptor. The caller must call the DestroyPrivateObjectSecurity function to free this security descriptor.
ObjectType
[in] Pointer to a GUID structure that identifies the type of object associated with CurrentSecurityDescriptor. Set ObjectType to NULL if the object does not have a GUID.
IsContainerObject
[in] Specifies whether the new object can contain other objects. A value of TRUE indicates that the new object is a container. A value of FALSE indicates that the new object is not a container.
AutoInheritFlags
[in] A set of bit flags that control how ACEs are inherited from ParentDescriptor. This parameter can be a combination of the following values.
Value | Meaning
SEF_DACL_AUTO_INHERIT | If this flag is set, the new DACL contains ACEs inherited from the DACL of the ParentDescriptor, as well as any explicit ACEs specified in the DACL of the CreatorDescriptor. If this flag is not set, the new DACL does not inherit ACEs.
SEF_SACL_AUTO_INHERIT | If this flag is set, the new SACL contains ACEs inherited from the SACL of the ParentDescriptor, as well as any explicit ACEs specified in the SACL of the CreatorDescriptor. If this flag is not set, the new SACL does not inherit ACEs.
SEF_DEFAULT_DESCRIPTOR_FOR_OBJECT | If this flag is set, the CreatorDescriptor is the default descriptor for the type of object specified by ObjectType. As such, the CreatorDescriptor is ignored if the ParentDescriptor has any object-specific ACEs for the type of object specified by the ObjectType-parameter. If no such ACEs are inherited, the CreatorDescriptor is handled as though this flag were not specified.
SEF_AVOID_PRIVILEGE_CHECK | If this flag is set, the function does not perform privilege checking. If the SEF_AVOID_OWNER_CHECK flag is also set, the Token parameter can be NULL. This flag is useful while implementing automatic inheritance to avoid checking privileges on each child updated.
SEF_AVOID_OWNER_CHECK | If this flag is set, the function does not check the validity of the owner in the resultant NewDescriptor as described in Remarks below. If the SEF_AVOID_PRIVILEGE_CHECK flag is also set, the Token parameter can be NULL.
SEF_DEFAULT_OWNER_FROM_PARENT | If this flag is set, the owner of NewDescriptor defaults to the owner from ParentDescriptor. If not set, the owner of NewDescriptor defaults to the owner of the token specified by the Token parameter. The owner of the token is specified in the token itself. In either case, if the CreatorDescriptor parameter is not NULL, the NewDescriptor owner is set to the owner from CreatorDescriptor.
SEF_DEFAULT_GROUP_FROM_PARENT | If this flag is set, the group of NewDescriptor defaults to the group from ParentDescriptor. If not set, the group of NewDescriptor defaults to the group of the token specified by the Token parameter. The group of the token is specified in the token itself. In either case, if the CreatorDescriptor parameter is not NULL, the NewDescriptor group is set to the group from CreatorDescriptor.

Token
[in] Handle to the access token for the client process on whose behalf the object is being created. If this is an impersonation token, it must be at SecurityIdentification level or higher. For a full description of the SecurityIdentification impersonation level, see the SECURITY_IMPERSONATION_LEVEL enumerated type.

The client token contains default security information, such as the default owner, primary group, and DACL. The function uses these defaults if the information is not in the input security descriptors. The token must be open for TOKEN_QUERY access.

GenericMapping
[in] Pointer to a GENERIC_MAPPING structure that specifies the mapping from each generic right to specific rights for the object.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. Some of the extended error codes and their meanings are listed in the following table.

Error code | Meaning
ERROR_INVALID_PRIMARY_GROUP | The function cannot retrieve a primary group for the new SD.
ERROR_INVALID_OWNER | The function cannot retrieve an owner for the new SD or the SID cannot be assigned as an owner. This occurs when validating the owner SID against the passed-in token.
ERROR_NO_TOKEN | The function received NULL instead of a token for owner validation or privilege checking.
ERROR_PRIVILEGE_NOT_HELD | A SACL is being set, SEF_AVOID_PRIVILEGE_CHECK was not passed in, and the token passed in did not have SE_SECURITY_NAME enabled.

Remarks

The CreatePrivateObjectSecurity function is identical to calling the CreatePrivateObjectSecurityEx function with ObjectType set to NULL and AutoInheritFlags set to zero.

The AutoInheritFlags parameter is distinct from the similarly named bits in the Control member of the SECURITY_DESCRIPTOR structure. For an explanation of the control bits, see SECURITY_DESCRIPTOR_CONTROL.

If AutoInheritFlags specifies the SEF_DACL_AUTO_INHERIT bit, the function applies the following rules to the DACL in the new security descriptor:

  • The SE_DACL_AUTO_INHERITED flag is set in the Control member of the new security descriptor.
  • The DACL of the new security descriptor inherits ACEs from the ParentDescriptor regardless of whether CreatorDescriptor is the default security descriptor or was explicitly specified by the creator. The new DACL is a combination of the parent and creator DACLs as defined by the rules of inheritance.
  • Inherited ACEs are marked as INHERITED_ACE.

If AutoInheritFlags specifies the SEF_SACL_AUTO_INHERIT bit, the function applies similar rules to the new SACL.

For both DACLs and SACLs, certain types of ACEs in ParentDescriptor and CreatorDescriptor will be manipulated and possibly replaced by two ACEs in NewDescriptor. Specifically, an inheritable ACE that contains at least one of the following mappable elements may result in two ACEs in the output security descriptor. Mappable elements include:

  • Generic access rights in the ACCESS_MASK
  • Creator Owner SID or Creator Group SID as the ACE subject identifier

ACEs with either of the mappable elements mentioned above will result in the following ACEs in NewDescriptor:

  • An ACE that is a copy of the original, but with the INHERIT_ONLY flag set. Exception: this ACE will not be created if either of the following two conditions exist:
    • IsContainerObject is FALSE. Inheritable ACEs are meaningless on non-container objects.
    • The original ACE contains the NO_PROPAGATE_INHERIT flag. The original ACE is intended to be inherited as an effective ACE on children, but not inheritable below those children.
  • An effective ACE in which the INHERITED_ACE bit is turned on and the generic elements are mapped to specific elements, including:
    • Generic access rights are replaced by the corresponding standard and specific access rights indicated in the input GenericMapping.
    • Creator Owner SID is replaced with the Owner in the resultant NewDescriptor.
    • Creator Group SID is replaced with the Group in the resultant NewDescriptor.

If AutoInheritFlags does not specify the SEF_AVOID_OWNER_CHECK bit, owner validity checking is performed. The Owner in the resultant NewDescriptor must be a legally formed SID, and either must match the TokenUser in Token, or match a group in the TokenGroups in Token where the attributes on the group must include SE_GROUP_OWNER, and must not include SE_GROUP_USE_FOR_DENY_ONLY.

Callers that do not have access to the token of the client that will ultimately be setting the owner may choose to skip owner validation checking.

To create a security descriptor for a new object, call CreatePrivateObjectSecurityEx with ParentDescriptor set to the security descriptor of the parent container and CreatorDescriptor set to the security descriptor proposed by the creator of the object.

To verify the current security descriptor on an object, call CreatePrivateObjectSecurityEx with ParentDescriptor set to the security descriptor of the parent container and CreatorDescriptor set to the current security descriptor of the object. This call ensures that the ACEs are appropriately inherited from parent to child security descriptors.

If the CreatorDescriptor security descriptor contains a SACL, Token must have the SE_SECURITY_NAME privilege enabled or the caller must specify the SEF_AVOID_PRIVILEGE_CHECK flag in AutoInheritFlags.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, DestroyPrivateObjectSecurity, GENERIC_MAPPING, GetTokenInformation, OpenProcessToken, SECURITY_DESCRIPTOR, SECURITY_IMPERSONATION_LEVEL, SetPrivateObjectSecurityEx


CreatePrivateObjectSecurityWithMultipleInheritance

[This is preliminary documentation and subject to change.]

The CreatePrivateObjectSecurityWithMultipleInheritance function allocates and initializes a self-relative security descriptor for a new private object created by the resource manager calling this function. This function supports private objects (such as Directory Service objects with attached auxiliary classes) composed of multiple object types or classes.

BOOL CreatePrivateObjectSecurityWithMultipleInheritance(
  PSECURITY_DESCRIPTOR ParentDescriptor,
  PSECURITY_DESCRIPTOR CreatorDescriptor,
  PSECURITY_DESCRIPTOR *NewDescriptor,
  GUID **ObjectTypes,
  ULONG GuidCount,
  BOOL IsContainerObject,
  ULONG AutoInheritFlags,
  HANDLE Token,
  PGENERIC_MAPPING GenericMapping
);

Parameters

ParentDescriptor
[in] Pointer to the security descriptor (SD) for the parent container of the object. If there is no parent container, this parameter is NULL.
CreatorDescriptor
[in] Pointer to a security descriptor (SD) provided by the creator of the object. If the object's creator does not explicitly pass security information for the new object, this parameter can be NULL. Alternatively, this parameter can point to a default security descriptor.
NewDescriptor
[out] Pointer to a variable to receive a pointer to the newly allocated self-relative security descriptor. The caller must call the DestroyPrivateObjectSecurity function to free this security descriptor.
ObjectTypes
[in] Array of pointers to GUID structures that identify the object types or classes of the object associated with CurrentSecurityDescriptor. For Active Directory objects, this array contains pointers to the class GUIDs of the object's structural class and all attached auxiliary classes. Set ObjectTypes to NULL if the object does not have a GUID.
GuidCount
Number of GUIDs present in the ObjectTypes parameter.
IsContainerObject
[in] Specifies whether the new object can contain other objects. A value of TRUE indicates that the new object is a container. A value of FALSE indicates that the new object is not a container.
AutoInheritFlags
[in] A set of bit flags that control how ACEs are inherited from ParentDescriptor. This parameter can be a combination of the following values.
Value | Meaning
SEF_DACL_AUTO_INHERIT | If this flag is set, the new DACL contains ACEs inherited from the DACL of the ParentDescriptor, as well as any explicit ACEs specified in the DACL of the CreatorDescriptor. If this flag is not set, the new DACL does not inherit ACEs.
SEF_SACL_AUTO_INHERIT | If this flag is set, the new SACL contains ACEs inherited from the SACL of the ParentDescriptor, as well as any explicit ACEs specified in the SACL of the CreatorDescriptor. If this flag is not set, the new SACL does not inherit ACEs.
SEF_DEFAULT_DESCRIPTOR_FOR_OBJECT | If this flag is set, the CreatorDescriptor is the default descriptor for the types of objects specified by ObjectTypes. As such, the CreatorDescriptor is ignored if the ParentDescriptor has any object-specific ACEs for the types of objects specified by the ObjectTypes-parameter. If no such ACEs are inherited, the CreatorDescriptor is handled as though this flag were not specified.
SEF_AVOID_PRIVILEGE_CHECK | If this flag is set, the function does not perform privilege checking. If the SEF_AVOID_OWNER_CHECK flag is also set, the Token parameter can be NULL. This flag is useful while implementing automatic inheritance to avoid checking privileges on each child updated.
SEF_AVOID_OWNER_CHECK | If this flag is set, the function does not check the validity of the owner in the resultant NewDescriptor as described in Remarks below. If the SEF_AVOID_PRIVILEGE_CHECK flag is also set, the Token parameter can be NULL.
SEF_DEFAULT_OWNER_FROM_PARENT | If this flag is set, the owner of NewDescriptor defaults to the owner from ParentDescriptor. If not set, the owner of NewDescriptor defaults to the owner of the token specified by the Token parameter. The owner of the token is specified in the token itself. In either case, if the CreatorDescriptor parameter is not NULL, the NewDescriptor owner is set to the owner from CreatorDescriptor.
SEF_DEFAULT_GROUP_FROM_PARENT | If this flag is set, the group of NewDescriptor defaults to the group from ParentDescriptor. If not set, the group of NewDescriptor defaults to the group of the token specified by the Token parameter. The group of the token is specified in the token itself. In either case, if the CreatorDescriptor parameter is not NULL, the NewDescriptor group is set to the group from CreatorDescriptor.

Token
[in] Handle to the access token for the client process on whose behalf the object is being created. If this is an impersonation token, it must be at SecurityIdentification level or higher. For a full description of the SecurityIdentification impersonation level, see the SECURITY_IMPERSONATION_LEVEL enumerated type.

The client token contains default security information, such as the default owner, primary group, and DACL. The function uses these defaults if the information is not in the input security descriptors. The token must be open for TOKEN_QUERY access.

GenericMapping
[in] Pointer to a GENERIC_MAPPING structure that specifies the mapping from each generic right to specific rights for the object.

Return Values

This function returns a non-zero value If the function succeeds and zero if the function fails. Call GetLastError for extended error information. Some extended error codes and their meanings are listed in the following table.

Error code | Meaning
ERROR_INVALID_PRIMARY_GROUP | The function cannot retrieve a primary group for the new SD.
ERROR_INVALID_OWNER | The function cannot retrieve an owner for the new SD or the SID cannot be assigned as an owner. This occurs when validating the owner SID against the passed-in token.
ERROR_NO_TOKEN | The function received NULL instead of a token for owner validation or privilege checking.
ERROR_PRIVILEGE_NOT_HELD | A SACL is being set, SEF_AVOID_PRIVILEGE_CHECK was not passed in, and the token passed in did not have SE_SECURITY_NAME enabled.

Remarks

The CreatePrivateObjectSecurityEx function is identical to calling the CreatePrivateObjectSecurityWithMultipleInheritance function with a single GUID in ObjectTypes.

The AutoInheritFlags are distinct from the similarly named bits in the Control member of the SECURITY_DESCRIPTOR structure. For an explanation of the control bits, see SECURITY_DESCRIPTOR_CONTROL.

If AutoInheritFlags specifies the SEF_DACL_AUTO_INHERIT bit, the function applies the following rules to the DACL in the new security descriptor:

  • The SE_DACL_AUTO_INHERITED flag is set in the Control member of the new security descriptor.
  • The DACL of the new security descriptor inherits ACEs from the ParentDescriptor regardless of whether CreatorDescriptor is the default security descriptor or was explicitly specified by the creator. The new DACL is a combination of the parent and creator DACLs as defined by the rules of inheritance. Specifically, any ACEs in ParentDescriptor that are inheritable either to all child objects or to any object class listed in ObjectTypes, will be applied to the new DACL.
  • Inherited ACEs are marked as INHERITED_ACE.

If AutoInheritFlags specifies the SEF_SACL_AUTO_INHERIT bit, the function applies similar rules to the new SACL.

For both DACLs and SACLs, certain types of ACEs in ParentDescriptor and CreatorDescriptor will be manipulated and possibly replaced by two ACEs in NewDescriptor. Specifically, an inheritable ACE that contains at least one of the following mappable elements may result in two ACEs in the output security descriptor. Mappable elements include:

  • Generic access rights in the ACCESS_MASK,
  • Creator Owner SID or Creator Group SID as the ACE subject identifier

ACEs with any of these mappable elements will result in the following two ACEs in NewDescriptor:

  • An ACE that is a copy of the original, but with the INHERIT_ONLY flag set. Exception: this ACE will not be created if either of the following two conditions exist:
    • IsContainerObject is FALSE. Inheritable ACEs are meaningless on non-container objects.
    • The original ACE contains the NO_PROPAGATE_INHERIT flag. The original ACE is intended to be inherited as an effective ACE on children, but not inheritable below those children.
  • An effective ACE in which the INHERITED_ACE bit is turned on and the generic elements are mapped to specific elements:
    • Generic access rights are replaced by the corresponding standard and specific access rights indicated in the input GenericMapping.
    • Creator Owner SID is replaced with the Owner in the resultant NewDescriptor.
    • Creator Group SID is replaced with the Group in the resultant NewDescriptor.

If AutoInheritFlags does not specify the SEF_AVOID_OWNER_CHECK bit, owner validity checking is performed according to the following rules. The Owner in the resultant NewDescriptor:

  • Must be a legally formed SID, and
  • Either must match the TokenUser in Token,
  • Or must match a group in the TokenGroups in Token where the attributes on the group:
    • must include SE_GROUP_OWNER, and
    • must not include SE_GROUP_USE_FOR_DENY_ONLY

Callers that do not have access to the token of the client that will ultimately be setting the owner may choose to skip owner validation checking.

To create a security descriptor for a new object, call CreatePrivateObjectSecurityWithMultipleInheritance with ParentDescriptor set to the security descriptor of the parent container and CreatorDescriptor set to the security descriptor proposed by the creator of the object.

To verify the current security descriptor on an object, call CreatePrivateObjectSecurityWithMultipleInheritance with ParentDescriptor set to the security descriptor of the parent container and CreatorDescriptor set to the current security descriptor of the object. This call ensures that the ACEs are appropriately inherited from parent to child security descriptors.

If the CreatorDescriptor security descriptor contains a SACL, Token must have the SE_SECURITY_NAME privilege enabled or the caller must specify the SEF_AVOID_PRIVILEGE_CHECK flag in AutoInheritFlags.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.


DestroyPrivateObjectSecurity

The DestroyPrivateObjectSecurity function deletes a private object's security descriptor.

BOOL DestroyPrivateObjectSecurity(
  PSECURITY_DESCRIPTOR *ObjectDescriptor   // SD
);

Parameters

ObjectDescriptor
[in, out] Pointer to a pointer to the SECURITY_DESCRIPTOR structure to be deleted. This security descriptor must have been created by a call to the CreatePrivateObjectSecurity function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, CreatePrivateObjectSecurity, GetPrivateObjectSecurity, SECURITY_DESCRIPTOR, SetPrivateObjectSecurity


GetPrivateObjectSecurity

The GetPrivateObjectSecurity retrieves information from a private object's security descriptor.

BOOL GetPrivateObjectSecurity(
  PSECURITY_DESCRIPTOR ObjectDescriptor,    // SD
  SECURITY_INFORMATION SecurityInformation, // requested info type
  PSECURITY_DESCRIPTOR ResultantDescriptor, // requested SD info
  DWORD DescriptorLength,                   // size of SD buffer
  PDWORD ReturnLength                       // required buffer size
);

Parameters

ObjectDescriptor
[in] Pointer to a SECURITY_DESCRIPTOR structure. This is the security descriptor to be queried.
SecurityInformation
[in] A set of bit flags that indicate the parts of the security descriptor to retrieve. This value can be a combination of the SECURITY_INFORMATION bit flags.
ResultantDescriptor
[out] Pointer to a buffer that receives a copy of the requested information from the specified security descriptor. The SECURITY_DESCRIPTOR structure is returned in self-relative format.
DescriptorLength
[in] Specifies the size, in bytes, of the buffer pointed to by the ResultantDescriptor parameter.
ReturnLength
[out] Pointer to a variable the function sets to zero if the descriptor is copied successfully. If the buffer is too small for the security descriptor, this variable receives the number of bytes required. If this variable's value is greater than the value of the DescriptorLength parameter when the function returns, the function returns FALSE and none of the security descriptor is copied to the buffer.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

An application must perform appropriate access/privilege checks and audits before calling this function.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, CreatePrivateObjectSecurity, DestroyPrivateObjectSecurity, GetFileSecurity, GetKernelObjectSecurity, GetUserObjectSecurity, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetPrivateObjectSecurity


ImpersonateLoggedOnUser

The ImpersonateLoggedOnUser function lets the calling thread impersonate the security context of a logged-on user. The user is represented by a token handle.

BOOL ImpersonateLoggedOnUser(
  HANDLE hToken  // handle to token for logged-on user
);

Parameters

hToken
[in] Handle to a primary or impersonation access token that represents a logged-on user. This can be a token handle returned by a call to LogonUser, CreateRestrictedToken, DuplicateToken, DuplicateTokenEx, OpenProcessToken, or OpenThreadToken functions. If hToken is a primary token, it must have TOKEN_QUERY and TOKEN_DUPLICATE access. If hToken is an impersonation token, it must have TOKEN_QUERY access.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The impersonation lasts until the thread exits or until it calls RevertToSelf.

The calling thread does not need to have any particular privileges to call ImpersonateLoggedOnUser.

For more information about impersonation, see Client Impersonation.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, CreateProcessAsUser, CreateRestrictedToken, DuplicateToken, DuplicateTokenEx, LogonUser, OpenProcessToken, or OpenThreadToken, RevertToSelf


ImpersonateNamedPipeClient

The ImpersonateNamedPipeClient function impersonates a named-pipe client application.

BOOL ImpersonateNamedPipeClient(
  HANDLE hNamedPipe   // handle to named pipe
);

Parameters

hNamedPipe
[in] Handle to a named pipe.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The ImpersonateNamedPipeClient function allows the server end of a named pipe to impersonate the client end. When this function is called, the named-pipe file system changes the thread of the calling process to start impersonating the security context of the last message read from the pipe. Only the server end of the pipe can call this function.

The server can call the RevertToSelf function when the impersonation is complete.

Warning If the ImpersonateNamedPipeClient function fails, the client is not impersonated, and all subsequent client requests are made in the security context of the process that called the function. If the calling process is running as a privileged account, it can perform actions that the client would not be allowed to perform. To avoid security risks, the calling process should always check the return value. If the return value indicates that the function call failed, no client requests should be executed.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, DdeImpersonateClient, DuplicateToken, RevertToSelf


ImpersonateSelf

The ImpersonateSelf function obtains an access token that impersonates the security context of the calling process. The token is assigned to the calling thread.

BOOL ImpersonateSelf(
  SECURITY_IMPERSONATION_LEVEL ImpersonationLevel // impersonation level
);

Parameters

ImpersonationLevel
[in] Specifies a SECURITY_IMPERSONATION_LEVEL enumerated type that supplies the impersonation level of the new token.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The ImpersonateSelf function is used for tasks, such as enabling a privilege for a single thread rather than for the entire process or for changing the default discretionary access-control list for a single thread.

The server can call the RevertToSelf function when the impersonation is complete.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, DuplicateToken, ImpersonateNamedPipeClient, RevertToSelf, SECURITY_IMPERSONATION_LEVEL


LogonUser

The LogonUser function attempts to log a user on to the local computer, that is, to the computer from which LogonUser was called. You cannot use LogonUser to log on to a remote computer. You specify the user with a user name and domain, and authenticate the user with a clear-text password. If the function succeeds, you receive a handle to a token that represents the logged-on user. You can then use this token handle to impersonate the specified user, or in most cases, to create a process running in the context of the specified user.

BOOL LogonUser(
  LPTSTR lpszUsername,    // user name
  LPTSTR lpszDomain,      // domain or server
  LPTSTR lpszPassword,    // password
  DWORD dwLogonType,      // type of logon operation
  DWORD dwLogonProvider,  // logon provider
  PHANDLE phToken         // receive tokens handle
);

Parameters

lpszUsername
[in] Pointer to a null-terminated string that specifies the user name. This is the name of the user account to log on to.
lpszDomain
[in] Pointer to a null-terminated string that specifies the name of the domain or server whose account database contains the lpszUserName account. LogonUser asks the domain controller or server to search for and validate the account. If this parameter is ".", LogonUser validates the account using only the local account database.

Windows 2000 or later: If this parameter is NULL, LogonUser attempts to validate the account using the local account database. If LogonUser cannot find the account in the local account database, its trusted domains search their account databases until a match is found. Note that if the security provider is LOGON32_PROVIDER_WINNT50, this parameter cannot be NULL unless you specify the user name in UPN format.

lpszPassword
[in] Pointer to a null-terminated string that specifies the clear-text password for the user account specified by lpszUsername.
dwLogonType
[in] Specifies the type of logon operation to perform. This parameter can be one of the following values.
Value | Meaning
LOGON32_LOGON_BATCH | This logon type is intended for batch servers, where processes may be executing on behalf of a user without their direct intervention; or for higher performance servers that process many clear-text authentication attempts at a time, such as mail or web servers. LogonUser does not cache credentials for this logon type.
LOGON32_LOGON_INTERACTIVE | This logon type is intended for users who will be interactively using the machine, such as a user being logged on by a terminal server, remote shell, or similar process. This logon type has the additional expense of caching logon information for disconnected operation, and is therefore inappropriate for some client/server applications, such as a mail server.
LOGON32_LOGON_NETWORK | This logon type is intended for high performance servers to authenticate clear text passwords. LogonUser does not cache credentials for this logon type.
LOGON32_LOGON_NETWORK_CLEARTEXT | Windows 2000 or later: This logon type preserves the name and password in the authentication packages, allowing the server to make connections to other network servers while impersonating the client. This allows a server to accept clear text credentials from a client, call LogonUser, verify that the user can access the system across the network, and still communicate with other servers.
LOGON32_LOGON_NEW_CREDENTIALS Windows 2000 or later: This logon type allows the caller to clone its current token and specify new credentials for outbound connections. The new logon session has the same local identify, but uses different credentials for other network connections.

This logon type is supported only by the LOGON32_PROVIDER_WINNT50 logon provider.

LOGON32_LOGON_SERVICE | Indicates a service-type logon. The account provided must have the service privilege enabled.
LOGON32_LOGON_UNLOCK | This logon type is intended for GINA DLLs logging on users who will be interactively using the machine. This logon type allows a unique audit record to be generated that shows when the workstation was unlocked.

dwLogonProvider
[in] Specifies the logon provider. This parameter can be one of the following values.
Value | Meaning
LOGON32_PROVIDER_DEFAULT Use the standard logon provider for the system. This is the recommended value for the dwLogonProvider parameter. It provides maximum compatibility with current and future releases of Windows NT/Windows 2000.

If you do not specify a domain name, you must specify the user name in UPN format, or the default security provider is NTLM.

LOGON32_PROVIDER_WINNT50 | Windows 2000 or later: Use the Windows 2000 logon provider.
LOGON32_PROVIDER_WINNT40 | Use the Windows NT 4.0 logon provider.
LOGON32_PROVIDER_WINNT35 | Use the Windows NT 3.5 logon provider.

phToken
[out] Pointer to a HANDLE variable that receives a handle to a token that represents the specified user.

You can use the returned handle in calls to the ImpersonateLoggedOnUser function.

In most cases, the returned handle is a primary token that you can use in calls to the CreateProcessAsUser function. However, if you specify the LOGON32_LOGON_NETWORK flag, LogonUser returns an impersonation token that you cannot use in CreateProcessAsUser unless you call DuplicateTokenEx to convert it to a primary token.

When you no longer need this handle, close it by calling the CloseHandle function.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The LOGON32_LOGON_NETWORK logon type is the fastest, but there are two limitations. First, the function returns an impersonation token, not a primary token. You cannot use this token directly in the CreateProcessAsUser function. However, you can call the DuplicateTokenEx function to convert the token to a primary token, and then use it in CreateProcessAsUser. Second, if you convert the token to a primary token and use it in CreateProcessAsUser to start a process, the new process will not be able to access other network resources, such as remote servers or printers, through the redirector.

In Windows 2000, the process calling LogonUser requires the SE_TCB_NAME privilege. The privilege does not need to be enabled. The LogonUser function enables the privilege as necessary. If the calling process does not have this privilege, LogonUser fails and GetLastError returns ERROR_PRIVILEGE_NOT_HELD. Beginning with Whistler, this privilege is no longer required.

In some cases, the process that calls LogonUser must also have the SE_CHANGE_NOTIFY_NAME privilege enabled; otherwise, LogonUser fails and GetLastError returns ERROR_ACCESS_DENIED. This privilege is not required for the local system account or accounts that are members of the administrators group. By default, SE_CHANGE_NOTIFY_NAME is enabled for all users, but some administrators may disable it for everyone. For more information about privileges, see Privileges. Beginning with Whistler, this privilege is no longer required.

The account being logged on, that is, the account specified by lpszUsername, must have the necessary account rights. For example, to log on a user with the LOGON32_LOGON_INTERACTIVE flag, the user (or a group to which the user belongs) must have the SE_INTERACTIVE_LOGON_NAME account right. For a list of the account rights that affect the various logon operations, see Account Rights.

A user is considered logged on as long as at least one token exists. If you call CreateProcessAsUser and then close the token, the system considers the user as still logged on until the process (and all child processes) have ended.

If the LogonUser call is successful, the system notifies network providers that the logon occurred by calling the provider's NPLogonNotify entry-point function.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, CreateProcessAsUser, ImpersonateLoggedOnUser


LookupSecurityDescriptorParts

The LookupSecurityDescriptorParts function retrieves security information from a self-relative security descriptor.

DWORD LookupSecurityDescriptorParts(
  PTRUSTEE *pOwner,                       // owner SID from SD
  PTRUSTEE *pGroup,                       // group SID from SD
  PULONG cCountOfAccessEntries,           // number of access-control entries
  PEXPLICIT_ACCESS *pListOfAccessEntries, // DACL access-control array
  PULONG cCountOfAuditEntries,            // number of audit-control entries
  PEXPLICIT_ACCESS *pListOfAuditEntries,  // SACL audit-control array
  PSECURITY_DESCRIPTOR pSD                // self-relative SD
);

Parameters

pOwner
[out] Pointer to a variable that receives a pointer to a TRUSTEE structure. The function looks up the name associated with the owner SID in the pSD security descriptor, and returns a pointer to the name in the ptstrName member of the TRUSTEE structure. The function sets the TrusteeForm member to TRUSTEE_IS_NAME.

This parameter can be NULL if you are not interested in the name of the owner.

pGroup
[out] Pointer to a variable that receives a pointer to a TRUSTEE structure. The function looks up the name associated with the primary group SID of the security descriptor, and returns a pointer to the name in the ptstrName member of the TRUSTEE structure. The function sets the TrusteeForm member to TRUSTEE_IS_NAME.

This parameter can be NULL if you are not interested in the name of the group.

cCountOfAccessEntries
[out] Pointer to a ULONG that receives the number of EXPLICIT_ACCESS structures returned in the pListOfAccessEntries array. This parameter can be NULL only if the pListOfAccessEntries parameter is also NULL.
pListOfAccessEntries
[out] Pointer to a variable that receives a pointer to an array of EXPLICIT_ACCESS structures that describe the ACEs in the DACL of the security descriptor. The TRUSTEE structure in these EXPLICIT_ACCESS structures use the TRUSTEE_IS_NAME form. For a description of how an array of EXPLICIT_ACCESS structures describes the ACEs in an ACL, see the GetExplicitEntriesFromAcl function. If this parameter is NULL, the cCountOfAccessEntries parameter must also be NULL.
cCountOfAuditEntries
[out] Pointer to a ULONG that receives the number of EXPLICIT_ACCESS structures returned in the pListOfAuditEntries array. This parameter can be NULL only if the pListOfAuditEntries parameter is also NULL.
pListOfAuditEntries
[out] Pointer to a variable that receives a pointer to an array of EXPLICIT_ACCESS structures that describe the ACEs in the SACL of the security descriptor. The TRUSTEE structure in these EXPLICIT_ACCESS structures uses the TRUSTEE_IS_NAME form. If this parameter is NULL, the cCountOfAuditEntries parameter must also be NULL.
pSD
[in] Pointer to an existing self-relative security descriptor from which the function retrieves security information. A self-relative security descriptor stores a SECURITY_DESCRIPTOR structure and associated security information in a contiguous block of memory. This differs from an absolute security descriptor, which contains pointers to the associated security information.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H.

Remarks

The LookupSecurityDescriptorParts function retrieves the names of the owner and primary group of the security descriptor. It also returns descriptions of the access-control entries in the DACL and audit-control entries in the SACL of the security descriptor.

The parameters other than pSD can be NULL if you are not interested in the information. If you do not want information about the DACL, both pListOfAccessEntries and cCountOfAccessEntries must be NULL. If you do not want information about the SACL, both pListOfAuditEntries and cCountOfAuditEntries must be NULL. Similarly, if you do want DACL or SACL information, both of the corresponding parameters must be non-NULL.

You must call the LocalFree function to free any buffers returned by the pOwner, pGroup, pListOfAccessEntries, or pListOfAuditEntries parameters.

The LookupSecurityDescriptorParts function is intended for trusted servers that implement or expose security on their own objects. The function works with a self-relative security descriptor suitable for serializing into a stream and storing to disk, as a trusted server might require.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Aclapi.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, ACE, ACL, EXPLICIT_ACCESS, LocalFree, SECURITY_DESCRIPTOR, GetExplicitEntriesFromAcl, SID, TRUSTEE


MapGenericMask

The MapGenericMask function maps the generic access rights in an access mask to specific and standard access rights. The function applies a mapping supplied in a GENERIC_MAPPING structure.

VOID MapGenericMask(
  PDWORD AccessMask,               // access mask
  PGENERIC_MAPPING GenericMapping  // mapping
);

Parameters

AccessMask
[out] Pointer to an access mask receiving the specific and standard rights mapped from generic access rights.
GenericMapping
[in] Pointer to a GENERIC_MAPPING structure specifying a mapping of generic access types to specific and standard access types.

Return Values

This function does not return a value.

Remarks

After calling the MapGenericMask function, the access mask pointed to by the AccessMask parameter has none of its generic bits (GenericRead, GenericWrite, GenericExecute, or GenericAll) or undefined bits set, although it can have other bits set. If bits other than the generic bits are provided on input, this function does not clear them.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheck, AreAllAccessesGranted, AreAnyAccessesGranted, GENERIC_MAPPING


ObjectCloseAuditAlarm

The ObjectCloseAuditAlarm function generates an audit message in the security event log when a handle to a private object is deleted. Alarms are not currently supported.

BOOL ObjectCloseAuditAlarm(
  LPCTSTR SubsystemName, // subsystem name
  LPVOID HandleId,       // handle identifier
  BOOL GenerateOnClose   // audit generation
);

Parameters

SubsystemName
[in] Pointer to a null-terminated string specifying the name of the subsystem calling the function. This string appears in any audit message that the function generates.
HandleId
[in] A unique value representing the client's handle to the object. This should be the same value that was passed to the AccessCheckAndAuditAlarm or ObjectOpenAuditAlarm function.
GenerateOnClose
[in] Specifies a flag set by a call to the AccessCheckAndAuditAlarm or ObjectOpenAuditAlarm function when the object handle is created. If this flag is TRUE, the function generates an audit message. If it is FALSE, the function does not generate an audit message.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The ObjectCloseAuditAlarm function requires the calling application to have the SE_AUDIT_NAME privilege enabled. The test for this privilege is always performed against the primary token of the calling process, allowing the calling process to impersonate a client.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheckAndAuditAlarm, ObjectDeleteAuditAlarm, ObjectOpenAuditAlarm, ObjectPrivilegeAuditAlarm


ObjectDeleteAuditAlarm

The ObjectDeleteAuditAlarm function generates audit messages when an object is deleted. Alarms are not currently supported.

BOOL ObjectDeleteAuditAlarm(
  LPCTSTR SubsystemName, // subsystem name
  LPVOID HandleId,       // handle to the object
  BOOL GenerateOnClose   // audit generation
);

Parameters

SubsystemName
[in] Pointer to a null-terminated string specifying the name of the subsystem calling the function. This string appears in any audit message that the function generates.
HandleId
[in] Specifies a unique value representing the client's handle to the object. This should be the same value that was passed to the AccessCheckAndAuditAlarm or ObjectOpenAuditAlarm function.
GenerateOnClose
[in] Specifies a flag set by a call to the AccessCheckAndAuditAlarm or ObjectOpenAuditAlarm function when the object handle is created.

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The ObjectDeleteAuditAlarm function requires the calling application to have the SE_AUDIT_NAME privilege enabled. The test for this privilege is always performed against the primary token of the calling process, allowing the calling process to impersonate a client.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheck, AccessCheckAndAuditAlarm, AreAllAccessesGranted, AreAnyAccessesGranted, MapGenericMask, ObjectCloseAuditAlarm, ObjectOpenAuditAlarm, ObjectPrivilegeAuditAlarm, PrivilegeCheck, PrivilegedServiceAuditAlarm


ObjectOpenAuditAlarm

The ObjectOpenAuditAlarm function generates audit messages when a client application attempts to gain access to an object or to create a new one. Alarms are not currently supported.

BOOL ObjectOpenAuditAlarm(
  LPCTSTR SubsystemName,                    // subsystem name
  LPVOID HandleId,                          // handle to object
  LPTSTR ObjectTypeName,                    // object type
  LPTSTR ObjectName,                        // object name
  PSECURITY_DESCRIPTOR pSecurityDescriptor, // SD
  HANDLE ClientToken,                       // handle to access token
  DWORD DesiredAccess,                      // desired access rights
  DWORD GrantedAccess,                      // granted access rights
  PPRIVILEGE_SET Privileges,                // privileges
  BOOL ObjectCreation,                      // object creation option
  BOOL AccessGranted,                       // results
  LPBOOL GenerateOnClose                    // audit generation
);

Parameters

SubsystemName
[in] Pointer to a null-terminated string specifying the name of the subsystem calling the function. This string appears in any audit message that the function generates.
HandleId
[in] Pointer to a unique value representing the client's handle of the object. If the access is denied, this parameter is ignored.

Note For cross-platform compatibility, the value addressed by this pointer should be sizeof(LPVOID) bytes long.

ObjectTypeName
[in] Pointer to a null-terminated string specifying the type of object to which the client is requesting access. This string appears in any audit message that the function generates.
ObjectName
[in] Pointer to a null-terminated string specifying the name of the object to which the client is requesting access. This string appears in any audit message that the function generates.
pSecurityDescriptor
[in] Pointer to the SECURITY_DESCRIPTOR structure for the object being accessed.
ClientToken
[in] Identifies an access token representing the client requesting the operation. This handle must be obtained by opening the token of a thread impersonating the client. The token must be open for TOKEN_QUERY access.
DesiredAccess
[in] Specifies the desired access mask. This mask must have been previously mapped by the MapGenericMask function to contain no generic access rights.
GrantedAccess
[in] Specifies an access mask indicating which access rights are granted. This access mask is intended to be the same value set by one of the access-checking functions in its GrantedAccess parameter. Examples of access-checking functions include AccessCheckAndAuditAlarm and AccessCheck.
Privileges
[in] Pointer to a PRIVILEGE_SET structure that specifies the set of privileges required for the access attempt. This parameter can be NULL.
ObjectCreation
[in] Specifies a flag that determines whether the application creates a new object when access is granted. When this value is TRUE, the application creates a new object; when it is FALSE, the application opens an existing object.
AccessGranted
[in] Specifies a flag indicating whether access was granted or denied in a previous call to an access-checking function, such as AccessCheck. If access was granted, this value is TRUE. If not, it is FALSE.
GenerateOnClose
[out] Pointer to a flag set by the audit-generation routine when the function returns. This value must be passed to the ObjectCloseAuditAlarm function when the object handle is closed.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The ObjectOpenAuditAlarm function requires the calling application to have the SE_AUDIT_NAME privilege enabled. The test for this privilege is always performed against the primary token of the calling process, not the impersonation token of the thread. This allows the calling process to impersonate a client during the call.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheck, AccessCheckAndAuditAlarm, AreAllAccessesGranted, AreAnyAccessesGranted, MapGenericMask, ObjectCloseAuditAlarm, ObjectDeleteAuditAlarm, ObjectPrivilegeAuditAlarm, PrivilegeCheck, PrivilegedServiceAuditAlarm, PRIVILEGE_SET, SECURITY_DESCRIPTOR


ObjectPrivilegeAuditAlarm

The ObjectPrivilegeAuditAlarm function generates an audit message in the security event log. A protected server can use this function to log attempts by a client to use a specified set of privileges with an open handle to a private object. Alarms are not currently supported.

BOOL ObjectPrivilegeAuditAlarm(
  LPCTSTR SubsystemName,      // subsystem name
  LPVOID HandleId,            // handle identifier
  HANDLE ClientToken,         // handle to client's access token
  DWORD DesiredAccess,        // desired access rights
  PPRIVILEGE_SET Privileges,  // privileges
  BOOL AccessGranted          // results
);

Parameters

SubsystemName
[in] Pointer to a null-terminated string specifying the name of the subsystem calling the function. This string appears in the audit message.
HandleId
[in] Pointer to a unique value representing the client's handle to the object.
ClientToken
[in] Identifies an access token representing the client that requested the operation. This handle must have been obtained by opening the token of a thread impersonating the client. The token must be open for TOKEN_QUERY access. The function uses this token to get the identity of the client for the audit message.
DesiredAccess
[in] Specifies an access mask indicating the privileged access types being used or whose use is being attempted. The access mask can be mapped by the MapGenericMask function so it does not contain any generic access types.
Privileges
[in] Pointer to a PRIVILEGE_SET structure containing the privileges that the client attempted to use. The names of the privileges appear in the audit message.
AccessGranted
[in] Indicating whether the client's attempt to use the privileges was successful. If this value is TRUE, the audit message indicates success. If this value is FALSE, the audit message indicates failure.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The ObjectPrivilegeAuditAlarm function does not check the client's access to the object or check the client's access token to determine whether the privileges are held or enabled. Typically, you would call the PrivilegeCheck function to determine whether the specified privileges are enabled in the access token, call the AccessCheck function to check the client's access to the object, and then call ObjectPrivilegeAuditAlarm to log the results.

The ObjectPrivilegeAuditAlarm function requires the calling process to have SE_AUDIT_NAME privilege enabled. The test for this privilege is always performed against the primary token of the calling process, not the impersonation token of the thread. This allows the calling process to impersonate a client during the call.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AccessCheck, AccessCheckAndAuditAlarm, MapGenericMask, ObjectCloseAuditAlarm, ObjectOpenAuditAlarm, PrivilegeCheck, PrivilegedServiceAuditAlarm, PRIVILEGE_SET


PrivilegeCheck

The PrivilegeCheck function determines whether a specified set of privileges are enabled in an access token. PrivilegeCheck is typically called by a server application to check the privileges of a client's access token.

BOOL PrivilegeCheck(
  HANDLE ClientToken,                 // handle to client's access token
  PPRIVILEGE_SET RequiredPrivileges,  // privileges
  LPBOOL pfResult                     // result
);

Parameters

ClientToken
[in] Handle to an access token representing a client process. This handle must have been obtained by opening the token of a thread impersonating the client. The token must be open for TOKEN_QUERY access.
RequiredPrivileges
[in] Pointer to a PRIVILEGE_SET structure. The Privilege member of this structure is an array of LUID_AND_ATTRIBUTES structures. Before calling PrivilegeCheck, use the Privilege array to indicate the set of privileges to check. Set the Control member to PRIVILEGE_SET_ALL_NECESSARY if all of the privileges must be enabled; or set it to zero if it is sufficient that any one of the privileges be enabled.

When PrivilegeCheck returns, the Attributes member of each LUID_AND_ATTRIBUTES structure is set to SE_PRIVILEGE_USED_FOR_ACCESS if the corresponding privilege is enabled.

pfResult
[out] Pointer to a value the function sets to indicate whether any or all of the specified privilege are enabled in the access token. If the Control member of the PRIVILEGE_SET structure specifies PRIVILEGE_SET_ALL_NECESSARY, this value is TRUE only if all the privileges are enabled; otherwise, this value is TRUE if any of the privileges are enabled.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

An access token contains a list of the privileges held by the account associated with the token. These privileges can be enabled or disabled; most are disabled by default. The PrivilegeCheck function checks only for enabled privileges. To get a list of all the enabled and disabled privileges held by an access token, call the GetTokenInformation function. To enable or disable a set of privileges in an access token, call the AdjustTokenPrivileges function.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, AdjustTokenPrivileges, GetTokenInformation, LookupPrivilegeValue, LUID_AND_ATTRIBUTES, ObjectPrivilegeAuditAlarm, PRIVILEGE_SET, PrivilegedServiceAuditAlarm


PrivilegedServiceAuditAlarm

The PrivilegedServiceAuditAlarm function generates an audit message in the security event log. A protected server can use this function to log attempts by a client to use a specified set of privileges.

Alarms are not currently supported.

BOOL PrivilegedServiceAuditAlarm(
  LPCTSTR SubsystemName,      // subsystem name
  LPCTSTR ServiceName,        // service name
  HANDLE ClientToken,         // handle to access token
  PPRIVILEGE_SET Privileges,  // privileges
  BOOL AccessGranted          // granted access rights
);

Parameters

SubsystemName
[in] Pointer to a null-terminated string specifying the name of the subsystem calling the function. This information appears in the security event log record.
ServiceName
[in] Pointer to a null-terminated string specifying the name of the privileged subsystem service. This information appears in the security event log record.
ClientToken
[in] Identifies an access token representing the client that requested the operation. This handle must have been obtained by opening the token of a thread impersonating the client. The token must be open for TOKEN_QUERY access. The function uses this token to get the identity of the client for the security event log record.
Privileges
[in] Pointer to a PRIVILEGE_SET structure containing the privileges that the client attempted to use. The names of the privileges appear in the security event log record.
AccessGranted
[in] Indicates whether the client's attempt to use the privileges was successful. If this value is TRUE, the security event log record indicates success. If this value is FALSE, the security event log record indicates failure.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The PrivilegedServiceAuditAlarm function does not check the client's access token to determine whether the privileges are held or enabled. Typically, you would first call the PrivilegeCheck function to determine whether the specified privileges are enabled in the access token, and then call PrivilegedServiceAuditAlarm to log the results.

The PrivilegedServiceAuditAlarm function requires the calling process to have SE_AUDIT_NAME privilege enabled. The test for this privilege is always performed against the primary token of the calling process. This allows the calling process to impersonate a client during the call.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, ObjectPrivilegeAuditAlarm, PrivilegeCheck, PRIVILEGE_SET


RevertToSelf

The RevertToSelf function terminates the impersonation of a client application.

BOOL RevertToSelf(VOID);

Parameters

This function has no parameters.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

A process should call the RevertToSelf function after finishing any impersonation begun by using the DdeImpersonateClient, ImpersonateDdeClientWindow, ImpersonateLoggedOnUser, ImpersonateNamedPipeClient, ImpersonateSelf, or SetThreadToken function.

An RPC server that used the RpcImpersonateClient function to impersonate a client must call the RpcRevertToSelf or RpcRevertToSelfEx to end the impersonation.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, DdeImpersonateClient, ImpersonateDdeClientWindow, ImpersonateLoggedOnUser, ImpersonateNamedPipeClient, ImpersonateSelf, RpcImpersonateClient, RpcRevertToSelf, RpcRevertToSelfEx, SetThreadToken


SetPrivateObjectSecurity

The SetPrivateObjectSecurity function modifies a private object's security descriptor.

To specify whether the protected server supports automatic inheritance of ACEs, use the SetPrivateObjectSecurityEx function.

BOOL SetPrivateObjectSecurity(
  SECURITY_INFORMATION SecurityInformation,        // type
  PSECURITY_DESCRIPTOR ModificationDescriptor,     // new SD
  PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor, // SD
  PGENERIC_MAPPING GenericMapping,                 // mapping
  HANDLE Token                                     // handle to client token
);

Parameters

SecurityInformation
[in] Indicates the parts of the security descriptor to set. This value can be a combination of the SECURITY_INFORMATION bit flags.
ModificationDescriptor
[in] Pointer to a SECURITY_DESCRIPTOR structure. The parts of this security descriptor indicated by the SecurityInformation parameter are applied to the ObjectsSecurityDescriptor security descriptor.
ObjectsSecurityDescriptor
[out] Pointer to a pointer to a SECURITY_DESCRIPTOR structure. This security descriptor must be in self-relative form.

On input, this is the current security descriptor of the private object. The function modifies it to produce the new security descriptor. If necessary, the SetPrivateObjectSecurityEx function allocates additional memory to produce a larger security descriptor.

GenericMapping
[in] Pointer to a GENERIC_MAPPING structure that specifies the specific and standard access rights that correspond to each of the generic access rights.
Token
[in] Handle to the access token for the client on whose behalf the private object's security is being modified. This parameter is required to ensure that the client has provided a legitimate value for a new owner security identifier (SID). The token must be open for TOKEN_QUERY access.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The SetPrivateObjectSecurity function is successful only if the following conditions are met:

  • If the object's owner is being set, the calling process must have either WRITE_OWNER permission or be the object's owner.
  • If the object's discretionary access-control list (DACL) is being set, the calling process must have either WRITE_DAC permission or be the object's owner.
  • If the object's system ACL (SACL) is being set, the SE_SECURITY_NAME privilege must be enabled for the calling process.

The process calling this function must not be impersonating a client.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, CreatePrivateObjectSecurity, DestroyPrivateObjectSecurity, GENERIC_MAPPING, GetPrivateObjectSecurity, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetFileSecurity, SetKernelObjectSecurity, SetPrivateObjectSecurityEx, SetUserObjectSecurity


SetPrivateObjectSecurityEx

The SetPrivateObjectSecurityEx function modifies the security descriptor of a private object maintained by the resource manager calling this function. SetPrivateObjectSecurityEx has a flags parameter that allows you to specify whether the resource manager supports automatic inheritance of ACEs.

BOOL SetPrivateObjectSecurityEx (
  SECURITY_INFORMATION SecurityInformation,     // type
  PSECURITY_DESCRIPTOR ModificationDescriptor,  // new SD
  PSECURITY_DESCRIPTOR *SecurityDescriptor,     // SD
  ULONG AutoInheritFlags,                       // inheritance option
  PGENERIC_MAPPING GenericMapping,              // mapping
  HANDLE Token                                  // handle to client token
);

Parameters

SecurityInformation
[in] Indicates the parts of the security descriptor to set. This value can be a combination of the SECURITY_INFORMATION bit flags.
ModificationDescriptor
[in] Pointer to a SECURITY_DESCRIPTOR structure. The parts of this security descriptor indicated by the SecurityInformation parameter are applied to the SecurityDescriptor security descriptor.
SecurityDescriptor
[out] Pointer to a pointer to a SECURITY_DESCRIPTOR structure. This security descriptor must be in self-relative form.

On input, this is the current security descriptor of the private object. The function modifies it to produce the new security descriptor. If necessary, the SetPrivateObjectSecurityEx function allocates additional memory to produce a larger security descriptor.

AutoInheritFlags
[in] Specifies automatic inheritance of ACEs. If the protected server does not implement automatic inheritance, it should specify zero; otherwise, it can specify a combination of the following values.
Value | Meaning
SEF_DACL_AUTO_INHERIT | If this flag is set, the DACL is treated as an auto-inherit DACL and is processed as described in the following Remarks section. This bit is ignored if DACL_SECURITY_INFORMATION is not set in the SecurityInformation parameter.
SEF_SACL_AUTO_INHERIT | If this flag is set, the SACL is treated as an auto-inherit SACL and is processed as described in the following Remarks section. This bit is ignored if SACL_SECURITY_INFORMATION is not set in the SecurityInformation parameter.
SEF_AVOID_PRIVILEGE_CHECK | If this flag is set, the Token parameter can be NULL, and the token is not checked to determine if the Owner in ModificationDescriptor is valid as described in the following Remarks.

GenericMapping
[in] Pointer to a GENERIC_MAPPING structure that specifies the specific and standard access rights that correspond to each of the generic access rights.
Token
[in] Identifies the access token for the client on whose behalf the private object's security is being modified. This parameter is required to ensure that the client has provided a legitimate value for a new owner SID. The token must be open for TOKEN_QUERY access.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

If the AutoInheritFlags parameter is zero, SetPrivateObjectSecurityEx is identical to the SetPrivateObjectSecurity function.

This function is intended for use by resource managers only. In order to implement the standard NT access control semantics for updating security descriptors, a resource manager should verify that the following conditions are met before calling SetPrivateObjectSecurityEx:

  • If the object's owner is being set, the calling process must have either WRITE_OWNER permission or be the object's owner.
  • If the object's DACL is being set, the calling process must have either WRITE_DAC permission or be the object's owner.
  • If the object's SACL is being set, the SE_SECURITY_NAME privilege must be enabled for the calling process.

If the preceding conditions are not met, a call to this function does not fail, however, standard NT access policy is not enforced.

The process calling this function should not be impersonating a client because clients do not typically have appropriate privileges required for underlying token operations.

If AutoInheritFlags specifies the SEF_DACL_AUTO_INHERIT bit, the function applies the following rules to the DACL to create the new security descriptor from the current descriptor

  • If the SE_DACL_PROTECTED flag is not set in the control bits of the either the current security descriptor or the ModificationDescriptor, the function constructs the output security descriptor from the inherited ACEs of the current security descriptor and non-inherited ACEs of ModificationDescriptor. That is, it is impossible to change an inherited ACE by changing the ACL on an object. This behavior preserves the inherited ACEs as they were inherited from the parent container.

    An ACL editor should "gray" inherited ACEs to prevent them from being modified.

  • If SE_DACL_PROTECTED is set in the ModificationDescriptor, the current security descriptor is ignored. The output security descriptor is built as a copy of the ModificationDescriptor with any INHERITED_ACE bits turned off.

    Ideally an ACL editor should turn off the INHERITED_ACE bits indicating to its caller that the ACEs inherited from the object's parent are now being explicitly set on the object.

  • If SE_DACL_PROTECTED is set in the current security descriptor and not in the ModificationDescriptor, the current security descriptor is ignored. The output security descriptor is built as a copy of the ModificationDescriptor. It is the caller's responsibility to ensure that the correct ACEs have the INHERITED_ACE bit turned on.

If AutoInheritFlags specifies the SEF_SACL_AUTO_INHERIT bit, the function applies similar rules to the new SACL.

For both DACLs and SACLs, certain types of ACEs in the input SecurityDescriptor and in ModificationDescriptor will be replaced by two ACEs in the output SecurityDescriptor. Specifically, an inheritable ACE that contains at least one of the following mappable elements will result in two ACEs in the output SecurityDescriptor. Mappable elements include:

  • Generic access rights in the ACCESS_MASK,
  • Creator Owner SID or Creator Group SID as the ACE subject identifier

ACEs with any of these mappable elements will result in the following two ACEs in the output SecurityDescriptor:

  • An ACE that is a copy of the original, but with the INHERIT_ONLY flag set, and
  • An ACE in which the INHERITED_ACE bit is turned on and the generic elements are mapped to specific elements:
    • Generic access rights are replaced by the corresponding standard and specific access rights indicated in the input GenericMapping.
    • Creator Owner SID is replaced with the Owner in the output SecurityDescriptor.
    • Creator Group SID is replaced with the Group in the output SecurityDescriptor.

If AutoInheritFlags does not specify the SEF_AVOID_PRIVILEGE_CHECK bit, owner validity checking is performed according to the following rules. The Owner in ModificationDescriptor:

  • Must be a legally formed SID, and
  • Either must match the TokenUser in Token,
  • Or must match a group in the TokenGroups in Token where the attributes on the group:
    • must include SE_GROUP_OWNER, and
    • must not include SE_GROUP_USE_FOR_DENY_ONLY

A resource manager that is setting the Owner on a subtree of objects can avoid the overhead of redundant owner validity checking. Provided the Owner in ModificationDescriptor and the Token remain the same for iterative calls to this function, the SEF_AVOID_PRIVILEGE_CHECK bit may be set in AutoInheritFlags for calls subsequent to an initial call in which owner validity checking is performed. Callers that do not have access to the token of the client that will ultimately be setting the owner should also choose to skip owner validation checking.

Note The SEF_AVOID_PRIVILEGE_CHECK bit as used in the SetPrivateObjectSecurityEx function is equivalent to the SEF_AVOID_OWNER_CHECK bit used in the CreatePrivateObjectSecurityEx function. This inconsistent use of the SEF_AVOID_PRIVILEGE_CHECK bit is historical legacy rather than an intentional distinction.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Client/Server Access Control Overview, Client/Server Access Control Functions, CreatePrivateObjectSecurityEx, DestroyPrivateObjectSecurity, GENERIC_MAPPING, GetPrivateObjectSecurity, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetFileSecurity, SetKernelObjectSecurity, SetUserObjectSecurity


Client/Server Access Control Structures

Use the following structures to implement client/server access control functionality:

AUTHZ_ACCESS_REPLY
AUTHZ_ACCESS_REQUEST
GENERIC_MAPPING
OBJECT_TYPE_LIST
PRIVILEGE_SET
SECURITY_QUALITY_OF_SERVICE


AUTHZ_ACCESS_REQUEST

[This is preliminary documentation and subject to change.]

The AUTHZ_ACCESS_REQUEST structure defines an access check request.

typedef struct _AUTHZ_ACCESS_REQUEST {
  ACCESS_MASK           DesiredAccess;
  PSID                  PrincipalSelfSid;
  POBJECT_TYPE_LIST     ObjectTypeList;
  DWORD                 ObjectTypeListLength;
  PVOID                 OptionalArguments;
} AUTHZ_ACCESS_REQUEST, *PAUTHZ_ACCESS_REQUEST;

Members

DesiredAccess
Value of type ACCESS_MASK that replaces the principal self SID in the ACL.
PrincipalSelfSid
SID of the entity that is setting access.
ObjectTypeList
Array of OBJECT_TYPE_LIST structures, each a level/GUID pair. This is a post-fix representation of the object tree. The Level and ObjectType members of each OBJECT_TYPE_LIST array element are set to NULL and 0 respectively except when per-property access is desired.
ObjectTypeListLength
Specifies DWORD number of elements in the ObjectTypeList member.
OptionalArguments
Buffer of type PVOID that supports business rules-based access. The buffer pointed to is passed as input to the callback access check function. Access check algorithm does not interpret any of the contents of this buffer.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


AUTHZ_ACCESS_REPLY

[This is preliminary documentation and subject to change.]

The AUTHZ_ACCESS_REPLY structure returns the results of the access check call.

typedef struct _AUTHZ_ACCESS_REPLY
{
  DWORD ResultListLength;
  PACCESS_MASK GrantedAccessMask;
  PDWORD Error;
} AUTHZ_ACCESS_REPLY, *PAUTHZ_ACCESS_REPLY;

Members

ResultListLength
Array of type DWORD that represents the object type list structure. If no object type is used to represent the object, the length is 1. This member cannot be empty.
GrantedAccessMask
Array of ACCESS_MASK structures. Memory for this array is allocated by the resource manager. Access checking functions do not allocate memory; they check or set values in previously allocated memory.
Error
Array of DWORD results associated with each element of the GrantedAccessMask array. Memory for this array is allocated by the resource manager. Access checking functions do not allocate memory ; they check or set values in previously allocated memory.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


GENERIC_MAPPING

The GENERIC_MAPPING structure defines the mapping of generic access rights to specific and standard access rights for an object. When a client application requests generic access to an object, that request is mapped to the access rights defined in this structure.

typedef struct _GENERIC_MAPPING {
  ACCESS_MASK GenericRead;
  ACCESS_MASK GenericWrite;
  ACCESS_MASK GenericExecute;
  ACCESS_MASK GenericAll;
} GENERIC_MAPPING;

Members

GenericRead
Specifies an access mask defining read access to an object.
GenericWrite
Specifies an access mask defining write access to an object.
GenericExecute
Specifies an access mask defining execute access to an object.
GenericAll
Specifies an access mask defining all possible types of access to an object.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Client/Server Access Control Overview, Client/Server Access Control Structures, AccessCheck, AccessCheckAndAuditAlarm, CreatePrivateObjectSecurity, MapGenericMask, SetPrivateObjectSecurity, ACCESS_MASK


OBJECT_TYPE_LIST

The OBJECT_TYPE_LIST structure identifies an object type element in a hierarchy of object types. The AccessCheckByType functions use an array of OBJECT_TYPE_LIST structures to define a hierarchy of an object and its subobjects, such as property sets and properties.

typedef struct _OBJECT_TYPE_LIST {
  WORD   Level;
  WORD   Sbz;
  GUID *ObjectType;
} OBJECT_TYPE_LIST, *POBJECT_TYPE_LIST;

Members

Level
Specifies the level of the object type in the hierarchy of an object and its subobjects. Level zero indicates the object itself. Level 1 indicates a subobject of the object, such as a property set. Level 2 indicates a subobject of the level 1 subobject, such as a property. There can be a maximum of 5 levels numbered 0 through 4.

Directory service objects use the following level values.
Value | Description
ACCESS_OBJECT_GUID | Indicates the object itself at level zero.
ACCESS_PROPERTY_SET_GUID | Indicates a property set at level 1.
ACCESS_PROPERTY_GUID | Indicates a property at level 2.

Sbz
Should be zero. Reserved for future use.
ObjectType
Pointer to the GUID for the object or subobject.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Client/Server Access Control Overview, Client/Server Access Control Structures, AccessCheckByType, AccessCheckByTypeAndAuditAlarm, AccessCheckByTypeResultList, AccessCheckByTypeResultListAndAuditAlarm


PRIVILEGE_SET

The PRIVILEGE_SET structure specifies a set of privileges. It is also used to indicate which, if any, privileges are held by a user or group requesting access to an object.

typedef struct _PRIVILEGE_SET {
  DWORD PrivilegeCount;
  DWORD Control;
  LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY];
} PRIVILEGE_SET, *PPRIVILEGE_SET;

Members

PrivilegeCount
Specifies the number of privileges in the privilege set.
Control
Specifies a control flag related to the privileges. The PRIVILEGE_SET_ALL_NECESSARY control flag is currently defined. It indicates that all of the specified privileges must be held by the process requesting access. If this flag is not set, the presence of any privileges in the user's access token grants the access.
Privilege
Specifies an array of LUID_AND_ATTRIBUTES structures describing the set's privileges. The following attributes are defined for privileges:
Attribute | Description
SE_PRIVILEGE_ENABLED_BY_DEFAULT | The privilege is enabled by default.
SE_PRIVILEGE_ENABLED | The privilege is enabled.
SE_PRIVILEGE_USED_FOR_ACCESS | The privilege was used to gain access to an object or service. This flag is used to identify the relevant privileges in a set passed by a client application that may contain unnecessary privileges.

Remarks

A privilege is used to control access to an object or service more strictly than is typical with discretionary access control. A system manager uses privileges to control which users are able to manipulate system resources. An application uses privileges when it changes a system-wide resource, such as when it changes the system time or shuts down the system.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Client/Server Access Control Overview, Client/Server Access Control Structures, PrivilegeCheck, LUID, LUID_AND_ATTRIBUTES


SECURITY_QUALITY_OF_SERVICE

The SECURITY_QUALITY_OF_SERVICE data structure contains information used to support client impersonation. A client can specify this information when it connects to a server; the information determines whether or not the server may impersonate the client, and if so, to what extent.

typedef struct _SECURITY_QUALITY_OF_SERVICE {
  DWORD Length;
  SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
  SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode;
  BOOLEAN EffectiveOnly;
} SECURITY_QUALITY_OF_SERVICE, *PSECURITY_QUALITY_OF_SERVICE;

Members

Length
Specifies the size, in bytes, of this structure.
ImpersonationLevel
Specifies what the server may be told about the client, and how the server may represent, or impersonate, the client. Security impersonation levels govern the degree to which a server process can act on behalf of a client process. This member is a SECURITY_IMPERSONATION_LEVEL enumeration type value.
ContextTrackingMode
Specifies whether the server is to be given a snapshot of the client's security context (called static tracking), or is to be continually updated to track changes to the client's security context (called dynamic tracking). The value SECURITY_STATIC_TRACKING specifies static tracking, and the value SECURITY_DYNAMIC_TRACKING specifies dynamic tracking. Not all communications mechanisms support dynamic tracking; those that do not will default to static tracking.
EffectiveOnly
Specifies whether or not the server may enable or disable privileges and groups that the client's security context may include.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Client/Server Access Control Overview, Client/Server Access Control Structures, DdeSetQualityOfService, SECURITY_IMPERSONATION_LEVEL


Client/Server Access Control Enumeration Types

Use the following enumeration types to implement client/server access control functionality:

AUDIT_EVENT_TYPE
AUTHZ_CONTEXT_INFORMATION_CLASS
SECURITY_IMPERSONATION_LEVEL


AUDIT_EVENT_TYPE

The AUDIT_EVENT_TYPE enumeration type defines values that indicate the type of object being audited. The AccessCheckByTypeAndAuditAlarm and AccessCheckByTypeResultListAndAuditAlarm functions use these values.

typedef enum _AUDIT_EVENT_TYPE {
  AuditEventObjectAccess,
  AuditEventDirectoryServiceAccess
} AUDIT_EVENT_TYPE, *PAUDIT_EVENT_TYPE;

Enumeration Values

AuditEventObjectAccess
Indicates an object that generates audit messages only if the system administrator has enabled auditing access to files and objects.
AuditEventDirectoryServiceAccess
Indicates a directory service object that generates audit messages only if the system administrator has enabled auditing access to directory service objects.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Client/Server Access Control Overview, Client/Server Access Control Enumeration Types, AccessCheckByTypeAndAuditAlarm, AccessCheckByTypeResultListAndAuditAlarm


AUTHZ_CONTEXT_INFORMATION_CLASS

[This is preliminary documentation and subject to change.]

The AUTHZ_CONTEXT_INFORMATION_CLASS specifies the type of information to be retrieved from an existing AuthzClientContext.

typedef enum _AUTHZ_CONTEXT_INFORMATION_CLASS  {
  AuthzContextInfoUserSid = 1,
  AuthzContextInfoGroupsSids,
  AuthzContextInfoRestrictedSids,
  AuthzContextInfoPrivileges,
  AuthzContextInfoExpirationTime,
  AuthzContextInfoServerContext,
  AuthzContextInfoIdentifier
} AUTHZ_CONTEXT_INFORMATION_CLASS;

Enumeration Values

AuthzContextInfoUserSid
Retrieve information on a user SID.
AuthzContextInfoGroupsSids
Retrieve information on a group SID.
AuthzContextInfoRestrictedSids
Retrieve information on a restricted SID.
AuthzContextInfoPrivileges
Retrieve information on the privileges of a SID.
AuthzContextInfoExpirationTime
Retrieve information on the expiration time of a SID.
AuthzContextInfoServerContext
Retrieve information on the context of a server SID.
AuthzContextInfoIdentifier
Retrieve information on the identifier of a SID.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


SECURITY_IMPERSONATION_LEVEL

The SECURITY_IMPERSONATION_LEVEL enumeration type contains values that specify security impersonation levels. Security impersonation levels govern the degree to which a server process can act on behalf of a client process.

typedef enum _SECURITY_IMPERSONATION_LEVEL {
  SecurityAnonymous,
  SecurityIdentification,
  SecurityImpersonation,
  SecurityDelegation
} SECURITY_IMPERSONATION_LEVEL;

Enumeration Values

SecurityAnonymous
The server process cannot obtain identification information about the client and it cannot impersonate the client. It is defined with no value given, and thus, by ANSI C rules, defaults to a value of 0.
SecurityIdentification
The server process can obtain information about the client, such as security identifiers and privileges, but it cannot impersonate the client. This is useful for servers that export their own objects — for example, database products that export tables and views. Using the retrieved client-security information, the server can make access-validation decisions without being able to utilize other services using the client's security context.
SecurityImpersonation
The server process can impersonate the client's security context on its local system. The server cannot impersonate the client on remote systems.
SecurityDelegation
The server process can impersonate the client's security context on remote systems.

Windows NT: This impersonation level is not supported.

Windows 2000: This impersonation level is supported.

Remarks

Impersonation is the ability of a process to take on the security attributes of another process.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Client/Server Access Control Overview, Client/Server Access Control Enumeration Types, CreatePrivateObjectSecurity, DuplicateToken, DuplicateTokenEx, GetTokenInformation, ImpersonateSelf, OpenThreadToken


Account Rights

Account rights, like privileges, determine the operations that a user account can perform. An administrator assigns account rights to user and group accounts. Each user's account rights include those granted to the user or to groups to which the user belongs.

A system administrator can use the Lsa functions to work with account rights. The LsaAddAccountRights and LsaRemoveAccountRights functions add or remove account rights from an account. The LsaEnumerateAccountRights function enumerates the account rights held by a specified account. The LsaEnumerateAccountsWithUserRight function enumerates the accounts that hold a specified account right.

Note All of the Lsa functions mentioned above support both account rights and Windows NT privileges. Unlike privileges, however, account rights are not supported by the LookupPrivilegeValue and LookupPrivilegeName functions. The GetTokenInformation function will obtain information on account rights if TokenGroups is specified as the value of the TokenInformationClass parameter, and not TokenPrivileges.

The following account right constants are used to control an account's ability to log on. The LogonUser or LsaLogonUser functions fail if the account being logged on does not have the account rights required for the type of logon being performed.

The SE_DENY rights override the corresponding account rights. An administrator can assign an SE_DENY right to an account to override any logon rights that an account might have as a result of a group membership. For example, you could assign the SE_NETWORK_LOGON_NAME right to Everyone but assign the SE_DENY_NETWORK_LOGON_NAME right to Administrators to prevent remote administration of computers.

Account right constant | Description
SE_INTERACTIVE_LOGON_NAME | Required for an account to log on using the interactive logon type.
SE_NETWORK_LOGON_NAME | Required for an account to log on using the network logon type.
SE_BATCH_LOGON_NAME | Required for an account to log on using the batch logon type.
SE_SERVICE_LOGON_NAME | Required for an account to log on using the service logon type.
SE_DENY_INTERACTIVE_LOGON_NAME | Explicitly denies an account the right to log on using the interactive logon type.
SE_DENY_NETWORK_LOGON_NAME | Explicitly denies an account the right to log on using the network logon type.
SE_DENY_BATCH_LOGON_NAME | Explicitly denies an account the right to log on using the batch logon type.
SE_DENY_SERVICE_LOGON_NAME | Explicitly denies an account the right to log on using the service logon type.

The preceding account right constants are defined as strings in Ntsecapi.h. For example, the SE_INTERACTIVE_LOGON_NAME constant is defined as "SeInteractiveLogonRight".


Low-Level Access-Control

This overview describes the low-level access-control functions for working with security descriptors and access-control lists (ACLs). Most low-level access-control functions are supported on all versions of Microsoft® Windows NT®/Windows® 2000. The low-level functions for working with object-specific access-control entries (ACEs) are supported by Windows 2000.

The Win32® API also provides a high-level set of access-control functions. For information about when to use each set of functions, see Access-Control Reference.

  • About Low-Level Access Control
  • Using Low-Level Access Control
  • Low-Level Access Control Reference


About Low-Level Access Control

This overview describes the low-level security functions for working with security descriptors, access-control lists (ACLs), and access-control entries (ACEs).

The access control model is basically the same for all versions of Microsoft® Windows NT®/Windows® 2000. For a description of the model, see Access-Control Model.


Low-Level Security Descriptor Functions

There are several pairs of low-level functions for setting and retrieving an object's security descriptor. Each of these pairs works only with a limited set of Win32® objects. For example, one pair works with file objects and another works with registry keys. The following table shows the low-level functions to use with the different types of securable objects.

Object type | Low-level functions
Files Directories Mailslots Named pipes | Use the GetFileSecurity and SetFileSecurity functions. These functions use character strings to identify the securable object, instead of using handles.
Processes Threads Access tokens File-mapping objects Semaphores Events Mutexes Waitable timers | Use the GetKernelObjectSecurity and SetKernelObjectSecurity functions.
Window stations Desktops | Use the GetUserObjectSecurity and SetUserObjectSecurity functions.
Registry keys | Use the RegGetKeySecurity and RegSetKeySecurity functions.
Win32 service objects | Use the QueryServiceObjectSecurity and SetServiceObjectSecurity functions.
Printer objects | Use the PRINTER_INFO_2 structure with the GetPrinter and SetPrinter functions.
Network shares | Use level 502 with the NetShareGetInfo and NetShareSetInfo functions.
Private objects (objects private to the creating application) | Use the CreatePrivateObjectSecurity, DestroyPrivateObjectSecurity, GetPrivateObjectSecurity and SetPrivateObjectSecurity functions.


Low-Level Security Descriptor Creation

Low-level access-control provides a set of functions for creating a security descriptor and getting and setting the components of a security descriptor. The low-level functions for initializing and setting the components of a security descriptor work only with absolute-format security descriptors. The low-level functions for getting the components of a security descriptor work with both absolute and self-relative security descriptors.

The InitializeSecurityDescriptor function initializes a SECURITY_DESCRIPTOR buffer. The initialized security descriptor is in absolute format and has no owner, primary group, discretionary access-control list (DACL), or system access-control list (SACL). You can use the following low-level functions to get or set specific components of a specified security descriptor.

Function | Description
GetSecurityDescriptorControl | Retrieves revision and control information from a security descriptor.
GetSecurityDescriptorDacl | Retrieves the DACL from a security descriptor.
GetSecurityDescriptorGroup | Retrieves the primary group security identifier (SID) from a security descriptor.
GetSecurityDescriptorLength | Returns the length of a security descriptor.
GetSecurityDescriptorOwner | Retrieves the owner SID from a security descriptor.
GetSecurityDescriptorSacl | Retrieves the SACL from a security descriptor.
SetSecurityDescriptorDacl | Puts a DACL into a security descriptor, superseding any existing DACL.
SetSecurityDescriptorGroup | Sets the primary group SID of a security descriptor.
SetSecurityDescriptorOwner | Sets the owner SID of a security descriptor.
SetSecurityDescriptorSacl | Puts a SACL into a security descriptor, superseding any existing SACL.

To check the revision level and structural integrity of a security descriptor, call the IsValidSecurityDescriptor function.


Absolute and Self-Relative Security Descriptors

A security descriptor can be in either absolute or self-relative format. In absolute format, a security descriptor contains pointers to its information, not the information itself. In self-relative format, a security descriptor stores a SECURITY_DESCRIPTOR structure and associated security information in a contiguous block of memory. To determine whether a security descriptor is self-relative or absolute, call the GetSecurityDescriptorControl function and check the SE_SELF_RELATIVE flag of the SECURITY_DESCRIPTOR_CONTROL parameter. You can use the MakeSelfRelativeSD and MakeAbsoluteSD functions for converting between these two formats.

The absolute format is useful when you are building a security descriptor and have pointers to all of the components, for example, when default settings for the owner, group, and discretionary ACL are available. In this case, you can call the InitializeSecurityDescriptor function to initialize a SECURITY_DESCRIPTOR structure, and then call functions such as SetSecurityDescriptorDacl to assign ACL and SID pointers to the security descriptor.

In self-relative format, a security descriptor always begins with a SECURITY_DESCRIPTOR structure, but the other components of the security descriptor can follow the structure in any order. Instead of using memory addresses, the security descriptor's components are identified by offsets from the beginning of the descriptor. This format is useful when a security descriptor must be stored on disk, transmitted by means of a communications protocol, or copied in memory.

All Win32 functions that return a security descriptor do so using the self-relative format. Security descriptors passed as arguments to a Win32 function either self-relative or absolute form. For more information, refer to the documentation for the function.


Low-Level ACL and ACE Functions

To create an access-control list (ACL) using the low-level functions, allocate a buffer for the ACL and then initialize it by calling the InitializeAcl function. To add access-control entries (ACEs) to the end of a discretionary access-control list (DACL), use the AddAccessAllowedAce and AddAccessDeniedAce functions. The AddAuditAccessAce function adds an ACE to the end of a SACL. You can use the AddAce function to add one or more ACEs at a specified position in an ACL. The AddAce function also allows you to add an inheritable ACE to an ACL. The DeleteAce function removes an ACE from a specified position in an ACL. The GetAce function retrieves an ACE from a specified position in an ACL. The FindFirstFreeAce function retrieves a pointer to the first free byte in an ACL.

To modify an existing ACL in an object's security descriptor, use the GetSecurityDescriptorDacl or GetSecurityDescriptorSacl function to get the existing ACL. You can use the GetAce function to copy ACEs from the existing ACL. After allocating and initializing a new ACL, use functions such as AddAccessAllowedAce and AddAce to add ACEs to it. When you have finished building the new ACL, use the SetSecurityDescriptorDacl or SetSecurityDescriptorSacl function to add the new ACL to the object's security descriptor.

Windows 2000 or later: You can use the AddAccessAllowedObjectAce, AddAccessDeniedObjectAce, or AddAuditAccessObjectAce functions to add object-specific ACEs to the end of an ACL.


Using Low-Level Access Control

The following examples use the Microsoft® Windows NT® version 3.x security functions:

  • Converting a Security Descriptor String
  • Denying Access Using Low-Level Functions
  • Allowing Access Using the Low-Level Functions


Converting a Security Descriptor String

The following example converts a security descriptor string to a self-relative security descriptor using the ConvertStringSecurityDescriptorToSecurityDescriptor function, then converts the self-relative security descriptor to an absolute security descriptor using the MakeAbsoluteSD function.

VARIANT var;
PSECURITY_DESCRIPTOR pSDCNV = NULL;
SECURITY_DESCRIPTOR SD = {0};
DWORD dwSDSize = sizeof(SECURITY_DESCRIPTOR);
PSID pOwnerSID = NULL;
DWORD dwOwnerSIDSize = 0;
PSID pGroupSID = NULL;
DWORD dwGroupSIDSize = 0;
PACL pDACL = NULL;
DWORD dwDACLSize = 0;
PACL pSACL = NULL;
DWORD dwSACLSize = 0;

// ...

// Convert the security descriptor string to a security descriptor.

if ( ! ConvertStringSecurityDescriptorToSecurityDescriptor (
         var.bstrVal, SDDL_REVISION_1, &pSDCNV, NULL ))
{
   wprintf( L"Error: %d\n", GetLastError() );
   goto Cleanup;
}

// Get the required buffer sizes.

if (! MakeAbsoluteSD(pSDCNV, &SD, &dwSDSize,
         pDACL, &dwDACLSize,
         pSACL, &dwSACLSize,
         pOwnerSID, &dwOwnerSIDSize,
         pGroupSID, &dwGroupSIDSize) )
{

  // Allocate the buffers.

   pDACL = (PACL) GlobalAlloc(GPTR, dwDACLSize);
   pSACL = (PACL) GlobalAlloc(GPTR, dwSACLSize);
   pOwnerSID = (PACL) GlobalAlloc(GPTR, dwOwnerSIDSize);
   pGroupSID = (PACL) GlobalAlloc(GPTR, dwGroupSIDSize);
   if (! (pDACL && pSACL && pOwnerSID && pGroupSID) )
   {
      wprintf(L"GlobalAlloc failed: %d\n", GetLastError() );
      goto Cleanup;
   }

// Convert self-relative security descriptor to absolute.

   if (! MakeAbsoluteSD(pSDCNV, &SD, &dwSDSize, pDACL, &dwDACLSize,
            pSACL, &dwSACLSize, pOwnerSID, &dwOwnerSIDSize,
            pGroupSID, &dwGroupSIDSize) )
   {
      wprintf(L"MakeAbsoluteSD: %d\n", GetLastError() );
      goto Cleanup;
   }
}

// Clean up.

Cleanup:
VariantClear(&var);
if (pSDCNV)
  LocalFree(pSDCNV);
if (pDACL)
  GlobalFree(pDACL);
if (pSACL)
  GlobalFree(pSACL);
if (pOwnerSID)
  GlobalFree(pOwnerSID);
if (pGroupSID)
  GlobalFree(pGroupSID);
if (pNewDACL)
  LocalFree(pNewDACL);


Denying Access Using Low-Level Functions

This example uses the low-level access-control functions to attach an empty DACL to a file object. The effect of an empty DACL is to deny all access to the object.

The example allocates a buffer for the security descriptor and calls the InitializeSecurityDescriptor function to initialize the buffer. Then, it allocates a buffer for the ACL and calls the InitializeAcl function to initialize that buffer. Next, it calls the SetSecurityDescriptorDacl function to attach the ACL to the security descriptor and then calls the SetFileSecurity function to attach the security descriptor to a file.

PSECURITY_DESCRIPTOR pSD;
PACL pACL;
DWORD cbACL = 1024;

// Initialize a security descriptor.

pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
    SECURITY_DESCRIPTOR_MIN_LENGTH);   // defined in Winnt.h
if (pSD == NULL) {
    ErrorHandler("LocalAlloc");
    goto Cleanup;
}

if (!InitializeSecurityDescriptor(pSD,
        SECURITY_DESCRIPTOR_REVISION)) { // defined in Winnt.h
    ErrorHandler("InitializeSecurityDescriptor");
    goto Cleanup;
}

// Initialize a DACL.

pACL = (PACL) LocalAlloc(LPTR, cbACL);
if (pACL == NULL) {
    ErrorHandler("LocalAlloc");
    goto Cleanup;
}

if (!InitializeAcl(pACL, cbACL, ACL_REVISION2)) {
    ErrorHandler("InitializeAcl");
    goto Cleanup;
}

// Add an empty ACL to the SD to deny access.

if (!SetSecurityDescriptorDacl(pSD,
        TRUE,     // fDaclPresent flag
        pACL,
        FALSE)) { // not a default DACL
    ErrorHandler("SetSecurityDescriptorDacl");
    goto Cleanup;
}

// Use the new SD as the file's security info.

if (!SetFileSecurity(lpszTestFile,
        DACL_SECURITY_INFORMATION,
        pSD)) {
    ErrorHandler("SetFileSecurity");
    goto Cleanup;
}

Cleanup:
    if(pSD != NULL)
        LocalFree((HLOCAL) pSD);
    if(pACL != NULL)
        LocalFree((HLOCAL) pACL);


Allowing Access Using the Low-Level Functions

This section shows how to use the low-level functions to work with ACLs and ACEs that allow access to an object.

The first example shows the use of the low-level access-control functions to add a NULL DACL to a file's security descriptor. The low-level example allocates a security descriptor buffer and calls the InitializeSecurityDescriptor function to initialize it. Then, it calls the SetSecurityDescriptorDacl function to attach a NULL DACL to the security descriptor. Finally, it calls the SetFileSecurity function to attach the security descriptor to a file. An equivalent high-level example could perform the same operation with a single call to the SetNamedSecurityInfo function.

Note You can write code that builds security descriptors from scratch, as in the example. However, when writing code that builds or manipulates security descriptors, your code should explore the default security descriptors that the system places on objects. For example, an object may have a default DACL that contains ACEs inherited from its parent object. Rather than simply replacing the default DACL, your code should first examine the default DACL to determine whether you want to include its ACEs in the new DACL.

PSECURITY_DESCRIPTOR pSD;

// Initialize a security descriptor.

pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
    SECURITY_DESCRIPTOR_MIN_LENGTH);   // defined in Winnt.h
if (pSD == NULL) {
    ErrorHandler("LocalAlloc");
    goto Cleanup;
}

if (!InitializeSecurityDescriptor(pSD,
        SECURITY_DESCRIPTOR_REVISION)) { // defined in Winnt.h
    ErrorHandler("InitializeSecurityDescriptor");
    goto Cleanup;
}

// Add a NULL disc. ACL to the security descriptor.

if (!SetSecurityDescriptorDacl(pSD,
        TRUE,     // specifying a disc. ACL
        (PACL) NULL,
        FALSE)) { // not a default disc. ACL
    ErrorHandler("SetSecurityDescriptorDacl");
    goto Cleanup;
}

// Add the security descriptor to the file.

if (!SetFileSecurity(lpszTestFile,
        DACL_SECURITY_INFORMATION,
        pSD)) {
    ErrorHandler("SetFileSecurity");
    goto Cleanup;
}

Cleanup:
    if(pSD != NULL)
        LocalFree((HLOCAL) pSD);

The following example shows the use of the low-level access-control functions to add a DACL with an access-allowed ACE to a file's security descriptor. The example allocates and initializes a security descriptor, allocates and initializes an ACL, and allocates and looks up a SID for a specified account. Then it adds an ACE to the ACL, adds the ACL as the DACL of the security descriptor, and finally, attaches the security descriptor to the file.

Note High-level functions perform many of these steps for you.

    PSECURITY_DESCRIPTOR pSD;
    PACL pACLNew;
    DWORD cbACL = 1024;
    PSID pSID;
    DWORD cbSID = 1024;
    LPSTR lpszAccount = "UserABC";
    LPSTR lpszDomain;
    DWORD cchDomainName = 80;
    PSID_NAME_USE psnuType;

    // Initialize a new security descriptor.

    pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
        SECURITY_DESCRIPTOR_MIN_LENGTH);  // defined in Winnt.h
    if (pSD == NULL) {
        ErrorHandler("LocalAlloc");
        goto Cleanup;
    }

    if (!InitializeSecurityDescriptor(pSD,
            SECURITY_DESCRIPTOR_REVISION)) {
        ErrorHandler("InitializeSecurityDescriptor");
        goto Cleanup;
    }

    // Initialize a new ACL.

    pACLNew = (PACL) LocalAlloc(LPTR, cbACL);
    if (pACLNew == NULL) {
        ErrorHandler("LocalAlloc");
        goto Cleanup;
    }

    if (!InitializeAcl(pACLNew, cbACL, ACL_REVISION2)) {
        ErrorHandler("InitializeAcl");
        goto Cleanup;
    }

    // Retrieve the SID for UserABC.

    pSID = (PSID) LocalAlloc(LPTR, cbSID);
    psnuType = (PSID_NAME_USE) LocalAlloc(LPTR, 1024);
    lpszDomain = (LPSTR) LocalAlloc(LPTR, cchDomainName);
    if (pSID == NULL || psnuType == NULL ||
        lpszDomain == NULL) {
        ErrorHandler("LocalAlloc");
        goto Cleanup;
    }

    if (!LookupAccountName((LPSTR) NULL, // local name
            lpszAccount,
            pSID,
            &cbSID,
            lpszDomain,
            &cchDomainName,
            psnuType)) {
        ErrorHandler("LookupAccountName");
        goto Cleanup;
    }
    if (!IsValidSid(pSID))
        TextOut(hdc, 10, yIncrement += 18,
            "SID is not valid.", 17);
    else
        TextOut(hdc, 10, yIncrement += 18,
            "SID is valid.", 13);

    // Allow read but not write access to the file.

    if (!AddAccessAllowedAce(pACLNew,
            ACL_REVISION2,
            GENERIC_READ,
            pSID)) {
        ErrorHandler("AddAccessAllowedAce");
        goto Cleanup;
    }

    // Add a new ACL to the security descriptor.

    if (!SetSecurityDescriptorDacl(pSD,
            TRUE,              // fDaclPresent flag
            pACLNew,
            FALSE)) {          // not a default disc. ACL
        ErrorHandler("SetSecurityDescriptorDacl");
        goto Cleanup;
    }

    // Apply the new security descriptor to the file.

    if (!SetFileSecurity("d:\\ntfs_sample_file",
            DACL_SECURITY_INFORMATION,
            pSD)) {
        ErrorHandler("SetFileSecurity");
        goto Cleanup;
    }
    TextOut(hdc, 10, yIncrement += 18,
        "Successfully added access-allowed ACE to file's DACL.", 53);

    Cleanup:
        FreeSid(pSID);
        if(pSD != NULL)
            LocalFree((HLOCAL) pSD);
        if(pACLNew != NULL)
            LocalFree((HLOCAL) pACLNew);
        if(psnuType != NULL)
            LocalFree((HLOCAL) psnuType);
        if(lpszDomain != NULL)
            LocalFree((HLOCAL) lpszDomain);


Low-Level Access Control Reference

The following elements are used with low-level access control.

  • Low-Level Access Control Functions
  • Low-Level Access Control Structures


Low-Level Access Control Functions

The following low-level functions are used to manipulate security descriptors.

Function | History
GetFileSecurity | Windows NT 3.51 and earlier
GetKernelObjectSecurity | Windows NT 3.51 and earlier
GetPrinter | Windows NT 3.51 and earlier
GetSecurityDescriptorDacl | Windows NT 3.51 and earlier
GetSecurityDescriptorGroup | Windows NT 3.51 and earlier
GetSecurityDescriptorLength | Windows NT 3.51 and earlier
GetSecurityDescriptorOwner | Windows NT 3.51 and earlier
GetSecurityDescriptorSacl | Windows NT 3.51 and earlier
GetUserObjectSecurity | Windows NT 3.51 and earlier
InitializeSecurityDescriptor | Windows NT 3.51 and earlier
IsValidSecurityDescriptor | Windows NT 3.51 and earlier
MakeAbsoluteSD | Windows NT 3.51 and earlier
MakeSelfRelativeSD | Windows NT 3.51 and earlier
NetShareGetInfo | Windows NT 3.51 and earlier
NetShareSetInfo | Windows NT 3.51 and earlier
QueryServiceObjectSecurity | Windows NT 3.51 and earlier
RegGetKeySecurity | Windows NT 3.51 and earlier
RegSetKeySecurity | Windows NT 3.51 and earlier
SetFileSecurity | Windows NT 3.51 and earlier
SetKernelObjectSecurity | Windows NT 3.51 and earlier
SetPrinter | Windows NT 3.51 and earlier
SetSecurityDescriptorDacl | Windows NT 3.51 and earlier
SetSecurityDescriptorGroup | Windows NT 3.51 and earlier
SetSecurityDescriptorOwner | Windows NT 3.51 and earlier
SetSecurityDescriptorSacl | Windows NT 3.51 and earlier
SetServiceObjectSecurity | Windows NT 3.51 and earlier
SetUserObjectSecurity | Windows NT 3.51 and earlier

The following low-level functions are used to manipulate ACEs and ACLs.

Function | History
AddAccessAllowedAce | Windows NT 3.51 and earlier
AddAccessAllowedAceEx | Windows 2000
AddAccessAllowedObjectAce | Windows 2000
AddAccessDeniedAce | Windows NT 3.51 and earlier
AddAccessDeniedAceEx | Windows 2000
AddAccessDeniedObjectAce | Windows 2000
AddAce | Windows NT 3.51 and earlier
AddAuditAccessAce | Windows NT 3.51 and earlier
AddAuditAccessAceEx | Windows 2000
AddAuditAccessObjectAce | Windows 2000
DeleteAce | Windows NT 3.51 and earlier
FindFirstFreeAce | Windows NT 3.51 and earlier
GetAce | Windows NT 3.51 and earlier
GetAclInformation | Windows NT 3.51 and earlier
InitializeAcl | Windows NT 3.51 and earlier
IsValidAcl | Windows NT 3.51 and earlier
SetAclInformation | Windows NT 3.51 and earlier


AddAccessAllowedAce

The AddAccessAllowedAce function adds an access-allowed ACE to an ACL. The access is granted to a specified SID.

To control whether the new ACE can be inherited by child objects, use the AddAccessAllowedAceEx function.

BOOL AddAccessAllowedAce(
  PACL pAcl,            // access-control list
  DWORD dwAceRevision,  // ACL revision level
  DWORD AccessMask,     // access mask
  PSID pSid             // security identifier
);

Parameters

pAcl
[in, out] Pointer to an ACL structure. This function adds an access-allowed ACE to the end of this ACL. The ACE is in the form of an ACCESS_ALLOWED_ACE structure.
dwAceRevision
[in] Specifies the revision level of the ACL being modified.

Windows NT 4.0 and earlier: This value must be ACL_REVISION.

Windows 2000 or later: This value can be ACL_REVISION or ACL_REVISION_DS. Use ACL_REVISION_DS if the ACL contains object-specific ACEs.

AccessMask
[in] Specifies the mask of access rights to be granted to the specified SID.
pSid
[in] Pointer to the SID structure representing a user, group, or logon account being granted access.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. The following are possible error values.

Error value | Description
ERROR_ALLOTTED_SPACE_EXCEEDED | The new ACE does not fit into the ACL. A larger ACL buffer is required.
ERROR_INVALID_ACL | The specified ACL is not properly formed.
ERROR_INVALID_SID | The specified SID is not structurally valid.
ERROR_REVISION_MISMATCH | The specified revision is not known or is incompatible with that of the ACL.
ERROR_SUCCESS | The ACE was successfully added.

Remarks

An ACE is an access-control entry. An ACL is an access-control list. A SID is a security identifier. The addition of an access-allowed ACE to an ACL is the most common form of ACL modification.

The AddAccessAllowedAce and AddAccessDeniedAce functions add a new ACE to the end of the list of ACEs for the ACL. These functions do not automatically place the new ACE in the proper canonical order. It is the caller's responsibility to ensure that the ACL is in canonical order by adding ACEs in the proper sequence. For Windows NT versions 4.0 and earlier, the canonical order for a DACL places all access-denied ACEs before any access-allowed ACEs.

The ACE_HEADER structure placed in the ACE by the AddAccessAllowedAce function specifies a type and size, but provides no inheritance and no ACE flags.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACCESS_ALLOWED_ACE, ACE_HEADER, ACL, AddAccessAllowedAceEx, AddAccessDeniedAce, AddAce, AddAuditAccessAce, DeleteAce, GetAce


AddAccessAllowedAceEx

The AddAccessAllowedAceEx function adds an access-allowed ACE to the end of a DACL.

BOOL AddAccessAllowedAceEx(
  PACL pAcl,            // access control list
  DWORD dwAceRevision,  // ACL revision level
  DWORD AceFlags,       // ACE inheritance flags
  DWORD AccessMask,     // access mask for the new ACE
  PSID pSid             // trustee SID for new ACE
);

Parameters

pAcl
[in, out] Pointer to a DACL. The AddAccessAllowedAceEx function adds an access-allowed ACE to the end of this DACL. The ACE is in the form of an ACCESS_ALLOWED_ACE structure.
dwAceRevision
[in] Specifies the revision level of the DACL being modified. This value can be ACL_REVISION or ACL_REVISION_DS. Use ACL_REVISION_DS if the DACL contains object-specific ACEs.
AceFlags
[in] A set of bit flags that control ACE inheritance. The function sets these flags in the AceFlags member of the ACE_HEADER structure of the new ACE. This parameter can be a combination of the following values.
Value | Meaning
CONTAINER_INHERIT_ACE | The ACE is inherited by container objects.
INHERIT_ONLY_ACE | The ACE does not apply to the object to which the ACL is assigned, but it can be inherited by child objects.
INHERITED_ACE | Indicates an inherited ACE. This flag allows operations that change the security on a tree of objects to modify inherited ACEs while not changing ACEs that were directly applied to the object.
NO_PROPAGATE_INHERIT_ACE | The OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE bits are not propagated to an inherited ACE.
OBJECT_INHERIT_ACE | The ACE is inherited by noncontainer objects

AccessMask
[in] A set of bit flags that use the ACCESS_MASK format to specify the access rights that the new ACE allows to the specified SID.
pSid
[in] Pointer to a SID structure that identifies the user, group, or logon session to which the new ACE allows access.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. The following are possible error values.

Error value | Description
ERROR_ALLOTTED_SPACE_EXCEEDED | The new ACE does not fit into the ACL. A larger ACL buffer is required.
ERROR_INVALID_ACL | The specified ACL is not properly formed.
ERROR_INVALID_FLAGS | The AceFlags parameter is invalid.
ERROR_INVALID_SID | The specified SID is not structurally valid.
ERROR_REVISION_MISMATCH | The specified revision is not known or is incompatible with that of the ACL.
ERROR_SUCCESS | The ACE was successfully added.

Remarks

The caller must ensure that ACEs are added to the DACL in the correct order. For more information, see Order of ACEs in a DACL.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACCESS_ALLOWED_ACE, ACE_HEADER, ACL, AddAccessDeniedAceEx, AddAuditAccessAceEx


AddAccessAllowedObjectAce

The AddAccessAllowedObjectAce function adds an access-allowed ACE to the end of a DACL. The new ACE can grant access to an object, or to a property set or property on an object. You can also use AddAccessAllowedObjectAce to add an ACE that only a specified type of child object can inherit.

BOOL AddAccessAllowedObjectAce(
  PACL pAcl,                     // ACL
  DWORD dwAceRevision,           // ACL revision level
  DWORD AceFlags,                // ACE inheritance flags
  DWORD AccessMask,              // access mask for new ACE
  GUID *ObjectTypeGuid,          // objects protected by ACE
  GUID *InheritedObjectTypeGuid, // objects inheriting ACE
  PSID pSid                      // trustee SID for new ACE
);

Parameters

pAcl
[in, out] Pointer to a DACL. The AddAccessAllowedObjectAce function adds an access-allowed ACE to the end of this DACL. The ACE is in the form of an ACCESS_ALLOWED_OBJECT_ACE structure.
dwAceRevision
[in] Specifies the revision level of the DACL being modified. This value must be ACL_REVISION_DS. If the DACL's revision level is lower than ACL_REVISION_DS, the function changes it to ACL_REVISION_DS.
AceFlags
[in] A set of bit flags that control ACE inheritance. The function sets these flags in the AceFlags member of the ACE_HEADER structure of the new ACE. This parameter can be a combination of the following values.
Value | Meaning
CONTAINER_INHERIT_ACE | The ACE is inherited by container objects.
INHERIT_ONLY_ACE | The ACE does not apply to the object to which the ACL is assigned, but it can be inherited by child objects.
INHERITED_ACE | Indicates an inherited ACE. This flag allows operations that change the security on a tree of objects to modify inherited ACEs, while not changing ACEs that were directly applied to the object.
NO_PROPAGATE_INHERIT_ACE | The OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE bits are not propagated to an inherited ACE.
OBJECT_INHERIT_ACE | The ACE is inherited by noncontainer objects.

AccessMask
[in] A set of bit flags that use the ACCESS_MASK format to specify the access rights that the new ACE allows to the specified SID.
ObjectTypeGuid
[in] Pointer to a GUID structure that identifies the type of object, property set, or property protected by the new ACE. If this parameter is NULL, the new ACE protects the object to which the DACL is assigned.
InheritedObjectTypeGuid
[in] Pointer to a GUID structure that identifies the type of object that can inherit the new ACE. If this parameter is non-NULL, only the specified object type can inherit the ACE. If NULL, any type of child object can inherit the ACE. In either case, inheritance is also controlled by the value of the AceFlags parameter, as well as by any protection against inheritance placed on the child objects.
pSid
[in] Pointer to a SID structure that identifies the user, group, or logon session to which the new ACE allows access.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. The following are possible error values.

Error value | Description
ERROR_ALLOTTED_SPACE_EXCEEDED | The new ACE does not fit into the ACL. A larger ACL buffer is required.
ERROR_INVALID_ACL | The specified ACL is not properly formed.
ERROR_INVALID_FLAGS | The AceFlags parameter is invalid.
ERROR_INVALID_SID | The specified SID is not structurally valid.
ERROR_REVISION_MISMATCH | The specified revision is not known or is incompatible with that of the ACL.
ERROR_SUCCESS | The ACE was successfully added.

Remarks

If both ObjectTypeGuid and InheritedObjectTypeGuid are NULL, use the AddAccessAllowedAceEx function rather than AddAccessAllowedObjectAce. This is suggested because an ACCESS_ALLOWED_ACE is smaller and more efficient than an ACCESS_ALLOWED_OBJECT_ACE.

The caller must ensure that ACEs are added to the DACL in the correct order. For more information, see Order of ACEs in a DACL.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACCESS_ALLOWED_ACE, ACCESS_ALLOWED_OBJECT_ACE, ACE_HEADER, ACL, AddAccessAllowedAceEx, AddAccessDeniedObjectAce, AddAuditAccessObjectAce


AddAccessDeniedAce

The AddAccessDeniedAce function adds an access-denied ACE to an ACL. The access is denied to a specified SID.

To control whether the new ACE can be inherited by child objects, use the AddAccessDeniedAceEx function.

BOOL AddAccessDeniedAce(
  PACL pAcl,            // access control list
  DWORD dwAceRevision,  // ACL revision level
  DWORD AccessMask,     // access mask
  PSID pSid             // security identifier
);

Parameters

pAcl
[in, out] Pointer to an ACL structure. This function adds an access-denied ACE to the end of this ACL. The ACE is in the form of an ACCESS_DENIED_ACE structure.
dwAceRevision
[in] Specifies the revision level of the ACL being modified.

Windows NT 4.0 and earlier: This value must be ACL_REVISION.

Windows 2000 or later: This value can be ACL_REVISION or ACL_REVISION_DS. Use ACL_REVISION_DS if the ACL contains object-specific ACEs.

AccessMask
[in] Specifies the mask of access rights being denied to the specified SID.
pSid
[in] Pointer to the SID structure representing the user, group, or logon account being denied access.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. The following are possible error values.

Error value | Description
ERROR_ALLOTTED_SPACE_EXCEEDED | The new ACE does not fit into the ACL. A larger ACL buffer is required.
ERROR_INVALID_ACL | The specified ACL is not properly formed.
ERROR_INVALID_SID | The specified SID is not structurally valid.
ERROR_REVISION_MISMATCH | The specified revision is not known or is incompatible with that of the ACL.
ERROR_SUCCESS | The ACE was successfully added.

Remarks

An ACE is an access-control entry. An ACL is an access-control list. A SID is a security identifier.

The AddAccessAllowedAce and AddAccessDeniedAce functions add a new ACE to the end of the list of ACEs for the ACL. These functions do not automatically place the new ACE in the proper canonical order. It is the caller's responsibility to ensure that the ACL is in canonical order by adding ACEs in the proper sequence. For Windows NT versions 4.0 and earlier, the canonical order for a DACL places all access-denied ACEs before any access-allowed ACEs.

The ACE_HEADER structure placed in the ACE by the AddAccessDeniedAce function specifies a type and size, but provides no ACE flags.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACCESS_DENIED_ACE, ACE_HEADER, ACL, AddAccessAllowedAce, AddAccessDeniedAceEx, AddAce, AddAuditAccessAce, DeleteAce, GetAce


AddAccessDeniedAceEx

The AddAccessDeniedAceEx function adds an access-denied ACE to the end of a DACL.

BOOL AddAccessDeniedAceEx(
  PACL pAcl,            // ACL
  DWORD dwAceRevision,  // ACL revision level
  DWORD AceFlags,       // ACE inheritance flags
  DWORD AccessMask,     // access mask for new ACE
  PSID pSid             // trustee SID for new ACE
);

Parameters

pAcl
[in, out] Pointer to a DACL. The AddAccessDeniedAceEx function adds an access-denied ACE to the end of this DACL. The ACE is in the form of an ACCESS_DENIED_ACE structure.
dwAceRevision
[in] Specifies the revision level of the DACL being modified. This value can be ACL_REVISION or ACL_REVISION_DS. Use ACL_REVISION_DS if the DACL contains object-specific ACEs.
AceFlags
[in] A set of bit flags that control ACE inheritance. The function sets these flags in the AceFlags member of the ACE_HEADER structure of the new ACE. This parameter can be a combination of the following values.
Value | Meaning
CONTAINER_INHERIT_ACE | The ACE is inherited by container objects.
INHERIT_ONLY_ACE | The ACE does not apply to the object to which the ACL is assigned, but it can be inherited by child objects.
INHERITED_ACE | Indicates an inherited ACE. This flag allows operations that change the security on a tree of objects to modify inherited ACEs, while not changing ACEs that were directly applied to the object.
NO_PROPAGATE_INHERIT_ACE | The OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE bits are not propagated to an inherited ACE.
OBJECT_INHERIT_ACE | The ACE is inherited by noncontainer objects.

AccessMask
[in] A set of bit flags that use the ACCESS_MASK format to specify the access rights that the new ACE denies to the specified SID.
pSid
[in] Pointer to a SID structure that identifies the user, group, or logon session to which the new ACE denies access.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. The following are possible error values.

Error value | Description
ERROR_ALLOTTED_SPACE_EXCEEDED | The new ACE does not fit into the ACL. A larger ACL buffer is required.
ERROR_INVALID_ACL | The specified ACL is not properly formed.
ERROR_INVALID_FLAGS | The AceFlags parameter is invalid.
ERROR_INVALID_SID | The specified SID is not structurally valid.
ERROR_REVISION_MISMATCH | The specified revision is not known or is incompatible with that of the ACL.
ERROR_SUCCESS | The ACE was successfully added.

Remarks

Although the AddAccessDeniedAceEx function adds the new ACE to the end of the DACL, access-denied ACEs should appear at the beginning of a DACL. The caller must ensure that ACEs are added to the DACL in the correct order. For more information, see Order of ACEs in a DACL.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACCESS_DENIED_ACE, ACE_HEADER, ACL, AddAccessAllowedAceEx, AddAuditAccessAceEx


AddAccessDeniedObjectAce

The AddAccessDeniedObjectAce function adds an access-denied ACE to the end of a DACL. The new ACE can deny access to an object, or to a property set or property on an object. You can also use AddAccessDeniedObjectAce to add an ACE that only a specified type of child object can inherit.

BOOL AddAccessDeniedObjectAce(
  PACL pAcl,                     // ACL
  DWORD dwAceRevision,           // ACL revision level
  DWORD AceFlags,                // ACE inheritance flags
  DWORD AccessMask,              // access mask for new ACE
  GUID *ObjectTypeGuid,          // object protected by ACE
  GUID *InheritedObjectTypeGuid, // objects inheriting ACE
  PSID pSid                      // trustee SID for ACE
);

Parameters

pAcl
[in, out] Pointer to a DACL. The AddAccessDeniedObjectAce function adds an access-denied ACE to the end of this DACL. The ACE is in the form of an ACCESS_DENIED_OBJECT_ACE structure.
dwAceRevision
[in] Specifies the revision level of the DACL being modified. This value must be ACL_REVISION_DS. If the DACL's revision level is lower than ACL_REVISION_DS, the function changes it to ACL_REVISION_DS.
AceFlags
[in] A set of bit flags that control ACE inheritance. The function sets these flags in the AceFlags member of the ACE_HEADER structure of the new ACE. This parameter can be a combination of the following values.
Value | Meaning
CONTAINER_INHERIT_ACE | The ACE is inherited by container objects.
INHERIT_ONLY_ACE | The ACE does not apply to the object to which the ACL is assigned, but it can be inherited by child objects.
INHERITED_ACE | Indicates an inherited ACE. This flag allows operations that change the security on a tree of objects to modify inherited ACEs, while not changing ACEs that were directly applied to the object.
NO_PROPAGATE_INHERIT_ACE | The OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE bits are not propagated to an inherited ACE.
OBJECT_INHERIT_ACE | The ACE is inherited by noncontainer objects.

AccessMask
[in] A set of bit flags that use the ACCESS_MASK format to specify the access rights that the new ACE denies to the specified SID.
ObjectTypeGuid
[in] Pointer to a GUID structure that identifies the type of object, property set, or property protected by the new ACE. If this parameter is NULL, the new ACE protects the object to which the ACL is assigned.
InheritedObjectTypeGuid
[in] Pointer to a GUID structure that identifies the type of object that can inherit the new ACE. If this parameter is non-NULL, only the specified object type can inherit the ACE. If NULL, any type of child object can inherit the ACE. In either case, inheritance is also controlled by the value of the AceFlags parameter, as well as by any protection against inheritance placed on the child objects.
pSid
[in] Pointer to a SID structure that identifies the user, group, or logon session to which the new ACE allows access.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. The following are possible error values.

Error value | Description
ERROR_ALLOTTED_SPACE_EXCEEDED | The new ACE does not fit into the ACL. A larger ACL buffer is required.
ERROR_INVALID_ACL | The specified ACL is not properly formed.
ERROR_INVALID_FLAGS | The AceFlags parameter is invalid.
ERROR_INVALID_SID | The specified SID is not structurally valid.
ERROR_REVISION_MISMATCH | The specified revision is not known or is incompatible with that of the ACL.
ERROR_SUCCESS | The ACE was successfully added.

Remarks

If both ObjectTypeGuid and InheritedObjectTypeGuid are NULL, use the AddAccessDeniedAceEx function rather than AddAccessDeniedObjectAce. This is suggested because an ACCESS_DENIED_ACE is smaller and more efficient than an ACCESS_DENIED_OBJECT_ACE.

Although the AddAccessDeniedObjectAce function adds the new ACE to the end of the ACL, access-denied ACEs should appear at the beginning of an ACL. The caller must ensure that ACEs are added to the DACL in the correct order. For more information, see Order of ACEs in a DACL.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACCESS_DENIED_ACE, ACCESS_DENIED_OBJECT_ACE, ACE_HEADER, ACL, AddAccessAllowedObjectAce, AddAccessDeniedAceEx, AddAuditAccessObjectAce


AddAce

The AddAce function adds one or more ACEs to a specified ACL.

An ACE is an access-control entry. An ACL is an access-control list.

BOOL AddAce(
  PACL pAcl,                 // access-control list
  DWORD dwAceRevision,       // ACL revision level
  DWORD dwStartingAceIndex,  // index of ACE position in ACL
  LPVOID pAceList,           // one or more ACEs
  DWORD nAceListLength       // size of buffer for ACEs
);

Parameters

pAcl
[in, out] Pointer to an ACL structure. This function adds an ACE to this ACL.
dwAceRevision
[in] Specifies the revision level of the ACL being modified.

Windows NT 4.0 and earlier: This value must be ACL_REVISION.

Windows 2000 or later: This value can be ACL_REVISION or ACL_REVISION_DS. Use ACL_REVISION_DS if the ACL contains object-specific ACEs.

dwStartingAceIndex
[in] Specifies the position in the ACL's list of ACEs at which to add new ACEs. A value of zero inserts the ACEs at the beginning of the list. A value of MAXDWORD appends the ACEs to the end of the list.
pAceList
[in] Pointer to a list of one or more ACEs to be added to the specified ACL. The ACEs in the list must be stored contiguously.
nAceListLength
[in] Specifies the size, in bytes, of the input buffer pointed to by the pAceList parameter.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. The following are possible error values.

Error value | Description
ERROR_ALLOTTED_SPACE_EXCEEDED | The new ACE does not fit into the ACL. A larger ACL buffer is required.
ERROR_INVALID_ACL | The specified ACL is not properly formed.
ERROR_INVALID_SID | The specified SID is not structurally valid.
ERROR_REVISION_MISMATCH | The specified revision is not known or is incompatible with that of the ACL.
ERROR_SUCCESS | The ACE was successfully added.

Remarks

Applications frequently use the FindFirstFreeAce and GetAce functions when using the AddAce function to manipulate an ACL. In addition, the ACL_SIZE_INFORMATION structure retrieved by the GetAclInformation function contains the size of the ACL and the number of ACEs it contains.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, ACL_SIZE_INFORMATION, AddAccessAllowedAce, AddAccessDeniedAce, AddAuditAccessAce, DeleteAce, FindFirstFreeAce, GetAce, GetAclInformation


AddAuditAccessAce

The AddAuditAccessAce function adds a system-audit ACE to a system ACL. The access of a specified SID is audited.

To control whether the new ACE can be inherited by child objects, use the AddAuditAccessAceEx function.

BOOL AddAuditAccessAce(
  PACL pAcl,           // access-control list
  DWORD dwAceRevision, // ACL revision level
  DWORD dwAccessMask,  // access mask
  PSID pSid,           // security identifier
  BOOL bAuditSuccess,  // auditing successful access
  BOOL bAuditFailure   // auditing unsuccessful access
);

Parameters

pAcl
[in, out] Pointer to an ACL structure. This function adds a system-audit ACE to this ACL. The ACE is in the form of an SYSTEM_AUDIT_ACE structure.
dwAceRevision
[in] Specifies the revision level of the ACL being modified.

Windows NT 4.0 and earlier: This value must be ACL_REVISION.

Windows 2000 or later: This value can be ACL_REVISION or ACL_REVISION_DS. Use ACL_REVISION_DS if the ACL contains object-specific ACEs.

dwAccessMask
[in] Specifies the mask of access rights to be audited for the specified SID.
pSid
[in] Pointer to the SID structure representing the process whose access is being audited.
bAuditSuccess
[in] Specifies whether successful access attempts are to be audited. Set this flag to TRUE to enable auditing; otherwise, set it to FALSE.
bAuditFailure
[in] Specifies whether unsuccessful access attempts are to be audited. Set this flag to TRUE to enable auditing; otherwise, set it to FALSE.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. The following are possible error values.

Error value | Description
ERROR_ALLOTTED_SPACE_EXCEEDED | The new ACE does not fit into the ACL. A larger ACL buffer is required.
ERROR_INVALID_ACL | The specified ACL is not properly formed.
ERROR_INVALID_SID | The specified SID is not structurally valid.
ERROR_REVISION_MISMATCH | The specified revision is not known or is incompatible with that of the ACL.
ERROR_SUCCESS | The ACE was successfully added.

Remarks

An ACE is an access-control entry. An ACL is an access-control list. A SID is a security identifier.

The ACE_HEADER structure placed in the ACE by the AddAuditAccessAce function specifies a type and size, but provides no ACE flags.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACE_HEADER, ACL, AddAccessAllowedAce, AddAccessDeniedAce, AddAce, AddAuditAccessAceEx, DeleteAce, GetAce, SID, SYSTEM_AUDIT_ACE


AddAuditAccessAceEx

The AddAuditAccessAceEx function adds a system-audit ACE to the end of a SACL.

BOOL AddAuditAccessAceEx(
  PACL pAcl,            // ACL
  DWORD dwAceRevision,  // ACL revision level
  DWORD AceFlags,       // ACE inheritance and audit type
  DWORD dwAccessMask,   // access mask for new ACE
  PSID pSid,            // SID of trustee for new ACE
  BOOL bAuditSuccess,   // audit successful access
  BOOL bAuditFailure    // audit unsuccessful access
);

Parameters

pAcl
[in, out] Pointer to a SACL. The AddAuditAccessAceEx function adds a system-audit ACE to this SACL. The ACE is in the form of a SYSTEM_AUDIT_ACE structure.
dwAceRevision
[in] Specifies the revision level of the SACL being modified. This value can be ACL_REVISION or ACL_REVISION_DS. Use ACL_REVISION_DS if the SACL contains object-specific ACEs.
AceFlags
[in] A set of bit flags that control ACE inheritance and the type of access attempts to audit. The function sets these flags in the AceFlags member of the ACE_HEADER structure of the new ACE. This parameter can be a combination of the following values.
Value | Meaning
CONTAINER_INHERIT_ACE | The ACE is inherited by container objects.
FAILED_ACCESS_ACE_FLAG | If you set this flag or specify TRUE for the bAuditFailure parameter, failed attempts to use the specified access rights cause the system to generate an audit record in the security event log.
INHERIT_ONLY_ACE | The ACE does not apply to the object to which the ACL is assigned, but it can be inherited by child objects.
INHERITED_ACE | Indicates an inherited ACE. This flag allows operations that change the security on a tree of objects to modify inherited ACEs, while not changing ACEs that were directly applied to the object.
NO_PROPAGATE_INHERIT_ACE | The OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE bits are not propagated to an inherited ACE.
OBJECT_INHERIT_ACE | The ACE is inherited by noncontainer objects.
SUCCESSFUL_ACCESS_ACE_FLAG | If you set this flag or specify TRUE for the bAuditSuccess parameter, successful uses of the specified access rights cause the system to generate an audit record in the security event log.

dwAccessMask
[in] A set of bit flags that use the ACCESS_MASK format to specify the access rights that the new ACE audits for the specified SID.
pSid
[in] Pointer to a SID structure that identifies the user, group, or logon session for which the new ACE audits access.
bAuditSuccess
[in] Specifies whether successful uses of the specified access rights cause the system to generate an audit record in the security event log. If this flag is TRUE or if the AceFlags parameter specifies the SUCCESSFUL_ACCESS_ACE_FLAG flag, the system records successful access attempts; otherwise, it does not.
bAuditFailure
[in] Specifies whether failed attempts to use the specified access rights cause the system to generate an audit record in the security event log. If this flag is TRUE or if the AceFlags parameter specifies the FAILED_ACCESS_ACE_FLAG flag, the system records failed access attempts; otherwise, it does not.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. The following are possible error values.

Error value | Description
ERROR_ALLOTTED_SPACE_EXCEEDED | The new ACE does not fit into the ACL. A larger ACL buffer is required.
ERROR_INVALID_ACL | The specified ACL is not properly formed.
ERROR_INVALID_FLAGS | The AceFlags parameter is invalid.
ERROR_INVALID_SID | The specified SID is not structurally valid.
ERROR_REVISION_MISMATCH | The specified revision is not known or is incompatible with that of the ACL.
ERROR_SUCCESS | The ACE was successfully added.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACE_HEADER, ACL, AddAccessAllowedAceEx, AddAccessDeniedAceEx, SYSTEM_AUDIT_ACE


AddAuditAccessObjectAce

The AddAuditAccessObjectAce function adds a system-audit ACE to the end of a SACL. The new ACE can audit access to an object, or to a property set or property on an object. You can also use AddAuditAccessObjectAce to add an ACE that only a specified type of child object can inherit.

BOOL AddAuditAccessObjectAce(
  PACL pAcl,                     // ACL
  DWORD dwAceRevision,           // ACL revision level
  DWORD AceFlags,                // ACE inheritance flags
  DWORD AccessMask,              // access mask for new ACE
  GUID *ObjectTypeGuid,          // objects protected by ACE
  GUID *InheritedObjectTypeGuid, // objects inheriting ACE
  PSID pSid,                     // trustee SID for new ACE
  BOOL bAuditSuccess,            // successful access
  BOOL bAuditFailure             // unsuccessful access
);

Parameters

pAcl
[in, out] Pointer to a SACL. The AddAuditAccessObjectAce function adds a system-audit ACE to the end of this SACL. The ACE is in the form of a SYSTEM_AUDIT_OBJECT_ACE structure.
dwAceRevision
[in] Specifies the revision level of the SACL being modified. This value must be ACL_REVISION_DS. If the SACL's revision level is lower than ACL_REVISION_DS, the function changes it to ACL_REVISION_DS.
AceFlags
[in] A set of bit flags that control ACE inheritance and the type of access attempts to audit. The function sets these flags in the AceFlags member of the ACE_HEADER structure of the new ACE. This parameter can be a combination of the following values.
Value | Meaning
CONTAINER_INHERIT_ACE | The ACE is inherited by container objects.
FAILED_ACCESS_ACE_FLAG | If you set this flag or specify TRUE for the bAuditFailure parameter, failed attempts to use the specified access rights cause the system to generate an audit record in the security event log.
INHERIT_ONLY_ACE | The ACE does not apply to the object to which the ACL is assigned, but it can be inherited by child objects.
INHERITED_ACE | Indicates an inherited ACE. This flag allows operations that change the security on a tree of objects to modify inherited ACEs, while not changing ACEs that were directly applied to the object.
NO_PROPAGATE_INHERIT_ACE | The OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE bits are not propagated to an inherited ACE.
OBJECT_INHERIT_ACE | The ACE is inherited by noncontainer objects.
SUCCESSFUL_ACCESS_ACE_FLAG | If you set this flag or specify TRUE for the bAuditSuccess parameter, successful uses of the specified access rights cause the system to generate an audit record in the security event log.

AccessMask
[in] An ACCESS_MASK that specifies the access rights that the new ACE audits for the specified SID.
ObjectTypeGuid
[in] Pointer to a GUID structure that identifies the type of object, property set, or property protected by the new ACE. If this parameter is NULL, the new ACE protects the object to which the ACL is assigned.
InheritedObjectTypeGuid
[in] Pointer to a GUID structure that identifies the type of object that can inherit the new ACE. If this parameter is non-NULL, only the specified object type can inherit the ACE. If NULL, any type of child object can inherit the ACE. In either case, inheritance is also controlled by the value of the AceFlags parameter, as well as by any protection against inheritance placed on the child objects.
pSid
[in] Pointer to a SID structure that identifies the user, group, or logon session for which the new ACE audits access.
bAuditSuccess
[in] Specifies whether successful uses of the specified access rights cause the system to generate an audit record in the security event log. If this flag is TRUE or if the AceFlags parameter specifies the SUCCESSFUL_ACCESS_ACE_FLAG flag, the system records successful access attempts; otherwise, it does not.
bAuditFailure
[in] Specifies whether failed attempts to use the specified access rights cause the system to generate an audit record in the security event log. If this flag is TRUE or if the AceFlags parameter specifies the FAILED_ACCESS_ACE_FLAG flag, the system records failed access attempts; otherwise, it does not.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. The following are possible error values.

Error value | Description
ERROR_ALLOTTED_SPACE_EXCEEDED | The new ACE does not fit into the ACL. A larger ACL buffer is required.
ERROR_INVALID_ACL | The specified ACL is not properly formed.
ERROR_INVALID_FLAGS | The AceFlags parameter is invalid.
ERROR_INVALID_SID | The specified SID is not structurally valid.
ERROR_REVISION_MISMATCH | The specified revision is not known or is incompatible with that of the ACL.
ERROR_SUCCESS | The ACE was successfully added.

Remarks

If both ObjectTypeGuid and InheritedObjectTypeGuid are NULL, use the AddAuditAccessAceEx function rather than AddAuditAccessObjectAce. This is suggested because a SYSTEM_AUDIT_ACE is smaller and more efficient than an SYSTEM_AUDIT_OBJECT_ACE.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACE_HEADER, ACL, AddAccessAllowedObjectAce, AddAccessDeniedObjectAce, AddAuditAccessAceEx, SYSTEM_AUDIT_ACE, SYSTEM_AUDIT_OBJECT_ACE


DeleteAce

The DeleteAce function deletes an ACE from an ACL.

An ACE is an access-control entry. An ACL is an access-control list.

BOOL DeleteAce(
  PACL pAcl,         // access-control list
  DWORD dwAceIndex   // index of ACE position in ACL
);

Parameters

pAcl
[in, out] Pointer to an ACL structure. The ACE specified by the dwAceIndex parameter is removed from this ACL.
dwAceIndex
[in] Specifies the ACE to delete. A value of 0 corresponds to the first ACE in the ACL, 1 to the second ACE, and so on.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

An application can use the ACL_SIZE_INFORMATION structure retrieved by the GetAclInformation function to discover the size of the ACL and the number of ACEs it contains. The GetAce function retrieves information about an individual ACE.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, ACL_SIZE_INFORMATION, AddAccessAllowedAce, AddAccessDeniedAce, AddAce, AddAuditAccessAce, GetAce, GetAclInformation


FindFirstFreeAce

The FindFirstFreeAce function retrieves a pointer to the first free byte in an access-control list (ACL).

BOOL FindFirstFreeAce(
  PACL pAcl,     // access-control list
  LPVOID *pAce   // first free byte
);

Parameters

pAcl
[in] Pointer to an ACL structure.
pAce
[out] Pointer to a pointer to the first free position in the ACL created when the function returns. If the ACL is invalid, this parameter is NULL. If the ACL is full, this parameter points to the byte immediately following the ACL.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, GetAce, GetAclInformation


GetAce

The GetAce function obtains a pointer to an ACE in an ACL.

An ACE is an access control entry. An ACL is an access control list.

BOOL GetAce(
  PACL pAcl,         // access-control list
  DWORD dwAceIndex,  // index of ACE to retrieve
  LPVOID *pAce       // ACE
);

Parameters

pAcl
[in] Pointer to an ACL structure containing the ACE to be retrieved.
dwAceIndex
[in] Specifies the ACE to which a pointer is retrieved. A value of 0 corresponds to the first ACE in the ACL, 1 to the second ACE, and so on.
pAce
[out] Pointer to a pointer the function sets to the address of the ACE.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, AddAccessAllowedAce, AddAccessDeniedAce, AddAce, AddAuditAccessAce, GetAclInformation, InitializeAcl


GetAclInformation

The GetAclInformation function retrieves information about an access-control list (ACL).

BOOL GetAclInformation(
  PACL pAcl,                                   // access-control list
  LPVOID pAclInformation,                      // ACL information
  DWORD nAclInformationLength,                 // size of ACL information
  ACL_INFORMATION_CLASS dwAclInformationClass  // info class
);

Parameters

pAcl
[in] Pointer to an ACL structure. The function retrieves information about this ACL. If a NULL ACL is passed, the function causes an access violation.
pAclInformation
[out] Pointer to a buffer receiving the requested information. The structure put into the buffer depends on the information class requested in the dwAclInformationClass parameter.
nAclInformationLength
[in] Specifies the size, in bytes, of the buffer pointed to by the pAclInformation parameter.
dwAclInformationClass
[in] Specifies an ACL_INFORMATION_CLASS enumerated value that gives the class of information requested. This parameter can be one of two values from this enumerated type. If the value is AclRevisionInformation, the function fills the buffer pointed to by the pAclInformation parameter with an ACL_REVISION_INFORMATION structure.

If the value is AclSizeInformation, the function fills the buffer pointed to by the pAclInformation parameter with an ACL_SIZE_INFORMATION structure.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, ACL_REVISION_INFORMATION, ACL_SIZE_INFORMATION, GetAce, InitializeAcl, IsValidAcl, SetAclInformation


GetFileSecurity

The GetFileSecurity function obtains specified information about the security of a file or directory. The information obtained is constrained by the caller's access rights and privileges.

Windows NT 4.0 and later: You can use the GetNamedSecurityInfo function.

BOOL GetFileSecurity(
  LPCTSTR lpFileName,                        // file name
  SECURITY_INFORMATION RequestedInformation, // request
  PSECURITY_DESCRIPTOR pSecurityDescriptor,  // SD
  DWORD nLength,                             // size of SD
  LPDWORD lpnLengthNeeded                    // required buffer size
);

Parameters

lpFileName
[in] Pointer to a null-terminated string specifying the file or directory for which security information is retrieved.
RequestedInformation
[in] Specifies a SECURITY_INFORMATION value that identifies the security information being requested.
pSecurityDescriptor
[out] Pointer to a buffer that receives a copy of the security descriptor of the object specified by the lpFileName parameter. The calling process must have the right to view the specified aspects of the object's security status. The SECURITY_DESCRIPTOR structure is returned in self-relative format.
nLength
[in] Specifies the size, in bytes, of the buffer pointed to by the pSecurityDescriptor parameter.
lpnLengthNeeded
[out] Pointer to the variable that receives the number of bytes necessary to store the complete security descriptor. If the returned number of bytes is less than or equal to nLength, the entire security descriptor is returned in the output buffer; otherwise none of the descriptor is returned.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

To read the owner, group, or DACL from the security descriptor for the specified file or directory, the DACL for the file or directory must grant READ_CONTROL access to the caller or the caller must be the owner of the file or directory.

To read the system access-control list (SACL) of a file or directory, the SE_SECURITY_NAME privilege must be enabled for the calling process.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetKernelObjectSecurity, GetPrivateObjectSecurity, GetUserObjectSecurity, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetFileSecurity


GetKernelObjectSecurity

The GetKernelObjectSecurity function retrieves a copy of the security descriptor protecting a kernel object.

BOOL GetKernelObjectSecurity(
  HANDLE Handle,                             // handle to object
  SECURITY_INFORMATION RequestedInformation, // request
  PSECURITY_DESCRIPTOR pSecurityDescriptor,  // SD
  DWORD nLength,                             // size of SD
  LPDWORD lpnLengthNeeded                    // required size of buffer
);

Parameters

Handle
[in] Handle to a kernel object.
RequestedInformation
[in] Specifies a SECURITY_INFORMATION value that identifies the security information being requested.
pSecurityDescriptor
[out] Pointer to a buffer the function fills with a copy of the security descriptor of the specified object. The calling process must have the right to view the specified aspects of the object's security status. The SECURITY_DESCRIPTOR structure is returned in self-relative format.
nLength
[in] Specifies the size, in bytes, of the buffer pointed to by the pSecurityDescriptor parameter.
lpnLengthNeeded
[out] Pointer to a variable the function sets to zero if the descriptor is copied successfully. If the buffer is too small for the security descriptor, this variable receives the number of bytes required. If this variable's value is greater than the value of the nLength parameter when the function returns, none of the security descriptor is copied to the buffer.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

To read the owner, group, or DACL from the kernel object's security descriptor, the calling process must have been granted READ_CONTROL access when the handle was opened. To get READ_CONTROL access, the caller must be the owner of the object or the object's DACL must grant the access.

To read the SACL from the security descriptor, the calling process must have been granted ACCESS_SYSTEM_SECURITY access when the handle was opened. The proper way to get this access is to enable the SE_SECURITY_NAME privilege in the caller's current token, open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetFileSecurity, GetPrivateObjectSecurity, GetUserObjectSecurity, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetKernelObjectSecurity


GetSecurityDescriptorDacl

The GetSecurityDescriptorDacl function retrieves a pointer to the discretionary access-control list (DACL) in a specified security descriptor.

BOOL GetSecurityDescriptorDacl(
  PSECURITY_DESCRIPTOR pSecurityDescriptor, // SD
  LPBOOL lpbDaclPresent,                    // DACL presence
  PACL *pDacl,                              // ACL
  LPBOOL lpbDaclDefaulted                   // default DACL
);

Parameters

pSecurityDescriptor
[in] Pointer to the SECURITY_DESCRIPTOR structure containing the discretionary ACL. The function retrieves a pointer to it.
lpbDaclPresent
[out] Pointer to a value that indicates the presence of a discretionary ACL in the specified security descriptor. If this parameter is TRUE, the security descriptor contains a discretionary ACL, and the remaining output parameters in this function receive valid values. If this parameter is FALSE, the security descriptor does not contain a discretionary ACL, and the remaining output parameters do not receive valid values.
pDacl
[out] Pointer to a pointer to an ACL structure. If a discretionary ACL exists, the function sets the pointer pointed to by pDacl to the address of the security descriptor's discretionary ACL. If a discretionary ACL does not exist, no value is stored.

If the function stores a NULL value in the pointer pointed to by pDacl, the security descriptor has a NULL discretionary ACL. A NULL discretionary ACL implicitly allows all access to an object.

lpbDaclDefaulted
[out] Pointer to a flag set to the value of the SE_DACL_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure if a discretionary ACL exists for the security descriptor. If this flag is TRUE, the discretionary ACL was retrieved by a default mechanism; if FALSE, the discretionary ACL was explicitly specified by a user.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, GetSecurityDescriptorControl, GetSecurityDescriptorGroup, GetSecurityDescriptorLength, GetSecurityDescriptorOwner, GetSecurityDescriptorSacl, InitializeSecurityDescriptor, IsValidSecurityDescriptor, SECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL, SetSecurityDescriptorDacl


GetSecurityDescriptorGroup

The GetSecurityDescriptorGroup function retrieves the primary group information from a security descriptor.

BOOL GetSecurityDescriptorGroup(
  PSECURITY_DESCRIPTOR pSecurityDescriptor, // SD
  PSID *pGroup,                             // group SID
  LPBOOL lpbGroupDefaulted                  // default group
);

Parameters

pSecurityDescriptor
[in] Pointer to a SECURITY_DESCRIPTOR structure whose primary group information the function retrieves.
pGroup
[out] Pointer to a pointer to a SID structure identifying the primary group when the function returns. (A SID is a security identifier.) If the security descriptor does not contain a primary group, the function sets the pointer pointed to by pGroup to NULL and ignores the remaining output parameter, lpbGroupDefaulted. If the security descriptor contains a primary group, the function sets the pointer pointed to by pGroup to the address of the security descriptor's group SID structure and provides a valid value for the variable pointed to by lpbGroupDefaulted.
lpbGroupDefaulted
[out] Pointer to a flag set to the value of the SE_GROUP_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure when the function returns. If the value stored in the variable pointed to by the pGroup parameter is NULL, no value is set.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetSecurityDescriptorControl, GetSecurityDescriptorDacl, GetSecurityDescriptorLength, GetSecurityDescriptorOwner, GetSecurityDescriptorSacl, IsValidSecurityDescriptor, SECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL, SetSecurityDescriptorGroup, SID


GetSecurityDescriptorLength

The GetSecurityDescriptorLength function returns the length, in bytes, of a structurally valid security descriptor. The length includes the length of all associated structures.

DWORD GetSecurityDescriptorLength(
  PSECURITY_DESCRIPTOR pSecurityDescriptor  // SD
);

Parameters

pSecurityDescriptor
[in] Pointer to the SECURITY_DESCRIPTOR structure whose length the function returns. The pointer is assumed to be valid.

Return Values

If the function succeeds, the return value is the length, in bytes, of the SECURITY_DESCRIPTOR structure. If the SECURITY_DESCRIPTOR structure is invalid, the return value is undefined.

Remarks

The minimum length of a security descriptor is SECURITY_DESCRIPTOR_MIN_LENGTH. A security descriptor of this length has no associated SID or ACL structures.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetSecurityDescriptorControl, GetSecurityDescriptorDacl, GetSecurityDescriptorGroup, GetSecurityDescriptorOwner, GetSecurityDescriptorSacl, IsValidSecurityDescriptor, SECURITY_DESCRIPTOR


GetSecurityDescriptorOwner

The GetSecurityDescriptorOwner function retrieves the owner information from a security descriptor.

BOOL GetSecurityDescriptorOwner(
  PSECURITY_DESCRIPTOR pSecurityDescriptor, // SD
  PSID *pOwner,                             // owner SID
  LPBOOL lpbOwnerDefaulted                  // default owner
);

Parameters

pSecurityDescriptor
[in] Pointer to a SECURITY_DESCRIPTOR structure whose owner information the function retrieves.
pOwner
[out] Pointer to a pointer to a SID structure identifying the owner when the function returns. (A SID is a security identifier.) If the security descriptor does not contain an owner, the function sets the pointer pointed to by pOwner to NULL and ignores the remaining output parameter, lpbOwnerDefaulted. If the security descriptor contains an owner, the function sets the pointer pointed to by pOwner to the address of the security descriptor's owner SID structure and provides a valid value for the variable pointed to by lpbOwnerDefaulted.
lpbOwnerDefaulted
[out] Pointer to a flag set to the value of the SE_OWNER_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure when the function returns. If the value stored in the variable pointed to by the pOwner parameter is NULL, no value is set.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetSecurityDescriptorControl, GetSecurityDescriptorDacl, GetSecurityDescriptorGroup, GetSecurityDescriptorLength, GetSecurityDescriptorSacl, IsValidSecurityDescriptor, SECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL, SetSecurityDescriptorOwner, SID


GetSecurityDescriptorSacl

The GetSecurityDescriptorSacl function retrieves a pointer to the system access-control list (SACL) in a specified security descriptor.

BOOL GetSecurityDescriptorSacl(
  PSECURITY_DESCRIPTOR pSecurityDescriptor,  // SD
  LPBOOL lpbSaclPresent,                     // system ACL presence
  PACL *pSacl,                               // system ACL
  LPBOOL lpbSaclDefaulted                    // default system ACL
);

Parameters

pSecurityDescriptor
[in] Pointer to the SECURITY_DESCRIPTOR structure containing the system ACL to which the function retrieves a pointer to.
lpbSaclPresent
[out] Pointer to a flag the function sets to indicate the presence of a system ACL in the specified security descriptor. If this parameter is TRUE, the security descriptor contains a system ACL, and the remaining output parameters in this function receive valid values. If this parameter is FALSE, the security descriptor does not contain a system ACL, and the remaining output parameters do not receive valid values.
pSacl
[out] Pointer to a pointer to an ACL structure. If a system ACL exists, the function sets the pointer pointed to by pSacl to the address of the security descriptor's system ACL. If a system ACL does not exist, no value is stored.

If the function stores a NULL value in the pointer pointed to by pSacl, the security descriptor has a NULL system ACL.

lpbSaclDefaulted
[out] Pointer to a flag set to the value of the SE_SACL_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure if a system ACL exists for the security descriptor.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, GetSecurityDescriptorControl, GetSecurityDescriptorDacl, GetSecurityDescriptorGroup, GetSecurityDescriptorLength, GetSecurityDescriptorOwner, InitializeSecurityDescriptor, IsValidSecurityDescriptor, SECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL, SetSecurityDescriptorSacl


GetUserObjectSecurity

The GetUserObjectSecurity function retrieves security information for the specified user object.

BOOL GetUserObjectSecurity(
  HANDLE hObj,                        // handle to user object
  PSECURITY_INFORMATION pSIRequested, // request
  PSECURITY_DESCRIPTOR pSD,           // SD
  DWORD nLength,                      // size of SD
  LPDWORD lpnLengthNeeded             // required buffer size
);

Parameters

hObj
[in] Handle to the user object for which to return security information.
pSIRequested
[in] Pointer to a SECURITY_INFORMATION value specifying the security information being requested.
pSD
[in, out] Pointer to a SECURITY_DESCRIPTOR structure in self-relative format that contains the requested information when the function returns.

Windows 2000 or later: This buffer must be aligned on a 4-byte boundary.

nLength
[in] Specifies the length, in bytes, of the buffer pointed to by the pSD parameter.
lpnLengthNeeded
[out] Pointer to a variable receiving the number of bytes required to store the complete security descriptor. If this variable's value is greater than the value of the nLength parameter when the function returns, the function returns FALSE and none of the security descriptor is copied to the buffer. Otherwise, the entire security descriptor is copied.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

To read the owner, group, or DACL from the user object's security descriptor, the calling process must have been granted READ_CONTROL access when the handle was opened. To get READ_CONTROL access, the caller must be the owner of the object or the object's DACL must grant the access.

To read the SACL from the security descriptor, the calling process must have been granted ACCESS_SYSTEM_SECURITY access when the handle was opened. The proper way to get this access is to enable the SE_SECURITY_NAME privilege in the caller's current token, open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winuser.h; include Windows.h.
Library: Use User32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, CreatePrivateObjectSecurity, GetKernelObjectSecurity, GetPrivateObjectSecurity, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetUserObjectSecurity


InitializeAcl

The InitializeAcl function creates a new ACL structure.

An ACL is an access-control list.

BOOL InitializeAcl(
  PACL pAcl,            // ACL
  DWORD nAclLength,     // size of ACL
  DWORD dwAclRevision   // revision level of ACL
);

Parameters

pAcl
[out] Pointer to an ACL structure initialized by this function.
nAclLength
[in] Specifies the length, in bytes, of the buffer pointed to by the pAcl parameter. This value must be large enough to contain the ACL header and all of the access-control entries (ACEs) to be stored in the ACL. See the following Remarks section for more information about calculating the size of an ACL.
dwAclRevision
[in] Specifies the revision level of the ACL being created.

Windows NT 4.0 and earlier: This value must be ACL_REVISION.

Windows 2000 or later: This value can be ACL_REVISION or ACL_REVISION_DS. Use ACL_REVISION_DS if the ACL supports object-specific ACEs.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The ACL initialized by this function contains no ACEs. It is empty, as opposed to being a nonexistent ACL. If an empty ACL is applied to an object, it implicitly denies all access to that object.

To calculate the size of an ACL, add sizeof(ACL) to the size of all the ACEs to be stored in the ACL. To calculate the size of an ACE, add the size of the ACE structure, such as sizeof(ACCESS_ALLOWED_ACE), to the length of the SID associated with the ACE, and then subtract the size of the SidStart member (which is part of both the ACE structure and the SID). Use the GetSidLength function to get the length of a specified SID.

The following example shows how to calculate the size of an access-allowed ACE:

sizeof (ACCESS_ALLOWED_ACE) - sizeof (ACCESS_ALLOWED_ACE.SidStart)
        + GetLengthSid (pAceSid);

To calculate the size of an ACL, use the following algorithm, substituting the appropriate ACE structure in the sizeof(ACE) expression:

cbAcl = sizeof (ACL);
for (i = 0 ; i < nAceCount ; i++) {
    // subtract ACE.SidStart from the size
    cbAce = sizeof (ACE) - sizeof (DWORD);
    // add this ACE's SID length
    cbAce += GetLengthSid (pAceSid[i]);
    // add the length of each ACE to the total ACL length
    cbAcl += cbAce;
}

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACCESS_ALLOWED_ACE, ACCESS_DENIED_ACE, ACL, AddAccessAllowedAce, AddAccessDeniedAce, AddAce, AddAuditAccessAce, DeleteAce, GetAce, GetAclInformation, IsValidAcl, SetAclInformation, SID


InitializeSecurityDescriptor

The InitializeSecurityDescriptor function initializes a new security descriptor.

BOOL InitializeSecurityDescriptor(
  PSECURITY_DESCRIPTOR pSecurityDescriptor, // SD
  DWORD dwRevision                          // revision level
);

Parameters

pSecurityDescriptor
[out] Pointer to a SECURITY_DESCRIPTOR structure that the function initializes.
dwRevision
[in] Specifies the revision level to assign to the security descriptor. This parameter must be SECURITY_DESCRIPTOR_REVISION.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The InitializeSecurityDescriptor function initializes a security descriptor in absolute format, rather than self-relative format.

The InitializeSecurityDescriptor function initializes a security descriptor to have no system ACL, no discretionary ACL, no owner, no primary group, and all control flags set to FALSE (NULL). Thus, except for its revision level, it is empty.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetSecurityDescriptorControl, GetSecurityDescriptorDacl, GetSecurityDescriptorGroup, GetSecurityDescriptorLength, GetSecurityDescriptorOwner, GetSecurityDescriptorSacl, IsValidSecurityDescriptor, SECURITY_DESCRIPTOR, SetSecurityDescriptorDacl, SetSecurityDescriptorGroup, SetSecurityDescriptorOwner, SetSecurityDescriptorSacl


IsValidAcl

The IsValidAcl function validates an access-control list (ACL).

BOOL IsValidAcl(
  PACL pAcl   // access-control list
);

Parameters

pAcl
[in] Pointer to an ACL structure validated by this function. This must be a non-NULL value.

Return Values

If the ACL is valid, the return value is nonzero.

If the ACL is not valid, the return value is zero. There is no extended error information for this function; do not call GetLastError.

Remarks

This function checks the revision level of the ACL and verifies that the number of access-control entries (ACEs) specified in the AceCount member of the ACL structure fits the space specified by the AclSize member of the ACL structure.

If pAcl is NULL, the application will fail with an access violation.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, GetAclInformation, InitializeAcl


IsValidSecurityDescriptor

The IsValidSecurityDescriptor function determines whether the components of a security descriptor are valid.

BOOL IsValidSecurityDescriptor(
  PSECURITY_DESCRIPTOR pSecurityDescriptor  // SD
);

Parameters

pSecurityDescriptor
[in] Pointer to a SECURITY_DESCRIPTOR structure that the function validates.

Return Values

If the components of the security descriptor are valid, the return value is nonzero.

If any of the components of the security descriptor are not valid, the return value is zero. There is no extended error information for this function; do not call GetLastError.

Remarks

The IsValidSecurityDescriptor function checks the validity of the components that are present in the security descriptor. It does not verify whether certain components are present.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetSecurityDescriptorControl, GetSecurityDescriptorDacl, GetSecurityDescriptorGroup, GetSecurityDescriptorLength, GetSecurityDescriptorOwner, GetSecurityDescriptorSacl, InitializeSecurityDescriptor, IsValidAcl, IsValidSid, SECURITY_DESCRIPTOR, SetSecurityDescriptorDacl, SetSecurityDescriptorGroup, SetSecurityDescriptorOwner, SetSecurityDescriptorSacl


MakeAbsoluteSD

The MakeAbsoluteSD function creates a security descriptor in absolute format by using a security descriptor in self-relative format as a template.

BOOL MakeAbsoluteSD(
  PSECURITY_DESCRIPTOR pSelfRelativeSD, // self-relative SD
  PSECURITY_DESCRIPTOR pAbsoluteSD,     // absolute SD
  LPDWORD lpdwAbsoluteSDSize,           // absolute SD size
  PACL pDacl,                           // DACL
  LPDWORD lpdwDaclSize,                 // size of DACL
  PACL pSacl,                           // SACL
  LPDWORD lpdwSaclSize,                 // size of SACL
  PSID pOwner,                          // owner SID
  LPDWORD lpdwOwnerSize,                // size of owner SID
  PSID pPrimaryGroup,                   // primary-group SID
  LPDWORD lpdwPrimaryGroupSize          // size of group SID
);

Parameters

pSelfRelativeSD
[in] Pointer to a SECURITY_DESCRIPTOR structure in self-relative format. The function creates an absolute-format version of this security descriptor without modifying the original security descriptor.
pAbsoluteSD
[out] Pointer to a buffer that the function fills with the main body of an absolute-format security descriptor. This information is formatted as a SECURITY_DESCRIPTOR structure.
lpdwAbsoluteSDSize
[out] Pointer to a variable specifying the size of the buffer pointed to by the pAbsoluteSD parameter. If the buffer is not large enough for the security descriptor, the function fails and sets this variable to the minimum required size.
pDacl
[out] Pointer to a buffer the function fills with the discretionary access-control list (ACL) of the absolute-format security descriptor. The main body of the absolute-format security descriptor references this pointer.
lpdwDaclSize
[out] Pointer to a variable specifying the size of the buffer pointed to by the pDacl parameter. If the buffer is not large enough for the ACL, the function fails and sets this variable to the minimum required size.
pSacl
[out] Pointer to a buffer the function fills with the system ACL of the absolute-format security descriptor. The main body of the absolute-format security descriptor references this pointer.
lpdwSaclSize
[out] Pointer to a variable specifying the size of the buffer pointed to by the pSacl parameter. If the buffer is not large enough for the ACL, the function fails and sets this variable to the minimum required size.
pOwner
[out] Pointer to a buffer the function fills with the security identifier (SID) of the owner of the absolute-format security descriptor. The main body of the absolute-format security descriptor references this pointer.
lpdwOwnerSize
[out] Pointer to a variable specifying the size of the buffer pointed to by the pOwner parameter. If the buffer is not large enough for the SID, the function fails and sets this variable to the minimum required size.
pPrimaryGroup
[out] Pointer to a buffer the function fills with the SID of the absolute-format security descriptor's primary group. The main body of the absolute-format security descriptor references this pointer.
lpdwPrimaryGroupSize
[out] Pointer to a variable specifying the size of the buffer pointed to by the pPrimaryGroup parameter. If the buffer is not large enough for the SID, the function fails and sets this variable to the minimum required size.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

A security descriptor in absolute format contains pointers to the information it contains, rather than the information itself. A security descriptor in self-relative format contains the information in a contiguous block of memory. In a self-relative security descriptor, a SECURITY_DESCRIPTOR structure always starts the information, but the security descriptor's other components can follow the structure in any order. Instead of using memory addresses, the components of the self-relative security descriptor are identified by offsets from the beginning of the security descriptor. This format is useful when an security descriptor must be stored on a floppy disk or transmitted by means of a communications protocol.

A server that copies secured objects to various media can use the MakeAbsoluteSD function to create an absolute security descriptor from a self-relative security descriptor and the MakeSelfRelativeSD function to create a self-relative security descriptor from an absolute security descriptor.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, MakeSelfRelativeSD, SECURITY_DESCRIPTOR


MakeSelfRelativeSD

The MakeSelfRelativeSD function creates a security descriptor in self-relative format by using a security descriptor in absolute format as a template.

BOOL MakeSelfRelativeSD(
  PSECURITY_DESCRIPTOR pAbsoluteSD,     // absolute SD
  PSECURITY_DESCRIPTOR pSelfRelativeSD, // self-relative SD
  LPDWORD lpdwBufferLength              // buffer size
);

Parameters

pAbsoluteSD
[in] Pointer to a SECURITY_DESCRIPTOR structure in absolute format. The function creates a version of this security descriptor in self-relative format without modifying the original.
pSelfRelativeSD
[out] Pointer to a buffer the function fills with a security descriptor in self-relative format.
lpdwBufferLength
[out] Pointer to a variable specifying the size of the buffer pointed to by the pSelfRelativeSD parameter. If the buffer is not large enough for the security descriptor, the function fails and sets this variable to the minimum required size.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

A security descriptor in absolute format contains pointers to the information it contains, rather than containing the information itself. A security descriptor in self-relative format contains the information in a contiguous block of memory. In a self-relative security descriptor, a SECURITY_DESCRIPTOR structure always starts the information, but the security descriptor's other components can follow the structure in any order. Instead of using memory addresses, the components of the security descriptor are identified by offsets from the beginning of the security descriptor. This format is useful when an security descriptor must be stored on a floppy disk or transmitted by means of a communications protocol.

A server that copies secured objects to various media can use the MakeSelfRelativeSD function to create a self-relative security descriptor from an absolute security descriptor and the MakeAbsoluteSD function to create an absolute security descriptor from a self-relative security descriptor.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, MakeAbsoluteSD, SECURITY_DESCRIPTOR


QueryServiceObjectSecurity

The QueryServiceObjectSecurity function retrieves a copy of the security descriptor associated with a service object.

Windows NT 4.0 and later: You can use the GetNamedSecurityInfo function.

BOOL QueryServiceObjectSecurity(
  SC_HANDLE hService,                         // handle to service
  SECURITY_INFORMATION dwSecurityInformation, // request
  PSECURITY_DESCRIPTOR lpSecurityDescriptor,  // SD
  DWORD cbBufSize,                            // size of SD
  LPDWORD pcbBytesNeeded                      // bytes needed
);

Parameters

hService
[in] Handle to the service. This handle is returned by the OpenService or CreateService function, and it must have READ_CONTROL access.
dwSecurityInformation
[in] Specifies the security information being requested. This parameter can be a combination of the following values.
Value | Meaning
DACL_SECURITY_INFORMATION | Requests the object's discretionary access control list (ACL).
GROUP_SECURITY_INFORMATION | Requests the object's primary group SID.
OWNER_SECURITY_INFORMATION | Requests the object's owner security identifier (SID).
SACL_SECURITY_INFORMATION | Requests the object's system ACL. The calling process must have the SE_SECURITY_NAME privilege. The proper way to obtain this access is to enable the SE_SECURITY_NAME privilege in the caller's current access token, open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege.

lpSecurityDescriptor
[out] Pointer to a buffer that receives a copy of the security descriptor of the specified service object. The calling process must have the appropriate access to view the specified aspects of the object's security descriptor. The SECURITY_DESCRIPTOR structure is returned in self-relative format.
cbBufSize
[in] Specifies the size, in bytes, of the buffer pointed to by the lpSecurityDescriptor parameter.
pcbBytesNeeded
[out] Pointer to a variable that receives the number of bytes needed to return all the requested security descriptor information, if the function fails.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Errors

The following error codes may be set by the service control manager. Other error codes may be set by the registry functions that are called by the service control manager.

Value | Meaning
ERROR_ACCESS_DENIED | The specified handle was not opened with READ_CONTROL access, or the calling process is not the owner of the object.
ERROR_INVALID_HANDLE | The specified handle is invalid.
ERROR_INSUFFICIENT_BUFFER | There is more security descriptor information than would fit into the lpSecurityDescriptor buffer. The number of bytes required to get all the information is returned in the pcbBytesNeeded parameter. Nothing is written to the lpSecurityDescriptor buffer.
ERROR_INVALID_PARAMETER | The specified security information is invalid.

Remarks

When a service is created, the service control manager assigns a default security descriptor to the service object. To retrieve a copy of the security descriptor for a service object, call the QueryServiceObjectSecurity function. To change the security descriptor, call the SetServiceObjectSecurity function. For a description of the default security descriptor for a service object, see Service Security.

To read the owner, group, or DACL from the service object's security descriptor, the calling process must have been granted READ_CONTROL access when the handle was opened. To get READ_CONTROL access, the caller must be the owner of the object or the object's DACL must grant the access.

To read the SACL from the security descriptor, the calling process must have been granted ACCESS_SYSTEM_SECURITY access when the handle was opened. The proper way to get this access is to enable the SE_SECURITY_NAME privilege in the caller's current token, open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winsvc.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, CreateService, OpenService, SECURITY_DESCRIPTOR, SetServiceObjectSecurity


RegGetKeySecurity

The RegGetKeySecurity function retrieves a copy of the security descriptor protecting the specified open registry key.

LONG RegGetKeySecurity(
  HKEY hKey,                                // handle to key
  SECURITY_INFORMATION SecurityInformation, // request
  PSECURITY_DESCRIPTOR pSecurityDescriptor, // SD
  LPDWORD lpcbSecurityDescriptor            // buffer size
);

Parameters

hKey
[in] Handle to an open key for which to retrieve the security descriptor.
SecurityInformation
[in] Specifies a SECURITY_INFORMATION value that indicates the requested security information.
pSecurityDescriptor
[out] Pointer to a buffer that receives a copy of the requested security descriptor.
lpcbSecurityDescriptor
[in, out] Pointer to a variable that specifies the size, in bytes, of the buffer pointed to by the pSecurityDescriptor parameter. When the function returns, the variable contains the number of bytes written to the buffer.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

If the buffer specified by the pSecurityDescriptor parameter is too small, the function returns ERROR_INSUFFICIENT_BUFFER and the lpcbSecurityDescriptor parameter contains the number of bytes required for the requested security descriptor.

To read the owner, group, or DACL from the key's security descriptor, the calling process must have been granted READ_CONTROL access when the handle was opened. To get READ_CONTROL access, the caller must be the owner of the key or the key's DACL must grant the access.

To read the SACL from the security descriptor, the calling process must have been granted ACCESS_SYSTEM_SECURITY access when the key was opened. The proper way to get this access is to enable the SE_SECURITY_NAME privilege in the caller's current token, open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winreg.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, RegDeleteKey, RegOpenKeyEx, RegSetKeySecurity, SECURITY_INFORMATION


RegSetKeySecurity

The RegSetKeySecurity function sets the security of an open registry key.

LONG RegSetKeySecurity(
  HKEY hKey,                                // handle to key
  SECURITY_INFORMATION SecurityInformation, // request
  PSECURITY_DESCRIPTOR pSecurityDescriptor  // SD
);

Parameters

hKey
[in] Handle to an open key for which the security descriptor is set.
SecurityInformation
[in] Specifies the components of the security descriptor to set. The value can be a combination of the following values.
Value | Meaning
DACL_SECURITY_INFORMATION | Sets the key's discretionary access control list (DACL). The hKey handle must have WRITE_DAC access, or the calling process must be the object's owner.
GROUP_SECURITY_INFORMATION | Sets the key's primary group SID. The hKey handle must have WRITE_OWNER access, or the calling process must be the object's owner.
OWNER_SECURITY_INFORMATION | Sets the key's owner security identifier (SID). The hKey handle must have WRITE_OWNER access, or the calling process must be the object's owner or have the SE_TAKE_OWNERSHIP_NAME privilege enabled.
SACL_SECURITY_INFORMATION | Sets the key's system access control list (SACL). The hKey handle must have ACCESS_SYSTEM_SECURITY access. The proper way to get this access is to enable the SE_SECURITY_NAME privilege in the caller's current access token, open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege.

pSecurityDescriptor
[in] Pointer to a SECURITY_DESCRIPTOR structure that specifies the security attributes to set for the specified key.

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

If hKey is one of the predefined keys, the predefined key should be closed with RegCloseKey. That ensures that the new security information is in effect the next time the predefined key is referenced.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winreg.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, RegCloseKey, RegDeleteKey, RegGetKeySecurity, SECURITY_DESCRIPTOR, SECURITY_INFORMATION


SetAclInformation

The SetAclInformation function sets information about an access-control list (ACL).

BOOL SetAclInformation(
  PACL pAcl,                                  // access-control list
  LPVOID pAclInformation,                     // ACL information
  DWORD nAclInformationLength,                // size of ACL information
  ACL_INFORMATION_CLASS dwAclInformationClass // class
);

Parameters

pAcl
[in] Pointer to an ACL structure. The function sets information in this ACL.
pAclInformation
[out] Pointer to a buffer containing the information to be set. This must be a pointer to an ACL_REVISION_INFORMATION structure.
nAclInformationLength
[in] Specifies the size, in bytes, of the buffer pointed to by the pAclInfo parameter.
dwAclInformationClass
[in] Specifies an ACL_INFORMATION_CLASS enumerated type that gives the class of information requested.

Currently, this parameter can be AclRevisionInformation. This means that the buffer pointed to by the pAclInformation parameter contains an ACL_REVISION_INFORMATION structure.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, ACL_INFORMATION_CLASS, ACL_REVISION_INFORMATION, GetAclInformation, InitializeAcl, IsValidAcl


SetFileSecurity

The SetFileSecurity function sets the security of a file or directory object.

Windows NT 4.0 and later: You can use the SetNamedSecurityInfo function.

BOOL SetFileSecurity(
  LPCTSTR lpFileName,                       // file name
  SECURITY_INFORMATION SecurityInformation, // contents
  PSECURITY_DESCRIPTOR pSecurityDescriptor  // SD
);

Parameters

lpFileName
[in] Pointer to a null-terminated string specifying the file or directory for which security is set. Note that security applied to a directory is not inherited by its children.
SecurityInformation
[in] Specifies a SECURITY_INFORMATION structure identifying the contents of the security descriptor pointed to by the pSecurityDescriptor parameter.
pSecurityDescriptor
[in] Pointer to a SECURITY_DESCRIPTOR structure.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The SetFileSecurity function is successful only if the following conditions are met:

  • If the object's owner is being set, the calling process must have either WRITE_OWNER permission or be the object's owner.
  • If the object's discretionary access-control list (ACL) is being set, the calling process must have either WRITE_DAC permission or be the object's owner.
  • If the object's system ACL is being set, the SE_SECURITY_NAME privilege must be enabled for the calling process.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetFileSecurity, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetKernelObjectSecurity, SetPrivateObjectSecurity, SetUserObjectSecurity


SetKernelObjectSecurity

The SetKernelObjectSecurity function sets the security of a kernel object. For example, this can be a process, thread, or event.

BOOL SetKernelObjectSecurity(
  HANDLE Handle,                            // handle to object
  SECURITY_INFORMATION SecurityInformation, // components
  PSECURITY_DESCRIPTOR SecurityDescriptor   // SD
);

Parameters

Handle
[in] Handle to a kernel object for which security information is set.
SecurityInformation
[in] Specifies the components of the security descriptor to set. The parameter can be a combination of the following values.
Value | Meaning
DACL_SECURITY_INFORMATION | Sets the object's discretionary access control list (DACL). The handle must have WRITE_DAC access, or the calling process must be the object's owner.
GROUP_SECURITY_INFORMATION | Sets the object's primary group SID. The handle must have WRITE_OWNER access, or the calling process must be the object's owner.
OWNER_SECURITY_INFORMATION | Sets the object's owner security identifier (SID). The handle must have WRITE_OWNER access, or the calling process must be the object's owner or have the SE_TAKE_OWNERSHIP_NAME privilege enabled.
SACL_SECURITY_INFORMATION | Sets the object's system access control list (SACL). The handle must have ACCESS_SYSTEM_SECURITY access. The proper way to get this access is to enable the SE_SECURITY_NAME privilege in the caller's current access token, open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege.

SecurityDescriptor
[in] Pointer to a SECURITY_DESCRIPTOR structure containing the new security information.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetKernelObjectSecurity, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetFileSecurity, SetPrivateObjectSecurity, SetUserObjectSecurity


SetSecurityDescriptorDacl

The SetSecurityDescriptorDacl function sets information in a discretionary access-control list (ACL). If a discretionary ACL is already present in the security descriptor, it is replaced.

BOOL SetSecurityDescriptorDacl(
  PSECURITY_DESCRIPTOR pSecurityDescriptor, // SD
  BOOL bDaclPresent,                        // DACL presence
  PACL pDacl,                               // DACL
  BOOL bDaclDefaulted                       // default DACL
);

Parameters

pSecurityDescriptor
[in, out] Pointer to the SECURITY_DESCRIPTOR structure to which the function adds the discretionary ACL. This security descriptor must be in absolute format, meaning that its members must be pointers to other structures, rather than offsets to contiguous data.
bDaclPresent
[in] Specifies a flag indicating the presence of a discretionary ACL in the security descriptor. If this parameter is TRUE, the function sets the SE_DACL_PRESENT flag in the SECURITY_DESCRIPTOR_CONTROL structure and uses the values in the pDacl and bDaclDefaulted parameters. If it is FALSE, the function clears the SE_DACL_PRESENT flag, and pDacl and bDaclDefaulted are ignored.
pDacl
[in] Pointer to an ACL structure specifying the discretionary ACL for the security descriptor. If this parameter is NULL, a NULL discretionary ACL is assigned to the security descriptor, allowing all access to the object. The discretionary ACL is referenced by, not copied into, the security descriptor.
bDaclDefaulted
[in] Specifies a flag indicating the source of the discretionary ACL. If this flag is TRUE, the discretionary ACL has been retrieved by some default mechanism. If FALSE, the discretionary ACL has been explicitly specified by a user. The function stores this value in the SE_DACL_DEFAULTED flag of the SECURITY_DESCRIPTOR_CONTROL structure. If this parameter is not specified, the SE_DACL_DEFAULTED flag is cleared.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

There is an important difference between an empty and a nonexistent discretionary ACL (DACL). When a DACL is empty, it contains no access-control entries (ACEs); therefore, no access rights are explicitly granted. As a result, access to the object is implicitly denied.

When an object has no DACL (when the pDacl parameter is NULL), no protection is assigned to the object, and all access requests are granted. Allowing this type of full access to objects can create serious security threats.

There are three possible outcomes in different configurations of the bDaclPresent flag and the pDacl parameter:

  • When the pDacl parameter points to a discretionary ACL and the bDaclPresent flag is TRUE, a discretionary ACL is specified and it must contain access-allowed ACEs to allow access to the object.
  • When the pDacl parameter does not point to a discretionary ACL and the bDaclPresent flag is TRUE, a NULL discretionary ACL is specified. All access is allowed. You should not use a NULL DACL with an object because any user can change the DACL and owner of the security descriptor and interfere with use of the object.
  • When the pDacl parameter does not point to a discretionary ACL and the bDaclPresent flag is FALSE, a discretionary ACL can be provided for the object through an inheritance or default mechanism.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, GetSecurityDescriptorDacl, InitializeSecurityDescriptor, IsValidSecurityDescriptor, SECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL, SetSecurityDescriptorGroup, SetSecurityDescriptorOwner, SetSecurityDescriptorSacl


SetSecurityDescriptorGroup

The SetSecurityDescriptorGroup function sets the primary group information of an absolute-format security descriptor, replacing any primary group information already present in the security descriptor.

BOOL SetSecurityDescriptorGroup(
  PSECURITY_DESCRIPTOR pSecurityDescriptor, // SD
  PSID pGroup,                              // group SID
  BOOL bGroupDefaulted                      // default group
);

Parameters

pSecurityDescriptor
[in, out] Pointer to the SECURITY_DESCRIPTOR structure whose primary group is set by this function. The function replaces any existing primary group with the new primary group.
pGroup
[in] Pointer to a SID structure for the security descriptor's new primary group. The SID structure is referenced by, not copied into, the security descriptor. If this parameter is NULL, the function clears the security descriptor's primary group information. This marks the security descriptor as having no primary group.
bGroupDefaulted
[in] Indicates whether the primary group information was derived from a default mechanism. If this value is TRUE, it is default information, and the function stores this value as the SE_GROUP_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure. If this parameter is zero, the SE_GROUP_DEFAULTED flag is cleared.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetSecurityDescriptorGroup, InitializeSecurityDescriptor, SECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL, SetSecurityDescriptorDacl, SetSecurityDescriptorOwner, SetSecurityDescriptorSacl, SID


SetSecurityDescriptorOwner

The SetSecurityDescriptorOwner function sets the owner information of an absolute-format security descriptor. It replaces any owner information already present in the security descriptor.

BOOL SetSecurityDescriptorOwner(
  PSECURITY_DESCRIPTOR pSecurityDescriptor, // SD
  PSID pOwner,                              // SID for owner
  BOOL bOwnerDefaulted                      // flag for default
);

Parameters

pSecurityDescriptor
[in, out] Pointer to the SECURITY_DESCRIPTOR structure whose owner is set by this function. The function replaces any existing owner with the new owner.
pOwner
[in] Pointer to a SID structure for the security descriptor's new primary owner. The SID structure is referenced by, not copied into, the security descriptor. If this parameter is NULL, the function clears the security descriptor's owner information. This marks the security descriptor as having no owner.
bOwnerDefaulted
[in] Indicates whether the owner information is derived from a default mechanism. If this value is TRUE, it is default information. The function stores this value as the SE_OWNER_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure. If this parameter is zero, the SE_OWNER_DEFAULTED flag is cleared.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetSecurityDescriptorOwner, InitializeSecurityDescriptor, IsValidSecurityDescriptor, SECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL, SetSecurityDescriptorDacl, SetSecurityDescriptorGroup, SetSecurityDescriptorSacl, SID


SetSecurityDescriptorSacl

The SetSecurityDescriptorSacl function sets information in a system access-control list (SACL). If there is already a system ACL present in the security descriptor, it is replaced.

BOOL SetSecurityDescriptorSacl(
  PSECURITY_DESCRIPTOR pSecurityDescriptor, // SD
  BOOL bSaclPresent,                        // SACL presence
  PACL pSacl,                               // SACL
  BOOL bSaclDefaulted                       // default SACL
);

Parameters

pSecurityDescriptor
[in, out] Pointer to the SECURITY_DESCRIPTOR structure to which the function adds the system ACL. This security descriptor must be in absolute format, meaning that its members must be pointers to other structures, rather than offsets to contiguous data.
bSaclPresent
[in] Indicates the presence of a system ACL in the security descriptor. If this parameter is TRUE, the function sets the SE_SACL_PRESENT flag in the SECURITY_DESCRIPTOR_CONTROL structure and uses the values in the pSacl and bSaclDefaulted parameters. If it is FALSE, the function does not set the SE_SACL_PRESENT flag, and pSacl and bSaclDefaulted are ignored.
pSacl
[in] Pointer to an ACL structure that specifies the system ACL for the security descriptor. If this parameter is NULL, a NULL system ACL is assigned to the security descriptor. The system ACL is referenced by, not copied into, the security descriptor.
bSaclDefaulted
[in] Indicates the source of the system ACL. If this flag is TRUE, the system ACL has been retrieved by some default mechanism. If it is FALSE, the system ACL has been explicitly specified by a user. The function stores this value in the SE_SACL_DEFAULTED flag of the SECURITY_DESCRIPTOR_CONTROL structure. If this parameter is not specified, the SE_SACL_DEFAULTED flag is cleared.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, ACL, GetSecurityDescriptorSacl, InitializeSecurityDescriptor, IsValidSecurityDescriptor, SECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL, SetSecurityDescriptorDacl, SetSecurityDescriptorGroup, SetSecurityDescriptorOwner


SetServiceObjectSecurity

The SetServiceObjectSecurity function sets the security descriptor of a service object.

Windows NT 4.0 and later: You can use the SetNamedSecurityInfo function.

BOOL SetServiceObjectSecurity(
  SC_HANDLE hService,                         // handle to service
  SECURITY_INFORMATION dwSecurityInformation, // components
  PSECURITY_DESCRIPTOR lpSecurityDescriptor   // SD
);

Parameters

hService
[in] Handle to the service. This handle is returned by the OpenService or CreateService function. The access required for this handle depends on the security information specified in the dwSecurityInformation parameter.
dwSecurityInformation
[in] Specifies the components of the security descriptor to set. This parameter can be a combination of the following values. Note that flags not handled by SetServiceObjectSecurity will be silently ignored.
Value | Meaning
DACL_SECURITY_INFORMATION | Sets the object's discretionary access control list (DACL). The hService handle must have WRITE_DAC access, or the calling process must be the object's owner.
GROUP_SECURITY_INFORMATION | Sets the object's primary group SID. The hService handle must have WRITE_OWNER access, or the calling process must be the object's owner.
OWNER_SECURITY_INFORMATION | Sets the object's owner security identifier (SID). The hService handle must have WRITE_OWNER access, or the calling process must be the object's owner or have the SE_TAKE_OWNERSHIP_NAME privilege enabled.
SACL_SECURITY_INFORMATION | Sets the object's system access control list (SACL). The hService handle must have ACCESS_SYSTEM_SECURITY access. The proper way to obtain this access is to enable the SE_SECURITY_NAME privilege in the caller's current access token, open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege.

lpSecurityDescriptor
[in] Pointer to a SECURITY_DESCRIPTOR structure containing the new security information.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Errors

The following error codes can be set by the service control manager. Other error codes can be set by the registry functions that are called by the service control manager.

Value | Meaning
ERROR_ACCESS_DENIED | The specified handle was not opened with the required access, or the calling process is not the owner of the object.
ERROR_INVALID_HANDLE | The specified handle is invalid.
ERROR_INVALID_PARAMETER | The specified security information or security descriptor is invalid.
ERROR_SERVICE_MARKED_FOR_DELETE | The specified service has been marked for deletion.

Remarks

The SetServiceObjectSecurity function sets the specified portions of the service object's security descriptor, based on the information specified in the lpSecurityDescriptor buffer. This function replaces any or all of the security information associated with the service object, according to the flags set in the dwSecurityInformation parameter and subject to the calling process's access rights.

When a service is created, the service control manager assigns a default security descriptor to the service object. To retrieve a copy of the security descriptor for a service object, call the QueryServiceObjectSecurity function. For a description of the default security descriptor for a service object, see Service Security.

Note that granting certain access to untrusted users (such as SERVICE_CHANGE_CONFIG or SERVICE_STOP) can allow them to interfere with the execution of your service, and possible allow them to run applications under the LocalSystem account.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winsvc.h; include Windows.h.
Library: Use Advapi32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, CreateService, OpenService, QueryServiceObjectSecurity, SECURITY_DESCRIPTOR


SetUserObjectSecurity

The SetUserObjectSecurity function sets the security of a user object. This can be, for example, a window or a DDE conversation.

BOOL SetUserObjectSecurity(
  HANDLE hObj,                         // handle to user object
  PSECURITY_INFORMATION pSIRequested,  // components
  PSECURITY_DESCRIPTOR pSD             // SD
);

Parameters

hObj
[in] Handle to a user object for which security information is set.
pSIRequested
[in] Pointer to a value that indicates the components of the security descriptor to set. This parameter can be a combination of the following values.
Value | Meaning
DACL_SECURITY_INFORMATION | Sets the object's discretionary access control list (DACL). The hObj handle must have WRITE_DAC access, or the calling process must be the object's owner.
GROUP_SECURITY_INFORMATION | Sets the object's primary group SID. The hObj handle must have WRITE_OWNER access, or the calling process must be the object's owner.
OWNER_SECURITY_INFORMATION | Sets the object's owner security identifier (SID). The hObj handle must have WRITE_OWNER access, or the calling process must be the object's owner or have the SE_TAKE_OWNERSHIP_NAME privilege enabled.
SACL_SECURITY_INFORMATION | Sets the object's system access control list (SACL). The hObj handle must have ACCESS_SYSTEM_SECURITY access. The proper way to get this access is to enable the SE_SECURITY_NAME privilege in the caller's current access token, open the handle for ACCESS_SYSTEM_SECURITY access, and then disable the privilege.

pSD
[in] Pointer to a SECURITY_DESCRIPTOR structure containing the new security information.

Windows 2000 or later: This buffer must be aligned on a 4-byte boundary.

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The SetUserObjectSecurity function applies changes specified in a security descriptor to the security descriptor assigned to a user object. The object's security descriptor must be in self-relative form. If necessary, this function allocates additional memory to increase the size of the security descriptor.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winuser.h; include Windows.h.
Library: Use User32.lib.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Functions, GetUserObjectSecurity, SECURITY_DESCRIPTOR, SECURITY_INFORMATION, SetFileSecurity, SetKernelObjectSecurity, SetPrivateObjectSecurity


Low-Level Access Control Structures

The following structures are used with low-level access control.

ACCESS_ALLOWED_ACE
ACCESS_ALLOWED_OBJECT_ACE
ACCESS_DENIED_ACE
ACCESS_DENIED_OBJECT_ACE
ACL_REVISION_INFORMATION
ACL_SIZE_INFORMATION
SECURITY_DESCRIPTOR_CONTROL
SYSTEM_AUDIT_ACE
SYSTEM_AUDIT_OBJECT_ACE

The following structures are reserved for future use.

SYSTEM_ALARM_ACE
SYSTEM_ALARM_OBJECT_ACE


ACCESS_ALLOWED_ACE

The ACCESS_ALLOWED_ACE structure defines an access-control entry (ACE) for the discretionary access-control list (DACL) that controls access to an object. An access-allowed ACE allows access to an object for a specific subject identified by a security identifier (SID).

typedef struct _ACCESS_ALLOWED_ACE {
  ACE_HEADER Header;
  ACCESS_MASK Mask;
  DWORD SidStart;
} ACCESS_ALLOWED_ACE;

Members

Header
Specifies an ACE_HEADER structure.
Mask
Specifies an ACCESS_MASK structure that specifies the access rights granted by this ACE.
SidStart
Specifies a SID. The access rights specified by the Mask member are granted to any subject possessing an enabled SID matching this member.

Remarks

ACE structures must be aligned on DWORD boundaries. All Win32 memory-management functions return DWORD-aligned handles to memory.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Structures, AddAccessAllowedAce, AddAce, GetAce, ACCESS_DENIED_ACE, ACCESS_MASK, ACE_HEADER, ACL, SID, SYSTEM_ALARM_ACE, SYSTEM_AUDIT_ACE


ACCESS_ALLOWED_OBJECT_ACE

The ACCESS_ALLOWED_OBJECT_ACE structure defines an access-control entry (ACE). The ACE can control access to an object, or to a subobject of an object, such as a property set or property. The ACE contains a set of access rights, a GUID that identifies the type of object or subobject, and a SID that identifies the trustee to whom the system will grant access. The ACE also contains a GUID and a set of flags that control inheritance of the ACE by child objects.

typedef struct _ACCESS_ALLOWED_OBJECT_ACE {
  ACE_HEADER Header;
  ACCESS_MASK Mask;
  DWORD Flags;
  GUID ObjectType;
  GUID InheritedObjectType;
  DWORD SidStart;
} ACCESS_ALLOWED_OBJECT_ACE, *PACCESS_ALLOWED_OBJECT_ACE;

Members

Header
An ACE_HEADER structure that specifies the size and type of ACE. It also contains flags that control inheritance of the ACE by child objects.
Mask
An ACCESS_MASK that specifies the access rights the system will allow to the trustee.
Flags
A set of bit flags that indicate whether the ObjectType and InheritedObjectType members are present. This parameter can be one or more of the following values.
Value | Meaning
0 | Neither ObjectType nor InheritedObjectType are present. The SidStart member follows immediately after the Flags member.
ACE_OBJECT_TYPE_PRESENT ObjectType is present and contains a GUID.

If this value is not specified, the InheritedObjectType member follows immediately after the Flags member.

ACE_INHERITED_OBJECT_TYPE_PRESENT InheritedObjectType is present and contains a GUID.

If this value is not specified, all types of child objects can inherit the ACE.

ObjectType
This member exists only if the ACE_OBJECT_TYPE_PRESENT bit is set in the Flags member. Otherwise, the InheritedObjectType member follows immediately after the Flags member.

If this member exists, it is a GUID structure that identifies a property set, property, extended right, or type of child object. The purpose of this GUID depends on the access rights specified in the Mask member.
Access rights | Meaning
ADS_RIGHT_DS_CONTROL_ACCESS | The ObjectType GUID identifies an extended access right.
ADS_RIGHT_DS_CREATE_CHILD | The ObjectType GUID identifies a type of child object. The ACE controls the trustee's right to create this type of child object.
ADS_RIGHT_DS_READ_PROP | The ObjectType GUID identifies a property set or property of the object. The ACE controls the trustee's right to read the property or property set.
ADS_RIGHT_DS_WRITE_PROP | The ObjectType GUID identifies a property set or property of the object. The ACE controls the trustee's right to write the property or property set.
ADS_RIGHT_DS_SELF | The ObjectType GUID identifies a validated write.

InheritedObjectType
This member exists only if the ACE_INHERITED_OBJECT_TYPE_PRESENT bit is set in the Flags member.

If this member exists, it is a GUID structure that identifies the type of child object that can inherit the ACE. Inheritance is also controlled by the inheritance flags in the ACE_HEADER, as well as by any protection against inheritance placed on the child objects.

The offset of this member can vary. If the Flags member does not contain the ACE_OBJECT_TYPE_PRESENT flag, the InheritedObjectType member starts at the offset specified by the ObjectType member.

SidStart
Specifies the first DWORD of a SID that identifies the trustee to whom the access rights are granted.

The offset of this member can vary. If the Flags member is zero, the SidStart member starts at the offset specified by the ObjectType member. If Flags contains only one flag (either ACE_OBJECT_TYPE_PRESENT or ACE_INHERITED_OBJECT_TYPE_PRESENT), the SidStart member starts at the offset specified by the InheritedObjectType member.

Remarks

If neither the ObjectType nor InheritedObjectType GUID is specified, the ACCESS_ALLOWED_OBJECT_ACE structure has the same semantics as those used by the ACCESS_ALLOWED_ACE structure. In that case, use the ACCESS_ALLOWED_ACE structure because it is smaller and more efficient.

An ACL that contains an ACCESS_ALLOWED_OBJECT_ACE must specify the ACL_REVISION_DS revision number in its ACL header.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Structures, ACCESS_ALLOWED_ACE, ACCESS_DENIED_OBJECT_ACE, ACCESS_MASK, ACE_HEADER, ACL, AddAccessAllowedObjectAce, GUID, SID, SYSTEM_AUDIT_OBJECT_ACE


ACCESS_DENIED_ACE

The ACCESS_DENIED_ACE structure defines an access-control entry (ACE) for the discretionary access-control list (DACL) controlling access to an object. An access-denied ACE denies access to an object for a specific subject identified by a security identifier (SID).

typedef struct _ACCESS_DENIED_ACE {
  ACE_HEADER Header;
  ACCESS_MASK Mask;
  DWORD SidStart;
} ACCESS_DENIED_ACE;

Members

Header
Specifies an ACE_HEADER structure.
Mask
Specifies an ACCESS_MASK structure specifying the access rights explicitly denied by this ACE.
SidStart
Specifies a SID. The access rights specified by the Mask member are denied to any subject possessing an enabled SID matching this member.

Remarks

ACE structures must be aligned on DWORD boundaries. All Win32 memory-management functions return DWORD-aligned handles to memory.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Structures, AddAccessDeniedAce, ACCESS_ALLOWED_ACE, ACCESS_MASK, ACE_HEADER, ACL, SID, SYSTEM_ALARM_ACE, SYSTEM_AUDIT_ACE


ACCESS_DENIED_OBJECT_ACE

The ACCESS_DENIED_OBJECT_ACE structure defines an access-control entry (ACE). The ACE can control access to an object, or to a subobject of an object, such as a property set or property. The ACE contains a set of access rights, a GUID that identifies the type of object or subobject, and a SID that identifies the trustee to whom the system will deny access. The ACE also contains a GUID and a set of flags that control inheritance of the ACE by child objects.

typedef struct _ACCESS_DENIED_OBJECT_ACE {
  ACE_HEADER Header;
  ACCESS_MASK Mask;
  DWORD Flags;
  GUID ObjectType;
  GUID InheritedObjectType;
  DWORD SidStart;
} ACCESS_DENIED_OBJECT_ACE, *PACCESS_DENIED_OBJECT_ACE;

Members

Header
An ACE_HEADER structure that specifies the size and type of ACE. It contains flags that control inheritance of the ACE by child objects.
Mask
An ACCESS_MASK that specifies the access rights the system will deny to the trustee.
Flags
A set of bit flags that indicate whether the ObjectType and InheritedObjectType members are present. This parameter can be one or more of the following values.
Value | Meaning
0 | Neither ObjectType nor InheritedObjectType are present. The SidStart member follows immediately after the Flags member.
ACE_OBJECT_TYPE_PRESENT ObjectType is present and contains a GUID.

If this value is not specified, the InheritedObjectType member follows immediately after the Flags member.

ACE_INHERITED_OBJECT_TYPE_PRESENT InheritedObjectType is present and contains a GUID.

If this value is not specified, all types of child objects can inherit the ACE.

ObjectType
This member exists only if the ACE_OBJECT_TYPE_PRESENT bit is set in the Flags member. Otherwise, the InheritedObjectType member follows immediately after the Flags member.

If this member exists, it is a GUID structure that identifies a property set, property, extended right, or type of child object. The purpose of this GUID depends on the access rights specified in the Mask member.
Access rights | Meaning
ADS_RIGHT_DS_CONTROL_ACCESS | The ObjectType GUID identifies an extended access right.
ADS_RIGHT_DS_CREATE_CHILD | The ObjectType GUID identifies a type of child object. The ACE controls the trustee's right to create this type of child object.
ADS_RIGHT_DS_READ_PROP | The ObjectType GUID identifies a property set or property of the object. The ACE controls the trustee's right to read the property or property set.
ADS_RIGHT_DS_WRITE_PROP | The ObjectType GUID identifies a property set or property of the object. The ACE controls the trustee's right to write the property or property set.
ADS_RIGHT_DS_SELF | The ObjectType GUID identifies a validated write.

InheritedObjectType
This member exists only if the ACE_INHERITED_OBJECT_TYPE_PRESENT bit is set in the Flags member.

If this member exists, it is a GUID structure that identifies the type of child object that can inherit the ACE. Inheritance is also controlled by the inheritance flags in the ACE_HEADER, as well as by any protection against inheritance placed on the child objects.

The offset of this member can vary. If the Flags member does not contain the ACE_OBJECT_TYPE_PRESENT flag, the InheritedObjectType member starts at the offset specified by the ObjectType member.

SidStart
Specifies the first DWORD of a SID that identifies the trustee for whom the access rights are denied.

The offset of this member can vary. If the Flags member is zero, the SidStart member starts at the offset specified by the ObjectType member. If Flags contains only one flag (either ACE_OBJECT_TYPE_PRESENT or ACE_INHERITED_OBJECT_TYPE_PRESENT), the SidStart member starts at the offset specified by the InheritedObjectType member.

Remarks

If neither the ObjectType nor InheritedObjectType GUID is specified, the ACCESS_DENIED_OBJECT_ACE structure has the same semantics as those used by the ACCESS_DENIED_ACE structure. In that case, use the ACCESS_DENIED_ACE structure because it is smaller and more efficient.

An ACL that contains an ACCESS_DENIED_OBJECT_ACE must specify the ACL_REVISION_DS revision number in its ACL header.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Structures, ACCESS_ALLOWED_OBJECT_ACE, ACCESS_DENIED_ACE, ACCESS_MASK, ACE_HEADER, ACL, AddAccessAllowedObjectAce, GUID, SID, SYSTEM_AUDIT_OBJECT_ACE


ACL_REVISION_INFORMATION

The ACL_REVISION_INFORMATION structure contains revision information about an ACL structure.

typedef struct _ACL_REVISION_INFORMATION {
  DWORD   AclRevision;
} ACL_REVISION_INFORMATION;

Members

AclRevision
Specifies a revision number. The current revision number is ACL_REVISION.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Structures, GetAclInformation, SetAclInformation, ACL, ACL_INFORMATION_CLASS, ACL_SIZE_INFORMATION


ACL_SIZE_INFORMATION

The ACL_SIZE_INFORMATION structure contains information about the size of an ACL structure.

typedef struct _ACL_SIZE_INFORMATION {
  DWORD   AceCount;
  DWORD   AclBytesInUse;
  DWORD   AclBytesFree;
} ACL_SIZE_INFORMATION;

Members

AceCount
Specifies the number of access-control entries (ACEs) in the access-control list (ACL).
AclBytesInUse
Specifies the number of bytes in the ACL actually used to store the ACEs and ACL structure. This may be less than the total number of bytes allocated to the ACL.
AclBytesFree
Specifies the number of unused bytes in the ACL.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Structures, GetAclInformation, SetAclInformation, ACL, ACL_INFORMATION_CLASS, ACL_REVISION_INFORMATION


SECURITY_DESCRIPTOR_CONTROL

The SECURITY_DESCRIPTOR_CONTROL type is a set of bit flags that qualify the meaning of a security descriptor or its components. Each security descriptor has a Control member that stores the SECURITY_DESCRIPTOR_CONTROL bits.

typedef WORD SECURITY_DESCRIPTOR_CONTROL;

Remarks

To get the control bits of a security descriptor, call the GetSecurityDescriptorControl function. To set the control bits of a security descriptor, use the Win32 functions for modifying security descriptors. These functions are listed in the See Also section.

Starting with Windows 2000, applications can use the SetSecurityDescriptorControl function to set the control bits that relate to automatic inheritance of ACEs.

The control value retrieved by the GetSecurityDescriptorControl function can include a combination of the following SECURITY_DESCRIPTOR_CONTROL bit flags:

Value | Meaning
SE_DACL_AUTO_INHERITED Windows 2000 or later: Indicates a security descriptor in which the DACL is set up to support automatic propagation of inheritable ACEs to existing child objects.

For Windows 2000 ACLs that support auto inheritance, this bit is always set. It is used to distinguish these ACLs from Windows NT 4.0 ACLs that do not support auto-inheritance. Protected servers can call the ConvertToAutoInheritPrivateObjectSecurity function to convert a security descriptor and set this flag.

This bit is not set in security descriptors for Windows NT versions 4.0 and earlier, which do not support automatic propagation of inheritable ACEs.
SE_DACL_DEFAULTED Indicates a security descriptor with a default DACL. For example, if an object's creator does not specify a DACL, the object receives the default DACL from the creator's access token. This flag can affect how the system treats the DACL, with respect to ACE inheritance. The system ignores this flag if the SE_DACL_PRESENT flag is not set.

This flag is used to determine how the final DACL on the object is to be computed and is not stored physically in the security descriptor control of the securable object.

To set this flag, use the SetSecurityDescriptorDacl function.
SE_DACL_PRESENT Indicates a security descriptor that has a DACL. If this flag is not set, or if this flag is set and the DACL is NULL, the security descriptor allows full access to everyone.

This flag is used to hold the security information specified by a caller until the security descriptor is associated with a securable object. Once the security descriptor is associated with a securable object, the SE_DACL_PRESENT flag is always set in the security descriptor control.

To set this flag, use SetSecurityDescriptorDacl.

SE_DACL_PROTECTED | Windows 2000 or later: Prevents the DACL of the security descriptor from being modified by inheritable ACEs. To set this flag, use the SetSecurityDescriptorControl function.
SE_GROUP_DEFAULTED | A default mechanism, rather than the original provider of the security descriptor, provided the security descriptor's group SID. To set this flag, use the SetSecurityDescriptorGroup function.
SE_OWNER_DEFAULTED | A default mechanism, rather than the original provider of the security descriptor, provided the security descriptor's owner security identifier (SID). To set this flag, use the SetSecurityDescriptorOwner function.
SE_SACL_AUTO_INHERITED Windows 2000 or later: Indicates a security descriptor in which the SACL is set up to support automatic propagation of inheritable ACEs to existing child objects.

The system sets this bit when it performs the automatic inheritance algorithm for the object and its existing child objects. Protected servers can call the ConvertToAutoInheritPrivateObjectSecurity function to convert a security descriptor and set this flag.

This bit is not set in security descriptors for Windows NT versions 4.0 and earlier, which do not support automatic propagation of inheritable ACEs.
SE_SACL_DEFAULTED | A default mechanism, rather than the original provider of the security descriptor, provided the SACL. This flag can affect how the system treats the SACL, with respect to ACE inheritance. The system ignores this flag if the SE_SACL_PRESENT flag is not set. To set this flag, use the SetSecurityDescriptorSacl function.
SE_SACL_PRESENT | Indicates a security descriptor that has a SACL. To set this flag, use the SetSecurityDescriptorSacl function.
SE_SACL_PROTECTED | Windows 2000 or later: Prevents the SACL of the security descriptor from being modified by inheritable ACEs. To set this flag, use the SetSecurityDescriptorControl function.
SE_SELF_RELATIVE | Indicates a security descriptor in self-relative format with all the security information in a contiguous block of memory. If this flag is not set, the security descriptor is in absolute format. For more information, see Absolute and Self-Relative Security Descriptors.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Structures, ConvertToAutoInheritPrivateObjectSecurity, GetSecurityDescriptorControl, GetSecurityDescriptorDacl, GetSecurityDescriptorGroup, GetSecurityDescriptorOwner, GetSecurityDescriptorSacl, SetSecurityDescriptorControl, SetSecurityDescriptorDacl, SetSecurityDescriptorGroup, SetSecurityDescriptorOwner, SetSecurityDescriptorSacl


SYSTEM_ALARM_ACE

Reserved for future use.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Structures


SYSTEM_ALARM_OBJECT_ACE

Reserved for future use.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Structures


SYSTEM_AUDIT_ACE

The SYSTEM_AUDIT_ACE structure defines an access-control entry (ACE) for the system access-control list (ACL) specifying what types of access cause system-level notifications. A system-audit ACE causes an audit message to be logged when a specified user or group attempts to gain access to an object. The user or group is identified by a security identifier (SID).

typedef struct _SYSTEM_AUDIT_ACE {
  ACE_HEADER  Header;
  ACCESS_MASK Mask;
  DWORD       SidStart;
} SYSTEM_AUDIT_ACE;

Members

Header
Specifies an ACE_HEADER structure.
Mask
Specifies an ACCESS_MASK structure that gives the access rights causing audit messages to be generated. The SUCCESSFUL_ACCESS_ACE_FLAG and FAILED_ACCESS_ACE_FLAG flags in the AceFlags member of the ACE_HEADER structure indicate whether messages are generated for successful access attempts, unsuccessful access attempts, or both.
SidStart
Specifies a SID. An access attempt of a kind specified by the Mask member by any user or group whose SID matches the SidStart member causes the system to generate an audit message. If an application does not specify a SID for this member, audit messages are generated for the specified access rights for all users and groups.

Remarks

Audit messages are stored in an event log that can be manipulated by using the Win32 API event-logging functions or by using the Event Viewer (EVENTVWR.EXE).

ACE structures should be aligned on doubleword boundaries. All Win32 memory-management functions return doubleword-aligned handles to memory.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Structures, ACCESS_ALLOWED_ACE, ACCESS_DENIED_ACE, ACCESS_MASK, ACE_HEADER, ACL, SYSTEM_ALARM_ACE


SYSTEM_AUDIT_OBJECT_ACE

The SYSTEM_AUDIT_OBJECT_ACE structure defines an access-control entry (ACE) for a system access-control list (SACL). The ACE can audit access to an object, or to a subobject of an object, such as a property set or property. The ACE contains a set of access rights, a GUID that identifies the type of object or subobject, and a SID that identifies the trustee for whom the system will audit access. The ACE also contains a GUID and a set of flags that control inheritance of the ACE by child objects.

typedef struct _SYSTEM_ALARM_OBJECT_ACE {
  ACE_HEADER Header;
  ACCESS_MASK Mask;
  DWORD Flags;
  GUID ObjectType;
  GUID InheritedObjectType;
  DWORD SidStart;
} SYSTEM_ALARM_OBJECT_ACE, *PSYSTEM_ALARM_OBJECT_ACE;

Members

Header
An ACE_HEADER structure that specifies the size and type of ACE. It contains flags that control inheritance of the ACE by child objects. The structure also contains flags that indicate whether the ACE audits successful access attempts, failed access attempts, or both.
Mask
An ACCESS_MASK that specifies the access rights the system will audit for access attempts by the trustee.
Flags
A set of bit flags that indicate whether the ObjectType and InheritedObjectType members contain GUIDs. This parameter can be a combination of the following values. Set all undefined bits to zero.
Value | Meaning
ACE_OBJECT_TYPE_PRESENT | The ObjectType member contains a GUID.
ACE_INHERITED_OBJECT_TYPE_PRESENT | The InheritedObjectType member contains a GUID.

ObjectType
A GUID structure that identifies a property set, property, extended right, or type of child object.

This member is valid only if the ACE_OBJECT_TYPE_PRESENT bit is set in the Flags member. Otherwise, ObjectType is ignored.

The purpose of this GUID depends on the access rights specified in the Mask member.
Access rights | Meaning
ADS_RIGHT_DS_READ_PROP and/or ADS_RIGHT_DS_WRITE_PROP | The ObjectType GUID identifies a property set or property of the object. The ACE controls auditing of the trustee's attempts to read or write the property or property set.
ADS_RIGHT_DS_CONTROL_ACCESS | The ObjectType GUID identifies an extended access right.
ADS_RIGHT_DS_CREATE_CHILD | The ObjectType GUID identifies a type of child object. The ACE controls auditing of the trustee's attempts to create this type of child object.
ADS_RIGHT_DS_SELF | The ObjectType GUID identifies a validated write.

InheritedObjectType
A GUID structure that identifies the type of child object that can inherit the ACE.

This member is valid only if the ACE_INHERITED_OBJECT_TYPE_PRESENT bit is set in the Flags member. If that bit is not set, InheritedObjectType is ignored and all types of child objects can inherit the ACE. In either case, inheritance is also controlled by the inheritance flags in the ACE_HEADER, as well as by any protection against inheritance placed on the child objects.

SidStart
Specifies the first DWORD of a SID that identifies the trustee for whom the access attempts are audited.

Remarks

If neither the ObjectType nor InheritedObjectType GUID is specified, the SYSTEM_AUDIT_OBJECT_ACE structure has the same semantics as the SYSTEM_AUDIT_ACE structure. In that case, use the SYSTEM_AUDIT_ACE structure because it is smaller and more efficient.

An ACL that contains an SYSTEM_AUDIT_OBJECT_ACE must specify the ACL_REVISION_DS revision number in its ACE_HEADER structure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Winnt.h; include Windows.h.

See Also

Low-Level Access-Control Overview, Low-Level Access Control Structures, ACCESS_ALLOWED_OBJECT_ACE, ACCESS_DENIED_OBJECT_ACE, ACCESS_MASK, ACE_HEADER, ACL, AddAuditAccessObjectAce, GUID, SID, SYSTEM_AUDIT_ACE


Logon Authentication

The following table describes the technologies that provide logon authentication support.

Technology | Description
Password Filters | Password filters provide password policy enforcement and password change notification.
Winlogon and Gina | Winlogon is the protected component of Windows NT/Windows 2000 that provides interactive logon services. Developers can create a custom Graphical Identification and Authentication (GINA) DLL to control the user interface and security protocol used to authenticate users during interactive logon.
Network Provider API | This application programmer's interface provides a mechanism for communications between the Multiple Provider Router and custom network providers.
LSA Authentication | LSA Authentication describes the services provided by the Local Security Authority (LSA) to authenticate and log users on a system, including customization of existing security protocols.


Password Filters

Purpose

Password filters provide a way for you to implement password policy and change notification.

When a password change request is made, the Local Security Authority (LSA) calls the password filters registered on the system. Each password filter is called twice: first to validate the new password and then, after all filters have validated the new password, to notify the filters that the change has been made.

Password change notification is used to synchronize password changes to foreign account databases. This functionality is available on Windows NT 3.51 and later.

Password filters are used to enforce password policy. Filters validate new passwords and indicate if the new password conforms to the implemented password policy. This functionality is available on the Microsoft® Windows NT®/Windows® 2000 operating system beginning with Windows NT version 4.0 SP2.

Password Filter Programming Considerations

Programming issues when implementing a password filter DLL.

Installing and Registering a Password Filter DLL

How to install and register your own password filter DLL.

Passfilt.DLL

The password filter DLL provided by Microsoft.

Password Filter Reference

Interface implemented by a password filter DLL.

Feedback

Make error reports and feature requests directly to Microsoft.


Password Filter Programming Considerations

When implementing password filter export functions, keep the following considerations in mind:

  • Take great care when working with cleartext passwords. Sending cleartext passwords over networks could compromise security. Network "sniffers" can easily watch for clear-text password traffic.
  • Erase all memory used to store passwords by calling the ZeroMemory function before freeing memory.
  • All buffers passed into password notification and filter routines should be treated as read-only. Writing data to these buffers may cause unstable behavior.
  • All password notification and filter routines should be thread-safe. Use critical sections or other synchronous programming techniques to protect data where appropriate.
  • Password notification and filtering only take place on the computer that houses the account.
  • Notification on domain accounts only takes place on the primary domain controller for the Windows NT 4.0 domains. In addition to the Primary domain controller, the password filter packages should be installed on all backup domain controllers to allow notifications to continue in the event of server role changes.

    On Windows 2000, all domain controllers are writeable, therefore password filter packages must be present on all domain controllers.

  • All password filter DLLs run in the security context of the local system account.
  • Password change notification and password filters only support password changes initiated from Windows 95 and Windows NT/Windows 2000 operating systems.
For Information On… | See…
How to install and register your own password filter DLL. | Installing and Registering a Password Filter DLL
The password filter DLL provided by Microsoft. | Passfilt.DLL
Export functions implemented by a password filter DLL. | Password Filter Reference


Installing and Registering a Password Filter DLL

After creating your own password filter, you must install and register the DLL on each domain controller in the domain as follows.

To install and register a password filter DLL

  1. Copy the DLL to the installation directory of your system.
  2. Register the password filter package by updating the following system registry key:
    HKEY_LOCAL_MACHINE\
 SYSTEM\
 CurrentControlSet\
 Control\
 Lsa

    If the "Notification Packages" key value exists, add the name of your DLL to the existing value data. Do not overwrite the existing values, and do not include the ".dll" extension.

    If the "Notification Packages" key value does not exist, add it, and specify the name of your DLL for the value data without the ".dll" extension.

    The "Notification Packages" key value may contain multiple packages.

  3. From the administration console locate "Local Security Policy". Select Account Policy, and then select Password Policy. Enable the "Passwords must meet complexity requirements" setting.
For Information On… | See…
Programming issues when implementing a password filter DLL. | Password Filter Programming Considerations
The password filter DLL provided by Microsoft. | Passfilt.DLL
Export functions implemented by a password filter DLL. | Password Filter Reference


Sample Password Filter

Microsoft provides a sample password filter (Pwdfilt.dll) for administrators who want to increase password policy.

The source code for Pwdfilt.dll is available in the Platform SDK under Samples\Winbase\Security\Winnt\Pwdfilt. For addition information on Pwdfilt.dll, see the Readme.txt file that accompanies the sample.

For information on | See
Programming issues when implementing a password filter DLL. | Password Filter Programming Considerations
How to install and register your own password filter DLL. | Installing and Registering a Password Filter DLL
Functions implemented by a password filter DLL. | Password Filter Reference


PassFilt.dll

Windows NT 4.0 SP2

System administrators who wish to increase password strength without having to write their own filter may use the password filter supplied by Microsoft as part of Windows NT 4.0 Service Pack 2. This filter, Passfilt.dll, must be registered on your system after Service Pack 2 is installed. For more information see Installing and Registering a Password Filter DLL.

Passfilt.dll implements the following password policy:

  • Passwords may not contain your user name or any part of your full name.
  • Passwords must be at least six characters long.
  • Passwords must contain elements from three of the four following types of characters.
Character types | Examples
English upper case letters | A, B, C, ... Z
English lower case letters | a, b, c, ... z
Westernized Arabic numerals | 0, 1, 2, ... 9
Non-alphanumeric characters (special characters) | $,!,%,^

Windows 2000

The functionality described above for Windows NT 4.0 has been moved into the operating system security components for Windows 2000. Strong password enforcement can be enabled on Windows 2000 using the system administration tools.

To enable strong password enforcement

  1. From the administration console locate Local Security Policy.
  2. Select Account Policy, and then select Password Policy.
  3. Enable the Passwords must meet complexity requirements setting.


Password Filter Reference

The following password filter functions are implemented by custom password filter DLLs to provide password filtering and password change notification.

Export Function | Description
InitializeChangeNotify | Indicates that a password filter DLL is initialized.
PasswordChangeNotify | Indicates that a password has been changed.
PasswordFilter | Validates a new password based on password policy.


InitializeChangeNotify

The InitializeChangeNotify function is implemented by a password filter DLL. This function initializes the DLL.

BOOLEAN InitializeChangeNotify();

Parameters

This function has no parameters.

Return Values

Value | Meaning
TRUE | The password filter DLL is initialized.
FALSE | The password filter DLL is not initialized.

Remarks

InitializeChangeNotify is called by the Local Security Authority (LSA) to verify that the password notification DLL is loaded and initialized. This function must use the __stdcall calling convention, and must be exported by the DLL.

This function is called only for password filters that are installed and registered on a system.

Any process exception that is not handled within this function may cause security-related failures system-wide. Structured exception handling should be used when appropriate.

For information on | See
Programming issues when implementing a password filter DLL. | Password Filter Programming Considerations
How to install and register your own password filter DLL. | Installing and Registering a Password Filter DLL
The password filter sample. | Sample Password Filter
The password filter DLL provided by Microsoft. | Passfilt.DLL

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Ntsecapi.h.

See Also

PasswordChangeNotify, PasswordFilter


PasswordChangeNotify

The PasswordChangeNotify function is implemented by a password filter DLL. It is used to notify the DLL that a password was changed.

NTSTATUS PasswordChangeNotify(
  PUNICODE_STRING UserName,
  ULONG RelativeId,
  PUNICODE_STRING NewPassword
);
UserName
[in] Account name of the user whose password changed.
RelativeId
[in] Relative identifier (RID) of the user specified in UserName.
NewPassword
[in] New clear-text password for the user specified in UserName.

Return Value

STATUS_SUCCESS
Indicates the password of the user was changed.

Remarks

PasswordChangeNotify is called after PasswordFilter has been called successfully and the new password has been stored.

This function must use the __stdcall calling convention, and must be exported by the DLL.

When the PasswordChangeNotify routine is running, processing is blocked until the routine is finished. When appropriate, move any lengthy processing to a separate thread prior to returning from this routine.

This function is called only for password filters that are installed and registered on a system.

Any process exception that is not handled within this function may cause security-related failures system-wide. Structured exception handling should be used when appropriate.

For information on | See
Programming issues when implementing a password filter DLL. | Password Filter Programming Considerations
How to install and register your own password filter DLL. | Installing and Registering a Password Filter DLL
The password filter sample. | Sample Password Filter
The password filter DLL provided by Microsoft. | Passfilt.DLL

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Ntsecapi.h.

See Also

InitializeChangeNotify, PasswordFilter


PasswordFilter

The PasswordFilter function is implemented by a password filter DLL. The value returned by this function determines whether or not the new password is accepted by the system. All of the password filters installed on a system must return TRUE for the password change to take effect.

BOOLEAN PasswordFilter(
  PUNICODE_STRING AccountName,
  PUNICODE_STRING FullName,
  PUNICODE_STRING Password,
  BOOLEAN SetOperation
);
AccountName
[in] Name of the user whose password changed.
FullName
[in] Full name of the user whose password changed.
Password
[in] New clear-text password.
SetOperation
[in] TRUE if the password was set rather than changed.

Return Values

Value | Meaning
TRUE | Return TRUE if the new password is valid with respect to the password policy implemented in the password filter DLL. When TRUE is returned, the LSA continues to evaluate the password by calling any other password filters installed on the system.
FALSE | Return FALSE if the new password is invalid with respect to the password policy implemented in the password filter DLL. When FALSE is returned, the LSA returns the ERROR_ILL_FORMED_PASSWORD (1324) status code to the source of the password change request.

Remarks

Password change requests may be made when users specify a new password, accounts are created, and when administrators override a password.

This function must use the __stdcall calling convention, and must be exported by the DLL.

When the PasswordFilter routine is running, processing is blocked until the routine is finished. When appropriate, move any lengthy processing to a separate thread prior to returning from this routine.

This function is called only for password filters that are installed and registered on a system.

Any process exception that is not handled within this function may cause security-related failures system-wide. Structured exception handling should be used when appropriate.

For information on | See
Programming issues when implementing a password filter DLL. | Password Filter Programming Considerations
How to install and register your own password filter DLL. | Installing and Registering a Password Filter DLL
The password filter sample. | Sample Password Filter
The password filter DLL provided by Microsoft. | Passfilt.DLL

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Ntsecapi.h.

See Also

InitializeChangeNotify, PasswordChangeNotify


Winlogon and GINA

Purpose

Winlogon is a component of the Microsoft® Windows NT®/Windows® 2000 operating system that provides interactive logon support. Winlogon is designed around an interactive logon model that consists of three components (as shown in the following illustration): the Winlogon executable program, a Graphical Identification and Authentication dynamic-link library (DLL)—referred to as the GINA—and any number of network providers.

Winlogon handles interface functions that are independent of authentication policy.

The GINA is a replaceable DLL component that is loaded by Winlogon. The GINA implements the authentication policy of the interactive logon model, and is expected to perform all identification and authentication user interactions. For example, replacement GINA DLLs can implement smart-card, retinal-scan, or other authentication mechanisms in place of the standard Windows NT/Windows 2000 user name and password authentication.

Winlogon can also load zero or more network providers that must perform secondary authentication.

Where Applicable

This technology is applicable only to Microsoft Windows NT/Windows 2000.

Developer Audience

The Winlogon and GINA DLL development information is intended for use by C/C++ programmers. Familiarity with Microsoft Windows NT/Windows 2000 security protocols and procedures is required.

Run-Time Requirements

Winlogon support for custom GINA DLLs requires Windows NT 3.51 or later, or Windows 2000. Winlogon notification packages require Windows 2000. For information on which operating systems are required to use a particular function, see the Requirements section of the documentation for the function.

See Also

LSA Authentication, LSA Policy

About Winlogon and Gina

Conceptual topics, including information on each component and their responsibilities.

Using GINA Export Functions

Examples of GINA export function implementations.

Winlogon and GINA Reference

Lists the functions a GINA DLL must export, the support functions provided by Winlogon, and the structures used.

Feedback

Make error reports and feature requests directly to Microsoft.


About Winlogon and GINA

The following topics cover conceptual information about Winlogon, the GINA, and network providers, which are the components of the interactive logon model. The interactive logon procedure is normally controlled by Winlogon, MSGina.dll and network providers. To alter the interactive logon procedure, MSGina.dll can be replaced with a customized GINA DLL. This documentation provides information on how to design your own GINA DLL, what support services Winlogon provides for custom GINA DLLs, and the protocols that these components must follow.

Note For information on specific functions and structures, see the Winlogon and GINA Reference. This reference section includes descriptions of the functions that a GINA DLL must implement, the Winlogon support functions that the GINA DLL can call, and the data structures used to pass information between Winlogon and the GINA.

For more information about custom GINA DLL development and sample code send e-mail to: ginareqs@microsoft.com.

To use this documentation, you should have a firm knowledge of the Windows NT/Windows 2000 security architecture, especially with regard to tokens, authentication packages, and related matters.


Further Information

The following documents provide information related to the topics discussed in this documentation:

LSA Authentication
This document describes the authentication model supported by Windows NT. It also describes and defines the Local Security Authority (LSA) services and Authentication Package interfaces.
LSA Policy
This document describes the aspects of the Windows NT Local Security Authority that relate to security policy administration. Security policy of a system includes trust relationships with other machines and domains, assignment of privileges, audit generation control, system accessibility, and other similar topics.


Winlogon

Winlogon handles interface functions that are independent of authentication policy. It creates the desktops for the window station, implements time-out operations, and provides a set of support functions for the GINA.

For Information on… | See
Creating desktops and registering a secure attention sequence (SAS) | Initializing Winlogon
The different states in which Winlogon can run | Winlogon States
Time out operations | Supported Dialog Service Time-out Operations
Sending messages to the GINA while a dialog box is displayed | Sending Messages to the GINA
Support functions for the GINA | Winlogon Support Functions


Initializing Winlogon

When Winlogon initializes, it registers the CTRL+ALT+DEL secure attention sequence (SAS) with the system, and then creates three desktops within the WinSta0 window station.

Registering CTRL+ALT+DEL makes this initialization the first process, thus ensuring that no other application has hooked that key sequence.

In Windows NT/Windows 2000, WinSta0 is the name of the window station object that represents the physical screen, keyboard and mouse. Winlogon creates the following desktops in the WinSta0 object.

Desktop | Description
Winlogon desktop | This is the desktop Winlogon and GINAs use for interactive identification and authentication, and other secure dialogs. Winlogon automatically switches to this desktop when it receives SAS event notification.
Application desktop | Each time a user successfully logs on, an application desktop is created for that logon session. The application desktop is also called the default or user desktop. This desktop is where all user activity takes place. The application desktop is protected; only the system and the interactive logon session have access to it. Note that only a particular instance of the logged-on user has access to the desktop. If the interactive user activates a process using the service controller, that service application will not have access to the application desktop.
Screen-saver desktop | This is the current desktop when a screen saver is running. If a user is logged on, both the system and the interactive logon session have access to the desktop. Otherwise, only the system has access to the desktop.

As the owner of these desktops, Winlogon can switch the current, or visible, desktop to any of the three desktops and allow the GINA access to this functionality. In general, GINA developers will not change the current desktop because Winlogon sets the desktop appropriately before communicating with the GINA. The description of each GINA function indicates which desktop is current for that call.

For Information on… | See…
The different states in which Winlogon can run | Winlogon States
Time out operations | Supported Dialog Service Time-out Operations
Sending messages to GINA while a dialog box is displayed | Sending Messages to the GINA
Support functions | Winlogon Support Functions


Winlogon States

Winlogon maintains the workstation state that is used by the GINA to determine what authentication actions are required. At any point in time, Winlogon is in one of three states, as illustrated in the following diagram.

Logged-Out State

When Winlogon is in the logged-out state, users are prompted to identify themselves and provide authentication information. If a user provides correct user account information and no restrictions prevent it, the user is logged on and a shell program (such as Explorer.exe) is executed in the application desktop. Winlogon changes to the logged-on state.

Logged-On State

When Winlogon is in the logged-on state, users can interact with the shell, activate additional applications, and do their work. From the logged-on state, users can either stop all work and log off, or lock their workstations (leaving all work in place). If the user decides to log off, Winlogon will terminate all processes associated with that logon session and the workstation will be available for another user. If, instead, the user decides to lock the workstation, Winlogon changes to the workstation-locked state.

Workstation-Locked State

When Winlogon is in the workstation-locked state, a secure desktop is displayed until the user unlocks the workstation by providing the same identification and authentication information as the user who originally logged on, or until an administrator forces a logoff. If the workstation is unlocked, the application desktop is displayed, and work can resume. If, however, an administrator unlocks the workstation (by providing the identification and authentication information of an administrator account), the logged-on user's processes are terminated, and Winlogon changes to the logged-out state.

As the section above indicates, a number of different actions can be performed in each of the Winlogon states. A GINA DLL may implement actions that are not part of the standard Windows NT/Windows 2000 system. For example, a high security system could automatically lock a workstation every 10 minutes and force users to reauthenticate themselves.

For Information on… | See…
Creating desktops and registering an SAS | Initializing Winlogon
Time out operations | Supported Dialog Service Time-out Operations
Sending messages to the GINA while a dialog box is displayed | Sending Messages to the GINA
Support functions | Winlogon Support Functions


Supported Dialog Service Time-out Operations

Winlogon implements two time-out operations, one for secure dialogs and the other for screen saver activation and termination.

During a secure dialog, such as logon or unlocking a workstation, Winlogon can time-out the dialog boxes and return an appropriate result code to the dialog box procedure. Winlogon provides a set of dialog support functions for the GINA. The GINA must use these functions instead of their Win32® counterparts to ensure that the GINA and Winlogon maintain appropriate control over the dialog boxes. Failure to use the Winlogon versions of these functions could result in unauthorized users gaining access to the system.

The Winlogon dialog services are provided by the following support functions.

Support function | Description
WlxMessageBox | Similar to the Win32 MessageBox function.
WlxDialogBox | Similar to the Win32 DialogBox function.
WlxDialogBoxIndirect | Similar to the Win32 DialogBoxIndirect function.
WlxDialogBoxParam | Similar to the Win32 DialogBoxParam function.
WlxDialogBoxIndirectParam | Similar to the Win32 DialogBoxIndirectParam function.

GINA DLLs can also receive WLX_WM_SAS messages from Winlogon. These messages are sent to active dialog boxes if an SAS is received. This is useful if the GINA is in the process of prompting for the matching PIN for a smart card and the card is removed from the smart card reader. Winlogon uses WLX_DLG_SAS as the EndDialog result code when an SAS event occurs during a dialog.

Time-outs are also delivered in this manner. A WLX_WM_SAS message is sent with WLX_SAS_TYPE_SCRNSVR_TIMEOUT or WLX_SAS_TYPE_TIMEOUT. The dialog box will end with an appropriate exit code to allow GINA developers to hook the time-out notifications.

GINA dialog boxes can be terminated by Winlogon with the code WLX_DLG_USER_LOGOFF. This indicates that the user has logged off during the running of the dialog box (for example, by calling the ExitWindowsEx function from another thread).

For Information On… | See…
Creating desktops and registering an SAS | Initializing Winlogon
The different states in which Winlogon can run | Winlogon States
Sending messages to the GINA while a dialog box is displayed | Sending Messages to the GINA
Support functions | Winlogon Support Functions


Sending Messages to the GINA

Winlogon sends messages to the GINA while dialog boxes are displayed. These messages are all encapsulated in the WLX_WM_SAS message as follows:

SAS type in wParam parameter | Description
WLX_SAS_TYPE_CTRL_ALT_DEL | Indicates that a CTRL+ALT+DEL key sequence was received.
WLX_SAS_TYPE_SC_INSERT | Indicates that a smart card has been inserted into a compatible device.
WLX_SAS_TYPE_SC_REMOVE | Indicates that a smart card has been removed from a compatible device.
WLX_SAS_TYPE_USER_LOGOFF | Indicates that a user requested log-off.
WLX_SAS_TYPE_SCRNSVR_TIMEOUT | Indicates that the screen saver should be run due to lack of user input.
WLX_SAS_TYPE_TIMEOUT | Indicates that no user input was received within the specified time-out period.

For time-outs and logoffs, Winlogon will end the dialog after the message has been sent. This message is sent so the dialog can respond in a useful manner (for example, by closing itself down if a logoff has occurred).

For input time-outs, the dialog is ended with the code WLX_DLG_INPUT_TIMEOUT.

For screen saver time-outs, the dialog is ended with the code WLX_DLG_SCREEN_SAVER_TIMEOUT.

For logoffs, the dialog is ended with the code WLX_DLG_USER_LOGOFF.

For information On… | See…
Creating desktops and registering an SAS | Initializing Winlogon
The different states in which Winlogon can run | Winlogon States
Time out operations | Supported Dialog Service Time-out Operations
Support functions | Winlogon Support Functions


GINA

The GINA operates in the context of the Winlogon process and, as such, the GINA DLL is loaded very early in the boot process. The GINA DLL must follow rules so that the integrity of the system is maintained, particularly with respect to interaction with the user.

The most common use of the GINA is to communicate with an external device such as a smart-card reader. It is essential to set the start parameter for the device driver to system (Winnt.h: SERVICE_SYSTEM_START) to ensure that the driver is loaded by the time the GINA is invoked.

The purpose of a GINA DLL is to provide customizable user identification and authentication procedures. The default GINA does this by delegating SAS event monitoring to Winlogon, which receives and processes CTL+ALT+DEL secure attention sequences (SASs). A custom GINA is responsible for setting itself up to receive SAS events (other than the default CTRL+ALT+DEL SAS event), and notifying Winlogon when SAS events occur. Winlogon will evaluate its state to determine what is required to process the custom GINA's SAS. This processing usually includes calls to the GINA's SAS processing functions.

For Information on… | See…
Specifying the registry key to load and run the GINA DLL | Loading and Running a GINA DLL
Debugging a GINA DLL | Building and Testing a GINA DLL
Specific GINA export functions | GINA Export Functions
Implementing GINA functions | Using GINA Export Functions
Using GINA structures to pass information | GINA Structures
GINA Functions called when Terminal Services is enabled | Terminal Services GINA Functions


Loading and Running a GINA DLL

Windows NT is shipped to load and execute the standard Microsoft GINA DLL (MSGina.dll). To load a different GINA, you must alter the following registry key value:

Key Name: | \HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon
Value Name: | GinaDLL
Value Type: | [REG_SZ]

If the GinaDLL key value is present it must contain the name of a GINA DLL, which Winlogon will load and use.

For Information On… | See…
Debugging a GINA DLL | Building and Testing a GINA DLL
Specific GINA export functions | GINA Export Functions
Implementing GINA functions | Using GINA Export Functions
Using GINA structures to pass information | GINA Structures
GINA functions called when Terminal Services is enabled | Terminal Services GINA Functions


Building and Testing a GINA DLL

All functions, prototypes, structures, and constants are defined in the Winwlx.h header file.

To test a GINA DLL, use the Winlogon.exe from a checked version of the operating system, which is available with the Windows NT DDK. The checked version of Winlogon supports the following features for debugging GINAs:

  • You can use the following syntax to create a section in Win.ini to specify Winlogon debugging options:
    [WinlogonDebug]
LogFile=C:\Winlogon.log
DebugFlags=Flag1[, Flag2...]

    If specified, LogFile should contain the fully qualified name of the file that will be used to log debugging information. If the file does not exist, it will be created.

    The DebugFlags options specify which kinds of debugging information to write to the log file, or debugger. DebugFlags can contain one or more of the following.
    Debugging Flag | Description
    CoolSwitch | The CTRL+ALT+SHIFT+TAB key combination will cause a debug break in Winlogon.
    Error | Print errors.
    Init | Print initialization and progress messages.
    Notify | Print notification package messages.
    SAS | Print information about SAS notifications.
    State | Print messages when Winlogon changes state.
    Timeout | Print messages when a time limit is set or a time limit is reached.
    Trace | Print verbose trace information.
    Warn | Print warnings.

  • To start the checked version of Winlogon in a debugger, add the following entry to the registry.
    Path: \HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
    Key Name: winlogon.exe
    Key Value: Debugger
    Value Type: [REG_SZ]
    Value Setting: ntsd -d

    Note that you must use the Windows NT symbolic debugger (NTSD) to debug Winlogon.

For more information, see the following topics.

For Information On… | See…
Specifying the registry key to load and run the GINA DLL | Loading and Running a GINA DLL
Specific GINA export functions | GINA Export Functions
Implementing GINA functions | Using GINA Export Functions
Using GINA structures to pass information | GINA Structures
GINA functions called when Terminal Services is enabled | Terminal Services GINA Functions


Terminal Services GINA Functions

When Terminal Services are enabled, the GINA must call Winlogon support functions to complete the setup for each user, to query the credentials of a Terminal Services client session, and to disconnect from a Terminal Services network session.

These support functions include the following.

Function | Description
WlxWin31Migrate | Completes the setup of the user (including migrating from Windows NT 3.51 settings to Windows NT 4.0 settings)
WlxQueryClientCredentials | Called to query the credentials of remote clients that are not using an Internet connector license.
WlxQueryInetConnectorCredentials | Called to query the credentials of remote clients that are using an Internet connector license.
WlxQueryTerminalServicesData | Called to retrieve Terminal Services user configuration information.
WlxDisconnect | Called to disconnect from a Terminal Services network session.

In order to access these Winlogon support functions, the GINA DLL must use the WLX_DISPATCH_VERSION_1_3 structure. In the GINA's WlxNegotiate function, both parameters must be at least WLX_VERSION_1_3.


Network Providers

You can configure a Windows NT/Windows 2000 system to support zero or more network providers. Each of these network providers can specify that it requires special interactive authentication processing. This capability allows installed networks to collect identification and authentication information specific to each network, yet allows them to collect it during normal logon and under the secure umbrella of Winlogon's context and desktop.

Winlogon calls network providers under a number of circumstances. Following a successful logon, Winlogon calls network providers so they can collect credentials and authenticate the user for their network. Winlogon also calls network providers when users change their passwords. This lets each user maintain a single password for use on all networks.

The WLX_MPR_NOTIFY_INFO structure is used to provide identification and authentication information in the relevant GINA functions. This structure includes the following members.

Member | Description
pszUserName | The account name of the logged-on user.
pszDomain | The domain name of the logged-on user. Not all authentication models have a domain concept (or its equivalent), so this member can be NULL.
pszPassword | When the user gave a clear-text password during authentication, providing it here lets other network providers use the same password (to achieve single logon) without prompting the user.
pszOldPassword | After a password change, providing the original password here and the new password in the pszPassword member, lets network providers upgrade their passwords without prompting the user.

A GINA does not have to provide this information to network providers. If a NULL pointer is passed instead of a valid structure pointer, the network providers will prompt the user for information.


Responsibilities and Features

Each component of the interactive logon process has a set of responsibilities. This section defines those responsibilities and indicates where you can implement features not contained in the standard version of Windows NT/Windows 2000.

This section also describes the optional features of MSGina.dll. If you are developing a replacement GINA DLL, you may want to implement some or all of these features as well.

For Information On… | See…
The responsibilities of Winlogon | Responsibilities of Winlogon
The responsibilities of the GINA | Responsibilities of the GINA
The features of the GINA provided by Microsoft | MSGina.dll Features
The request and response process between Winlogon and the GINA | Interaction Between Winlogon and GINA


Responsibilities of Winlogon

Winlogon has the following responsibilities:

  • Window Station and Desktop Protection

    Winlogon sets the protection of the window station and corresponding desktops to ensure that each is properly accessible. In general, this means that the local system will have full access to these objects and that an interactively logged-on user will have read access to the window station object and full access to the application desktop object.

  • Standard SAS Recognition

    Winlogon has special hooks into the User32 server that allow it to monitor CTRL+ALT+DEL secure attention sequence (SAS) events. Winlogon makes this SAS event information available to GINAs to use as their SAS, or as part of their SAS. In general, GINAs should monitor SASs on their own; however, any GINA that has the standard CTRL+ALT+DEL SAS as one of the SASs it recognizes should use the Winlogon support provided for this purpose.

  • SAS Routine Dispatching

    When Winlogon encounters an SAS event or when an SAS is delivered to Winlogon by the GINA, Winlogon sets the state accordingly, changes to the Winlogon desktop, and calls one of the GINA's SAS processing functions.

  • User Profile Loading

    When users log on, their user profiles are loaded into the registry. In this way, the user's processes can use the special registry key HKEY_LOCAL_USER. Winlogon does this automatically after a successful logon, but before activation of the shell for the newly logged-on user.

  • Assignment of Security To User Shell

    When a user logs on, the GINA is responsible for creating one or more initial processes for that user. Winlogon provides a support function for the GINA to apply the newly logged-on user's security to these processes. However, the preferred way to do this is for the GINA to call the Win32 function, CreateProcessAsUser, and let the system provide the service.

  • Screen Saver Control

    Winlogon monitors keyboard and mouse activity to determine when to activate screen savers. Once the screen saver is activated, Winlogon continues to monitor keyboard and mouse activity to determine when to terminate the screen saver. If the screen saver is marked as secure, Winlogon treats the workstation as locked. When there is mouse or keyboard activity, Winlogon invokes the GINA's WlxDisplayLockedNotice function and locked workstation behavior resumes. If the screen saver is not secure, any keyboard or mouse activity terminates the screen saver without notification to the GINA.

  • Multiple Network Provider Support

    Multiple networks installed on a Windows NT system can be included in the authentication process and in password-updating operations. This inclusion lets additional networks gather identification and authentication information all at once during normal logon, using Winlogon's secure desktop. Some of the parameters required in the Winlogon services available to GINAs explicitly support these additional network providers.


Responsibilities of the GINA

A GINA DLL has the following responsibilities:

  • SAS Monitoring

    The GINA is responsible for recognizing a secure attention sequence (SAS), monitoring for SAS events, and notifying Winlogon when an SAS has occurred. Note that there can be more than one SAS defined and the set of defined SASs can change over time. For example, there can be one set of SASs when Winlogon is in the logged-off state and another set when it is in the logged-on state.

    Winlogon provides services to assist the GINA in using the CTRL+ALT+DEL SAS.

  • SAS Processing

    One reason for modularizing Winlogon and making the GINA replaceable is to provide alternative identification and authentication mechanisms. To do this, the GINA must present all user interfaces resulting from the recognition of an SAS. When no user is logged on, the GINA is responsible for presenting identification and authentication options and any other permissible, nonauthenticated options. When a user is logged on, the GINA is responsible for presenting the relevant options to the user as well as taking whatever actions are deemed appropriate. For example, in a system that includes a smart card, it may be appropriate to automatically lock the workstation if the user removes the smart card.

  • Shell Activation

    When a user logs on, the GINA is responsible for creating one or more initial processes for that user. (In this documentation, it is assumed that these initial processes present an interface to the user. However, the processes can actually be any processes and do not necessarily have to interact with the user.) These processes are referred to as the user shell or just the shell. As part of shell activation, the GINA must assign the newly logged-on user's token to the processes. Winlogon provides a service to assist the GINA in assigning the token.


MSGina.dll Features

If you are writing a GINA to replace the Microsoft standard GINA DLL (MSGina.dll), you may want to provide some or all of the standard GINA functionality. Following is a list of standard features and a brief description of how they are controlled.

Registry key values control the availability or behavior of many of these standard GINA features. Unless otherwise noted, these key values belong to the Winlogon registry key and have a value type of [REG_SZ]. The actual path of the Winlogon key is:

\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon

The [REG_SZ] value type makes it convenient to query the key values using the GetProfileString and GetProfileInt functions.

  • Legal Notification Dialog Box

    In some places, it is legal for anyone who has access to a workstation to log on, and begin working unless there is a notice indicating that the system is for authorized users only. Also, many users want company-specific messages displayed before normal logon. The standard GINA uses two Winlogon registry key values to allow a system to display information before logon. If either key value is present and contains a non-null string, then a Legal Notice dialog box is displayed before the usual Welcome screen. These key value names are shown in the following table.
    Key Value Name | Contents
    LegalNoticeCaption | The string to display as the caption of the legal notice dialog box.
    LegalNoticeText | The string to display as the message of the legal notice dialog box.

  • Display Last User Name

    By default, the logon screen displays the name of the last user to successfully log on to the workstation. This feature is controlled by the DontDisplayLastUserName registry key value. When this key value is set to 1, the user name is not displayed in the logon dialog box.

  • Automatic Logon

    This feature allows a Windows NT system to log on a user automatically every time the system boots, by using default information and disabling the CTRL+ALT+DEL logon box.

    This feature uses the following values of the Winlogon key.
    Value | Contents
    AutoAdminLogon | 1
    AutoLogonCount | The number of times to do an automatic logon.
    DefaultUserName | The name of the user account.
    DefaultDomainName | The name of the domain that the user account is in.
    DefaultPassword | The password of the user account, in clear text.

    If the AutoAdminLogon key value is present and contains a 1, and the AutoLogonCount key value is not present, an automatic logon will occur every time the current user logs off or the system is rebooted. The account being logged onto is specified using the DefaultUserName and DefaultDomainName key values, and the password is specified in DefaultPassword key value.

    If the AutoAdminLogon key value is present and contains a one (1), and if the AutoLogonCount key value is present and is not zero (0), AutoLogonCount will determine the number of automatic logons that occur. Each time the system is rebooted, the value of AutoLogonCount will be decremented by one (1), until it reaches zero (0). When AutoLogonCount reaches zero (0), no account will be logged on automatically, the AutoLogonCount and DefaultPassword key values will be deleted from the registry, and AutoAdminLogon will be set to zero (0).

    There is one additional caveat to using AutoAdminLogon: By default, MSGina.dll checks the state of the SHIFT key when AutoAdminLogon is 1. If the SHIFT key is held down during the boot process, MSGina.dll will ignore the AutoAdminLogon key value, and prompt the user for identification and authentication information interactively. This is a useful feature when you are debugging a dedicated application. To disable the meaning of the SHIFT key, set the IgnoreShiftOverride key value to one (1).

  • Allow Unauthenticated Shutdown

    You can configure the default GINA to include a Shutdown button in the logon dialog box. This lets users shut down the system without first logging on. The following key value controls whether this button is included.
    Value | Description
    ShutdownWithoutLogon | 1 to include the button; 0 to exclude the button.

  • Userinit.exe Activation

    Userinit.exe is an application that is executed by MSGina.dll when the user has logged on. It runs in the newly logged-on user's context and on the application desktop. Its purpose is to set up the user's environment, including restoring net uses, establishing profile settings such as fonts and screen colors, and running logon scripts. After completing those tasks, Userinit.exe executes the user shell program(s).The shell programs inherit the environment that Userinit.exe sets up. The specific shell programs that Userinit.exe executes are stored in the Shell key value under the Winlogon registry key.

    The Shell key value can contain a comma separated list of programs that will be executed. Explorer is the default shell program and will be executed if the Shell key value is null or not present. By default, Explorer is listed.

  • Logged-On Security Options

    When logged on, if a user enters a secure attention sequence (SAS), the user is presented with a security options screen. Among the options listed are:

    • Shut down the system.
    • Log off.
    • Change your password.
    • Go to the task list.
    • Lock the workstation.

    A replacement GINA may provide similar options when an SAS event is received while a user is logged on.


Interaction Between Winlogon and GINA

Winlogon and the GINA must communicate initialization information, handle secure attention sequence (SAS) monitoring and notification, and permit logoff and shutdown activities. The state of Winlogon determines which GINA function is called to process any given SAS event. Communications occur in the order shown here:

Workstation boot:
Winlogon calls the GINA's WlxNegotiate function to notify the GINA about the version of Winlogon in use.

Winlogon calls the GINA's WlxInitialize function to give the GINA the addresses of the support functions, a handle to Winlogon, and to obtain the context information for the GINA (to be used in all future calls to the GINA).

Winlogon is in the logged-out state.

No one is logged on:
(The GINA monitors devices for SAS events).

The GINA calls Winlogon's WlxSasNotify function when an SAS event has been recieved.

Winlogon calls the GINA's WlxLoggedOutSAS function, allowing the GINA to process a user's identification and authentication information.

When logon is successful, Winlogon is in the logged-on state.

The user is logged on:
(The GINA monitors devices for SAS events).

The GINA calls Winlogon's WlxSasNotify function when an SAS event has been received.

Winlogon calls the GINA's WlxLoggedOnSAS function, allowing the GINA to present options to the user who is currently logged on.

The user is logged on and wants to lock computer:
(The GINA monitors devices for SAS events).

The GINA calls the WlxSasNotify function.

Winlogon calls the GINA's WlxLoggedOnSAS function.

The GINA returns WLX_SAS_ACTION_LOCK_WKSTA.

Winlogon is in the workstation-locked state

The user is logged on; the workstation is locked; and the user wants to unlock computer:
(The GINA monitors devices for SAS events).

The GINA calls the WlxSasNotify function.

Winlogon calls the GINA's WlxWkstaLockedSAS function.

The GINA returns WLX_SAS_ACTION_UNLOCK_WKSTA.

The user is logged on, and the program calls the ExitWindowsEx function:
Winlogon calls the GINA's WlxLogoff function.
The user is logged on and wants to log off using SAS:
(The GINA monitors devices for SAS events).

The GINA calls the WlxSasNotify function.

Winlogon calls the GINA's WlxLoggedOnSAS function.

The GINA returns WLX_SAS_ACTION_LOGOFF.

Winlogon calls the GINA's WlxLogoff function.

The user is logged on and wants to log off and shut down using ExitWindowsEx:
Winlogon calls the GINA's WlxLogoff function.

Winlogon calls the GINA's WlxShutdown function.

The user is logged on and wants to log off and shut down using SAS:
(The GINA monitors devices for SAS events).

The GINA calls the WlxSasNotify function.

Winlogon calls the GINA's WlxLoggedOnSAS function.

The GINA returns WLX_SAS_ACTION_SHUTDOWN.

Winlogon calls the GINA's WlxLogoff function.

Winlogon calls the GINA's WlxShutdown function.


Using GINA Export Functions

A GINA DLL must implement and export a set of functions that Winlogon will call to identify and authenticate the user. The following topics show examples of how to implement some of these functions. For a complete list of the functions that the GINA must implement and export see Winlogon and GINA Reference.

Each of the functions exported by the GINA has a parameter (pWlxContext) that Winlogon uses to pass context-specific information provided by the GINA when WlxInitialize is called. For information on the GINA context, see Implementing a GINA Context.

The following examples show how to implement the GINA export functions:

  • Implementing WlxActivateUserShell
  • Implementing WlxDisplaySASNotice
  • Implementing WlxInitialize
  • Implementing WlxLoggedOnSAS
  • Implementing WlxLoggedOutSAS
  • Implementing WlxLogoff
  • Implementing WlxNegotiate
  • Implementing WlxScreenSaverNotify
  • Implementing WlxShutdown
  • Implementing WlxStartApplication
  • Implementing WlxWkstaLockedSAS


Implementing a GINA Context

The first argument to all of the exported GINA functions is a pointer to a context that is implementation-dependent. A GINA DLL can use this context to save information specific to a particular window station, such as the current user's logon credentials or a pointer to the Winlogon dispatch table. In the following examples, the GINA context is a structure and is declared as:

typedef struct {
  HANDLE hWlx;
  LPWSTR station;
  PWLX_DISPATCH_VERSION_1_3 pWlxFuncs;
  HANDLE hDllInstance;
  HANDLE UserToken;
} GINA_CONTEXT, *PGINA_CONTEXT;

This structure has the following members:

hWlx
Handle to Winlogon. Winlogon passes this handle to the GINA when it calls WlxInitialize.
station
The name of this window station. Winlogon passes this handle to the GINA when it calls WlxInitialize. Currently, only "winsta0" is supported.
pWlxFuncs
Pointer to the Winlogon function dispatch table. Winlogon passes this pointer to the GINA when it calls WlxInitialize.
hDllInstance
Handle to this instance of the custom GINA DLL. The GINA receives this handle in DLLMain.
UserToken
A handle to the user who has sucessfully logged on. Provided by calling the LogonUser function in WlxLoggedOutSAS.


Implementing WlxActivateUserShell

The following code shows an example WlxActivateUserShell implementation. This example calls the Windows function CreateProcessAsUser to run Userinit.exe, which sets up some user preferences and starts the shell.

Note that if CreateProcessAsUser is not successful, your implementation must return FALSE to tell Winlogon to log off.

BOOL WINAPI
WlxActivateUserShell (
  PVOID pWlxContext,
  PWSTR pszDesktopName,
  PWSTR pszMprLogonScript,
  PVOID pEnvironment)
{
  PGINA_CONTEXT pgContext = (PGINA_CONTEXT) pWlxContext;
  STARTUPINFO si;
  PROCESS_INFORMATION pi;
  BOOL bRet;

// Setup STARTUPINFO to pass to CreateProcessAsUser.
  si.cb = sizeof(STARTUPINFO);
  si.lpReserved = NULL;
  si.lpTitle = L"userinit";
  si.dwX = si.dwY = si.dwXSize = si.dwYSize = 0L;
  si.dwFlags = 0;
  si.wShowWindow = SW_SHOW;
  si.lpReserved2 = NULL;
  si.cbReserved2 = 0;
  si.lpDesktop = pszDesktopName;

// Create the process for Userinit.exe.
  bRet = CreateProcessAsUser(pgContext->UserToken,
                             L"userinit.exe",
                             NULL, NULL, NULL, FALSE,
                             CREATE_UNICODE_ENVIRONMENT,
                             pEnvironment,
                             NULL,
                             &si,
                             &pi );

// Release the memory winlogon allocated for the environment.
  VirtualFree(pEnvironment, 0, MEM_RELEASE);
  return bRet;
}


Implementing WlxDisplaySASNotice

The following code shows an example WlxDisplaySASNotice implementation. This function is called when no one is logged on and there are no SAS events waiting to be processed.

VOID WINAPI WlxDisplaySASNotice (
  PVOID pWlxContext)
{
  int ret;
  PGINA_CONTEXT pgContext;

  pgContext = (PGINA_CONTEXT) pWlxContext;

  ret = pWlxFuncs->WlxMessageBox(pgContext->hWlx,
                                 NULL,
                                 L"CTRL+ALT+DEL to Logon",
                                 L"WlxDisplaySASNotice Message",
                                 MB_OK| MB_DEFBUTTON1);

  // Send CTRL+ALT+DEL SAS to winlogon when the user clicks the OK button.

  if (ret == IDOK) {
    pgContext->pWlxFuncs->WlxSasNotify(pgContext->hWlx,
      WLX_SAS_TYPE_CTRL_ALT_DEL);
  }
}


Implementing WlxInitialize

The following code shows an example WlxInitialize implementation.

BOOL WINAPI WlxInitialize (
  LPWSTR  lpWinsta,
  HANDLE  hWlx,
  PVOID   pvReserved,
  PVOID   pWinlogonFunctions,
  PVOID * pWlxContext)
{
  PGINA_CONTEXT pgContext;

  pgContext = (PGINA_CONTEXT) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,
    sizeof(GINA_CONTEXT));

  if (!pgContext) {
    return FALSE;
  }

  // Return the GINA context to winlogon.
  *pWlxContext = (PVOID) pgContext;

  // myHandle was saved in DLLMAIN.
  pgContext->hDllInstance = myHandle;

  // Save pointer to dispatch table.
  pgContext->pWlxFuncs = (PWLX_DISPATCH_VERSION_1_3) pWinlogonFunctions;

   // Save the winlogon handle used to call the dispatch functions.
   pgContext->hWlx = hWlx;

   // Save the name of the window station.
   pgContext->station = lpWinsta;

   // Notify winlogon that we will use the default SAS.
   pgContext->pWlxFuncs->WlxUseCtrlAltDel(hWlx);

   return TRUE;
}


Implementing WlxLoggedOnSAS

The following code shows an example WlxLoggedOnSAS implementation.

int WINAPI WlxLoggedOnSAS (
  PVOID pWlxContext,
  DWORD dwSasType,
  PVOID pReserved)
{
  PGINA_CONTEXT pgContext = (PGINA_CONTEXT) pWlxContext;
  int Result;

    if ( dwSasType != WLX_SAS_TYPE_CTRL_ALT_DEL ) {
        return( WLX_SAS_ACTION_NONE );
    }

  // Create a dialog box that checks to see if user wants to lock the computer.

    Result = pgContext->pWlxFuncs->WlxDialogBoxParam(pgContext->hWlx,
                                    pgContext->hDllInstance,
                                    (LPTSTR)IDD_LOGGEDON_DLG,
                                    NULL,
                                    LoggedOnDlgProc,
                                    (LPARAM) pgContext);

  if (Result == IDOK) {
    return WLX_SAS_ACTION_LOCK_WKSTA;
  } else {
    return WLX_SAS_ACTION_NONE;
  }
}


Implementing WlxLoggedOutSAS

The following code shows an example WlxLoggedOutSAS implementation. This implementation uses a user-defined function DupString to make copies of strings.

int WINAPI WlxLoggedOutSAS (
  PVOID                pWlxContext,
  DWORD                dwSasType,
  PLUID                pAuthenticationId,
  PSID                 pLogonSid,
  PDWORD               pdwOptions,
  PHANDLE              phToken,
  PWLX_MPR_NOTIFY_INFO pMprNotifyInfo,
  PVOID *              pProfile)
{

  PGINA_CONTEXT pgContext = (PGINA_CONTEXT) pWlxContext;
  TOKEN_STATISTICS userStats;
  DWORD cbStats;

  if (!phToken)
    return WLX_SAS_ACTION_NONE;

  // Attempt to log on the user: guest, domain: earth
  // with password: secret.

  if (!LogonUser(L"guest",
                 L"earth",
                 L"secret",
                 LOGON32_LOGON_UNLOCK,
                 LOGON32_PROVIDER_DEFAULT,
                 phToken))
    return WLX_SAS_ACTION_NONE;

// Check the user token.
 if (!(*phToken)) {
     return WLX_SAS_ACTION_NONE;
 }

// Save the user token in the GINA context
  pgContext->UserToken =*phToken;

//  Pass back null profile and options.
  *pdwOptions = 0;
  *pProfile =NULL;

 // Get the authenticationid from the user token.
 if (!GetTokenInformation(*phToken,
                          TokenStatistics,
                          (PVOID) &userStats,
                          sizeof(TOKEN_STATISTICS),
                          &cbStats))
  {
    return WLX_SAS_ACTION_NONE;
  }
  else
  {
    *pAuthenticationId = userStats.AuthenticationId;
  }

// Pass back multiple provider information.
  pMprNotifyInfo->pszUserName = DupString(L"guest");
  pMprNotifyInfo->pszDomain = DupString(L"earth");
  pMprNotifyInfo->pszPassword = DupString(L"secret");
  pMprNotifyInfo->pszOldPassword = NULL;

  return WLX_SAS_ACTION_LOGON;
}

PWSTR DupString(PWSTR pszString)
{
  DWORD cbString;
  PWSTR pszNewString;

  cbString = (wcslen(pszString) + 1) * sizeof(WCHAR);
  pszNewString = LocalAlloc(LMEM_FIXED, cbString);
  if (pszNewString)
  {
    CopyMemory(pszNewString, pszString, cbString);
  }
  return(pszNewString);
}


Implementing WlxLogoff

The following code shows an example WlxLogoff implementation.

VOID WINAPI WlxLogoff (PVOID pWlxContext)
{
  PGINA_CONTEXT pgContext = (PGINA_CONTEXT) pWlxContext;

  // Clear out any user specific information in the context.
  pgContext->UserToken = NULL;

}


Implementing WlxNegotiate

The following code shows an example WlxNegotiate implementation.

BOOL WINAPI WlxNegotiate (
  DWORD  dwWinlogonVersion,
  PDWORD pdwDllVersion)
{
  if (dwWinlogonVersion < WLX_VERSION_1_3)
  {
    return FALSE;
  }

  *pdwDllVersion = WLX_VERSION_1_3;

  return TRUE;
}


Implementing WlxScreenSaverNotify

The following code shows an example WlxScreenSaverNotify implementation.

BOOL WINAPI WlxScreenSaverNotify (
  PVOID  pWlxContext,
  BOOL  *pSecure)
{
  if (*pSecure)
  {
    *pSecure = WlxIsLockOk(pWlxContext);
  }
  return TRUE;
}


Implementing WlxShutdown

The following code shows an example WlxShutdown implementation.

VOID WINAPI WlxShutdown(
  PVOID pWlxContext,
  DWORD ShutdownType)
{
   PGINA_CONTEXT pgContext = (PGINA_CONTEXT) pWlxContext;
  pgContext->pWlxFuncs->WlxMessageBox(pgContext->hWlx,
                                      NULL,
                                      L"Shutdown In Progress",
                                      L"Gina WlxShutdown",
                                      MB_OK);
}


Implementing WlxStartApplication

The following code shows an example WlxStartApplication implementation.

BOOL WINAPI WlxStartApplication (
  PVOID pWlxContext,
  PWSTR pszDesktopName,
  PVOID pEnvironment,
  PWSTR pszCmdLine)
{

  PGINA_CONTEXT pgContext = (PGINA_CONTEXT) pWlxContext;
  STARTUPINFO si;
  PROCESS_INFORMATION pi;
  BOOL bRet;

// Setup STARTUPINFO to pass to CreateProcessAsUser.
  si.cb = sizeof(STARTUPINFO);
  si.lpReserved = NULL;
  si.lpTitle = pszCmdLine;
  si.dwX = si.dwY = si.dwXSize = si.dwYSize = 0L;
  si.dwFlags = 0;
  si.wShowWindow = SW_SHOW;
  si.lpReserved2 = NULL;
  si.cbReserved2 = 0;
  si.lpDesktop = pszDesktopName;

// Start the application.
  bRet = CreateProcessAsUser(pgContext->UserToken,
                             NULL,
                             pszCmdLine,
                             NULL,
                             NULL,
                             FALSE,
                             CREATE_UNICODE_ENVIRONMENT,
                             pEnvironment
                             NULL,
                             &si,
                             &pi);

// Release the memory winlogon allocated for the environment.
  VirtualFree(pEnvironment, 0, MEM_RELEASE);
  return bRet;
}


Implementing WlxWkstaLockedSAS

The following code shows an example WlxWkstaLockedSAS implementation.

int WINAPI WlxWkstaLockedSAS (
  PVOID pWlxContext,
  DWORD dwSasType
)
{
  PGINA_CONTEXT pgContext = (PGINA_CONTEXT) pWlxContext;
  int Result;

  if ( dwSasType != WLX_SAS_TYPE_CTRL_ALT_DEL ) {
    return( WLX_SAS_ACTION_NONE );
  }

  // Create a dialog box to re-authenticate the user.

    Result = pgContext->pWlxFuncs->WlxDialogBoxParam(pgContext->hWlx,
                                    pgContext->hDllInstance,
                                    (LPTSTR)IDD_WKSTALOCKED_DLG,
                                    NULL,
                                    WkLockedDlgProc,
                                    (LPARAM) pgContext);
  return Result;
}


Winlogon and GINA Reference

This section covers the functions that the GINA DLL must export, the GINA structures, and the Winlogon support functions that the GINA DLL can call.

For Information On… | See…
Functions that must be implemented by a custom GINA DLL | GINA Export Functions
Winlogon functions that can be called by the GINA | Winlogon Support Functions
Structures used to pass information between the GINA and Winlogon | GINA Structures


GINA Export Functions

A GINA DLL must export the following functions.

Function | Description
WlxActivateUserShell | Activates the user shell program.
WlxDisplayLockedNotice | Allows the GINA DLL to display lock information.
WlxDisplaySASNotice | Winlogon calls this function when no user is logged on.
WlxDisplayStatusMessage | Winlogon calls this function with a status message to display.
WlxGetStatusMessage | Winlogon calls this function to get the current status message.
WlxInitialize | Initializes the GINA DLL for a specific window station.
WlxIsLockOk | Verifies that workstation lock is okay.
WlxIslogoffOk | Verifies that logoff is okay.
WlxLoggedOnSAS | Winlogon calls this function when it receives a secure attention sequence (SAS) event while the user is logged on and the workstation is not locked.
WlxLoggedOutSAS | Winlogon calls this function when it receives an SAS event while no user is logged on.
WlxLogoff | Notifies the GINA DLL that a logoff operation was requested.
WlxNegotiate | Indicates whether the current version of Winlogon can be used with the GINA DLL.
WlxNetworkProviderLoad | Winlogon calls this function after it loads a network provider to collect valid authentication and identification information.
WlxRemoveStatusMessage | Winlogon calls this function to tell the GINA DLL to stop displaying the status message.
WlxScreensaverNotify | Allows the GINA to interact with the screen saver operation.
WlxShutdown | Winlogon calls this function just before shutting down, allowing the GINA to perform any shutdown tasks, such as ejecting a smart card from a reader.
WlxStartApplication | Winlogon calls this function when the system needs an application started in the user's context.
WlxWkstaLockedSAS | Winlogon calls this function when it receives an SAS while the workstation is locked.


WlxActivateUserShell

The WlxActivateUserShell function must be implemented by a replacement GINA DLL. Winlogon calls this function following a successful logon to request that the GINA activate the user's shell program.

BOOL WlxActivateUserShell(
  PVOID pWlxContext,
  PWSTR pszDesktopName,
  PWSTR pszMprLogonScript,
  PVOID pEnvironment
);

Parameters

pWlxContext
[in] Pointer to the GINA context associated with this window station. This is the context value that the GINA returns when Winlogon calls WlxInitialize for this station.
pszDesktopName
[in] Specifies the name of the desktop where the shell will start. Pass this string to the CreateProcess or CreateProcessAsUser functions through the lpDesktop member of the STARTUPINFO structure.
pszMprLogonScript
[in] Specifies any script names returned from the network provider DLLs. Network provider DLLs can return scripts to be executed during logon, however, the GINA may ignore them.
pEnvironment
[in] Specifies the initial environment variables for the process. Winlogon creates a copy of the environment and hands it off to the GINA. The GINA can modify this environment before using it to initialize the user's shell. The GINA should call VirtualFree to free the memory allocated for pEnvironment.

Return Values

TRUE
Return TRUE if the shell process was started.
FALSE
Return FALSE if the shell process could not be started. When FALSE is returned, Winlogon cancels the logon in process.

Remarks

Before calling WlxActivateUserShell, Winlogon sets the desktop and workstation states as follows.

Sets the | So that
Desktop state | The current desktop is the Winlogon desktop.
Workstation state | The desktop is locked.

Always activate the user shell program in WlxActivateUserShell rather than WlxLoggedOutSAS. This gives Winlogon a chance to update its state, including setting workstation and desktop protections, before any logged-on user processes are allowed to run.

Example Code

For an Example of… | See…
WlxActivateUserShell | Implementing WlxActivateUserShell

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxLoggedOutSAS, WlxInitialize, WlxLogoff


WlxDisplayLockedNotice

The WlxDisplayLockedNotice function must be implemented by a replacement GINA DLL. Winlogon calls this function when the workstation is placed in the locked state.

WlxDisplayLockedNotice allows the GINA to display information about the lock, such as who locked the workstation and when it was locked.

VOID WlxDisplayLockedNotice(
  PVOID pWlxContext
);

Parameters

pWlxContext
[in] Pointer to the GINA context associated with this window station. This is the context value that the GINA returns when Winlogon calls WlxInitialize for this station.

Return Values

This function has no return values.

Remarks

To display lock information, the GINA must display a dialog box that will be interrupted by a WLX_WM_SAS message. For more information, see Sending Messages to the GINA.

Before calling WlxDisplayLockedNotice, Winlogon sets the desktop and workstation states as follows.

Sets the | So that
Desktop state | The current desktop is the Winlogon desktop.
Workstation state | The desktop is locked.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxDisplaySASNotice, WlxInitialize


WlxDisplaySASNotice

The WlxDisplaySASNotice function must be implemented by a replacement GINA DLL. Winlogon calls this function when no user is logged on.

VOID WlxDisplaySASNotice(
  PVOID pWlxContext
);

Parameters

pWlxContext
[in] Pointer to the GINA context associated with this window station. This is the context value that the GINA returns when Winlogon calls WlxInitialize for this station.

Return Values

This function has no return values.

Remarks

Before calling WlxDisplaySASNotice, Winlogon sets the desktop and workstation states as follows.

Sets the… | So that…
Desktop state | The current desktop is the Winlogon desktop.
Workstation state | The desktop is locked.

Example Code

For an Example of… | See…
WlxDisplaySASNotice | Implementing WlxDisplaySASNotice

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize


WlxDisplayStatusMessage

The WlxDisplayStatusMessage function must be implemented by a replacement GINA DLL. Winlogon calls this function when the GINA DLL should display a message.

BOOL WlxDisplayStatusMessage(
  PVOID pWlxContext,
  HDESK hDesktop,
  DWORD dwOptions,
  PWSTR pTitle,
  PWSTR pMessage
);

Parameters

pWlxContext
[in] Pointer to the GINA context associated with this window station. The GINA returns this context value when Winlogon calls WlxInitialize for this station.
hDesktop
[in] Handle to the desktop where the status message should be displayed.
dwOptions
[in] Specifies display options for the status dialog box. The following options are valid:

STATUSMSG_OPTION_NOANIMATION

STATUSMSG_OPTION_SETFOREGROUND

pTitle
[in] Specifies the title of the message to be displayed.
pMessage
[in] Specifies the message to be displayed.

Return Values

TRUE
Return TRUE if the message was displayed.
FALSE
Return FALSE if the message was not displayed.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.3.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize


WlxGetStatusMessage

The WlxGetStatusMessage function must be implemented by a replacement GINA DLL. Winlogon calls this function to get the status message being displayed by the GINA DLL.

BOOL WlxGetStatusMessage(
  PVOID pWlxContext,
  DWORD *pdwOptions,
  PWSTR pMessage,
  DWORD dwBufferSize
);

Parameters

pWlxContext
[in] Pointer to the GINA context associated with this window station. The GINA returns this context value when Winlogon calls WlxInitialize for this station.
pdwOptions
[out] Pointer to a DWORD that will hold the display options for the current status message.
pMessage
[out] Returns the current status message text.
dwBufferSize
[in] Size of the pMessage buffer.

Return Values

TRUE
Return TRUE if the message was retrieved.
FALSE
Return FALSE if the message was not retrieved.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.3.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxDisplayStatusMessage, WlxInitialize, WlxRemoveStatusMessage


WlxInitialize

The WlxInitialize function must be implemented by a replacement GINA DLL. Winlogon calls this function once for each window station present on the computer. Currently, the operating system supports one window station per workstation.

The context returned by this function will be passed back to the GINA in all subsequent calls.

BOOL WlxInitialize(
  LPWSTR lpWinsta,
  HANDLE hWlx,
  PVOID pvReserved,
  PVOID pWinlogonFunctions,
  PVOID *pWlxContext
);

Parameters

lpWinsta
[in] Pointer to the name of the window station being initialized.
hWlx
[in] Handle to Winlogon. The GINA must supply this handle in all calls to Winlogon support functions that involve this window station.
pvReserved
Reserved.
pWinlogonFunctions
[in] Pointer to a Winlogon support function dispatch table. The contents of the table depends on the GINA DLL version returned by the WlxNegotiate call. This table does not change, allowing the GINA DLL to reference the table without copying it. If the GINA DLL needs to make a copy of the table, it should call WlxGetOption and supply WLX_OPTION_DISPATCH_TABLE_SIZE for the Option parameter.
For Information On… | See…
Winlogon dispatch table - version 1.0 | WLX_DISPATCH_VERSION_1_0
Winlogondispatch table - wersion 1.1 | WLX_DISPATCH_VERSION_1_1
Winlogon dispatch table - verison 1.2 | WLX_DISPATCH_VERSION_1_2
Winlogon dispatch table - version 1.3 | WLX_DISPATCH_VERSION_1_3

pWlxContext
[out] Pointer to a pointer to VOID which will contain the address of the GINA context for this window station. This context is passed in all subsequent calls to the GINA from Winlogin. The GINA DLL manages any memory used by the context. The context pointer can be changed later by calling WlxSetOption with WLX_OPTION_CONTEXT_POINTER.

Return Values

Value | Meaning
TRUE | Return TRUE if the GINA DLL was successfully initialized.
FALSE | Return FALSE if the GINA DLL was not initialized. Winlogon will terminate and the system will not boot.

Remarks

WlxInitialize is called once for each window station present on the computer.

Note Windows 2000 supports a single window station called Winsta0. Additional physical window stations may be supported in future releases.

Before calling WlxInitialize, Winlogon sets the desktop and workstation states as follows.

Sets the… | So that…
Desktop state | The current desktop is the Winlogon desktop.
Workstation state | The desktop is locked.

Example Code

For an Example of… | See…
WlxInitialize | Implementing WlxInitialize

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxNegotiate


WlxIsLockOk

The WlxIsLockOk function must be implemented by a replacement GINA DLL. Winlogon calls this function before attempting to lock the workstation.

BOOL WlxIsLockOk(
  PVOID pWlxContext
);

Parameters

pWlxContext
[in] Pointer to the GINA context associated with this window station. The GINA supplies this context when Winlogon calls WlxInitialize.

Return Values

Value | Meaning
TRUE | Return TRUE if it is acceptable to lock the workstation.
FALSE | Return FALSE if it is not acceptable to lock the workstation.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize


WlxIsLogoffOk

The WlxIsLogoffOk function must be implemented by a replacement GINA DLL. Winlogon calls this function when the user initiates a logoff operation.

BOOL WlxIsLogoffOk(
  PVOID pWlxContext
);

Parameters

pWlxContext
[in] Pointer to the GINA context associated with this window station. The GINA returns this context value when Winlogon calls WlxInitialize for this station.

Return Values

Value | Meaning
TRUE | Return TRUE if it is acceptable to perform the logoff operation.
FALSE | Return FALSE if it is not acceptable to perform the logoff operation.

Remarks

WlxIsLogoffOk can return FALSE to prevent the user from logging off the workstation.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize


WlxLoggedOnSAS

The WlxLoggedOnSAS function must be implemented by a replacement GINA DLL. Winlogon calls this function when it receives an SAS event while the user is logged on and the workstation is not locked.

int WlxLoggedOnSAS(
  PVOID pWlxContext,
  DWORD dwSasType,
  PVOID pReserved
);

Parameters

pWlxContext
[in] Pointer to the GINA context associated with this window station. The GINA returns this context value when Winlogon calls WlxInitialize for this station.
dwSasType
[in] Specifies the type of SAS that occurred. Values from 0 to WLX_SAS_TYPE_MAX_MSFT_VALUE are reserved to define standard Microsoft SAS types. GINA developers can define additional SAS types using values greater than WLX_SAS_TYPE_MAX_MSFT_VALUE.

The following SAS types are predefined.
Type | Description
WLX_SAS_TYPE_CTRL_ALT_DEL | Indicates a user has typed the standard CTRL+ALT+DEL secure attention sequence (SAS).
WLX_SAS_TYPE_SC_INSERT | Indicates that a smart card has been inserted into a compatible device.
WLX_SAS_TYPE_SC_REMOVE | Indicates that a smart card has been removed from a compatible device.
WLX_SAS_TYPE_TIMEOUT | Indicates that no user input was received within the specified time-out period.

pReserved
[in] Reserved.

Return Values

The WlxLoggedOnSAS function should return one of the following values:

Value | Meaning
WLX_SAS_ACTION_NONE | Returns to the default desktop.
WLX_SAS_ACTION_LOCK_WKSTA | Locks the workstation and waits for the next SAS.
WLX_SAS_ACTION_LOGOFF | Logs the user off the workstation.
WLX_SAS_ACTION_SHUTDOWN | Logs the user off and shuts down the computer.
WLX_SAS_ACTION_SHUTDOWN_REBOOT | Logs the user off, shuts down the computer, and then reboots the computer.
WLX_SAS_ACTION_SHUTDOWN_POWER_OFF | If hardware allows, logs the user off, shuts down the computer, and then turns off the computer.
WLX_SAS_ACTION_PWD_CHANGE | Notifies network providers that the user changed their password. Obsolete GINA DLLs should call WlxPasswordChangeNotify whenever a password is changed.
WLX_SAS_ACTION_TASKLIST | Invokes the task list.
WLX_SAS_ACTION_FORCE_LOGOFF | Forcibly logs off the user.
WLX_SAS_ACTION_SHUTDOWN_SLEEP | Puts the computer in suspend mode.
WLX_SAS_ACTION_SHUTDOWN_SLEEP2 | Shuts down the system into an ACPI power-down state. If the machine is not an ACPI machine, this option will have no effect.
WLX_SAS_ACTION_SHUTDOWN_HIBERNATE | Shuts down the system into the hibernate mode. If the system was not configured for hibernation, this option will have no effect.

Remarks

Winlogon calls WlxLoggedOnSAS when the logged-on user wants to shut down, log out, or lock the workstation. The GINA DLL can lock the workstation by returning WLX_SAS_LOCK_WKSTA. When this value is returned, Winlogon locks the workstation and calls WlxWkstaLockedSAS the next time it receives an SAS.

Before calling WlxLoggedOnSAS, Winlogon sets the desktop and workstation states as follows.

Sets the… | So that…
Desktop state | The current desktop is the Winlogon desktop.
Workstation state | The desktop is locked.

Example Code

For an Example of… | See…
WlxLoggedOnSAS | Implementing WlxLoggedOnSAS

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize, WlxWkstaLockedSAS


WlxLoggedOutSAS

The WlxLoggedOutSAS function must be implemented by a replacement GINA DLL. Winlogon calls this function when it receives a secure attention sequence (SAS) event while no user is logged on.

int WlxLoggedOutSAS(
  PVOID pWlxContext,
  DWORD dwSasType,
  PLUID pAuthenticationId,
  PSID pLogonSid,
  PDWORD pdwOptions,
  PHANDLE phToken,
  PWLX_MPR_NOTIFY_INFO pNprNotifyInfo,
  PVOID *pProfile
);

Parameters

pWlxContext
[in] Pointer to the GINA context associated with this window station. The GINA returns this context value when Winlogon calls WlxInitialize for this station.
dwSasType
[in] Specifies the type of SAS that occurred. Values from 0 to WLX_SAS_TYPE_MAX_MSFT_VALUE are reserved to define standard Microsoft SAS types. GINA developers can define additional SAS types using values greater than WLX_SAS_TYPE_MAX_MSFT_VALUE.

The following SAS types are predefined.
Type | Description
WLX_SAS_TYPE_CTRL_ALT_DEL | Indicates a user has typed the standard CTRL+ALT+DEL secure attention sequence (SAS).
WLX_SAS_TYPE_SC_INSERT | Indicates that a smart card has been inserted into a compatible device.
WLX_SAS_TYPE_SC_REMOVE | Indicates that a smart card has been removed from a compatible device.
WLX_SAS_TYPE_TIMEOUT | Indicates that no user input was received within the specified time-out period.

pAuthenticationId
[out] Specifies the authentication identifier associated with the current logon session. You can get this value by calling GetTokenInformation to obtain a TOKEN_STATISTS structure for the token returned by the LogonUser function.
pLogonSid
[in, out] On input, this parameter points to a security identifier (SID) that is unique to the current logon session. Winlogon uses this SID to change the protection on the window station and application desktop so that the new logged-on user can access them.

On output, Winlogon provides an SID. You can also get the SID by using the GetTokenInformation function to retrieve a TOKEN_GROUPS structure for the token returned by the LogonUser function. To do this, search the array returned in the TOKEN_GROUPS structure for the group with the SE_GROUP_LOGON_ID attribute.

pdwOptions
[out] Pointer to a DWORD that contains the set of logon options. The following option is defined.
Value | Description
WLX_LOGON_OPT_NO_PROFILE | Indicates that Winlogon must not load a profile for the logged-on user. Either the GINA DLL will take care of this activity, or the user does not need a profile.

phToken
[out] Points to a handle variable. When the logon operation succeeds, set this handle to a token that represents the logged-on user. Use the LogonUser function to get this token, then when the user logs off, Winlogon closes this handle and calls the WlxLogoff function.

If you need this handle during your WlxLogoff, make a duplicate of the handle before returning it to Winlogon.

pNprNotifyInfo
[out] Points to an WLX_MPR_NOTIFY_INFO structure that contains domain, user name, and password information for the user. Winlogon will use this information to provide identification and authentication information to network providers.

The GINA is not required to return password information. Any NULL fields within the structure will be ignored by Winlogon. Use LocalAlloc to allocate each string; Winlogon will free them when they are no longer needed.

pProfile
[out] On return from a successful authentication, the pProfile parameter points to either a WLX_PROFILE_V1_0 or a WLX_PROFILE_V2_0 structure. The first DWORD in the structure indicates which structure it is. Winlogon uses this structure to load the logged-on user's profile, and frees the memory associated with the structure when it no longer needs it.

Return Values

WlxLoggedOutSAS should return the following values.

Value | Meaning
WLX_SAS_ACTION_LOGON | Indicates a user has logged on.
WLX_SAS_ACTION_NONE | Indicates the logged attempt was unsuccessful or canceled.
WLX_SAS_ACTION_SHUTDOWN | Indicates the user requested that the system be shut down.

Remarks

Before calling WlxLoggedOutSAS, Winlogon sets the desktop and workstation state as follows.

Sets the | So that
Desktop state | The current desktop is the Winlogon desktop.
Workstation state | The desktop is locked.

Do not activate the user shell program in WlxLoggedOutSAS. The user shell program should always be activated in WlxActivateUserShell.

Example Code

For an Example of… | See…
WlxLoggedOutSAS | Implementing WlxLoggedOutSAS

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxActivateUserShell, WlxInitialize


WlxLogoff

The WlxLogoff function must be implemented by a replacement GINA DLL. Winlogon calls this function to notify the GINA of a logoff operation on this workstation, allowing the GINA to perform any logoff operations that may be required.

VOID WlxLogoff(
  PVOID pWlxContext
);

Parameters

pWlxContext
[in] Pointer to the GINA context associated with this window station. The GINA returns this context value when Winlogon calls WlxInitialize for this station.

Return Values

This function has no return values.

Remarks

Before calling WlxLogoff, Winlogon sets the desktop and workstation state as follows.

Sets the… | So that…
Desktop state | The current desktop is the Winlogon desktop.
Workstation state | The desktop is locked.

Example Code

For an Example of… | See…
Implementing a logoff operation | Implementing WlxLogoff

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize


WlxNegotiate

The WlxNegotiate function must be implemented by a replacement GINA DLL. This is the first call made by Winlogon to the GINA DLL. WlxNegotiate allows the GINA to verify that it supports the installed version of Winlogon.

BOOL WlxNegotiate(
  DWORD dwWinLogonVersion,
  PDWORD pdwDllVersion
);

Parameters

dwWinLogonVersion
[in] Specifies which version of Winlogon will be communicating with the GINA.
pdwDllVersion
[out] Indicates which version of Winlogon the GINA supports. This version information is also used by Winlogon to determine which dispatch table is passed to the GINA in subsequent calls to WlxInitialize. This version cannot be greater than the version specified by dwWinLogonVersion.

Return Values

Value | Meaning
TRUE | Return TRUE if the Winlogon version specified by dwWinLogonVersion is greater than or equal to the version returned in pdwDllVersion. When TRUE is returned, Winlogon will continue to initialize.
FALSE | Return FALSE if dwWinLogonVersion is less than pdwDllVersion. When FALSE is returned, Winlogon will terminate and the system will not boot.

Remarks

Before calling WlxNegotiate, Winlogon sets the desktop and workstation state as follows.

Sets the… | So that…
Desktop state | The current desktop is the Winlogon desktop.
Workstation state | The desktop is locked.

Example Code

For an Example of… | See…
WlxNegotiate | Implementing WlxNegotiate

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize


WlxNetworkProviderLoad

The WlxNetworkProviderLoad function must be implemented by a replacement GINA DLL. Winlogon calls this function to collect valid authentication and identification information.

BOOL WlxNetworkProviderLoad(
  PVOID pWlxContext,
  PWLX_MPR_NOTIFY_INFO pNprNotifyInfo
);

Parameters

pWlxContext
[in] Pointer to the GINA context associated with this window station. The GINA returns this context value when Winlogon calls WlxInitialize for this station.
pNprNotifyInfo
[out] Points to an WLX_MPR_NOTIFY_INFO structure that contains domain, user name, and password information for the user. Winlogon will use this information to provide identification and authentication information to network providers.

The GINA is not required to return password information. Any NULL fields within the structure will be ignored by Winlogon. Use LocalAlloc to allocate each string; Winlogon will free them when they are no longer needed.

Return Values

Value | Meaning
TRUE | Return TRUE if the user was authenticated.
FALSE | Return FALSE if the user was not authenticated.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.3.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize


WlxRemoveStatusMessage

The WlxRemoveStatusMessage function must be implemented by a replacement GINA DLL. Winlogon calls this function to tell the GINA DLL to stop displaying the status message.

BOOL WlxRemoveStatusMessage(
  PVOID pWlxContext
);

Parameters

pWlxContext
[in] Pointer to the GINA context associated with this window station. The GINA returns this context value when Winlogon calls WlxInitialize for this station.

Return Values

Value | Meaning
TRUE | Return TRUE if the message was removed.
FALSE | Return FALSE if the message was not removed.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.3.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize, WlxDisplayStatusMessage, WlxGetStatusMessage


WlxScreenSaverNotify

The WlxScreenSaverNotify function may be implemented by a replacement GINA DLL. Winlogon calls this function immediately before a screen saver is activated, allowing the GINA to interact with the screen saver program.

BOOL WlxScreenSaverNotify(
  PVOID pWlxContext,
  BOOL *pSecure
);

Parameters

pWlxContext
[in] Pointer to the GINA context associated with this window station. The GINA returns this context value when Winlogon calls WlxInitialize for this station.
pSecure
[in, out] Pointer to a boolean. On input, specifies whether the current screen saver is secure.

On output, indicates whether the workstation should be locked.

Return Values

Value | Meaning
TRUE | Return TRUE if the screen saver should be activated.
FALSE | Return FALSE of the screen saver should not be activated.

Remarks

If your GINA DLL does not export this function, Winlogon uses the following default behavior.

BOOL
DefaultScreenSaverNotify(
   PVOID   pWlxContext,
   BOOL    *pSecure)
{
  if (*pSecure)
  {
    *pSecure = WlxIsLockOk(pWlxContext);
  }
  return(TRUE);
}

Before calling WlxScreenSaverNotify, Winlogon sets the desktop and workstation states as follows.

Sets the… | So that…
Desktop state | The current desktop is the Winlogon desktop.
Workstation state | The desktop is locked.

Example Code

For an Example of… | See…
WlxScreenSaverNotify | Implementing WlxScreenSaverNotify

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.1.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize


WlxShutdown

The WlxShutdown function must be implemented by a replacement GINA DLL. Winlogon calls this function just before shutting down, allowing the GINA to perform any shutdown tasks, such as ejecting a smart card from a reader.

VOID WlxShutdown(
  PVOID pWlxContext,
  DWORD ShutdownType
);

Parameters

pWlxContext
[in] Pointer to the GINA context associated with this window station. The GINA returns this context value when Winlogon calls WlxInitialize for this station.
ShutdownType
[in] Specifies the type of shutdown. One of the following values is specified:
Value | Meaning
WLX_SAS_ACTION_SHUTDOWN | Logs the user off and shuts down the computer.
WLX_SAS_ACTION_SHUTDOWN_REBOOT | Shuts down and then reboots the computer.
WLX_SAS_ACTION_SHUTDOWN_POWER_OFF | Shuts down and turns off the computer, if the hardware allows.

Return Values

This function has no return values.

Remarks

Winlogon calls WlxShutdown after the user has logged off and the WlxLogoff function has been called.

Before calling WlxShutdown, Winlogon sets the desktop and workstation state as follows.

Sets the… | So that…
Desktop state | The current desktop is the Winlogon desktop.
Workstation state | The desktop is locked.

Example Code

For an Example of… | See…
WlxShutdown | Implementing WlxShutdown

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize, WlxLogoff


WlxStartApplication

The WlxStartApplication function may be implemented by a replacement GINA DLL. Winlogon calls this function when the system needs an application started in the user's context. In a Microsoft® Windows® NT 4.0 release, this can occur for two reasons: Explorer has terminated unexpectedly and needs to be restarted, or the extended task manager needs to run. The GINA can override this behavior, if appropriate, through the WlxStartApplication function.

BOOL WlxStartApplication(
  PVOID pWlxContext,
  PWSTR pszDesktopName,
  PVOID pEnvironment,
  PWSTR pszCmdLine
);

Parameters

pWlxContext
[in] Pointer to the GINA context associated with this window station. The GINA returns this context value when Winlogon calls WlxInitialize for this station.
pszDesktopName
[in] Specifies the name of the desktop on which to start the application. Pass this string to the CreateProcess or CreateProcessAsUser functions through the lpDesktop member of the STARTUPINFO structure.
pEnvironment
[in] Specifies the initial environment for the process. Winlogon creates this environment and hands it off to the GINA. The GINA can modify this environment before using it to initialize the user's shell. The GINA is responsible for calling the VirtualFree function to free the memory allocated for pEvironment.
pszCmdLine
[in] Program to execute.

Return Values

Return TRUE if the application started.

Return FALSE if the application did not start.

Remarks

Before calling WlxStartApplication, Winlogon sets the desktop and workstation states as follows.

Sets the | So that
Desktop state | The current desktop is the Winlogon desktop.
Workstation state | The desktop is locked.

If WlxStartApplication function is not exported by the GINA, Winlogon will execute the process.

Example Code

For an Example of… | See…
WlxStartApplication | Implementing WlxStartApplication

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.1.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize


WlxWkstaLockedSAS

The WlxWkstaLockedSAS function must be implemented by a replacement GINA DLL. Winlogon calls this function when it receives a secure attention sequence (SAS) and the workstation is locked. The GINA should return a value indicating the workstation is to remain locked, the workstation is to be unlocked, or the logged-on user is being forced to log off (which leaves the workstation locked until the logoff is completed).

int WlxWkstaLockedSAS(
  PVOID pWlxContext,
  DWORD dwSasType
);

Parameters

pWlxContext
[in] Pointer to the GINA context associated with this window station. The GINA returns this context value when Winlogon calls WlxInitialize for this station.
dwSasType
[in] Specifies the type of SAS that occurred. Values from zero to WLX_SAS_TYPE_MAX_MSFT_VALUE are reserved for standard Microsoft SAS types. GINA developers can use values greater than WLX_SAS_TYPE_MAX_MSFT_VALUE to define additional SAS types. The following SAS types are predefined.
Type | Description
WLX_SAS_TYPE_CTRL_ALT_DEL | Indicates a user has typed the standard CTRL+ALT+DEL secure attention sequence (SAS).
WLX_SAS_TYPE_SC_INSERT | Indicates that a smart card has been inserted into a compatible device.
WLX_SAS_TYPE_SC_REMOVE | Indicates that a smart card has been removed from a compatible device.
WLX_SAS_TYPE_TIMEOUT | Indicates that no user input was received within the specified time-out period.

Return Values

WlxWkstaLockedSAS should return the following values:

Value | Meaning
WLX_SAS_ACTION_NONE | Tells Winlogon to keep the workstation locked.
WLX_SAS_ACTION_UNLOCK_WKSTA | Tells Winlogon to unlock the workstation.
WLX_SAS_ACTION_FORCE_LOGOFF | Tells Winlogon to force the user to log off.

Remarks

Before calling WlxWkstaLockedSAS, Winlogon sets the desktop and workstation states as follows.

Sets the… | So that…
Desktop state | The current desktop is the Winlogon desktop.
Workstation state | The desktop is locked.

Example Code

For an Example of… | See…
WlxWkstaLockedSAS | Implementing WlxWkstaLockedSAS

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize


GINA Structures

GINA interface functions and Winlogon support functions use the following structures.

Structure | Description
WLX_CLIENT_CREDENTIALS_INFO_V1_0 | Contains client credential information.
WLX_DESKTOP | Contains desktop information.
WLX_DISPATCH_VERSION_1_0 | Contains the Winlogon, version 1.0 dispatch table.
WLX_DISPATCH_VERSION_1_1 | Contains the Winlogon, version 1.1 dispatch table.
WLX_DISPATCH_VERSION_1_2 | Contains the Winlogon, version 1.2 dispatch table.
WLX_DISPATCH_VERSION_1_3 | Contains the Winlogon, version 1.3 dispatch table.
WLX_MPR_NOTIFY_INFO | Contains authentication and identification information.
WLX_PROFILE_V1_0 | Contains information used for setting up the initial environment.
WLX_PROFILE_V2_0 | Contains information used for setting up the initial environment.
WLX_TERMINAL_SERVICES_DATA | Contains the Terminal Services profile path and home directory information.


WLX_CLIENT_CREDENTIALS_INFO_V1_0

The WLX_CLIENT_CREDENTIALS_INFO_V1_0 structure contains the client credentials returned by a call to WlxQueryClientCredentials or WlxQueryInetConnectorCredentials. This allows a network client session to pass client credentials for automatic logon.

Note WlxQueryClientCredentials is called when Terminal Services is enabled.

The GINA DLL is responsible for calling LocalFree to free the resources used by this structure when the structure is no longer needed.

Typedef struct _WLX_CLIENT_CREDENTIALS_INFO {
  DWORD  dwType;
  PWSTR  pszUserName;
  PWSTR  pszDomain;
  PWSTR  pszPassword;
  BOOL   fPromptForPassword;
}WLX_CLIENT_CREDENTIALS_INFO_V1_0, *PWLX_CLIENT_CREDENTIALS_INFO_V1_0;

Members

dwType
Specifies the type of credentials structure allocated by the GINA DLL. Credential types are defined with the prefix WLX_CREDENTIAL_TYPE_xxx.
pszUserName
A pointer to the name of the account logged onto (for example "joeu").
pszDomain
A pointer to the name of the domain used to log on.
pszPassword
A pointer to the clear-text password of the user account.
fPromptForPassword
Forces a prompt for the password due to an administration override. This allows the distinction of auto logon with no password.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.3.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See also

LocalFree, WlxQueryClientCredentials, WlxQueryInetConnectorCredentials


WLX_DESKTOP

The WLX_DESKTOP structure is used to pass desktop information between your GINA DLL and Winlogon.

Typedef struct _WLX_DESKTOP {
  DWORD   Size;
  DWORD   Flags;
  HDESK   hDesktop;
  PWSTR   pszDesktopName;
}WLX_DESKTOP;

Members

Size
Specifies the size of the WLX_DESKTOP structure. Set to sizeof(WLX_DESKTOP).
Flags
Specifies the valid fields. Specify one of the following.
Flag | Description
WLX_DESKTOP_NAME | Indicates that the name specified in pszDesktopName is valid.
WLX_DESKTOP_HANDLE | Indicates that the handle specified in hDesktop is valid.

hDesktop
Handle to the desktop returned by CreateDesktop and OpenDesktop.
pszDesktopName
Name of the desktop.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.1.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See also

WlxGetSourceDesktop, WlxCreateUserDesktop


WLX_DISPATCH_VERSION_1_0

The WLX_DISPATCH_VERSION_1_0 structure defines the format of the Winlogon version 1.0 function dispatch table passed to your GINA DLL in the WlxInitialize call.

This dispatch table is used if your GINA DLL specifies version 1.0 in its implementation of WlxNegotiate.

Typedef struct __win32_DISPATCH_VERSION_1_0 {
  PWLX_USE_CTRL_ALT_DEL            WlxUseCtrlAltDel;
  PWLX_SET_CONTEXT_POINTER         WlxSetContextPointer;
  PWLX_SAS_NOTIFY                  WlxSasNotify;
  PWLX_SET_TIMEOUT                 WlxSetTimeout;
  PWLX_ASSIGN_SHELL_PROTECTION     WlxAssignShellProtection;
  PWLX_MESSAGE_BOX                 WlxMessageBox;
  PWLX_DIALOG_BOX                  WlxDialogBox;
  PWLX_DIALOG_BOX_PARAM            WlxDialogBoxParam;
  PWLX_DIALOG_BOX_INDIRECT         WlxDialogBoxIndirect;
  PWLX_DIALOG_BOX_INDIRECT_PARAM   WlxDialogBoxIndirectParam;
  PWLX_SWITCH_DESKTOP_TO_USER     WlxSwitchDesktopToUser;
  PWLX_SWITCH_DESKTOP_TO_WINLOGON  WlxSwitchDesktopToWinlogon;
  PWLX_CHANGE_PASSWORD_NOTIFY      WlxChangePasswordNotify;
} WLX_DISPATCH_VERSION_1_0;

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize


WLX_DISPATCH_VERSION_1_1

The WLX_DISPATCH_VERSION_1_1 structure defines the format of the Winlogon version 1.1 function dispatch passed to your GINA DLL in the WlxInitialize call.

This dispatch table is used if your GINA DLL specifies version 1.1 in its implementation of WlxNegotiate.

Typedef struct __win32_DISPATCH_VERSION_1_1 {
  PWLX_USE_CTRL_ALT_DEL            WlxUseCtrlAltDel;
  PWLX_SET_CONTEXT_POINTER         WlxSetContextPointer;
  PWLX_SAS_NOTIFY                  WlxSasNotify;
  PWLX_SET_TIMEOUT                 WlxSetTimeout;
  PWLX_ASSIGN_SHELL_PROTECTION     WlxAssignShellProtection;
  PWLX_MESSAGE_BOX                 WlxMessageBox;
  PWLX_DIALOG_BOX                  WlxDialogBox;
  PWLX_DIALOG_BOX_PARAM            WlxDialogBoxParam;
  PWLX_DIALOG_BOX_INDIRECT         WlxDialogBoxIndirect;
  PWLX_DIALOG_BOX_INDIRECT_PARAM   WlxDialogBoxIndirectParam;
  PWLX_SWITCH_DESKTOP_TO_USER      WlxSwitchDesktopToUser;
  PWLX_SWITCH_DESKTOP_TO_WINLOGON  WlxSwitchDesktopToWinlogon;
  PWLX_CHANGE_PASSWORD_NOTIFY      WlxChangePasswordNotify;
  PWLX_GET_SOURCE_DESKTOP          WlxGetSourceDesktop;
  PWLX_SET_RETURN_DESKTOP          WlxSetReturnDesktop;
  PWLX_CREATE_USER_DESKTOP         WlxCreateUserDesktop;
  PWLX_CHANGE_PASSWORD_NOTIFY_EX   WlxChangePasswordNotifyEx;
} WLX_DISPATCH_VERSION_1_1;

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.1.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize


WLX_DISPATCH_VERSION_1_2

The WLX_DISPATCH_VERSION_1_2 structure defines the format of the Winlogon version 1.2 function dispatch table passed to your GINA DLL in the WlxInitialize call.

This dispatch table is used if your GINA DLL specifies version 1.2 in its implementation of WlxNegotiate.

Typedef struct __win32_DISPATCH_VERSION_1_2 {
  PWLX_USE_CTRL_ALT_DEL            WlxUseCtrlAltDel;
  PWLX_SET_CONTEXT_POINTER         WlxSetContextPointer;
  PWLX_SAS_NOTIFY                  WlxSasNotify;
  PWLX_SET_TIMEOUT                 WlxSetTimeout;
  PWLX_ASSIGN_SHELL_PROTECTION     WlxAssignShellProtection;
  PWLX_MESSAGE_BOX                 WlxMessageBox;
  PWLX_DIALOG_BOX                  WlxDialogBox;
  PWLX_DIALOG_BOX_PARAM            WlxDialogBoxParam;
  PWLX_DIALOG_BOX_INDIRECT         WlxDialogBoxIndirect;
  PWLX_DIALOG_BOX_INDIRECT_PARAM   WlxDialogBoxIndirectParam;
  PWLX_SWITCH_DESKTOP_TO_USER      WlxSwitchDesktopToUser;
  PWLX_SWITCH_DESKTOP_TO_WINLOGON  WlxSwitchDesktopToWinlogon;
  PWLX_CHANGE_PASSWORD_NOTIFY      WlxChangePasswordNotify;
  PWLX_GET_SOURCE_DESKTOP          WlxGetSourceDesktop;
  PWLX_SET_RETURN_DESKTOP          WlxSetReturnDesktop;
  PWLX_CREATE_USER_DESKTOP         WlxCreateUserDesktop;
  PWLX_CHANGE_PASSWORD_NOTIFY_EX   WlxChangePasswordNotifyEx;
  PWLX_CLOSE_USER_DESKTOP          WlxCloseUserDesktop;
} WLX_DISPATCH_VERSION_1_2

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.3.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize


WLX_DISPATCH_VERSION_1_3

The WLX_DISPATCH_VERSION_1_3 structure defines the format of the Winlogon version 1.3 function dispatch table passed to your GINA DLL in the WlxInitialize call.

This dispatch table is used if your GINA DLL specifies version 1.3 in its implementation of WlxNegotiate.

Typedef struct __win32_DISPATCH_VERSION_1_3 {
  PWLX_USE_CTRL_ALT_DEL             WlxUseCtrlAltDel;
  PWLX_SET_CONTEXT_POINTER          WlxSetContextPointer;
  PWLX_SAS_NOTIFY                   WlxSasNotify;
  PWLX_SET_TIMEOUT                  WlxSetTimeout;
  PWLX_ASSIGN_SHELL_PROTECTION      WlxAssignShellProtection;
  PWLX_MESSAGE_BOX                  WlxMessageBox;
  PWLX_DIALOG_BOX                   WlxDialogBox;
  PWLX_DIALOG_BOX_PARAM             WlxDialogBoxParam;
  PWLX_DIALOG_BOX_INDIRECT          WlxDialogBoxIndirect;
  PWLX_DIALOG_BOX_INDIRECT_PARAM    WlxDialogBoxIndirectParam;
  PWLX_SWITCH_DESKTOP_TO_USER       WlxSwitchDesktopToUser;
  PWLX_SWITCH_DESKTOP_TO_WINLOGON   WlxSwitchDesktopToWinlogon;
  PWLX_CHANGE_PASSWORD_NOTIFY       WlxChangePasswordNotify;
  PWLX_GET_SOURCE_DESKTOP           WlxGetSourceDesktop;
  PWLX_SET_RETURN_DESKTOP           WlxSetReturnDesktop;
  PWLX_CREATE_USER_DESKTOP          WlxCreateUserDesktop;
  PWLX_CHANGE_PASSWORD_NOTIFY_EX    WlxChangePasswordNotifyEx;
  PWLX_CLOSE_USER_DESKTOP           WlxCloseUserDesktop;
  PWLX_SET_OPTION                   WlxSetOption;
  PWLX_GET_OPTION                   WlxGetOption;
  PWLX_WIN31_MIGRATE                WlxWin31Migrate;
  PWLX_QUERY_CLIENT_CREDENTIALS     WlxQueryClientCredentials;
  PWLX_QUERY_IC_CREDENTIALS         WlxQueryInetConnectorCredentials;
  PWLX_DISCONNECT                   WlxDisconnect;
  PWLX_QUERY_TERMINAL_SERVICES_DATA WlxQueryTerminalServicesData;
} WLX_DISPATCH_VERSION_1_3;

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.3.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize


WLX_MPR_NOTIFY_INFO

The WLX_MPR_NOTIFY_INFO structure provides identification and authentication information to network providers. Your GINA DLL returns this information to Winlogon following a successful authentication. Winlogon is responsible for freeing both the main structure and all strings pointed to from within the structure.

Typedef struct _WLX_MPR_NOTIFY_INFO {
  PWSTR    pszUserName;
  PWSTR    pszDomain;
  PWSTR    pszPassword;
  PWSTR   pszOldPassword;
} WLX_MPR_NOTIFY_INFO;

Members

pszUserName
A pointer to the name of the account logged onto (for example "joeu").

The string pointed to by pszUserName must be separately allocated by your GINA DLL. It will be deallocated by Winlogon.

pszDomain
A pointer to the name of the domain used to log on.

The string pointed to by pszDomain must be separately allocated by your GINA DLL. It will be deallocated by Winlogon.

pszPassword
A pointer to the clear-text password of the user account. If pszOldPassword is non-Null, pszPassword contains the new password from a password-change operation.

The string pointed to by pszPassword must be separately allocated by your GINA DLL. It will be deallocated by Winlogon.

pszOldPassword
A pointer to the clear-text old password of the user account whose password has just been changed (in this case, pszPassword contains the new password).

The string pointed to by pszOldPassword must be separately allocated by your GINA DLL. It will be deallocated by Winlogon.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.


WLX_PROFILE_V1_0

The WLX_PROFILE_V1_0 structure contains information used for setting up the initial environment.

Typedef struct _WLX_PROFILE_V1_0 {
  DWORD   dwType;
  PWSTR   pszProfile;
} WLX_PROFILE_V1_0;

Members

dwType
Must be set to WLX_PROFILE_TYPE_V1_0.
pszProfile
Pointer to the profile path (for example, "%SystemRoot%\system32\config\JoeU001").

The string pointed to by pszProfile must be separately allocated by your GINA DLL. It will be deallocated by Winlogon.

Remarks

The WLX_PROFILE_V1_0 structure is returned to Winlogon by your GINA DLL following authentication. Winlogon uses the path specified by pwzProfile to load the profile of the newly logged-on user.

GINA uses two structures to provide profile information: WLX_PROFILE_V2_0 and WLX_PROFILE_V1_0.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WLX_PROFILE_V2_0


WLX_PROFILE_V2_0

The WLX_PROFILE_V2_0 structure contains profile information in addition to the information provided by WLX_PROFILE_V1_0.

Typedef struct _WLX_PROFILE_V2_0 {
  DWORD   dwType;
  PWSTR   pszProfile;
  PWSTR   pszPolicy;
  PWSTR   pszNetworkDefaultUserProfile;
  PWSTR   pszServerName;
  PWSTR   pszEnvironment;
} WLX_PROFILE_V2_0;

Members

dwType
Must be set to WLX_PROFILE_TYPE_V2_0.
pszProfile
Pointer to the profile path (for example, "%SystemRoot%\system32\config\JoeU001", or a network path such as "\\server\share\profiles\floating\JoeU.usr").

The string pointed to by pszProfile must be separately allocated by your GINA DLL. It will be deallocated by Winlogon.

pszPolicy
Pointer to the policy file that will be applied to the user logging on.

The string pointed to by pszPolicy must be separately allocated by your GINA DLL. It will be deallocated by Winlogon.

pszNetworkDefaultUserProfile
If a new profile is to be created, a pointer to the path of the default profile to use.

The string pointed to by pszNetworkDefaultUserProfile must be separately allocated by your GINA DLL. It will be deallocated by Winlogon.

pszServerName
Pointer to the name of the server that validated the logon. This name will be used to enumerate the global groups of which the user is a member.

The string pointed to by pszServerName must be separately allocated by your GINA DLL. It will be deallocated by Winlogon.

pszEnvironment
Pointer to the default environment variables to include in the construction of the environment of the user. This member is a series of null-terminated strings using any of the following forms:
Variable=Value
variable=%other variable%
variable=%othervariable%\additional text

For example:

logonServer=\\pdc
homepath=%logonServer%\share

Remarks

This structure is returned to Winlogon by your GINA DLL.

Your GINA DLL may use two structures to provide profile information: WLX_PROFILE_V2_0 and WLX_PROFILE_V1_0. The information in WLX_PROFILE_V1_0 only includes the profile type and path to the profile.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WLX_PROFILE_V1_0


WLX_TERMINAL_SERVICES_DATA

The WLX_TERMINAL_SERVICES_DATA structure is used to provide GINA with Terminal Services user configuration information. The structure is populated by the WlxQueryTerminalServicesData function.

typedef struct _WLX_TERMINAL_SERVICES_DATA {
  WCHAR           ProfilePath[WLX_DIRECTORY_LENGTH + 1];
  WCHAR           HomeDir[WLX_DIRECTORY_LENGTH + 1];
  WCHAR           HomeDirDrive[4];
} WLX_TERMINAL_SERVICES_DATA, *PWLX_TERMINAL_SERVICES_DATA;

Members

ProfilePath
Terminal Services profile path, overrrides the standard profile path.
HomeDir
Terminal Services home directory, overrides standard home directory.
HomeDirDrive
Terminal Services home directory drive, overrides the standard drive.

Remarks

The Terminal Sevices user configuration information is received from the Domain Controller and SAM database.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later. Available as a redistributable for Windows NT 4.0.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.3.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxQueryTerminalServicesData


Gina Defined Values

GINA interface functions and Winlogon support functions use the following defined values.

WLX_LOGON_OPTION_XXX | Contains predefined logon options. It is used by the dwOptions parameter of WlxLoggedOutSAS.
WLX_SAS_TYPE_XXX | Defines a specific SAS type.


WLX_LOGON_OPTION_XXX

The WLX_LOGON_OPTION_XXX values are used by the dwOptions parameter of WlxLoggedOutSAS. Upon a successful logon, your GINA DLL can use this value to specify the following option.

Option | Description
WLX_LOGON_OPT _NO_PROFILE | Specifies that Winlogon must not load a profile for the logged-on user. In this case either, your GINA DLL will load the profile or the user does not need a profile.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.


WLX_SAS_TYPE_XXX

The WLX_SAS_TYPE_XXX values define a specific SAS type.

All values from 0 to 127 are reserved for Microsoft-defined types. Values above 127 are available for customer-defined types. The following types are passed to functions that have a dwSasType parameter.

Type | Description
WLX_SAS_TYPE_CTRL_ALT_DEL | Indicates a user has typed the standard CTRL+ALT+DEL SAS.
WLX_SAS_TYPE_SC_INSERT | Indicates that a smart card has been inserted into a compatible device.
WLX_SAS_TYPE_SC_REMOVE | Indicates that a smart card has been removed from a compatible device.
WLX_SAS_TYPE_SCRNSVR_ACTIVITY | Indicates that keyboard or mouse activity occurred while a secure screen saver was active.
WLX_SAS_TYPE_SCRNSVR_TIMEOUT | Indicates that screen saver activation has occurred due to keyboard and mouse inactivity.
WLX_SAS_TYPE_TIMEOUT | Indicates that no user input was received within the specified time-out period.
WLX_SAS_TYPE_USER_LOGOFF | Indicates the user is being logged off the system.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.


Winlogon Support Functions

GINA DLLs can call the following Winlogon support functions.

Function | Called by GINA
WlxAssignShellProtection | Requests protection for the shell program of a newly logged-on user.
WlxChangePasswordNotify | Indicates that the user has changed a password. Used to notify all network providers.
WlxChangePasswordNotifyEx | Indicates that the user has changed a password. Used to notify a single network provider or all network providers.
WlxCloseUserDesktop | Closes a desktop for the user.
WlxCreateUserDesktop | Creates a desktop for the user.
WlxDialogBox | Creates a modal dialog box from a dialog box template resource.
WlxDialogBoxIndirect | Creates a modal dialog box from a dialog box template in memory.
WlxDialogBoxIndirectParam | Initializes dialog box controls and then create a modal dialog box from a dialog box template in memory.
WlxDialogBoxParam | Initializes dialog box controls and then create a modal dialog box from a dialog box template resource.
WlxDisconnect | Disconnects a Terminal Services network session.
WlxGetOption | Retrieves the current value of a specified option.
WlxGetSourceDesktop | Determines the name and handle of the desktop that was active prior to Winlogon switching to the Winlogon desktop.
WlxMessageBox | Creates, displays, and operates a message box.
WlxQueryClientCredentials | Queries the credentials of a remote client that is not using an Internet connector license.
WlxQueryInetConnectorCredentials | Queries the credentials of a remote client that is using an Internet connector license.
WlxQueryTerminalServicesData | Queries Terminal Services user configuration information.
WlxSasNotify | Notifies Winlogon of a secure attention sequence (SAS) event.
WlxSetContextPointer | Specifies the context pointer passed by Winlogon as the first parameter to all the GINA functions.
WlxSetOption | Specifies a value for a specific option.
WlxSetReturnDesktop | Specifies the desktop Winlogon will switch to once the current SAS event processing is complete.
WlxSetTimeout | Changes the time-out associated with a dialog box.
WlxSwitchDesktopToUser | Switches to the application desktop.
WlxSwitchDesktopToWinlogon | Switches to the Winlogon desktop.
WlxWin31Migrate | Completes the setup of the user (including migrating from Windows NT 3.51 settings to Windows NT 4.0 settings)
WlxUseCtrlAltDel | Prompts Winlogon to use the standard CTRL+ALT+DEL key combination as a secure attention sequence (SAS).


WlxAssignShellProtection

The WlxAssignShellProtection function is called by GINA to assign protection to the shell program of a newly logged-on user. The shell process should be created in a suspended state, then the WlxAssignShellProtection function should be called to apply the correct protection to the shell process.

This function has been superceded by the Win32 API CreateProcessAsUser function.

int WlxAssignShellProtection(
  HANDLE hWlx,
  HANDLE hToken,
  HANDLE hProcess,
  HANDLE hThread
);

Parameters

hWlx
[in] Specifies the Winlogon handle passed to GINA in the WlxInitialize call.
hToken
[in] Specifies the handle to a primary token.
hProcess
[in] Specifies the handle to the process to modify. The process must be created in the suspended state, and this should be the handle returned in the PROCESS_INFORMATION structure.
hThread
[in] Specifies the handle to the initial thread of the process.

Return Values

The WlxAssignShellProtection function returns any errors encountered while trying to assign protection.

Remarks

The Win32 API CreateProcessAsUser function supersedes WlxAssignShellProtection. Call CreateProcessAsUser in WlxActivateUserShell to create the shell process and set its protections in a single call.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

CreateProcessAsUser, WlxActivateUserShell WlxInitialize


WlxChangePasswordNotify

The WlxChangePasswordNotify function is called by GINA to indicate it has changed a password. This allows Winlogon to notify other network providers on the computer to update their passwords as well.

This function has been superseded by the WlxChangePasswordNotifyEx function.

int WlxChangePasswordNotify(
  HANDLE hWlx,
  PWLX_MPR_NOTIFY_INFO pMprInfo,
  DWORD dwChangeInfo
);

Parameters

hWlx
[in] Specifies the Winlogon handle passed to GINA in the WlxInitialize call.
pMprInfo
[in] Points to a WLX_MPR_NOTIFY_INFO structure that contains Multiple Provider Router (MPR) information. Winlogon will call LocalFree to free all the data pointed to by this structure when it is done with it.
dwChangeInfo
[in] Changes the information flags from Network Provider API.

Return Values

The WlxChangePasswordNotifyEx function returns zero if the function call succeeds. Any other value indicates an error.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize, WLX_MPR_NOTIFY_INFO


WlxChangePasswordNotifyEx

The WlxChangePasswordNotifyEx function is called by GINA to tell a specific network provider (or all network providers) that a password has changed. In this way, GINA can pass a change password request through to a specific network provider.

This function supersedes the WlxChangePasswordNotify function.

int WlxChangePasswordNotifyEx(
  HANDLE hWlx,
  PWLX_MPR_NOTIFY_INFO pMprInfo,
  DWORD dwChangeInfo,
  PWSTR ProviderName,
  PVOID Reserved
);

Parameters

hWlx
[in] Specifies the Winlogon handle passed to GINA in the WlxInitialize call.
pMprInfo
[in] Points to a WLX_MPR_NOTIFY_INFO structure that contains Multiple Provider Router (MPR) information. Winlogon will call LocalFree to free all the data pointed to by this structure when it is done with it.
dwChangeInfo
Changes the information flags from Network Provider API.
ProviderName
[in] Specifies the name of a network provider, or NULL to allow the system to notify all network providers.
Reserved
[in] Reserved. Must be set to zero.

Return Values

The WlxChangePasswordNotifyEx function returns zero if the function call succeeds. Any other value indicates an error.

Remarks

This function supersedes the WlxChangePasswordNotify function.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.1.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxChangePasswordNotify, WlxInitialize, WLX_MPR_NOTIFY_INFO


WlxCloseUserDesktop

The WlxCloseUserDesktop function is called by GINA to close an alternate user desktop and cleanup after the desktop is closed.

BOOL WlxCloseUserDesktop(
  HANDLE hWlx,
  PWLX_DESKTOP pDesktop,
  HANDLE hToken
);

Parameters

hWlx
[in] Specifies the Winlogon handle passed to GINA in the WlxInitialize call.
pDesktop
[in] Specifies a pointer to a WLX_DESKTOP structure, obtained by calling the WlxCreateUserDesktop function.
hToken
[in] Specifies the handle to the token of the user whose desktop is to be closed.

Return Values

The WlxCloseUserDesktop function returns one of the following values.

Value | Meaning
TRUE | The desktop has been closed.
FALSE | The desktop has not been closed.

Remarks

In addition to closing the desktop, this function will modify access to the parent window station to remove aces added during the creation of the user desktop.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.2.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxCreateUserDesktop, WLX_DESKTOP, WlxInitialize


WlxCreateUserDesktop

The WlxCreateUserDesktop function is called by GINA to create alternate application desktops for the user.

Bool WlxCreateUserDesktop(
  HANDLE hWlx,
  HANDLE hToken,
  DWORD Flags,
  PWSTR pszDesktopName,
  PWLX_DESKTOP *ppDesktop
);

Parameters

hWlx
[in] Specifies the Winlogon handle passed to GINA in the WlxInitialize call.
hToken
[in] Specifies the handle to the token of the user for whom the desktop is being created.
Flags
[in] Specifies access to the desktop. Specify one of the following:
WLX_CREATE_INSTANCE_ONLY
Specifies that only this instance of the user has access.
WLX_CREATE_USER
Specifies that any instance of this user has access.
pszDesktopName
[in] Specifies the name of the desktop to be created.
ppDesktop
[out] If the desktop is created, returns a pointer to a WLX_DESKTOP structure for the new desktop. This pointer can be used in a call to WlxSetReturnDesktop to make this the current desktop after a SAS event is processed.

Return Values

The WlxCreateUserDesktop function returns one of the following values.

Value | Meaning
TRUE | The desktop has been created.
FALSE | The desktop has not been created.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.1.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize, WlxSetReturnDesktop


WlxDialogBox

The WlxDialogBox function is called by the GINA to create a modal dialog box from a dialog box template.

int WlxDialogBox(
  HANDLE hWlx,
  HANDLE hInst,
  LPWSTR lpszTemplate,
  HWND hwndOwner,
  DLGPROC dlgprc
);

Parameters

hWlx
[in] Specifies the Winlogon handle passed to GINA in the WlxInitialize call.
hInst
[in] Specifies an instance of the module whose executable file contains the dialog box template.
lpszTemplate
[in] Specifies the dialog box template. This parameter is either the address of a null-terminated character string that specifies the name of the dialog box template, or an integer value that specifies the resource identifier of the dialog box template. If the parameter specifies a resource identifier, its high-order word must be zero and its low-order word must contain the identifier. You can use the MAKEINTRESOURCE macro to create this value.
hwndOwner
[in] Specifies the window that owns the dialog box.
dlgprc
[in] Points to the dialog box procedure. For more information about the dialog box procedure, see the DialogProc callback function.

Return Values

If the WlxDialogBox function succeeds, the return value is the nResult parameter given in the call to the EndDialog function used to terminate the dialog box.

If the function fails, the return value is –1.

Remarks

GINA must use the Winlogon WlxDialogBox function, not the Win32 DialogBox macro. WlxDialogBox duplicates the Win32 DialogBox macro, and also allows Winlogon to terminate the dialog box. For more information, see DialogBox.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

DialogBox, DialogProc, EndDialog, MAKEINTRESOURCE, WlxInitialize


WlxDialogBoxIndirect

The WlxDialogBoxIndirect function is called by GINA to create a modal dialog box from a dialog box template in memory.

int WlxDialogBoxIndirect(
  HANDLE hWlx,
  HANDLE hInst,
  LPCDLGTEMPLATE hDialogTemplate,
  HWND hwndOwner,
  DLGPROC dlgprc
);

Parameters

hWlx
[in] Winlogon handle provided to GINA in the WlxInitialize call.
hInst
[in] Identifies the instance of the module that creates the dialog box.
hDialogTemplate
[in] Specifies the address of a global memory object that contains a dialog box template used to create the dialog box. The template is in the form of a DLGTEMPLATE structure followed by one or more DLGITEMTEMPLATE structures. For a full description of these structures, see the Platform SDK.
hwndOwner
[in] Identifies the window that owns the dialog box.
dlgprc
[in] Points to the dialog box procedure. For more information about the dialog box procedure, see DialogProc.

Return Values

If the WlxDialogBoxIndirect function succeeds, the return value is the nResult parameter given in the call to the EndDialog function used to terminate the dialog box.

If the function fails, the return value is –1.

Remarks

WlxDialogBoxIndirect duplicates the Win32 DialogBoxIndirect macro, and also allows Winlogon to terminate the dialog box. For more information, see DialogBoxIndirect.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

DialogBoxIndirect, DialogProc, DLGTEMPLATE, DLGITEMTEMPLATE, EndDialog , WlxInitialize


WlxDialogBoxIndirectParam

The WlxDialogBoxIndirectParam function is called by GINA to initialize dialog box controls and then create a modal dialog box from a dialog box template in memory.

int WlxDialogBoxIndirectParam(
  HANDLE hWlx,
  HANDLE hInst,
  LPCDLGTEMPLATE hDialogTemplate,
  HWND hwndOwner,
  DLGPROC dlgprc,
  LPARAM dwInitParam
);

Parameters

hWlx
[in] Specifies the Winlogon handle passed to GINA in the WlxInitialize call.
hInst
[in] Specifies the instance of the module that creates the dialog box.
hDialogTemplate
[in] Specifies the address of a global memory object that contains a dialog box template used to create the dialog box. The template is in the form of a DLGTEMPLATE structure followed by one or more DLGITEMTEMPLATE structures. For a full description of these structures, see the Platform SDK.
hwndOwner
[in] Specifies the window that owns the dialog box.
dlgprc
[in] Points to the dialog box procedure. For more information about the dialog box procedure, see the description of the DialogProc callback function in the Platform SDK.
dwInitParam
[in] Specifies the value used to initialize the dialog control. This value is passed to the dialog box in the lParam parameter of the WM_INITDIALOG message.

Return Values

If the WlxDialogBoxIndirectParam function succeeds, the return value is the nResult parameter given in the call to the EndDialog function used to terminate the dialog box.

If the function fails, the return value is –1.

Remarks

WlxDialogBoxIndirectParam duplicates the Win32 DialogBoxIndirectParam function, and also allows Winlogon to terminate the dialog box. For more information, see DialogBoxIndirectParam.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

DialogBoxIndirectParam, DialogProc, DLGTEMPLATE, DLGITEMTEMPLATE, EndDialog, WlxInitialize , WM_INITDIALOG


WlxDialogBoxParam

The WlxDialogBoxParam function is called by GINA to initialize dialog box controls and then create a modal dialog box from a dialog box template resource.

int WlxDialogBoxParam(
  HANDLE hWlx,
  HANDLE hInst,
  LPWSTR lpszTemplate,
  HWND hwndOwner,
  DLGPROC dlgprc,
  LPARAM dwInitParam
);

Parameters

hWlx
[in] Specifies the Winlogon handle passed to GINA in the WlxInitialize call.
hInst
[in] Specifies an instance of the module whose executable file contains the dialog box template.
lpszTemplate
[in] Specifies the dialog box template. This parameter is either the address of a null-terminated character string that specifies the name of the dialog box template, or an integer value that specifies the resource identifier of the dialog box template. If the parameter specifies a resource identifier, its high-order word must be zero and its low-order word must contain the identifier. You can use the MAKEINTRESOURCE macro to create this value.
hwndOwner
[in] Specifies the window that owns the dialog box.
dlgprc
[in] Points to the dialog box procedure. For more information about the dialog box procedure, see DialogProc.
dwInitParam
Specifies the value to pass to the dialog box in the lParam parameter of the WM_INITDIALOG message.

Return Values

If the WlxDialogBoxParam function succeeds, the return value is the value of the nResult parameter given in the call to the EndDialog function used to terminate the dialog box.

If the function fails, the return value is –1.

Remarks

WlxDialogBoxParam duplicates the Win32 DialogBoxParam function, and also allows Winlogon to terminate the dialog box. For more information, see DialogBoxParam.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

DialogBoxParam, EndDialog, DialogProc, MAKEINTRESOURCE, WlxInitialize


WlxDisconnect

The WlxDisconnect function is called by a replacement GINA DLL if Terminal Services is enabled. GINA calls this function to disconnect from a Terminal Services network session.

WlxDisconnect allows GINA to optionally support a disconnect dialog item.

BOOL WlxDisconnect();

Parameters

This function has no parameters.

Return Values

The WlxDisconnect function returns one of the following values.

Value | Meaning
TRUE | Terminal Services session was disconnected.
FALSE | Terminal Services session was not disconnected, or Terminal Services was not enabled.

Remarks

In order to access this function, the GINA DLL must use the WLX_DISPATCH_VERSION_1_3 structure, and set the Winlogon version to at least WLX_VERSION_1_3 in its WlxNegotiate call.

Other Winlogon support functions that may be called when Terminal Services is enabled are WlxWin31Migrate, WlxQueryClientCredentials, and WlxQueryInetConnectorCredentials.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.3.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxWin31Migrate, WLX_DISPATCH_VERSION_1_3, WlxNegotiate, WlxQueryClientCredentials, WlxQueryInetConnectorCredentials


WlxGetSourceDesktop

The WlxGetSourceDesktop function is called by GINA to determine the name and handle of the desktop that was current before Winlogon switched to the Winlogon desktop. GINA can use this function to modify its behavior, depending on the originating desktop.

BOOL WlxGetSourceDesktop(
  HANDLE hWlx,
  PWLX_DESKTOP *ppDesktop
);

Parameters

hWlx
[in] Specifies the Winlogon handle passed to GINA in the WlxInitialize call.
ppDesktop
[out] Receives a pointer to a WLX_DESKTOP structure containing necessary information describing the desktop. This pointer can be freed with LocalFree.

Return Values

The WlxGetSourceDesktop function returns one of the following values.

Value | Meaning
TRUE | The call succeeded.
FALSE | The call failed.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.1.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

LocalFree, WlxInitialize WLX_DESKTOP


WlxGetOption

The WlxGetOption function is called by GINA to retrieve the current value of an option.

BOOL WlxGetOption(
  HANDLE hWlx,
  DWORD Option,
  ULONG_PTR *Value
);

Parameters

hWlx
[in] Specifies the Winlogon handle passed to GINA in the WlxInitialize call.
Option
[in] Specifies one of the following options:

WLX_OPTION_USE_CTRL_ALT_DEL
WLX_OPTION_CONTEXT_POINTER
WLX_OPTION_USE_SMART_CARD
WLX_OPTION_SMART_CARD_PRESENT
WLX_OPTION_SMART_CARD_INFO
WLX_OPTION_DISPATCH_TABLE_SIZE

Value
[out] Returns the current value of the option.

Return Values

The WlxGetOption function returns one of the following values.

Value | Meaning
TRUE | The value of the option was returned in the Value parameter.
FALSE | Winlogon did not return the value.

Remarks

In order to access this function, the GINA DLL must use the WLX_DISPATCH_VERSION_1_3 structure, and set the Winlogon version to at least WLX_VERSION_1_3 in its WlxNegotiate call.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.3.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize, WLX_DISPATCH_VERSION_1_3, WlxNegotiate, WlxSetOption


WlxMessageBox

The WlxMessageBox function is called by GINA to create, display, and operate a message box.

int WlxMessageBox(
  HANDLE hWlx,
  HWND hwndOwner,
  LPWSTR lpszText,
  LPWSTR lpszTitle,
  UINT fuStyle
);

Parameters

hWlx
[in] Specifies the Winlogon handle passed to GINA in the WlxInitialize call.
hwndOwner
[in] Specifies the owner window of the message box to be created. If this parameter is NULL, the message box has no owner window.
lpszText
[in] Points to a null-terminated string containing the message to be displayed.
lpszTitle
[in] Points to a null-terminated string used for the dialog box title. If this parameter is NULL, the default title Error is used.
fuStyle
[in] Specifies the content and behavior of the dialog box. This parameter can be a combination of the following values:
MB_ABORTRETRYIGNORE
The message box contains three push buttons: Abort, Retry, and Ignore.
MB_APPLMODAL
The user must respond to the message box before continuing work in the window identified by the hWnd parameter. However, the user can move to windows of other applications to work.

Depending on the hierarchy of windows in the application, the user may be able to move to other windows within the application. All child windows of the parent of the message box are automatically disabled, but pop-up windows are not.

MB_APPLMODAL is the default value if neither MB_SYSTEMMODAL nor MB_TASKMODAL is specified.

MB_DEFAULT_DESKTOP_ONLY
The desktop currently receiving input must be a default desktop; otherwise, the function fails. A default desktop is one on which an application runs after the user has logged on.
MB_DEFBUTTON1
The first button is the default button. Note that the first button is always the default unless MB_DEFBUTTON2 or MB_DEFBUTTON3 is specified.
MB_DEFBUTTON2
The second button is a default button.
MB_DEFBUTTON3
The third button is a default button.
MB_DEFBUTTON4
The fourth button is a default button.
MB_ICONASTERISK
An icon consisting of a lowercase letter i in a circle appears in the message box.
MB_ICONEXCLAMATION
An exclamation-point icon appears in the message box.
MB_ICONHAND
A stop-sign icon appears in the message box.
MB_ICONINFORMATION
An icon consisting of a lowercase letter i in a circle appears in the message box.
MB_ICONQUESTION
A question-mark icon appears in the message box.
MB_ICONSTOP
A stop-sign icon appears in the message box.
MB_OK
The message box contains one push button: OK.
MB_OKCANCEL
The message box contains two push buttons: OK and Cancel.
MB_RETRYCANCEL
The message box contains two push buttons: Retry and Cancel.
MB_SERVICE_NOTIFICATION
The caller is a service notifying the user of an event. The function brings up a message box on the current active desktop, even if there is no user logged on to the computer.
MB_SETFOREGROUND
The message box becomes the foreground window. Internally, Windows calls the SetForegroundWindow function for the message box.
MB_SYSTEMMODAL
All applications are suspended until the user responds to the message box. Unless the application specifies MB_ICONHAND, the message box does not become modal until after it is created. Consequently, the owner window and other windows continue to receive messages resulting from its activation. Use system-modal message boxes to notify the user of serious, potentially damaging errors that require immediate attention (for example, running out of memory).
MB_TASKMODAL
Same as MB_APPLMODAL except that all the top-level windows belonging to the current task are disabled if the hWnd parameter is NULL. Use this flag when the calling application or library does not have a window handle available, but still needs to prevent input to other windows in the current application without suspending other applications.
MB_YESNO
The message box contains two push buttons: Yes and No.
MB_YESNOCANCEL
The message box contains three push buttons: Yes, No, and Cancel.

Return Values

The WlxMessageBox function returns zero if there is not enough memory to create the message box.

If the function succeeds, the return value is one of the following menu item values returned by the dialog box.

Value | Description
IDABORT | Abort button was selected.
IDCANCEL | Cancel button was selected.
IDIGNORE | Ignore button was selected.
IDNO | No button was selected.
IDOK | OK button was selected.
IDRETRY | Retry button was selected.
IDYES | Yes button was selected.

If a message box has a Cancel button, the function returns the IDCANCEL value if either the ESC key is pressed or the Cancel button is clicked. If the message box has no Cancel button, pressing ESC has no effect.

Remarks

The WlxMessageBox function does not handle SAS events, and is not suitable for security dialogs. Use the WlxDialogBox, WlxDialogBoxIndirect, or WlxDialogBoxIndirectParam function for security dialogs.

WlxMessageBox duplicates the Win32 MessageBox function, with the exception that this function also allows Winlogon to time out the dialog box. For more information, see MessageBox.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

MessageBox, SetForegroundWindow, WlxDialogBox, WlxDialogBoxIndirect, WlxDialogBoxIndirectParam, WlxInitialize


WlxQueryClientCredentials

The WlxQueryClientCredentials function is called by a replacement GINA DLL if Terminal Services is enabled. GINA calls this function to retrieve the credentials of remote Terminal Services clients that are not using an Internet connector license.

The GINA DLL can use this information to fill in a logon box automatically and attempt to log the user in.

BOOL WlxQueryClientCredentials(
  PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred
);

Parameters

pCred
[out] Specifies a pointer to a WLX_CLIENT_CREDENTIALS_INFO_V1_0 structure that contains the credentials of the client on return.

Return Values

The WlxQueryClientCredentials function returns one of the following values.

Value | Meaning
TRUE | The credentials information was retrieved and returned in pCred.
FALSE | The credentials information was not retrieved.

Remarks

The GINA DLL is responsible for calling LocalFree to free the resources used by this structure when the structure is no longer needed.

In order to access this function, the GINA DLL must use the WLX_DISPATCH_VERSION_1_3 structure, and set the Winlogon version to at least WLX_VERSION_1_3 in its WlxNegotiate call.

If the Terminal Services client is using an Internet connector license, the GINA DLL must call WlxQueryInetConnectorCredentials.

Other Winlogon support functions that may be called when Terminal Services is enabled are WlxDisconnect, WlxQueryInetConnectorCredentials, and WlxWin31Migrate.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.3.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxDisconnect, WLX_DISPATCH_VERSION_1_3, WlxNegotiate, WlxQueryInetConnectorCredentials, WlxWin31Migrate


WlxQueryInetConnectorCredentials

The WlxQueryInetConnectorCredentials function is called by a replacement GINA DLL if Terminal Services is enabled. GINA calls this function to determine if Terminal Server is using Internet connector licensing and to retrieve credentials information.

The GINA DLL can then use this information to fill in a logon box automatically and attempt to log the user in.

BOOL WlxQueryInetConnectorCredentials(
  PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred
);

Parameters

pCred
[out] When the return value is TRUE, pCred specifies a pointer to a WLX_CLIENT_CREDENTIALS_INFO_V1_0 structure that contains the credentials to use for auto logon.

Return Values

The WlxQueryInetConnectorCredentials function returns one of the following values.

Value | Meaning
TRUE | Internet connector licensing is enabled.
FALSE | Internet connector licensing is not available.

Remarks

The GINA DLL is responsible for calling LocalFree to free the resources used by this structure when the structure is no longer needed.

In order to access this function, the GINA DLL must use the WLX_DISPATCH_VERSION_1_3 structure, and set the Winlogon version to at least WLX_VERSION_1_3 in its WlxNegotiate call.

If Terminal Services is not using an Internet connector license, the GINA DLL must call WlxQueryClientCredentials.

Other Winlogon support functions that may be called when Terminal Services is enabled are WlxDisconnect, WlxQueryClientCredentials, WlxQueryTerminalServicesData and WlxWin31Migrate.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.3.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxDisconnect, WLX_DISPATCH_VERSION_1_3, WlxNegotiate, WlxQueryClientCredentials, WlxWin31Migrate


WlxQueryTerminalServicesData

The WlxQueryTerminalServicesData function is called by GINA to retrieve Terminal Services user configuration information after a user has logged on.

DWORD
WlxQueryTerminalServicesData(
  HANDLE hWlx,
  PWLX_TERMINAL_SERVICES_DATA pTSData,
  WCHAR *UserName,
  WCHAR *Domain
);

Parameters

hWlx
[in] Specifies the Winlogon handle passed to GINA in the WlxInitialize call.
pTSData
[out] Points to a structure that will contain the Terminal Services – specific user configuration information.
UserName
[in] The name of the newly logged-on user.
Domain
[in] The newly logged-on user's domain.

Return Values

The WlxQueryTerminalServicesData function returns zero (0) if the user-configuration information was retrieved successfully. Otherwise, it returns an error code.

Remarks

WlxQueryTerminalServicesData should be called from within GINA's implementation of WlxLoggedOutSAS after a user has been authenticated.

In order to access this function, the GINA DLL must use the WLX_DISPATCH_VERSION_1_3 structure, and set the Winlogon version to at least WLX_VERSION_1_3 in its WlxNegotiate call.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.3.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxDisconnect, WLX_DISPATCH_VERSION_1_3, WlxLoggedOutSAS, WlxNegotiate, WlxQueryClientCredentials, WlxWin31Migrate


WlxSasNotify

The WlxSasNotify function is called by GINA to notify Winlogon of a secure attention sequence (SAS) event.

VOID WlxSasNotify(
  HANDLE hWlx,
  DWORD dwSasType
);

Parameters

hWlx
[in] Specifies the Winlogon handle passed to GINA in the WlxInitialize call.
dwSasType
[in] Specifies the type of SAS that occurred.

Values from zero to WLX_SAS_TYPE_MAX_MSFT_VALUE are reserved to define standard Microsoft SAS types. GINA developers can use values greater than WLX_SAS_TYPE_MAX_MSFT_VALUE to define additional SAS types.

The following values are predefined.
Value | Description
WLX_SAS_TYPE_CTRL_ALT_DEL | Indicates that the user has typed the CTRL+ALT+DEL SAS.

This value will be delivered to one of the GINA SAS service routines called by Winlogon (WlxLoggedOutSAS, WlxLoggedOnSAS, or WlxWkstaLockedSAS).

Return Values

The WlxSasNotify function has no return values.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize, WlxLoggedOnSAS, WlxLoggedOutSAS, WlxWkstaLockedSAS


WlxSetContextPointer

The WlxSetContextPointer function is called by GINA to specify the context pointer passed by Winlogon as the first parameter to all future calls to GINA functions. This allows GINA to specify a new context pointer that replaces the one returned by the WlxInitialize function.

This function has been superceded by the WlxSetOption function called with the Option parameter set to WLX_OPTION_CONTEXT_POINTER.

VOID WlxSetContextPointer(
  HANDLE hWlx,
  PVOID pWlxContext
);

Parameters

hWlx
[in] Specifies the Winlogon handle passed to GINA in the WlxInitialize call.
pWlxContext
[in] Pointer to the new context that Winlogon will use in future calls to GINA.

Return Values

The WlxSetContextPointer function has no return values.

Remarks

If the GINA must call WlxSasNotify from the WlxInitialize function, it should first call WlxSetContextPointer to let Winlogon associate a context with the GINA.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize, WlxSasNotify, WlxSetOption


WlxSetOption

The WlxSetOption function is called by GINA to set the value of an option.

BOOL WlxSetOption(
  HANDLE hWlx,
  DWORD Option,
  ULONG_PTR Value,
  ULONG_PTR *OldValue
);

Parameters

hWlx
[in] Specifies the Winlogon handle passed to GINA in the WlxInitialize call.
Option
[in] Specifies one of the following options:

WLX_OPTION_USE_CTRL_ALT_DEL
WLX_OPTION_CONTEXT_POINTER
WLX_OPTION_USE_SMART_CARD

Value
[in] Specifies a new value for the option.
OldValue
[Out] On return, pointer to the old value the option was set to.

Return Values

The WlxSetOption function returns one of the following values.

Value | Meaning
TRUE | The option was set to the value specified in the Value parameter.
FALSE | Winlogon did not set Option to Value.

Remarks

In order to access this function, the GINA DLL must use the WLX_DISPATCH_VERSION_1_3 structure and set the Winlogon version to at least WLX_VERSION_1_3 in its WlxNegotiate call.

Use WlxGetOption to retrieve the current value of an option.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.3.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxGetOption, WLX_DISPATCH_VERSION_1_3, WlxInitialize, WlxNegotiate


WlxSetReturnDesktop

The WlxSetReturnDesktop function is called by GINA to specify the alternate application desktop that Winlogon will switch to when the current SAS event processing function is complete.

Bool WlxSetReturnDesktop(
  HANDLE hWlx,
  PWLX_DESKTOP pDesktop
);

Parameters

hWlx
[in] Specifies the Winlogon handle passed to GINA in the WlxInitialize call.
pDesktop
[in] Pointer to desktop information about the alternate desktop. This desktop is created by calling the WlxCreateUserDesktop function.

Return Values

The WlxSetReturnDesktop function returns one of the following values.

Value | Meaning
TRUE | The function call was successful.
FALSE | The function call failed to set the return desktop.

Remarks

WlxSetReturnDesktop can be called only within WlxLoggedOnSAS or WlxWkstaLockedSAS routines. Attempts to call this function at other times will fail.

If a handle to the desktop is provided, Winlogon will duplicate the handle. If no handle is provided, Winlogon will attempt to open the desktop named in the pDesktop parameter. If the provided desktop is not valid, or is the Winlogon or screen-saver desktop, the call will fail.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.1.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxCreateUserDesktop, WlxInitialize, WlxLoggedOnSAS, WlxWkstaLockedSAS


WlxSetTimeout

The WlxSetTimeout function is called by GINA to change the time-out associated with a dialog box. The default time-out is two minutes.

BOOL WlxSetTimeout(
  HANDLE hWlx,
  DWORD Timeout
);

Parameters

hWlx
[in] Specifies the Winlogon handle passed to GINA in the WlxInitialize call.
Timeout
[in] Requested time-out, in seconds.

Return Values

The WlxSetTimeout function returns one of the following values.

Value | Meaning
TRUE | If the new time-out was accepted.
FALSE | If the new time-out was not accepted.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize


WlxSwitchDesktopToUser

The WlxSwitchDesktopToUser function is called by GINA to switch to the application desktop. This function is valid only for the currently operating thread.

int WlxSwitchDesktopToUser(
  HANDLE hWlx
);

Parameters

hWlx
[in] Specifies the Winlogon handle passed to GINA in the WlxInitialize call.

Return Values

The WlxSwitchDesktopToUser function returns 0 if the function call succeeds. Otherwise, it returns an error code.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize


WlxSwitchDesktopToWinlogon

The WlxSwitchDesktopToWinlogon function lets the GINA DLL switch to the Winlogon desktop. This function is valid only for the currently operating thread.

int WlxSwitchDesktopToWinlogon(
  HANDLE hWlx
);

Parameters

hWlx
[in] Specifies the Winlogon handle passed to GINA in the WlxInitialize call.

Return Values

The WlxSwitchDesktopToWinlogon function returns 0 if the function call succeeds. Otherwise, it returns an error code.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize


WlxWin31Migrate

The WlxWin31Migrate function is called by a replacement GINA DLL if Terminal Services is enabled. GINA calls this function to complete the setup of the Terminal Services client.

VOID Wlx31Migrate(
  HANDLE hWlx
);

Parameters

hWlx
[in] Specify the handle received in the call to WlxInitialize.

Return Values

The WlxWin31Migrate function has no return values.

Remarks

GINA needs to call this function before starting the shell, so that the migration and setup will be complete before the shell starts, but after it has processed any logon scripts.

In order to use this function, the GINA DLL must specify the WLX_DISPATCH_VERSION_1_3 structure in its call WlxInitialize, and set the Winlogon version to at least WLX_VERSION_1_3 in its WlxNegotiate call.

Other Winlogon support functions that may be called when Terminal Services is enabled are WlxDisconnect, WlxQueryClientCredentials, and WlxQueryInetConnectorCredentials.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.3.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxDisconnect, WLX_DISPATCH_VERSION_1_3, WlxNegotiate, WlxQueryClientCredentials, WlxQueryInetConnectorCredentials


WlxUseCtrlAltDel

The WlxUseCtrlAltDel function is called by GINA to tell Winlogon to use the standard CTRL+ALT+DEL key combination as a secure attention sequence (SAS).

This function has been superceded by the WlxSetOption function called with Option parameter set to WLX_OPTION_USE_CTRL_ALT_DEL.

VOID WlxUseCtrlAltDel(
  HANDLE hWlx
);

Parameters

hWlx
(IN parameter) Winlogon handle provided to GINA in the WlxInitialize call.

Remarks

If GINA uses this function, it is not required to use the WlxSasNotify function. However, if GINA is monitoring for other SASes in addition to CTRL+ALT+DEL, it must use WlxSasNotify to deliver the additional SAS event notifications.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Version: Requires GINA version 1.0.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.

See Also

WlxInitialize, WlxSasNotify, WlxSetOption


Winlogon Notification Packages

Winlogon notification packages are DLLs that receive and handle events generated by Winlogon. You can implement such a notification package to monitor and respond to Winlogon events. This is useful for applications that need to perform additional processing during logon or logoff, or maintain state information that must be updated when Winlogon events occur.

Winlogon notification packages require Microsoft® Windows® 2000.

For more information about Winlogon and GINAs, see Winlogon and GINA.


Creating a Winlogon Notification Package

A Winlogon notification package is a DLL which exports functions that handle Winlogon events. For example, when a user logs onto the system, Winlogon calls each notification package's logon event handler function to provide information about the event.

The names of the event handler functions implemented in a notification package are left up to the developer; Winlogon checks the registry to obtain the names of the event handler functions. For example, one notification package might implement the logon event handler function as "WLEventLogon" whereas another might use "HandleLogonEvent".

You do not have to implement and register event handlers for every Winlogon event, only for events that are useful to your application. Each event handler function must use the function prototype described in Event Handler Function Prototype. This prototype has a single parameter, a WLX_NOTIFICATION_INFO structure which contains details about the event.

Winlogon ignores the output of event handler functions. If handling an event requires interacting with Winlogon, use the Winlogon Support Functions.


Registering a Winlogon Notification Package

Information about Winlogon notification packages is stored in the registry. Registry entries specify the name of the notification package, the name of the DLL that implements the package, and the names of the functions that handle Winlogon events.

When Winlogon starts, it checks the registry and loads any registered notification packages. When an event occurs, Winlogon calls the designated event handler function for each package. Multiple event notification packages may be registered on a system.

To register your notification package, create a registry key named Notify as a subkey of HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon, and add the values detailed in Registry Entries.


Winlogon Notification Events

Winlogon can inform your notification package of the following events:

Lock
This event occurs when the user locks the workstation.
Logoff
This event occurs when a user logs off from the system. The Logoff event is performed synchronously, even if the notification package's registry settings indicate that it can handle events asynchronously.
Logon
This event occurs when a user logs on the system. The Logon event handler is executed synchronously, even if the notification package's registry settings indicate that it can handle events asynchronously.

Note that the Logon event occurs before the user's network connections are restored. If your event handler requires access to the user's network connections, it should handle the StartShell event instead of the Logon event.

Shutdown
This event occurs just before the system shuts down.
StartScreenSaver
This event occurs when the screen saver has started. Typically, this happens after a user has been inactive for a set period of time.

Functions handling this event should not display a user interface. StartScreenSaver event notification is intended for informational purposes only.

StartShell
This event occurs after the user has logged onto the system, network connections have been established, and the user specified shell program, (usually Explorer.exe), has been started.
Startup
This event occurs when the system is started up or rebooted.
StopScreenSaver
This event occurs when the screen saver has stopped. Typically this happens when there is keyboard or mouse activity.

Functions handling this event should not display a user interface. StopScreenSaver event notification is intended for informational purposes only.

Unlock
This event occurs when the user unlocks the workstation or when a system administrator overrides the lock and logs the user off.


Winlogon Notification Package Reference

The following topics provide reference information for Winlogon notification packages:

  • Registry Entries lists the key values and settings that must be entered in the system registry in order to register a notification package and its event handler functions.
  • Event Handler Function Prototype details the prototype for event handler functions. Each event handler function in your notification package must match this prototype.


Registry Entries

In order for your package to receive event notifications from Winlogon, you must provide the name of the package, the names of the event handler functions in the package, the DLL responsible for implementing the package, and information about whether the DLL supports asynchronous events and impersonation.

You should create the notification package registry key as a subkey of HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify. The name of the key is usually the same as the name of the DLL; however, this is not mandatory. The name chosen for your package must not conflict with the names of other installed notification packages.

In the Notify registry key, create the following registry values if there is a relevant event handler function in your package.

Value Name [Data Type] | Description
Asynchronous [REG_DWORD] | Indicates whether the package can handle events asynchronously. If this value is set to 1, Winlogon calls the package functions in a separate thread. Otherwise, it does not.
DllName [REG_EXPAND_SZ] | Name of the DLL that implements the notification package, for example: "Notify.dll".
Impersonate [REG_DWORD] | Indicates whether Winlogon should impersonate the security context of the logged-on user when it calls the notification package functions. If this value is set to 1, Winlogon uses impersonation. Otherwise, it does not.
Lock [REG_SZ] | Name of the function which handles desktop lock events, for example: "WLEventLock".
Logoff [REG_SZ] | Name of the function which handles logoff events, for example: "WLEventLogoff".
Logon [REG_SZ] | Name of the function which handles logon events, for example: "WLEventLogon".
Shutdown [REG_SZ] | Name of the function which handles shutdown events, for example: "WLEventShutdown".
StartScreenSaver [REG_SZ] | Name of the function which handles screen saver start events, for example: "WLEventStartScreenSaver".
StartShell [REG_SZ] | Name of the function which handles shell start events, for example: "WLEventStartShell". A shell start event occurs after the user has logged on but before the desktop appears. It differs from the logon event in that the user's security context has been established, and resources such as network connections are available.
Startup [REG_SZ] | Name of the function which handles system startup events, for example: "WLEventStartup".
StopScreenSaver [REG_SZ] | Name of the function which handles screen saver stop events, for example: "WLEventStopScreenSaver".
Unlock [REG_SZ] | Name of the function which handles desktop unlock events, for example: "WLEventUnlock".


Event Handler Function Prototype

The following prototype is used for all functions that handle Winlogon notification events. The name of the function, represented below by the place holder, FunctionName, typically reflects the name of the event that the function handles. For example, the function that handles logon events might be named: WLEventLogon.

VOID <FunctionName> (
  PWLX_NOTIFICATION_INFO pInfo
);

Parameters

pInfo
Pointer to a WLX_NOTIFICATION_INFO structure which contains the details of the event.

Return Values

None.

Remarks

If your event handler needs to create child processes, it should call the CreateProcessAsUser function. Otherwise the new process will be created on the Winlogon desktop, not the user's desktop.

Example Code

The following example illustrates how to implement event handlers for Winlogon events. For simplicity, only the implementations of the Logon and Logoff event handlers are shown. You can implement handlers for the rest of the events in exactly the same manner.

//Entrance function for the DLL
BOOL WINAPI LibMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
    switch (dwReason)
    {
        case DLL_PROCESS_ATTACH:
            {
             //Disable DLL_THREAD_ATTACH & DLL_THREAD_DETACH
             //notification calls. This is a performance optimization
             //for multi-threaded applications that do not need
             //thread-level notifications of attachment or detachment.

            DisableThreadLibraryCalls (hInstance);
            }
            break;
    }

    return TRUE;
}

//Event handler for the Winlogon Logon event
VOID WLEventLogon (PWLX_NOTIFICATION_INFO pInfo)
{
    //Print the name of the handler to debug output.
    //You can replace this with more useful functionality.
    OutputDebugString (TEXT("NOTIFY:  Entering WLEventLogon.\r\n"));
}

//Event handler for the Winlogon Logoff event.
VOID WLEventLogoff (PWLX_NOTIFICATION_INFO pInfo)
{
    //Print the name of the handler to debug output.
    //You can replace this with more useful functionality.
    OutputDebugString (TEXT("NOTIFY:  Entering WLEventLogff.\r\n"));
}


WLX_NOTIFICATION_INFO

This structure stores information about a Winlogon event.

typedef struct _WLX_NOTIFICATION_INFO {
  ULONG Size;
  ULONG Flags;
  PWSTR UserName;
  PWSTR Domain;
  PWSTR WindowStation;
  HANDLE hToken;
  HDESK hDesktop;
  PFNMSGECALLBACK pStatusCallback;
} WLX_NOTIFICATION_INFO, *PWLX_NOTIFICATION_INFO;

Members

Size
Indicates the size of the structure, in bytes. Your application can check this value against the structure size to validate the structure.
Flags
Reserved for internal use.
UserName
String that specifies the name of the user currently logged on to the system. If the event occurs before a user logs on, this value is NULL.
Domain
String that specifies the name of the domain the user is currently logged on to. If the event occurs before a user logs on, this value is NULL.
WindowStation
Specifies the name of the window station the user is currently logged on to. If the event occurs before a user logs on, this value is NULL. Note that most configurations use a single, default window station. Some applications, such as Terminal Services, use multiple windows stations.
hToken
Handle to the user's token. This value is NULL if the event occurs before a user logs on.
hDesktop
Handle to the desktop that is currently active.
pStatusCallback
Reserved for internal use.

Requirements

Windows NT/2000: Requires Windows 2000.
Windows 95/98: Unsupported.
Header: Declared in Winwlx.h.
Unicode: Declared only as Unicode.


Network Provider API

Purpose

The Network Provider API provides an interface between the Multiple Provider Router (MPR) and any network provider, including credential manager providers, whose network is active.

When the system makes a logon call, the Microsoft® Windows® 2000 operating system routes the call to an MPR, which in turn calls a Network Provider function implemented by each network provider. Network Provider functions can only be called by an MPR.

About Network Provider API

The type of functions specified in the Network Provider API

Using the Network Provider API

Tasks in creating a network provider

Network Provider API Reference

Network Provider API functions

Feedback

Make error reports and feature requests directly to Microsoft.


About Network Provider API

A network provider is a DLL that enables the Microsoft® Windows® NT/2000 operating system to interact with other types of networks, such as Novell. It is a client of the Win32 WNet driver. A network provider implements network-specific actions, such as making a connection, and exposes a common interface to the Windows operating system. This interface is called the Network Provider API and consists of functions implemented by the network provider. You can create a network provider DLL to support new network protocols.

Because each network exposes a common interface through its provider, the Windows operating system can interact with several types of networks without knowing their network-specific implementation details.

The Multiple Provider Router (MPR) is a component of the Windows NT/Windows 2000 operating system that handles communication with all of the various network providers on the system and presents an integrated network to the user.


Network Providers

A network provider is a DLL that supports a specific network protocol. It also implements the Network Provider API. This enables it to interact with the Windows operating system to receive standard network requests, such as connection or disconnection requests. To handle these requests, the network provider then calls the network-specific API appropriate to the network protocol the network provider supports. In other words, the network provider wraps the network-specific functionality in a DLL which exposes a standard interface to the Windows operating system.

Using network providers, the Windows operating system can support many different types of network protocols without having to know the network-specific details of each network. This is essential, since new network protocols are being developed all the time. With network providers, supporting a new protocol simply requires creating and installing a new network provider.

For details about the common interface that network providers expose, see Network Provider API Reference.


Credential Managers

A credential manager is similar to a network provider in that it provides entry points that are called by the MPR. In fact, some network providers are also credential managers. Whether you implement the credential management functions in the same DLL as the network provider functions depends on the requirements of your application.

Credential managers receive notifications when authentication information changes. For example, credential managers are notified when a user logs on or an account password changes.

When a logon process, such as Winlogon, is in the process of logging on or changing the password for an account, it calls the appropriate MPR Windows Networking (WNet) function. The MPR then calls the appropriate entry point for each credential manager. These credential management functions will always be called in the system context, LocalSystem, rather than the user context.

For more information about the WNet functions, see Windows Networking (WNet).

For more information about the interface that credential managers must implement, see Credential Management Functions.


Multiple Provider Router

The Multiple Provider Router (MPR) is a component of the Windows NT/Windows 2000 operating system which handles communication between the Windows operating system and the installed network providers. It enables the Windows operating system to present an integrated network to the user.

When the MPR starts, it checks the registry to determine which network providers are installed on the system and the order they should be cycled through. It loads all registered network provider DLLs, and uses them to process subsequent WNet calls made by the user interface or other applications.

For more information about the WNet functions, see Windows Networking (WNet).


Functions Implemented by Network Providers

The following sections describe the functions implemented by a network provider DLL in order to communicate with the MPR. Note that only the Capabilities functions must be implemented by a network provider. Implementation of the other types of functions is optional and depends on the requirements of the network provider.

Function set | Description
Capabilities functions | Allows the caller to determine the capabilities of the network provider.
User Name functions | Prompts the network provider for the user name associated with a connection.
Device Redirecting functions | Allows a network provider to redirect standard MS-DOS® devices, drive letters, and LPT ports.
Provider-Specific Dialog functions | Allows a network provider to display or act on network-specific information.
Administrative functions | Allows a network provider to display or act on special network directories.
Enumeration functions | Allows the user to browse network resources.

For more information about how to create and register a network provider, see Implementing a Network Provider and Registering Network Providers and Credential Managers.


Capabilities Functions

The Network Provider API specifies a single capabilities function. When the operating system requests information about a network provider's capabilities, the Multiple Provider Router (MPR) calls the NPGetCaps function of each network provider whose network is active.

The NPGetCaps function returns a bit mask indicating which of the Network Provider API functions the network provider supports. The NPGetCaps function is the only function that a network provider must implement. The operating system calls this function to determine which of the other Network Provider API functions the provider supports.


User Name Functions

User name functions include a single function, NPGetUser. This function retrieves either the current default username or the username used to establish the network connection.


Device-Redirecting Functions

The device-redirecting functions redirect standard MS-DOS devices, drive letters and LPT ports. This enables applications running on the system to use the devices and access the network in a totally transparent manner.

Function | Description
NPAddConnection | Redirects or connects a local device to a network resource.
NPAddConnection3 | Performs the same action as NPAddConnection, but lets the user specify which window should own any dialogs and how the connection should be established.
NPCancelConnection | Breaks a network connection. The changes are remembered if a device is disconnected unless the connection is a deviceless connection.
NPGetConnection | Returns information about a connection.
NPGetConnection3 | Returns information about a connection, even if the connection is currently disconnected.
NPGetConnectionPerformance | Returns performance information about a connection.
NPGetUniversalName | Returns the remote or local universal name, in the format specified during the function call.


Provider-Specific Dialog Functions

The provider-specific dialog functions enable a provider to display and handle network-specific information by altering system dialog boxes or displaying custom dialog boxes.

The first set of dialog functions adds buttons to File Manager's Properties dialog box. The provider can then handle the events of those buttons to perform network-specific tasks. Note that there is a limit to the number of buttons that can be added. Because of this, providers should use this capability sparingly. Also, a provider may find itself unable to add a button because the available space has been used already by other providers. A network provider should handle this situation.

Function | Description
NPGetPropertyText | Determines the names of buttons added to a property dialog for a specific resource.
NPPropertyDialog | Called when a user clicks on a button added through the NPGetPropertyText function.
NPSearchDialog | Enables network providers to implement their own searching functionality beyond that provided in the Connection dialog box.
NPFormatNetworkName | Enables network providers to format or otherwise modify network names before they are presented to the user.

The second set of dialog functions are only supported by the File Manager component of Windows NT 3.51 and earlier. These functions enable providers to display their own permission dialog boxes in File Manager when the current drive selection belongs to them. These functions are called by File Manager and depend on the File Manager Extensions. There are no equivalent functions for the Windows Explorer component of Windows NT 4.0 and later.

Function | Description
NPFMXGetPermCaps | Gets the capabilities bits of the permission editor. The return value determines which Security menu items in File Manager should be enabled.
NPFMXEditPerm | Enables network vendors to supply their own permission editor dialog boxes.
NPFMXGetPermHelp | Gets the help file and context of the permission editor dialogs when a menu item in the Security menu of File Manager is selected and F1 is pressed.


Administrative Functions

The following administrative functions enables a network provider to take network-specific action to display and manipulate network-specific directories, in other words, directories mapped to non-Windows protocols.

Function | Description
NPGetDirectoryType | Called by File Manager to determine the type of a network directory.
NPDirectoryNotify | Called by File Manager to notify the network provider of directory operations. This function can be used to perform special behavior for certain directories.


Enumeration Functions

If your network provider needs to support browsing of its network resources, it should implement the following functions. MPR calls these functions to enumeration the resources.

A network provider is not required to implement any of the enumeration functions. If, however, a network provider implements one of NPOpenEnum, NPEnumResource, or NPCloseEnum, it must also implement the other two enumeration functions.

Function | Description
NPOpenEnum | Opens an enumeration of network resources or existing connections.
NPEnumResource | Performs an enumeration on a handle returned by NPOpenEnum.
NPCloseEnum | Closes an enumeration.
NPGetResourceInformation | Determines whether the provider is the correct provider to respond to a request for a specified network resource and returns information about the resource's type.
NPGetResourceParent | Returns the parent of a specified network resource in the browse hierarchy.


Credential Management API

The credential management functions constitute the set of functions that a credential manager must implement. These are

  • NPLogonNotify, an event-handler function that the MPR calls when a user logs on.
  • NPPasswordChangeNotify, an event-handler function the MPR calls when an account password is changed.

The credential management functions are always called in the system context (LocalSystem) rather than the user context.

For more information about how to create and register a credential manager application, see Implementing a Credential Manager and Registering Network Providers and Credential Managers.


Connection Notification API

The connection notification functions are a set of two functions that the Multiple Provider Router (MPR) calls when it connects or disconnects a network resource. You can implement these functions in a DLL in order to receive such notifications.

The first of the network connection functions is AddConnectNotify which is called before and after each add-connection operation (WNetAddConnection, WNetAddConnection2, or WNetAddConnection3) is attempted by the Multiple Provider Router. This function is not called when MPR is automatically restoring network connections.

The second function, CancelConnectNotify, is called before and after each cancel-connection operation (WNetCancelConnection or WNetCancelConnection2) is attempted by the Multiple Provider Router.

For more information about the WNet functions, see Windows Networking (WNet)..

For more information about how to create and register an application that receives network connection notifications, see Receiving Connection Notifications and Registering to Receive Connection Notifications.


Using the Network Provider API

The following topics describe tasks you need to perform in order to create a network provider and related applications:

  • Implementing a Network Provider
  • Implementing a Credential Manager
  • Registering Network Providers and Credential Managers
  • Returning Values to the MPR
  • Handling Buffered Data
  • Returning Values to the MPR
  • Receiving Connection Notifications
  • Registering to Receive Connection Notifications
  • Overriding the Default MPR Time-out Interval


Implementing a Network Provider

A network provider is a DLL that enables the Windows operating system to support a specific network protocol. It does this by implementing the Network Provider API. This API is a set of functions the Multiple Provider Router (MPR) calls in order to communicate with the network. The network provider then translates these calls into network-specific API calls in order to perform the action specified by the MPR. In this way, the Windows operating system can interact with new network protocols without having to understand their network-specific APIs.

In order to create a network provider, you write a DLL which exports the NPGetCaps function.

Support of the other Network Provider API functions is optional. If your network provider does not require a function, your DLL does not need to implement it or provide a stub implementation. For more information, see see the the individual function topics in Network Provider API Reference.

The exception is that if you support one of the following enumeration functions, you must support the other two functions as well: NPOpenEnum, NPEnumResource, and NPCloseEnum.

The following guidelines describe how to write a network provider that interacts well with the MPR and Windows operating system. Whenever possible your provider should adhere to the following guidelines for speed, validation, and routing.

Speed

A network provider should quickly determine whether a network resource is its own. This is because the MPR may have to cycle through many providers to find the owner of a resource.

If the network provider does not own the resource, it should immediately return the WN_BAD_NETNAME status code.

It is also important that providers that support NPGetDirectoryType return results for this function quickly since it is called while WinFile is painting the directory tree.

Validation

The order of validation is important. A network provider should first check whether its network is started and then check whether the network and network provider support the operation. If, after these checks, the network provider receives any network resources, it should check whether it owns them. Finally, it should validate other parameters.

Routing

If the MPR has to cycle through network providers, it will try all providers until one accepts the call. This is different from Microsoft® Windows NT® 3.1, where MPR continued its search only when each provider that rejected the call returned specific error codes. In other words, the MPR now always continues to try to find a network provider.

It does, however, take note of the first significant error reported by a provider. Errors such as ERROR_BAD_NETPATH, ERROR_BAD_NET_NAME, ERROR_INVALID_PARAMETER, ERROR_INVALID_LEVEL are considered insignificant, because they simply mean that the provider doesn't manage the resource. However, if the provider fails with the error ERROR_INVALID_PASSWORD or some other significant error, MPR records this error and continues cycling through the network providers. In general, when routing, if no provider accepts the call, the MPR reports the first significant error it encounters while cycling through the network providers.

Your network provider should take this behavior of the MPR into account when deciding what error message to return.


Implementing a Credential Manager

To create a credential manager, you must create a DLL which exports the following functions:

  • NPLogonNotify
  • NPPasswordChangeNotify

In addition, credential managers should also support the NPGetCaps function for WNNC_START (supporting other indexes is not required for credential managers). This tells MPR when a credential manager will start. By calling NPGetCaps with the nIndex parameter set to WNNC_START, the MPR can find out whether it needs to wait before calling the provider's credential management entry point functions. And if the MPR knows this, it can, in turn, tell the credential manager how long to wait before timing out.


Registering Network Providers and Credential Managers

After you have created your network provider or credential manager, you must register it with the system. This is necessary so the MPR will know what network providers are installed. When the MPR starts, it checks the registry and loads any network providers or credential managers it finds.

Because network providers and credential managers are related, they are registered in the same subkeys of the registry. In fact, network provider DLLs can also be credential managers.

For detailed information about the registry keys you should create for your network provider or credential manager, see Registry Keys.


Returning Values to the MPR

The Windows Networking functions return WN_SUCCESS on success, or they return a unique non-zero value if the function encounters an error. In addition, they return extended error information using WNetSetLastError and SetLastError.

To support the above behavior, network provider functions should not call SetLastError before returning. This is because the MPR calls SetLastError for the Network Provider API functions after they return. If the network providers call SetLastError directly, they will be making redundant function calls. Network provider functions should simply return an error code. These The error codes are specified in the function description or Return Values. Also, network provider functions may return any Win32 error code, such as insufficient memory. The only exception is NPGetCaps, which should return a mask indicating the functions supported by the network provider.

If a network provider function needs to return extended error information, it should call WNetSetLastError. This function is provided by the Windows operating system for use by network providers. When the provider calls WNetSetLastError, it can set a string containing additional information about the error. This information is stored on a per-thread basis. This is analogous to SetLastError for Win32 applications. The Windows operating system calls WNetGetLastError to checks for a string stored using WNetSetLastError and, if found, returns the extended error information to the calling application that initiated the network request.

Note The WNet prefix of WNetSetLastError is misleading since this API, unlike WNetGetLastError, is not part of the Win32 Networking API set. WNetSetLastError is intended for use only by network providers. The name, WNetSetLastError, is retained for compatibility with existing providers.


Handling Buffered Data

Several of the network provider functions take the address and size of a buffer into which the function places a variable-sized data structure.

In each case, the mechanism used is the same. The caller allocates a buffer and passes its address to the function. It also passes the address of a DWORD that specifies the size of the buffer, in bytes.

The function then copies as much of the requested data structure as it can into the buffer. If all of the data fits into the buffer, the function returns WN_SUCCESS. If the data does not fit into the buffer, the data may be left incomplete, and the function sets the WN_MORE_DATA error. In either case, the DWORD indicating the size of the buffer is set to the number of bytes actually required by the data structure. This way, if the buffer passed in was too small and the function failed, the caller may allocate a new buffer of the required size and call the function again.

When the data structures returned include variable-length strings, the individual data structures typically contain pointers to these strings. The strings themselves should also be placed within the buffer. However, it is important to place them at the end of the buffer. Otherwise, they will make indexing to the Nth structure impossible. In other words, all structures are located contiguously at the beginning of the buffer. Pointers to strings or variable length data must be actual pointers, not offsets into the buffer.

When a buffer is used to pass in and return data that consists only of strings, the DWORD specifying the size of the buffer should be set to the total number of characters that will fit in these strings, not to the number of bytes.


Receiving Connection Notifications

Some applications need to receive notification of connection events, either before the event, just after it occurs, or both. You can create a DLL to receive advance and after-the-fact notification of connection events.

An example of an application that needs to receive advance notification of a connection event is the Remote Access Service (RAS). RAS needs to be informed before a connection is made because it may be necessary to establish a modem connection before making the network connection.

Similarly, application components may need to clean up resources after the connection is made, therefore requiring a post-connection notification.

Applications interested in receiving advance and after-the-fact notification of connection events must supply a DLL that exports two functions, AddConnectNotify and CancelConnectNotify.

After you implement these functions, you must register your DLL as described in Registering to Receive Connection Notifications.


Registering to Receive Connection Notifications

After you have created a DLL to receive connection notifications, you must register it with the system. You do this by adding a REG_EXPAND_SZ value under the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\NetworkProvider\Notifyees key. This value specifies the path to the DLL that implements the Connection Notification API.

The value can have any name. All values under the Notifyees key are treated as paths to DLLs that are notified of connection events. It is recommended that you use a name that identifies your component. This lessens the chance of a name conflict with other connection notification applications.

For more information about how to create an application that receives connection notifications, see Receiving Connection Notifications.


Overriding the Default MPR Time-out Interval

The Multiple Provider Router (MPR) calls NPGetCaps to find out when the network providers will start (nIndex is set to WNNC_START). The MPR then waits for the longest time-out period specified by all network providers before it presents the consolidated network to the user. If one of the network providers does not know when it will start, MPR uses a default time-out of 60 seconds for that provider.

If necessary, the administrator can override the default time-out by creating the following registry time-out, where n is the time-out interval in milliseconds:

HKEY_LOCAL_MACHINE
SYSTEM
CurrentControlSet
Control
NetworkProvider
RestoreTimeout = REG_DWORD n

The complete logic flow for time-out handling by the MPR is shown in the following pseudocode.

To define MaxTimeout…
If there is a RegistryTimeout,
Then MaxTimeout = RegistryTimeout.
Otherwise,
MaxTimeout = 0.
For each provider…
If the provider doesn't supply a timeout,
If there is a RegistryTimeout,
ProviderTimeout is set to RegistryTimeout.
Otherwise,
ProviderTimeout is set to DefaultTimeout.
Otherwise,
If the ProviderTimeout is longer than MaxTimeout,
MaxTimeout = ProviderTimeout.


Network Provider API Reference

This section provides reference information for the functions implemented or used by network providers. It also details the structures and data types used by those functions.

Topic | Content
Network Provider Functions | Functions implemented by network providers.
File Manager Functions | Functions implemented by network providers and called by File Manager. Only network providers that support Windows NT 3.51 and earlier versions need to implement these functions. Later versions of Windows NT/2000 do not call these functions.
Support Functions | Support functions available to network providers.
Credential Management Functions | Functions implemented by credential managers.
Connection Notification Functions | Functions that can be implemented by an application in order to receive notifications when network resources are connected or disconnected.
Network Provider Structures | Structures used with network provider functions.
Return Values | Values returned by network provider functions.
Registry Keys | Registry keys and values that should be created when a network provider or credential manager is installed.

Note Although string parameters of functions are documented as having the LPTSTR or LPCTSTR data type, network providers must implement them as the LPWSTR or LPCWSTR data type for Windows NT/Windows 2000.


Network Provider Functions

The following functions can be implemented by network providers. The only function that network providers are required to support is NPGetCaps.

Function | Description
NPAddConnection | Connects a local device to a network resource.
NPAddConnection3 | Connects a local device to a network resource and lets you specify the type of connection and the window that will own any messages or dialog boxes.
NPCancelConnection | Disconnects a network connection.
NPCloseEnum | Closes an enumeration.
NPDeviceMode | Sets the parent window of a device. This window owns any dialog boxes originating from the device.
NPDirectoryNotify | Notifies the network provider of certain directory operations.
NPEnumResource | Enumerates network resources or existing connections.
NPFormatNetworkName | Formats the network name in a provider-specific format.
NPGetCaps | Queries a provider for supported capabilities. Returns the capabilities supported by the provider.
NPGetConnection | Retrieves information about a network connection.
NPGetConnection3 | Retrieves information about a network connection, even if it is currently disconnected.
NPGetConnectionPerformance | Retrieves performance information about a network connection.
NPGetDirectoryType | Retrieves a value indicating whether a special icon should be displayed for a directory.
NPGetPropertyText | Adds buttons to a property dialog box for a network resource.
NPGetResourceInformation | Retrieves information about a network resource.
NPGetResourceParent | Retrieves the parent of the specified network resource.
NPGetUniversalName | Retrieves the universal name.
NPGetUser | Retrieves the username of the current user.
NPOpenEnum | Opens an enumeration of network resources or existing connections.
NPPropertyDialog | Handles the event that occurs when a user clicks on a button added with NPGetPropertyText.
NPSearchDialog | Performs a network-specific search.


NPAddConnection

The NPAddConnection function connects a local device to a network resource.

DWORD NPAddConnection(
  LPNETRESOURCE lpNetResource,
  LPTSTR lpPassword,
  LPTSTR lpUserName
);

Parameters

lpNetResource
Pointer to a NETRESOURCE structure which specifies the network resource to connect to. The following fields must be set in the NETSOURCE structure you pass in. The NPAddConnection function ignores the other fields.
lpRemoteName
Specifies the network resource to connect to.
lpLocalName
Specifies the name of a local device to be redirected, such as "F:" or "LPT1". This name is treated as case insensitive and may be an empty string or NULL pointer. If the string is empty or NULL, the function connects to the network resource without making a redirection.
dwType
Specifies the type of resource to connect to. This can be RESOURCETYPE_DISK, RESOURCETYPE _PRINT, or RESOURCETYPE_ANY. The value RESOURCETYPE _ANY is used if the caller does not care or does not know.
lpPassword
Pointer to the password to be used in making the connection, normally the password associated with lpUserName. The NULL value may be passed in to cause the function to use the default password. An empty string may be used to indicate no password.
lpUserName
Pointer to the username used to make the connection. If NULL, the default username (that of the currently logged-on user) is applied. This is used when the user wishes to connect to a resource but has a different assigned username or account for that resource.

For example, if you were logged using the username "MyAccount" and wanted to connect to a network resource that was available only to a second account, where the username was "MyOtherAccount", you could specify "MyOtherAccount" in lpUserName in order to connect to the resource. You would also specify the password of this second account in lpPassword.

Return Value

If the function succeeds, it should return WN_SUCCESS. Otherwise, it should return an error code, which can be one of the following.

Error code | Description
WN_BAD_NETNAME | The value of the lpRemoteName member of the structure passed into lpNetResource is invalid for this provider.
WN_BAD_LOCALNAME | The value of the lpLocalName member of the structure passed into lpNetResource is invalid.
WN_BAD_PASSWORD | The specified password is invalid.
WN_ALREADY_CONNECTED | The device specified in the lpLocalName member of the structure passed into lpNetResource is already connected
WN_ACCESS_DENIED | Permission to establish the connection is denied.
WN_NO_NETWORK | The network is not present.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.


NPAddConnection3

The NPAddConnection3 function connects a local device to a network resource. It performs the same operation as NPAddConnection but in addition lets you specify a handle to the window that should own any resulting dialog boxes and specify how the connection should be established.

DWORD NPAddConnection3(
  HWND hwndOwner,
  LPNETRESOURCE lpNetResource,
  LPTSTR lpPassword,
  LPTSTR lpUserName,
  DWORD dwFlags
);

Parameters

hwndOwner
A handle to a window that should own any messages or dialog boxes. This handle is valid only if CONNECT_INTERACTIVE is set in dwFlags, and the handle should only be used to produce dialog boxes needed for authentication.
lpNetResource
Pointer to a NETRESOURCE structure that specifies the network resource to connect to. The following fields must be set when making a connection. The others are ignored.
lpRemoteName
Specifies the network resource to connect to.
lpLocalName
Specifies the name of a local device to be redirected, such as "F:" or "LPT1". This name is treated as case insensitive and may be the empty string or NULL pointer. If the string is empty or NULL, the function connects to the network resource without making a redirection.
dwType
Specifies the type of resource to connect to. This can be RESOURCETYPE_DISK, RESOURCETYPE_PRINT, or RESOURCETYPE_ANY. The value RESOURCETYPE_ANY is used if the caller does not care or does not know.
lpPassword
Pointer to the password to be used in making the connection, normally the password associated with lpUserName. The NULL value may be passed in to cause the function to use the default password. An empty string may be used to indicate no password.
lpUserName
Pointer to the username used to make the connection. If NULL, the default username (that of the currently logged-on user) is applied. This is used when the user wishes to connect to a resource but has a different assigned username or account for that resource.
dwFlags
Any combination of the following values. The provider should ignore any other bits of dwFlags that may be set.
Value | Description
CONNECT_TEMPORARY | The connection is being established for browsing purposes and will probably be released quickly.
CONNECT_INTERACTIVE | The connection may have interaction with the user for authentication purposes.
CONNECT_PROMPT | Do no use any defaults for usernames or passwords without offering the user a chance to supply an alternative. This flag is only valid if CONNECT_INTERACTIVE is also set.
CONNECT_DEFERRED Do not perform any remote network operations to make the network connection; instead, restore the connection in a "disconnected state." Attempt the actual connection only when some process attempts to use the connection. If this bit is set, the caller must supply lpLocalName.

This feature is used to speed the restoring of network connections at logon. A provider that supports it should return the WNNC_CON_DEFERRED bit in NPGetCaps.

Return Value

If the function succeeds, it should return WN_SUCCESS. Otherwise, it should return an error code. This may include one of the following.

Error value | Description
WN_BAD_NETNAME | The value of the lpRemoteName member of the structure passed into lpNetResource is invalid for this provider.
WN_BAD_LOCALNAME | The value of the lpLocalName member of the structure passed into lpNetResource is invalid.
WN_BAD_PASSWORD | The specified password is invalid.
WN_ALREADY_CONNECTED | The device specified in the lpLocalName member of the structure passed into lpNetResource is already connected.
WN_ACCESS_DENIED | Permission to establish the connection is denied.
WN_NO_NETWORK | The network is not present.
WN_CANCEL | The attempt to make the connection was canceled by the user using a dialog box displayed by the provider.

Remarks

If a provider displays a password dialog box because the specified credentials are insufficient and the CONNECT_INTERACTIVE flag is set, then the provider may not return an access-denied error code (one of ERROR_LOGON_FAILURE, WN_BAD_PASSWORD, WN_ACCESS_DENIED). The suggested behavior is for the provider to continue asking the user for valid credentials until the user either supplies them, or presses a "cancel" button. If NPAddConnection3 is called to make the connection requested during the WNetConnectionDialog or WNetConnectionDialog1 function and an access-denied code is returned, the WNetConnectionDialog or WNetConnectionDialog1 function will, itself, display a password dialog box.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.

See Also

NPAddConnection


NPCancelConnection

The NPCancelConnection function breaks a network connection. The changes you make to the connection are remembered if the connection is to a device. If, however, the connection is to a remote network resource, changes are not remembered.

DWORD NPCancelConnection(
  LPTSTR lpName,
  BOOL fForce
);

Parameters

lpName
Pointer to the name of either the redirected local device or the remote network resource to disconnect from.
fForce
Indicates whether the disconnect should continue in the event of open files or jobs on the connection. If FALSE is specified, the call will fail if there are open files or jobs.

Return Values

If the function succeeds, it should return WN_SUCCESS. Otherwise, it should return an error. This can be one of the following.

Error code | Description
WN_NOT_CONNECTED | lpName is not a redirected device, or is not currently connected to lpName.
WN_OPEN_FILES | There are open files and fForce was set to FALSE.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.


NPCloseEnum

The NPCloseEnum function closes an enumeration.

DWORD NPCloseEnum (
  HANDLE hEnum
);

Parameters

hEnum
Must be a handle obtained from NPOpenEnum call.

Return Values

If the function succeeds, it should return WN_SUCCESS. Otherwise, it should return an error code, which can be one of the following.:

Error Codes | Description
WN_NO_NETWORK | The network is not present. This condition is checked for before hEnum is tested for validity.
WN_BAD_HANDLE | hEnum is not a valid handle.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.


NPDeviceMode

The NPDeviceMode function specifies the parent window of a device. This window owns any dialog boxes originating from the device.

DWORD NPDeviceMode(
  HWND hParent
);

Parameters

hParent
Handle to the window that owns dialog boxes originating from this device.

Return Values

If the function succeeds, it should return WN_SUCCESS. Otherwise, it should return an Win32 error code.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.


NPDirectoryNotify

The NPDirectoryNotify function is used by File Manager to notify the network provider of certain directory operations. This function can be used to perform special operations on certain directories.

DWORD NPDirectoryNotify(
  HWND hwnd,
  LPTSTR lpDir,
  DWORD dwOper
);

Parameters

hwnd
A handle to a window that should own any messages or dialog boxes in the event the network provider needs to interact with the user.
lpDir
Pointer to the fully qualified name of the directory.
dwOper
Indicates the operation about to be performed. This can be one of the following values.
Value | Description
WNDN_MKDIR | File Manager is about to create a directory with the given name.
WNDN_RMDIR | File Manager is about the remove the directory.
WNDN_MVDIR | File Manager is about to rename the directory.

Return Values

This function should return WN_SUCCESS if it is successful. This indicates to the caller that it should continue and perform the operation. Otherwise, it should return the appropriate code, which may include:

Error code | Description
WN_CANCELLED | The provider would have handled the operation, but the user canceled it. The caller should not perform the operation.
WN_CONTINUE | The network provider has already handled the operation. The caller should proceed normally but should not perform the operation.
WN_NOT_SUPPORTED | The network does not have special directory handling. This is treated as WN_SUCCESS.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.


NPEnumResource

The NPEnumResource function performs an enumeration based on a handle returned by NPOpenEnum.

DWORD NPEnumResource (
  HANDLE hEnum,
  LPDWORD lpcCount,
  LPVOID lpBuffer,
  LPDWORD lpBufferSize
);

Parameters

hEnum
Must be a handle obtained from NPOpenEnum call.
lpcCount
Pointer to the number of entries requested. It may be 0xFFFFFFFF to request as many entries as possible. If the call succeeds, this location will receive the number of entries actually read.
lpBuffer
Pointer to the buffer to receive the enumeration result, which are returned as an array of NETRESOURCE entries. The buffer is valid until the next call using hEnum.
lpBufferSize
Pointer to the size, in bytes, of the buffer passed to the function call on entry. If the buffer is too small for even one entry, this should contain, on exit, the number of bytes needed to read one entry. This value is only set if the return code is WN_MORE_DATA.

Return Values

If the function succeeds, it should return WN_SUCCESS. The caller may continue to call NPEnumResource to continue the enumeration. Otherwise, it should return one of the following error codes.

Error code | Description
WN_NO_MORE_ENTRIES | No more entries. The enumeration was completed successfully. When this occurs, the contents of the return buffer, lpBuffer, are undefined.
WN_MORE_DATA | The buffer is too small to hold even a single entry
WN_BAD_HANDLE | hEnum is not a valid handle.
WN_NO_NETWORK | The network is not present. This condition is checked for before hEnum is tested for validity.

Remarks

When this function is called, the provider should fill the buffer with the requested number of entries (or the maximum that can fit). The returned NETRESOURCE structures should be located contiguously at the head of the buffer, like an array of such structures. The pointers in these structures must point to locations within the buffer. Therefore, data referenced by these pointers should be located at the end of the buffer, after the array of structures. It is the provider's responsibility to package this information correctly.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.


NPFormatNetworkName

The NPFormatNetworkName function formats a network name in a provider-specific format for display in a control.

DWORD NPFormatNetworkName(
  LPTSTR lpRemoteName,
  LPTSTR lpFormattedName,
  LPDWORD lpnLength,
  DWORD dwFlags,
  DWORD dwAveCharPerLine
);

Parameters

lpRemoteName
Pointer to the network name to format.
lpFormattedName
Pointer to a string that receives the formatted name.
lpnLength
Pointer to DWORD that specifies the size of the lpFormattedName buffer, in characters. If the return value of this function is WN_MORE_DATA, lpnLength contains the buffer size required, in characters.
dwFlags
Bitfield indicating the type of format being requested. Can be one of the following values.
Flag | Description
WNFMT_MULTILINE | The provider should place the '\n' character where line breaks should appear in the name. The full name should be expressed.
WNFMT_ABBREVIATED | The provider should shorten the network name so that the information most useful for the user will fit in the available space.

In addition, the following flag may be included by means of the OR operator to act as modifiers to the preceding flags.
Flag | Description
WNFMT_INENUM | The network name is presented in the context of an enumeration where the name of the "container" appears immediately before the network name in the enumeration. This allows network providers to remove redundant information from the formatted name, providing a less cluttered display for the user.

dwAveCharPerLine
Specifies the average number of characters that will fit on a single line where the network name is being presented. Specifically, this value is defined as the width of the control divided by the tmAveCharWidth field of the TEXTMETRIC structure from the font used for display in the control.

Return Values

If the function succeeds, it should return WN_SUCCESS. Otherwise, it should return an error code, which can be one of the following. All other errors will be ignored and the unformatted network name will be used.

Error code | Description
WN_MORE_DATA | The input buffer is too small.

Remarks

This function allows network vendors to trim or modify network names before they are presented to the user. For example, in the File Open common dialog, the "Drives" combo box presents all connected resources and their associated network name. Before each item is displayed, NPFormatNetworkName is called and the network provider has the option of editing the name so it will fit in the combo box. More importantly, the network provider can edit the name to present the most significant portion of the network name to the user.

Note that NPFormatNetworkName is not routed to each network provider, as most of the other network provider functions are. Each network vendor need worry only about formatting their own network name. They can assume that only names produced by their network provider driver will be passed to NPFormatNetworkName.

The following table is a general guide to how the WNFMT_ flags are typically passed at various places in the Windows NT/Windows 2000 user interface. No assumptions should be made about what flags are passed where; this table is provided solely to help each network vendor to decide the best method for modifying their network name.

Display location | WNFMT_ MULTILINE | WNFMT_ ABBREVIATED | WNFMT_ INENUM
File Manager Connection dialog box, Drive combo box, selection (The selection section of the combo box is the upper rectangle, above the list section, that displays the current selection.) |  | X |
File Manager Connection dialog box, Drive combo box, list (The list section of the combo box is the list box that appears below the selection portion of the combo box.) | X |  |
File Manager, Shared Directories list |  | X | X
File Manager Disconnect Network Drive list | X |  |
File Manager, toolbar, combo box, selection |  | X |
File Manager toolbar combo box list | X |  |
Common File, Open/Save dialog boxes, Drive combo box, selection |  | X |
Common File, Open/Save dialog boxes, Drive combo box, list |  | X |

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.


NPGetCaps

The NPGetCaps function returns information about which services are supported on the network.

DWORD NPGetCaps(
  DWORD nIndex
);

Parameters

nIndex
Specifies the type of information to return. The following values are defined.
Value | What to return
WNNC_SPEC_VERSION | WNet API version supported by the provider.
WNNC_NET_TYPE | Network type and provider version.
WNNC_USER | A bitmask indicating which user functions the network provider supports.
WNNC_CONNECTION | A bitmask indicating which connection functions the network provider supports.
WNNC_DIALOG | A bitmask indicating which provider-specific dialog box functions the network providers supports.
WNNC_ADMIN | A bitmask indicating which administrative functions the network provider supports.
WNNC_ENUMERATION | A bitmask indicating which enumeration functions the network provider supports.
WNNC_START | The state of the network provider.

Return Values

NPGetCaps returns either a constant or a bitmask, depending on the value of the nIndex parameter. A few of the nIndex values cause a constant to be returned. But in most cases, the nIndex parameter specifies which set of services to query, and the returned value is a bitmask indicating which services in this set are supported. In these cases, a zero return value indicates that none of the services in the set are supported.

The following list shows the values that nIndex may contain, each followed by a description of what is returned for that value.

WNNC_SPEC_VERSION
Currently this returns WNNC_SPEC_VERSION51. The high and low words of the return value contain the major and minor version numbers of the WNet API specification supported by the credential manager.
WNNC_NET_TYPE
Returns a value indicating the type of network that the network provider supports. The high word contains the provider type, and the low word may contain a subtype. Developers working on new providers should obtain a new network type from Microsoft. A provider that does not return the correct network type may cause the WNET functions to behave in unpredictable ways.

The network type can be one of the following.
WNNC_NET_10NET | WNNC_NET_INTERGRAPH
WNNC_NET_3IN1 | WNNC_NET_LANMAN
WNNC_NET_9TILES | WNNC_NET_LANSTEP
WNNC_NET_APPLETALK | WNNC_NET_LANTASTIC
WNNC_NET_AS400 | WNNC_NET_LIFENET
WNNC_NET_BMC | WNNC_NET_LOCUS
WNNC_NET_BWNFS | WNNC_NET_MASFAX
WNNC_NET_CLEARCASE | WNNC_NET_MSNET
WNNC_NET_COGENT | WNNC_NET_NETWARE
WNNC_NET_CSC | WNNC_NET_OBJECT_DIRE
WNNC_NET_DCE | WNNC_NET_PATHWORKS
WNNC_NET_DECOREB | WNNC_NET_POWERLAN
WNNC_NET_DISTENCT | WNNC_NET_PROTSTOR
WNNC_NET_EXTENDNET | WNNC_NET_RDR2SAMPLE
WNNC_NET_FARALLON | WNNC_NET_SHIVA
WNNC_NET_FJ REDIR | WNNC_NET_SUN_PC_NFS
WNNC_NET_FRONTIER | WNNC_NET_SYMFONET
WNNC_NET_FTP_NFS | WNNC_NET_TWINS
WNNC_NET_HOB_NFS | WNNC_NET_VINES
WNNC_NET_IBMAL

WNNC_USER
Returns WNNC_USR_GETUSER if the network provider supports the NPGetUser function.
WNNC_CONNECTION
Returns a mask that indicates which of the connection functions the network provider supports. This can be one or more of the following.
Flag | Function supported
WNNC_CON_ADDCONECTION | NPAddConnection
WNNC_CON_CANCELCONNECTION | NPCancelConnection
WNNC_CON_GETCONNECTION | NPGetConnection
WNNC_CON_ADDCONECTION3 | NPAddConnection3
WNNC_CON_GETPERFORMANCE | NPGetConnectionPerformance

WNNC_DIALOG
Returns a mask that indicates which of the dialog box functions the network provider supports. This can be one or more of the following.
Flag | Function supported
WNNC_DLG_DEVICEMODE | NPDeviceMode
WNNC_DLG_PROPERTYDIALOG | NPPropertyDialog and NPGetPropertyText
WNNC_DLG_SEARCHDIALOG | NPSearchDialog
WNNC_DLG_FORMATNETNAME | NPFormatNetworkName
WNNC_DLG_PERMISSIONEDITOR | For Windows NT 3.51 and earlier, this is the File Manager functions. There is no equivalent for the Windows NT Explorer component used in Windows NT 4.0 and later.
WNNC_DLG_GETRESOURCEPARENT | NPGetResourceParent
WNNC_DLG_GETRESOURCEINFORMATION | NPGetResourceInformation

WNNC_ADMIN
Returns a mask indicating which of the administrative functions the network provider supports. This can be one or more of the following.
Flag | Function supported
WNNC_ADM_GETDIRECTORYTYPE | NPGetDirectoryType
WNNC_ADM_DIRECTORYNOTIFY | NPDirectoryNotify

WNNC_ENUMERATION
Returns a mask indicating which scopes of enumeration, if any, are supported. For more information about enumeration scopes, see the Parameters description in the NPOpenEnum reference topic. This can be one or more of the following.
Flag | Enumeration type supported
WNNC_ENUM_GLOBAL | NPOpenEnum is implemented and supports a scope of all resources on the network. In other words, NPOpenEnum supports RESOURCE_GLOBALNET.
WNNC_ENUM_LOCAL | NPOpenEnum is implemented and supports a scope of all currently connected resources. In other words, NPOpenEnum supports RESOURCE_CONNECTED.
WNNC_ENUM_CONTEXT | NPOpenEnum is implemented and supports a scope of all resources associated with the user's current and default network context. In other words, NPOpenEnum supports RESOURCE_CONTEXT.

Note that if WNNC_ENUMERATION returns a non-zero bitmask, you know that the network provider supports NPOpenEnum and can infer that the provider also supports NPEnumResource and NPCloseEnum. This is because a network provider that supports NPOpenEnum is also expected to support NPEnumResource and NPCloseEnum.

WNNC_START
Returns one of the following values to indicate if and when the provider is likely to start. The MPR will wait for the longest time-out period specified by all network providers.
Flag | Start Time
0x0 | Indicates the provider will not start: for example, if it is disabled. The MPR will not retry starting the network provider.
time | Indicates the time, in milliseconds, until the provider starts.
0xFFFFFFFF | Indicates that the provider does not know when it will start. If the network provider returns this value, the MPR uses its default value, 60 seconds.
0x1 | Indicates that the provider is already started.

Remarks

When a start time is returned by NPGetCaps, the MPR uses this value to determine when to try to start all network providers again. MPR uses the longest start time returned by the providers it called.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.

See Also

NPLogonNotify, NPPasswordChangeNotify


NPGetConnection

The NPGetConnection function obtains information about a connection.

DWORD NPGetConnection(
  LPTSTR lpLocalName,
  LPTSTR lpRemoteName,
  LPDWORD lpBufferSize
);

Parameters

lpLocalName
Pointer to the name of the local device the caller is interested in. The network provider can assume this name is syntactically valid.
lpRemoteName
Pointer to a buffer that will receive the remote name used to make the connection. This buffer is allocated by the caller. This data is stored in a NETCONNECTINFOSTRUCT structure. Additional, network-specific information can be appended to the end of the structure. For more information, see the reference information on NETCONNECTINFOSTRUCT.
lpBufferSize
Pointer to the size, in characters, of the lpRemoteName buffer. If the call fails because the buffer is not big enough, lpBufferSize is set to the required buffer size.

Remarks

The NPGetConnection function can return information only about a network connection that is currently connected. To retrieve information about a network connection that is currently disconnected, use NPGetConnection3.

Return Value

If the function succeeds, it should return WN_SUCCESS. Otherwise, it should return an error code, which can be one of the following.

Error code | Description
WN_NOT_CONNECTED | The device specified by lpLocalName is not redirected by this provider.
WN_MORE_DATA | The buffer was too small to receive all of the data.
WN_NO_NETWORK | The network is not present.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.


NPGetConnection3

The NPGetConnection3 function retrieves information about a network connection, even if it is currently disconnected.

DWORD NPGetConnection3(
  LPCWSTR lpLocalName,
  DWORD dwLevel,
  LPVOID lpBuffer,
  LPDWORD lpBufferSize
);

Parameters

lpLocalName
Pointer to the name of the local device the caller is interested in. The provider can assume that this is syntactically valid.
dwLevel
Value that specifies whether the network connection is currently connected or disconnected.
Value | Description
WNGETCON_CONNECTED | The network connection is connected.
WNGETCON_DISCONNECTED | The network connection is disconnected.

lpBuffer
Void pointer that receives a buffer containing the requested information. This data is stored in a NETCONNECTINFOSTRUCT structure. Additional, network-specific information can be appended to the end of the structure. For more information, see the reference information on NETCONNECTINFOSTRUCT.
lpBufferSize
Pointer to the size, in characters, of the lpBuffer buffer. If the call fails because the buffer is not big enough, lpBufferSize is set to the required buffer size.

Remarks

In Windows NT 3.51 and earlier versions of Windows NT, a network connection could exist in only two states: connected and disconnected. Windows NT 4.0 and later versions add a third state, unavailable. The NPGetConnection3 function cannot retrieve information about network connections that are currently unavailable. It can, however, retrieve information about network connections that are currently disconnected, because Windows stores the connection information.

Return Value

If the function succeeds, it should return WN_SUCCESS. Otherwise, it should return an error code, which can be one of the following.

Error code | Description
WN_NOT_CONNECTED | The device specified by lpLocalName is not redirected by this provider.
WN_MORE_DATA | The buffer was too small to receive all of the data.
WN_NO_NETWORK | The network is not present.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Npapi.h.


NPGetConnectionPerformance

The NPGetConnectionPerformance function returns information about the expected performance of a connection used to access a network resource. The request can only be for a network resource that is currently connected.

DWORD NPGetConnectionPerformance(
  LPTSTR lpRemoteName,
  LPNETCONNECTINFOSTRUCT lpNetConnectInfo
);

Parameters

lpRemoteName
Pointer to the local name or remote name for a connected resource.
lpNetConnectInfo
Pointer to a NETCONNECTINFOSTRUCT structure, which is filled in by the network provider if the provider has a connection to the network resource. All other fields of this structure, except the cbStructure field, are filled with zeros before the MPR passes the request on to the network providers. As a result, the provider has to write only to fields for which it has information available. Also, for rate values, a value of 1 means that the performance is better than can be represented in the unit.

Remarks

The information returned may be an estimate. If the network cannot obtain information about the resource on the network, it can return information about the network adaptor and its associated performance and then set dwFlags accordingly.

Return Values

If the function succeeds, it should return WN_SUCCESS. Otherwise, it should return an error code, which can be one of the following.

Error code | Description
WN_NOT_CONNECTED | lpRemoteName is not a connected network resource.
WN_NO_NETWORK | The network is not present.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Npapi.h.


NPGetDirectoryType

The NPGetDirectoryType function is used by File Manager to determine the type of a network directory.

DWORD NPGetDirectoryType(
  LPTSTR lpName,
  LPINT lpType,
  BOOL bFlushCache
);

Parameters

lpName
Pointer to the fully qualified name of the directory. The network provider returns the type to the address pointed to by lpType. If the value returned in lpType is 0 or if the network provider returns an error, File Manager displays the directory as a "normal" directory.
lpType
Pointer to a value defined by the network provider. This valueis used to modify the display of the drive tree in File Manager. In this way, the network provider can show special directories to the user.
bFlushCache
Set to TRUE when File Manager calls MPR to get the directory type for the first time while repainting a window on Refresh. Subsequently, it will be FALSE. This gives a provider the opportunity to optimize performance if it wishes to just read the data for a drive once and then cache it until the next Refresh.

Return Values

This function should return WN_SUCCESS if it is successful. Otherwise, it should return an error code, which may include the following.

Error Code | Description
WN_NOT_SUPPORTED | NPGetDirectoryType is not supported.

Remarks

File Manager will supply its own icon for all special network directories; that is, when lpType is set to a non-zero value, File Manager will display a special folder icon.

The implementation of this function should be high-performance, or fast, since the call occurs while File Manager is painting the directory tree.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.


NPGetPropertyText

The NPGetPropertyText function specifies the names of buttons to add to a property dialog box for a network resource.

DWORD NPGetPropertyText(
  DWORD iButtonDlg,
  DWORD nPropSel,
  LPTSTR lpFileName,
  LPTSTR lpButtonName,
  DWORD cchButtonName,
  DWORD nType
);

Parameters

iButtonDlg
Indicates the index of the button. File Manager supports a maximum of six buttons. This parameter is numbered 1-6 for each of the possible buttons if only one file is selected, or 11-16 if multiple files are selected.
nPropSel
Specifies what items the property dialog focuses on. It can be one of the following values.
Value | Description
WNPS_FILE | A single file.
WNPS_DIR | A single directory.
WNPS_MULT | A selection of multiple files, directories, or both.

lpFileName
Pointer to names of the item or items to be viewed or edited by means of the dialog box. Currently, the only supported items are files and directories, so the item names are file names. These should be unambiguous, contain no wildcard characters, and be fully qualified (for example, C:\LOCAL\FOO.BAR). Multiple filenames should be separated with spaces. A filename that contains spaces may be surrounded by quotes (for example, "C:\My File"). In this case. it is treated as a single name. The caret character '^' may also be used as the quotation mechanism for single characters (for example, C:\My^"File, "C:\My^"File" both refer to the file C:\My"File).
lpButtonName
Pointer to a buffer where the network provider should copy the name of the property button. On success, the buffer pointed to by lpButtonName contains the name of the property button. If this buffer, on exit, contains the empty string, the button corresponding to that name, and all succeeding buttons, will be removed from the dialog box. The network provider cannot "skip" a button.
cchButtonName
Specifies the size of the lpButtonName buffer in characters.
nType
Specifies the item type. Currently, only WNTYPE_FILE is used.

Remarks

File Manager calls this function each time the property dialog box is brought up, and it does this before displaying the dialog box. If the user clicks a button added through this function by the network provider, NPPropertyDialog is called with the appropriate parameters.

Currently, only File Manager calls NPGetPropertyText, and it uses this function for files and directories.

Return Value

If the function succeeds, it should return WN_SUCCESS and lpButtonName can be used. If it points to the empty string, no button corresponds to an index as high as iButton. If the return value is other than WN_SUCCESS, the provider should also call SetLastError to set extended error information. Extended error codes include the following.

Error code | Description
WN_OUT_OF_MEMORY | Couldn't load string from resources.
WN_MORE_DATA | The given buffer is too small to fit the text of the button.
WN_BAD_VALUE | The lpFileName parameter is an unexpected form.
WN_NOT_SUPPORTED | Property dialog boxes are not supported for the given object type, nType.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.


NPGetResourceInformation

The NPGetResourceInformation function separates the part of a network resource accessed through the WNet API from the part accessed through APIs specific to the resource type.

DWORD NPGetResourceInformation(
  LPNETRESOURCE lpNetResource,
  LPVOID lpBuffer,
  LPDWORD lpcbBuffer,
  LPTSTR *lplpSystem
);

Parameters

lpNetResource
Specifies the network resource for which information is required. The lpRemoteName field specifies the remote name of the resource. The calling program should fill in the values for the lpProvider and dwType fields if it knows these values; otherwise, it should set these fields to NULL. All other fields in the NETRESOURCE are ignored and are not initialized.

If the lpRemoteName string contains a portion that is accessed through WNet APIs and a portion that is accessed through other system APIs specific to the resource type, the function should return information only about the network portion of the resource (except for lplpSystem, as described under).

For example, if the resource is "\\server\share\dir1\dir2" where "\\server\share" is accessed through WNet APIs and "\dir1\dir2" is accessed through file system APIs, the provider should verify that it is the right provider for "\\server\share", but need not check whether "\dir1\dir2" actually exists.

lpBuffer
Pointer to the buffer to receive the result. The first field in the result is a single NETRESOURCE structure, and associated strings, representing that portion of the input resource that is accessed through the WNet API, rather than system APIs specific to the resource type. (For example, if the input remote resource name was "\\server\share\dir1\dir2", then the output NETRESOURCE contains information about the resource "\\server\share".) The lpRemoteName, lpProvider, dwType, dwDisplayType, and dwUsage fields are returned containing values, all other fields being set to NULL.

The lpRemoteName field should be returned in the same format as that returned from an enumeration by the NPEnumResource function, so that the caller can perform a case-sensitive string comparison. This is necessary to determine whether the output network resource is the same as one returned by NPEnumResource.

The provider should not do purely syntactic checking to determine whether it owns the resource. This could produce incorrect results when two networks are running on the client and the provider doing syntactic checking is called first.

lpcbBuffer
Pointer to a location that specifies the size, in bytes, of the buffer pointed to by lpBuffer. If the buffer is too small for the result, the function places the required buffer size at this location and returns the error WN_MORE_DATA.
lplpSystem
On a successful return, a pointer to a string in the output buffer specifying that part of the resource that is accessed through system APIs specific to the resource type, rather than through the WNet API. If there is no such part, lplpSystem is set to NULL. For example, if the input remote resource name was "\\server\share\dir", lpRemoteName is returned pointing to "\\server\share" and lplpSystem points to "\dir", both strings being stored in the buffer pointed to by lpBuffer.

Return Values

If the function succeeds, it should return WN_SUCCESS. Otherwise, it should return an error code, which may be one of the following.

Error code | Description
WN_MORE_DATA | The input buffer is too small.
WN_BAD_NETNAME | The resource is not recognized by this provider.
WN_BAD_VALUE | Invalid dwUsage or dwType.
WN_BAD_DEV_TYPE | The caller passed in a non-zero dwType that does not match the actual type of the network resource.
WN_NOT_AUTHENTICATED | The caller has not been authenticated to the network.
WN_ACCESS_DENIED | The caller has been authenticated to the network but does not have sufficient permissions.

Remarks

The enumeration tree can be navigated down from a named network resource by using NPOpenEnum and its related functions. To navigate up from a named resource, the NPGetResourceInformation function can be called to obtain information about the resource, followed by the NPGetResourceParent function to obtain the name and type of the parent resource.

NPGetResourceInformation determines whether the specified provider is the right provider to respond to a request for a specified network resource. It then returns information about the resource's type.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Npapi.h.


NPGetResourceParent

The NPGetResourceParent function retrieves the parent of a specified network resource in the browse hierarchy. This function is typically called for resources that were returned by the same provider from prior calls to NPEnumResource or NPGetResourceInformation.

DWORD NPGetResourceParent(
  LPNETRESOURCE lpNetResource,
  LPVOID lpBuffer,
  LPDWORD lpcbBuffer
);

Parameters

lpNetResource
Pointer to the network resource whose parent name is required. The NETRESOURCE could have been obtained from a previous call to NPEnumResource or NPGetResourceInformation, or constructed by the caller.

The lpRemoteName field specifies the remote name of the network resource whose parent is required.

The lpProvider field specifies the provider to call. This must be supplied.

The dwType field is filled in if the calling program knows its value. Otherwise, it is set to NULL.

All other fields in the NETRESOURCE are ignored and are not initialized.

lpBuffer
Pointer to a buffer to receive the result, which is a single NETRESOURCE structure representing the parent resource. The lpRemoteName, lpProvider, dwType, dwDisplayType, and dwUsage fields are returned; all other fields are set to NULL.

The output lpRemoteName should be in the same format as that returned from an enumeration by NPEnumResource, so that the caller can perform a case-sensitive string comparison to determine whether the parent resource is the same as one returned by NPEnumResource. If the input resource syntactically has a parent, the provider can return it, without determining whether the input resource or its parent actually exist. If a resource has no browse parent on the network, then lpRemoteName is returned as NULL.

The RESOURCEUSAGE_CONNECTABLE bit in the returned dwUsage field does not necessarily indicate that the resource can currently be connected to, only that the resource is connectable when it is available on the network.

lpcbBuffer
Pointer to a location that specifies the size, in bytes, of the buffer pointed to by lpBuffer. If the buffer is too small for the result, the function places the required buffer size at this location and returns the error WN_MORE_DATA.

Return Values

If the function succeeds, it should return WN_SUCCESS. Otherwise, it should return an error code, which may be one of the following.

Error code | Description
WN_MORE_DATA | The input buffer is too small.
WN_BAD_NETNAME | This provider does not own the resource specified by lpNetResource (or the resource is syntactically invalid).
WN_BAD_VALUE | Invalid dwUsage or dwType, or bad combination of parameters is specified (for example, lpRemoteName is syntactically invalid for dwType).
WN_NOT_AUTHENTICATED | The caller has not been authenticated to the network.
WN_ACCESS_DENIED | The caller has been authenticated to the network, but does not have sufficient permissions.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Npapi.h.


NPGetUniversalName

The NPGetUniversalName function retrieves the universal name of a network resource. It can retrieve this in UNC format, or the older remote-name format.

DWORD NPGetUniversalName(
  LPCTSTR lpLocalPath,
  DWORD dwInfoLevel,
  LPVOID lpBuffer,
  LPDWORD lpBufferSize
);

Parameters

lpLocalPath
Pointer to the local path of an object on a network resource. This is a drive-based path.
dwInfoLevel
The level of detail of information the caller is interested in. This can be one of the following values.
Information level Description
UNIVERSAL_NAME_INFO_LEVEL Retrieves the UNC form of the name, for example: "file:\\server\share"

If this value is set, the data returned in lpBuffer is stored as a UNIVERSAL_NAME_INFO structure.
REMOTE_NAME_INFO_LEVEL Retrieves the remote form of the name, for example: "\\server\share"

If this value is set, the data returned in lpBuffer is stored as a REMOTE_NAME_INFO structure.

lpBuffer
Pointer to a buffer to receive the information the user has requested. The specific structure returned depends on the information level specified in dwInfoLevel.
lpBufferSize
Pointer to the size, in bytes, of the lpBuffer buffer. If the call fails because the buffer is not big enough, this location will be used to return the required buffer size.

Return Values

If the function succeeds, it should return WN_SUCCESS. Otherwise, it should return an error code, which may be one of the following.

Error code | Description
WN_BAD_LOCALNAME | The value passed into lpLocalName is invalid.
WN_NOT_CONNECTED | The value passed into lpLocalName is not a redirected device.
WN_MORE_DATA | The buffer is too small.
WN_NO_NETWORK | The network is not present.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.


NPGetUser

The NPGetUser function retrieves the value of the current default username or the username used to establish a network connection.

DWORD NPGetUser(
  LPTSTR lpName,
  LPTSTR lpUserName,
  LPDWORD lpBufferSize
);

Parameters

lpName
Pointer to the name of the local device the caller is interested in, or a remote name for a resource that the user has made a connection to. This parameter may be NULL or the empty string if the caller is interested in the name of the user currently logged on to the system. If a remote name for a resource is passed in, and the user is connected to that resource using different names, it is possible that a provider cannot resolve which username to return. In this case the provider may make an arbitrary choice amongst the possible usernames.
lpUserName
Pointer to a buffer to receive the username. This should be a name that can be passed into the NPAddConnection or NPAddConnection3 function to re-establish the connection with the same user name.
lpBufferSize
Pointer to the size, in characters, of the lpUserName buffer. If the call fails because the buffer is not big enough, this location will be used to return the required buffer size.

Return Value

If the function succeeds, it should return WN_SUCCESS. Otherwise it should return an error code, which can be one of the following.

Error Code | Description
WN_NOT_CONNECTED | The the value in the lpName parameter is not the name of a redirected device or a connected remote name.
WN_MORE_DATA | The buffer, lpUserName, is too small.
WN_NO_NETWORK | The network is not present.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.


NPOpenEnum

The NPOpenEnum function opens an enumeration of network resources or existing connections. It must be called to obtain a valid handle for an enumeration.

DWORD NPOpenEnum (
  DWORD dwScope,
  DWORD dwType,
  DWORD dwUsage,
  LPNETRESOURCE lpNetResource,
  LPHANDLE lphEnum
);

Parameters

dwScope
Determines the scope of the enumeration. This can be one of the following.
Value | Description
RESOURCE_CONNECTED | All currently connected resources.
RESOURCE_GLOBALNET | All resources on the network.
RESOURCE_CONTEXT | The resources associated with the user's current and default network context (used for a "Network Neighborhood" view). The interpretation of this is left to the provider.

dwType
Specifies the type of resources of interest. This is a bitmask, which may be any combination of the following flags.
Flag | Description
RESOURCETYPE_DISK | All disk resources.
RESOURCETYPE_PRINT | All print resources.
RESOURCEUSAGE_ATTACHED | Specifies that the function should fail if the caller is not authenticated (even if the network permits enumeration without authentication).

If dwType is 0, or is just RESOURCEUSAGE_ATTACHED, all types of resources are returned. If a provider does not have the capability to distinguish between print and disk resources at the same level, it may return all resources.

dwUsage
Specifies the usage of resources of interested. This is a bitmask, which may be any combination of the following flags.
Flag | Description
RESOURCEUSAGE_CONNECTABLE | All connectable resources
RESOURCEUSAGE_CONTAINER | All container resources

The bitmask may be 0 to match all of the flags. This parameter may be ignored if dwScope is not set to RESOURCE_GLOBALNET.

lpNetResource
Pointer to the container to perform the enumeration. The NETRESOURCE could have been obtained through a previous NPEnumResource call, or constructed by the caller, or it can be NULL. If it is NULL or if the lpRemoteName field of the NETRESOURCE is NULL, the provider should enumerate the top level of its network. Note that this means a provider cannot use an lpRemoteName of NULL to represent any network resource. A caller would normally start off by calling NPOpenEnum with this parameter set to NULL and then use the returned results for further enumeration. If the calling program knows exactly the provider and remote path to enumerate from, it may build its own NETRESOURCE structure to pass in, filling in the lpProvider and lpRemoteName fields. Note that if dwScope is RESOURCE_CONNECTED or RESOURCE_CONTEXT this parameter will be NULL.
lphEnum
If function call is successful, a handle is set here that can be used for enumeration.

Return Values

If the function succeeds, it should return WN_SUCCESS. Otherwise, it should return an error code which may include one of the following.

Error code | Description
WN_NOT_SUPPORTED | The provider does not support the type of enumeration being requested, or the specific network resource cannot be browsed.
WN_NOT_CONTAINER | lpNetResource does not point to a container.
WN_BAD_VALUE | Invalid dwScope, dwUsage, or dwType or bad combination of parameters is specified.
WN_NO_NETWORK | The network is not present.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.


NPPropertyDialog

The NPPropertyDialog function is called when the user clicks a button added using NPGetPropertyText. Currently, this will only be called for file and directory network properties.

DWORD NPPropertyDialog(
  HWND hwndParent,
  DWORD iButtonDlg,
  DWORD nPropSel,
  LPTSTR lpFileName,
  DWORD nType
);

Parameters

hwndParent
Handle to the parent window that should own the file property dialog box.
iButtonDlg
Indicates the index of the button that was pressed.

This index specifies which property dialog was requested, starting with 1 for the first button returned from NPGetPropertyText. If there are multiple filenames selected, 10 is added to this number. In other words, if there is more than one file selected and the user presses the first provider-defined property button iButtonDlg will be 11. If there is only one file selected, and the user presses the second network property button, iButtonDlg will be 2.

nPropSel
Specifies what items the property dialog should act on. It can be one of the following values.
Value | Description
WNPS_FILE | A single file.
WNPS_DIR | A single directory.
WNPS_MULT | A selection of multiple files, directories, or both.

lpFileName
Pointer to the names of the items that the property dialog should act on. Currently, the only supported items are files and directories, so the item names are file names. These should be unambiguous, contain no wildcard characters and will be fully qualified (for example, C:\LOCAL\FOO.BAR). Multiple filenames should be separated with spaces. A filename which contains spaces may be surrounded by quotes (for example, "C:\My File"). In this case, it is treated as a single name. The caret character '^' may also be used as the quotation mechanism for single characters (e.g., C:\My^"File, "C:\My^"File" both refer to the file C:\My"File).
nType
Specifies the item type. Currently, only WNTYPE_FILE is used.

Return Value

If the function succeeds, it should return WN_SUCCESS. Otherwise, the function should return an error code and call SetLastError to set this extended error code, which may include the following.

Error code | Description
WN_BAD_VALUE | One or more parameters is an unexpected form or value.
WN_OUT_OF_MEMORY | There is insufficient memory to display the dialog.
WN_NET_ERROR | A network error occurred.

Remarks

This function is only called on sets of properties for which NPGetPropertyText has assigned a button name.

This function is used in File Manager to view and modify the network properties (for example, permissions) for files on a network device. If this function is not supported, File Manager does not provide any default behavior.

In this version of the Network Provider interface, lpFileName may point to only filenames. The network provider should return WN_BAD_VALUE if it sees an inappropriate device.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.

See Also

NPGetPropertyText, SetLastError


NPSearchDialog

The NPSearchDialog function enables network vendors to supply their own form of browsing and search, beyond the hierarchical view presented in the Connection dialog box. If a network provider supports this function, the Connection dialog box will enable the Search button when the selected item belongs to that provider. If the user hits the Search button, the Connection dialog box calls NPSearchDialog to handle the user request.

DWORD NPSearchDialog(
  HWND hParent,
  LPNETRESOURCE lpNetResource,
  LPVOID lpBuffer,
  DWORD cbBuffer,
  LPDWORD lpnFlags
);

Parameters

hParent
Handle of the window that will be used as the dialog box's parent.
lpNetResource
Pointer to the currently selected item in the Network Connections dialog box. A provider may choose to ignore this field.
lpBuffer
Pointer to buffer that will receive the result of the search.
cbBuffer
DWORD that will specify size of buffer passed in.
lpnFlags
Pointer to a DWORD of flags that the provider can set to force certain actions after the dialog is dismissed. Currently, the only flag supported is WNSRCH_REFRESH_FIRST_LEVEL, which forces MPR to collapse then expand and refresh the first level below this provider after the dialog box is dismissed.

Return Values

If the function succeeds and the user has clicked OK, NPSearchDialog should return WN_SUCCESS. Otherwise, it should return an error value, which can be one of the following. All other errors should be handled or reported directly by the provider's dialog.

Error code | Description
WN_CANCEL | The user canceled the operation.
WN_MORE_DATA | The input buffer is too small.

Remarks

If the provider does not support enumeration, then the action associated with double clicking on the provider's entry will be to invoke its Search dialog box.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.


File Manager Functions

The following functions are called only by the File Manager supported by Windows NT 3.51 and earlier. The Windows NT Explorer component of Windows NT 4.0 and later does not call these functions. They are included here to support earlier Windows versions.

Function | Description
NPFMXEditPerm | Displays provider-specific permissions dialog boxes.
NPFMXGetPermCaps | Retrieves the capabilities of the permission editor.
NPFMXGetPermHelp | Retrieves the help file and context of the permissions editor dialog box.


NPFMXEditPerm

The NPFMXEditPerm function enables network vendors to supply their own permission editor dialog boxes.

DWORD NPFMXEditPerm(
  LPTSTR lpDriveName,
  HWND hwndFMX,
  DWORD nType
);

Parameters

lpDriveName
Pointer to the current drive name selected in File Manager.
hwndFMX
Handle to the FMX window which can be used to query selections.
nType
Specifies the type of permission dialog box to bring up. It can be one of the following values.
Value | Description
WNPERM_DLG_PERM | Brings up the Permissions dialog box.
WNPERM_DLG_AUDIT | Brings up the Auditing dialog box.
WNPERM_DLG_OWNER | Brings up the Owner dialog box.

Return Values

This function should return WN_SUCCESS if it is successful. Otherwise, it should call SetLastError to set extended error information, which may include the following.

Error code | Description
WN_NOT_SUPPORTED | NPFMXEditPerm is not supported in the provider.
WN_BAD_VALUE | Some parameter takes an unexpected form or value.
WN_OUT_OF_MEMORY | Not enough memory to display the dialog box.
WN_NET_ERROR | Some other network error occurred

Remarks

This function is used in File Manager to view and modify the permissions, which may include permissions for files or directories, auditing of files or directories, and taking ownership of files or directories. The hwndFMX parameter specifies the handle of the current File Manager window, and File Manager Extension messages can be sent to hwndFMX to query current file selections in File Manager.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.


NPFMXGetPermCaps

The NPFMXGetPermCaps function retrieves the capabilities of the permission editor. The return value is a bitmask, indicating which of the Security menu items in File Manager are to be enabled.

DWORD NPFMXGetPermCaps(
  LPTSTR lpDriveName
);

Parameters

lpDriveName
Pointer to the name of the drive currently selected in File Manager.

Return Values

A bitmask indicating what permission capability the user has on the selected drive. The bitmask is a combination of the following flags.

Flag | Description
WNPERM_PERM | The Permissions menu item is enabled.
WNPERM_AUDIT | The Auditing menu item is enabled.
WNPERM_OWNER | The Owner menu item is enabled.

Remarks

The Security menu currently includes three menu items: Permissions, Auditing and Owner. If the bitmask returned by NPFMXGetPermCaps has the bit WNPERM_PERM set, then the Permissions menu item is enabled. The individual provider should only return with the bit WNPERM_PERM set if the provider supports its own permission editor dialog boxes and the user has the rights to modify permissions on the given drive. The same applies to the WNPERM_AUDIT and WNPERM_OWNER bits.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.


NPFMXGetPermHelp

The NPFMXGetPermHelp function is used to get the help file and help context of the permission editor dialog boxes when a menu item in the Security menu of File Manager is selected and F1 is pressed.

DWORD NPFMXGetPermHelp(
  LPTSTR lpDriveName,
  DWORD nType,
  BOOL fDirectory,
  LPVOID lpBuffer,
  LPDWORD lpBufferSize,
  LPDWORD lpnHelpContext
);

Parameters

lpDriveName
Pointer to the name of the drive currently selected in File Manager.
nType
Specifies the menu item in the Security menu of File Manager to bring up help on. This can be one of the following values.
Value | Description
WNPERM_DLG_PERM | Show help on the Permissions menu item.
WNPERM_DLG_AUDIT | Show help on the Auditing menu item.
WNPERM_DLG_OWNER | Show help on the Owner menu item.

fDirectory
Specifies whether the selected item is a directory. This should be set to TRUE if the selected item in File Manager is a directory, and FALSE if it is a file.
lpBuffer
Pointer to a buffer that will receive the help file name.
lpBufferSize
DWORD that specifies size of buffer passed in. If lpBuffer is not large enough, on return, this contains the size of buffer needed.
lpnHelpContext
Pointer to a DWORD that will receive the help context for the given nType.

Return Values

This function should return WN_SUCCESS if it is successful. Otherwise, it should call SetLastError in order to set extended error information, which may include the following.

Value | Description
WN_NOT_SUPPORTED | NPFMXGetPermHelp is not supported in the provider.
WN_BAD_VALUE | One or more parameters is an unexpected form or value.
WN_MORE_DATA | The input buffer is too small.

Remarks

This function is called by File Manager to get the help file name and help context when F1 is pressed on a selected item in its Security menu. TheSecurity menu currently includes three menu items: Permissions, Auditing and Owner. File Manager bring up Help based on the help file name and the help context returned by the provider.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.


Support Functions

The following functions are implemented by the Windows operating system and can be called by network providers.

Function | Description
WNetSetLastError | Sets extended error information. .


WNetSetLastError

The WNetSetLastError function sets extended error information. Network providers should call this function instead of SetLastError. When necessary, the MPR calls SetLastError to set the Win32 error returned from a network provider.

VOID
WNetSetLastError (
  DWORD err,
  LPTSTR lpError,
  LPTSTR lpProvider
);

Parameters

err
The error that occurred. This is a network-specific error code.
lpError
String describing the network-specific error.
lpProvider
String naming the network provider which raised the error.

Return Values

This function has no return values.

Remarks

A provider should use this function to report errors that contain provider specific information. The error information is saved until it is overwritten by another call to WNetSetLastError in the same thread.

The recommended way for a provider functions to handle general errors is to:

return(providerError) ;

where providerError is a Win32 error code, such as one of the return codes listed for the provider API in this document.

For provider-specific errors, a provider should do the following:

//... setup lpErrorString to be the error to be reported
WNetSetLastError(providerError,
lpErrorString,
lpProviderName) ;
return(ERROR_EXTENDED_ERROR) ;

where providerError is the provider-specific error code.

Providers do not need to call SetLastError before returning from a provider function. The MPR calls SetLastError to set the Win32 error returned from a provider when necessary to satisfy applications.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.


Credential Management Functions

The following functions are implemented by credential managers in order to receive notifications when authentication information changes.

Function | Description
NPLogonNotify | Notifies the credential manager of a logon event.
NPPasswordChangeNotify | Notifies a credential manager provider when the password of an account changes.


NPLogonNotify

The NPLogonNotify function is implemented by a credential manager DLL. MPR calls this function to notify the credential manager that a logon event has occurred, allowing the credential manager to return a logon script.

DWORD APIENTRY NPLogonNotify(
  PLUID lpLogon,
  LPCWSTR lpAuthentInfoType,
  LPVOID lpAuthentInfo,
  LPCWSTR lpPreviousAuthentInfoType,
  LPVOID lpPreviousAuthentInfo,
  LPWSTR lpStationName,
  LPVOID StationHandle,
  LPWSTR *lpLogonScript
);

Parameters

lpLogon
Pointer to the identifier of the session that just logged on.
lpAuthentInfoType
Pointer to astring that identifies the type of structure pointed to by lpAuthentInfo.

When Microsoft is the primary authenticator, one of the following strings is specified for interactive and service controller logons:

MSV1_0:Interactive
Kerberos:Interactive
lpAuthentInfo
Pointer to a structure that contains the credentials used to successfully log the user on through the primary authenticator.

When Microsoft is the primary authenticator, in other words, when lpAuthentifoType is "MSV1_0:Interactive" or "Kerberos:Interactive", the structure used is MSV1_0_INTERACTIVE_LOGON or KERB_INTERACTIVE_LOGON.

lpPreviousAuthentInfoType
Pointer to a string that identifies the type of structure pointed to by lpPreviousAuthentInfo. If the pointer is NULL, there was no previous information. The values that are expected here are the same as those in lpAuthentInfoType.

When Microsoft is the primary authenticator, the following string is specified for interactive and service controller logons:

MSV1_0:Interactive
lpPreviousAuthentInfo
Pointer to a structure that contains the credentials used before the authentication information change. Prior information is provided if the user was forced to change the password (or other authentication information) before logging on. If the user was not forced to change authentication information, this pointer is NULL. The values that are expected here are the same as those in lpAuthentInfo.

When Microsoft is the primary authenticator, the structure used is MSV1_0_INTERACTIVE_LOGON or KERB_INTERACTIVE_LOGON.

lpStationName
Pointer to a string that specifies the name of the station that the user has logged on to. The station name may be used to determine whether or not additional (provider-specific) information can be obtained.

When Microsoft is the primary authenticator, one of the following strings will be specified:

WinSta_0
Indicates that this is an interactive logon through the window station. In this case, StationHandle is an HWND to the parent dialog.
SvcCtl
Indicates that this is a logon initiated by the Service controller. StationHandle is not used in this case.
StationHandle
A 32-bit value whose meaning is dependent upon the name (and consequently, the type) of the station specified in lpStationName.
Station name in lpStationName | Contents of StationHandle
WinSta_0 | A handle to the owner dialog box (hwndOwner) currently displayed on the screen.
SvcCtr | Random data. Do not use.

lpLogonScript
Pointer to a location where a pointer to a null-terminated string may be returned.

After the function completes, this value may point to a null-terminated string that contains the name of a program to execute plus any parameters the program requires. LocalAlloc should be used to allocate the memory for the returned string. This memory will be freed by MPR when it is no longer needed.

Return Values

If the function succeeds, it should return WN_SUCCESS. Otherwise, it should return an error code, which can be one of the following.

Error code | Description
WN_NOT_SUPPORTED | NPLogonNotify is not supported by the credential manager.
WN_NO_NETWORK | The network is not present.
WN_FUNCTION_BUSY | The credential manager is still initializing and is not ready to be called.

Remarks

Each credential manager is allowed to return a single command-line string that can be used to execute a logon script. The buffer of this string is allocated by the credential manager. MPR is responsible for freeing it. The string returned in lpLogonScript should contain all the information necessary to run the script as a command line passed to CreateProcess.

If the string requires the command processor to process the string, as in the case of commands or batch files, then the string should be prefixed with "cmd /C". For example, if MyFile is a command or a batch file, the following string could be returned:

"cmd /C MyFile"      // run as MyFile.bat on DOS
                     // run as MyFile.cmd on OS/2
                     // run as MyFile.bat on NT

Logon scripts will be run in the user context when the user profile is available. However, environment variables that are set will not be global and will not be available to the initial shell (for example, Program Manager) or any other program run on behalf of the user.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.

See Also

CreateProcess, LocalAlloc, NPGetCaps, NPPasswordChangeNotify, MSV1_0_INTERACTIVE_LOGON


NPPasswordChangeNotify

The NPPasswordChangeNotify function is implemented by a credential manager DLL. MPR calls this function to notify the credential manager of a password change event.

DWORD APIENTRY NPPasswordChangeNotify(
  LPCWSTR lpAuthentInfoType,
  LPVOID lpAuthentInfo,
  LPCWSTR lpPreviousAuthentInfoType,
  LPVOID lpPreviousAuthentInfo,
  LPWSTR lpStationName,
  LPVOID StationHandle,
  DWORD dwChangeInfo
);

Parameters

lpAuthentInfoType
Pointer to a string that identifies the type of structure pointed to by lpAuthentInfo.

When Microsoft is the primary authenticator, the following string is specified for interactive and service controller logons:

MSV1_0:Interactive
Kerberos:Interactive
lpAuthentInfo
Pointer to an structure that contains the new credentials.

When Microsoft is the primary authenticator, in other words, when lpAuthentifoType is "MSV1_0:Interactive" or "Kerberos:Interactive", the structure used is MSV1_0_INTERACTIVE_LOGON or KERB_INTERACTIVE_LOGON.

lpPreviousAuthentInfoType
Pointer to a string that identifies the type of structure pointed to by lpPreviousAuthentInfo. If the pointer is NULL, there was no previous information. The values that are expected here are the same as those in lpAuthentInfoType.

When Microsoft is the primary authenticator, the following string is specified for interactive and service controller logons:

MSV1_0:Interactive
lpPreviousAuthentInfo
Pointer to a structure that contains the credentials used before the authentication information change. Prior information is provided if the user was forced to change the password (or other authentication information) before logging on. If the user was not forced to change authentication information, this pointer is NULL. The values expected here are the same as those in lpAuthentInfo.

When Microsoft is the primary authenticator, the structure used is MSV1_0_INTERACTIVE_LOGON or KERB_INTERACTIVE_LOGON.

lpStationName
Pointer to a string that specifies the name of the station the user has logged on to. The station name may be used to determine whether or not additional provider-specific information can be obtained.

When Microsoft is the primary authenticator, one of the following strings will be specified:

WinSta_0
Indicates that this is an interactive logon through the window station. In this case, StationHandle is an HWND to the parent dialog.
SvcCtl
Indicates that this is a logon initiated by the service controller. StationHandle is not used in this case.
StationHandle
A 32-bit value whose meaning is dependent upon the name (and consequently, the type) of the station specified in lpStationName.
Station name in lpStationName | Contents of StationHandle
WinSta_0 | A handle to the owner dialog box (hwndOwner) currently displayed on the screen.
SvcCtr | Random data. Do not use.

dwChangeInfo
If set, specifies a flag that provides change information. Currently the following flags are defined.
Flag | Description
WN_VALID_LOGON_ACCOUNT | This flag indicates that the authentication information changed will affect all future logons. The user belongs to a trusted domain.
WN_NT_PASSWORD_CHANGED This flag indicates that the password was changed.

Some authentication information changes will only affect connections made in untrusted domains. These are the accounts that the user cannot use to log onto this computer anyway. In these cases, dwChangeInfo is not set.

Return Values

If the function succeeds, it should return WN_SUCCESS. Otherwise, it should return an error code, which can be one of the following.

Error code | Description
WN_NOT_SUPPORTED | NPPasswordChangeNotify is not supported.
WN_NO_NETWORK | The network is not present.
WN_FUNCTION_BUSY | The credential manager is still initializing and is not ready to be called.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.

See Also

NPGetCaps, NPLogonNotify, MSV1_0_INTERACTIVE_LOGON


Connection Notification Functions

The following functions are implemented by applications that need to receive notification from the MPR when a network resource is connected or disconnected. For more information about how to write an application that receives such notifications, see Receiving Connection Notifications.

Function | Description
AddConnectNotify | Called before and after each add connection operation (WNetAddConnection, WNetAddConnection2, and WNetAddConnection3)
CancelConnectNotify | Called before and after each cancel connection operation (WNetCancelConnection or WNetCancelConnection2)


AddConnectNotify

The AddConnectNotify function is called before and after each add connection operation (WNetAddConnection, WNetAddConnection2, and WNetAddConnection3) is attempted by the Multiple Provider Router. The AddConnectNotify function is not called when MPR is automatically restoring network connections.

DWORD APIENTRY AddConnectNotify(
  LPNOTIFYINFO lpNotifyInfo,
  LPNOTIFYADD lpAddInfo
);

Parameters

lpNotifyInfo
Pointer to a NOTIFYINFO structure that contains information about the notification.
lpAddInfo
Pointer to a NOTIFYADD structure that contains information about the connection being added.

Return Values

If the function succeeds, it should return WN_SUCCESS. Otherwise, it should return an error code. This can be any of the error codes specified in Return Values.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.

See Also

CancelConnectNotify


CancelConnectNotify

The Multiple Router Provider calls CancelConnectNotify before and after each cancel connection operation (WNetCancelConnection and WNetCancelConnection2).

DWORD APIENTRY CancelConnectNotify(
  LPNOTIFYINFO lpNotifyInfo,
  LPNOTIFYCANCEL lpCancelInfo
);

Parameters

lpNotifyInfo
Pointer to a NOTIFYINFO structure which contains information about the notification.
lpCancelInfo
Pointer to a NOTIFYCANCEL structure which contains the cancel connection specific information.

Return Values

If the function succeeds, it should return WN_SUCCESS. Otherwise, it should return an error code. This can be any of the error codes specified in Return Values.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.

See Also

AddConnectNotify


Network Provider Structures

The following structures are used by the Network Provider APIs and related functions.

Structure | Description
NETCONNECTINFOSTRUCT | Contains information about the performance of a network connection.
UNIVERSAL_NAME_INFO | Contains a local universal name.
REMOTE_NAME_INFO | Contains information about a remote universal name.
NOTIFYINFO | Contains status information about a network connect or disconnect operation.
NOTIFYADD | Contains the details of a network connect operation.
NOTIFYCANCEL | Contains the details of a network disconnect operation.
NETRESOURCE | Contains information about an enumerated network resource.


NETCONNECTINFOSTRUCT

The NETCONNECTINFOSTRUCT structure contains information about the performance of a network. It is used by the NPGetConnectionPerformance function.

typedef struct _NETCONNECTINFOSTRUCT {
  DWORD cbStructure;
  DWORD dwFlags;
  DWORD dwSpeed;
  DWORD dwDelay;
  DWORD dwOptDataSize;
} NETCONNECTINFOSTRUCT,  *LPNETCONNECTINFOSTRUCT;

Members

cbStructure
The size of the NETCONNECTINFOSTRUCT structure, in bytes. This is filled in by the caller to indicate the size of the structure passed in. The network provider should leave this field unchanged and can assume that the structure is large enough to contain all fields up to and including dwOptDataSize.
dwFlags
This is a bit mask which may have one or more of the following flags.
Flag | Description
WNCON_FORNETCARD If set, the information returned is for the performance of the netcard used for the connection. This information is returned if information about the actual connection is not available.

If not set, the information returned is for the current connection with the resource, with any routing degradation taken into consideration.
WNCON_NOTROUTED If set, the connection is not treated as being routed. In other words, routing is not taken into account when estimating the performance. This means actual performance may be much less than the information returned.

If not set, the connection may be going through routers that limit performance.

WNCON_SLOWLINK If set, the connection is known at some point to be over a medium that is typically slow (for example, a modem using a normal quality phone line).

Providers that return a value in dwSpeed do not have to set this bit.
WNCON_DYNAMIC | If set, some of the information returned is dynamically recalculated. If that is the case, reissuing this request on the connection may return different, more current, information.

dwSpeed
The speed of the media to the network resource in units of 100bps. For example, a 1,200 baud point-to-point link returns 12.
dwDelay
The delay introduced by the network when sending information, in milliseconds. In other words, the time between when the network starts to send data and the time it is received. This is in addition to any latency that was incorporated into the calculation of dwSpeed, so the value returned will be 0 for accessing most resources.
dwOptDataSize
A recommendation for the size of data, in bytes, that is most efficiently sent through the network when an application makes a single request to the network resource. For example, for a disk network resource, this value might be 2048 or 512 when writing a block of data.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winnetwk.h.


UNIVERSAL_NAME_INFO

The UNIVERSAL_NAME_INFO structure contains information about the UNC form of a universal name. It is used by the NPGetUniversalName function.

typedef struct _UNIVERSAL_NAME_INFO {
LPTSTR lpUniversalName;
} UNIVERSAL_NAME_INFO, *LPUNIVERSAL_NAME_INFO;

Members

lpUniversalName
If the provider supports a universal name, it will return that here.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winnetwk.h.
Unicode: Declared as Unicode and ANSI structures.


REMOTE_NAME_INFO

The REMOTE_NAME_INFO structure contains information about the remote form of a universal name. It is used by the NPGetUniversalName function.

typedef struct _REMOTE _NAME_INFO {
LPTSTR lpUniversalName;
LPTSTR lpConnectionName;
LPTSTR lpRemainingPath;
} REMOTE_NAME_INFO, *LPREMOTE_NAME_INFO;

Members

lpUniversalName
Pointer to the universal name if the provider supports universal names. Otherwise, this points to NULL.
lpConnectionName
Pointer to a string containing the remote name used to make the connection. This string does not have a trailing backslash.
lpRemainingPath
Pointer to the remaining path that must to be concatenated to a drive letter after a connection is established by means of lpConnectionName, to refer to the object specified during the call to NPGetUniversalName. This string has a backslash at the start of path.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winnetwk.h.
Unicode: Declared as Unicode and ANSI structures.


NOTIFYINFO

The NOTIFYINFO structure contains status information about a network connect or disconnect operation. It is used by the AddConnectNotify and CancelConnectNotify functions.

typedef struct _NOTIFYINFO {
  DWORD dwNotifyStatus;
  DWORD dwOperationStatus;
  LPVOID lpContext;
} NOTIFYINFO, *LPNOTIFYINFO;

Members

dwNotifyStatus
This will be either NOTIFY_PRE or NOTIFY_POST to indicate whether this notification is sent before or after the connection or disconnection is performed.
dwOperationStatus
This is set to WN_SUCCESS when dwNotifyStatus is NOTIFY_PRE.

If dwNotifyStatus is set to NOTIFY_POST, dwOperationStatus contains the return status code from the function performing the operation: NPAddConnection or NPCancelConnection.

lpContext
Used by the application receiving the notification in order to keep a context for the operation between the pre-notification and the post-notification calls. In other words, it enables the notification application to match the advance notification call to the corresponding after-the-fact notification call for a particular event. The lpContext member is a NULL pointer when the notification function is called for advance notification. The notification function can return with lpContext still NULL, indicating that it is not interested in further notification for this specific operation. In this case, the notification function will not be called again with after-the-fact notification for this operation. If the advance notification function call returns a non-NULL value in lpContext, this value is passed in when the notification function is called for the after-the-fact notification for that same operation.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.


NOTIFYADD

The NOTIFYADD structure contains the details of a network connect operation. It is used by the AddConnectNotify function.

typedef struct _NOTIFYADD {
  HWND hwndOwner;
  NETRESOURCE NetResource;
  DWORD dwAddFlags;
} NOTIFYADD, *LPNOTIFYADD;

Members

hwndOwner
Handle to a window which should own any messages or dialog boxes the application receiving the notification might display.
NetResource
Specifies the network resource to connect to. The valid fields are the same as for the NPAddConnection function.
dwAddFlags
Any combination of the following values.
Value | Description
CONNECT_TEMPORARY | The connection is being established for browsing purposes and may be released quickly.
CONNECT_INTERACTIVE | The connection may have interaction with the user.
CONNECT_PROMPT | Do not use any defaults without offering user the chance to supply an alternative. This flag is only valid if CONNECT_INTERACTIVE is set.
CONNECT_UPDATE_PROFILE | The connection is being made persistent.
CONNECT_UPDATE_RECENT | The connection is being added to the recent connection list.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.


NOTIFYCANCEL

The NOTIFYCANCEL structure contains the details of a network disconnect operation. It is used by the CancelConnectNotify function.

typedef struct _NOTIFYCANCEL {
  LPTSTR  lpName;
  LPTSTR  lpProvider;
  DWORD dwFlags;
  BOOL  fForce;
} NOTIFYCANCEL, *LPNOTIFYCANCEL;

Members

lpName
Pointer to the name of the local device or network resource whose connection is being canceled.
lpProvider
For advance notification, this field is not defined. The MPR will try all valid providers to cancel the connection.

For after-the-fact notification, if the cancel operation was successful, this field specifies the name of the network provider that canceled the connection.

dwFlags
Currently, the only flag supported is CONNECT_UPDATE_PROFILE, which indicates whether the disconnection should remain persistent. If this flag is set, Windows no longer restores this connection when the user logs on.
fForce
Indicates whether the disconnect should continue even if there are open files or jobs on the connection. If this field is TRUE, the connection is canceled regardless of open files or jobs. If this field is FALSE, the connection will not be canceled if there are open files or jobs.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Npapi.h.


NETRESOURCE

The following structure contains information about a network resource. It is used by several of the network provider functions, including NPOpenEnum, NPAddConnection, and others.

typedef struct _NETRESOURCE {
  DWORD dwScope;
  DWORD dwType;
  DWORD dwDisplayType;
  DWORD dwUsage;
  LPTSTR lpLocalName;
  LPTSTR lpRemoteName;
  LPTSTR lpComment;
  LPTSTR lpProvider;
} NETRESOURCE, *LPNETRESOURCE;

Members

dwScope
Indicates the scope of the enumeration. This can be one of the following values.
Value | Description
RESOURCE_CONNECTED | Current connections to network resources.
RESOURCE_GLOBALNET | All network resources. These may or may not be connected.
RESOURCE_CONTEXT | The network resources associated with the user's current and default network context. The meaning of this is provider-specific.

dwType
Indicates the resource type. This can be one of the following values.
Value | Description
RESOURCETYPE_DISK | The resource is a shared disk volume.
RESOURCETYPE_PRINT | The resource is a shared printer.
RESOURCETYPE_ANY | The resource matches more than one type, for example, a container of both print and disk resources, or a resource which is neither print or disk.

dwDisplayType
Set by the provider to indicate what display type a user interface should use to represent this resource. Currently, the following types are defined.
Type | Description
RESOURCEDISPLAYTYPE_NETWORK | The resource is a network provider.
RESOURCEDISPLAYTYPE_DOMAIN | The resource is a collection of servers.
RESOURCEDISPLAYTYPE_SERVER | The resource is a server.
RESOURCEDISPLAYTYPE_SHARE | The resource is a share point.
RESOURCEDISPLAYTYPE_DIRECTORY | The resource is a directory.
RESOURCEDISPLAYTYPE_GENERIC | The resource type is unspecified. This value is used by network providers that do not specify resource types.

dwUsage
A bit mask that indicates how you can enumerate information about the resource. It is defined only if dwScope is set to RESOURCE_GLOBALNET. The dwUsage field can contain one or more of the following flags.
Flag | Description
RESOURCEUSAGE_CONNECTABLE | You can connect to the resource by calling NPAddConnection. If dwType is RESOURCETYPE_DISK, then, after you have connected to the resource, you can use the file system APIs, such as FindFirstFile, and FindNextFile, to enumerate any files and directories the resource contains.
RESOURCEUSAGE_CONTAINER The resource is a container for other resources that can be enumerated by means of the NPOpenEnum, NPEnumResource, and NPCloseEnum functions.

The container may, however, be empty at the time of the enumeration is made. In other words, the first call to NPEnumResource may return WN_NO_MORE_ENTRIES.

lpLocalName
If dwScope is RESOURCE_CONNECTED the lpLocalName field contains the name of a redirected device. If the connection is a deviceless connection, this field contains NULL.

If dwScope is not set to RESOURCE_CONNECTED, this field is undefined.

lpRemoteName
If the enumerated item is a network resource, this field contains a remote network name. This name may be then passed to NPAddConnection to make a network connection if dwUsage is set toRESOURCEUSAGE_CONNECTABLE. If the enumerated item is a current connection, this field will refer to the remote network name that lpLocalName is connected to.
lpComment
May be any provider-supplied comment associated with the enumerated item.
lpProvider
Specifies the name of the provider that owns this enumerated item.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Winnetwk.h.
Unicode: Declared as Unicode and ANSI structures.


Return Values

The return values that a network provider can set include the following error codes.

Error codes | Description
WN_SUCCESS | The function succeeded.
WN_NOT_SUPPORTED | The function is not supported on this network provider.
WN_NET_ERROR | A unknown network error occurred.
WN_MORE_DATA | The data buffer passed in is insufficient to contain all of the available data.
WN_BAD_POINTER | An invalid pointer was specified during the function call.
WN_BAD_VALUE | An invalid numeric value was specified during the function call.
WN_BAD_PASSWORD | An incorrect password was specified.
WN_ACCESS_DENIED | The caller does not have sufficient permissions to complete the operation.
WN_FUNCTION_BUSY | This function cannot be reentered and is currently being used, or the provider is still initializing and is not ready to be called yet. The provider should only return this error code if it is going to be available; this return code is passed by the MPR back to its caller and is likely to cause the caller to retry.
WN_WINDOWS_ERROR | A required Windows function failed.
WN_BAD_USER | An invalid username was specified.
WN_OUT_OF_MEMORY | There is insufficient memory to complete the operation.
WN_NOT_CONNECTED | The device is not redirected.
WN_OPEN_FILES | The connection could not be canceled because files are still open.
WN_BAD_NETNAME | The network name is invalid.


Registry Keys

When it installs a network provider, your application should create the registry keys and values described in this topic.. These keys and values provide information to the MPR about the network providers installed on the system. The MPR checks these keys when it starts up and loads the network provider DLLs that it finds.

Before you create a set of keys to hold information about your network provider, you should add the name of your network provider to the order key. This key is a subkey of HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\NetworkProvider. The order key contains a single value, ProviderOrder, which lists the installed providers and specifies the order in which they should be tried during operations that cycle through providers until an accepting provider is found.

The ProviderOrder value contains a comma-separated list of key names. Each key name in ProviderOrder identifies a network provider. When MPR cycles through the providers, it calls them in the order in which they appear in this list.

The provider name set in ProviderOrder should also be used as the name of the registry key that contains information about that provider. The provider-specific registry keys are created as subkeys of HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\. In other words, the provider names specified in ProviderOrder are the path to the registry of the network provider – specific keys, relative to HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\.

When your network provider service is installed, the installation application should add a key as follows: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\ProviderName\, where ProviderName is the name of the network provider as specified in the ProviderOrder value of the order key. The Group value under the ProviderName key should be set to "NetworkProvider". This identifies the service as being in the network provider group.

You must also create a subkey of ProviderName, networkprovider. This key contains the following values that describe the network provider.

Value | Description
Name | Contains the name of the provider. This name is displayed to the user as the name of the network in the browse dialog boxes and should match the lpProvider field returned in NETRESOURCE structures. This name should be some variation of the product name, preferably with some indication of the company as well, so that it is clear and unique. "MS-LanMan" for example is a good name, whereas "The Net" would be a poor choice.
ProviderPath | Contains the full path of the the DLL that implements the network provider. MPR calls LoadLibrary on this path.

The following values are only used by network providers that support the credential management functions, NPLogonNotify and NPPasswordChangeNotify.

Value | Description
Class | A DWORD that identifies the class, or type, of provider functionality that this provider supports. Values may be joined by the OR operator when appropriate. Valid values for this are WN_NETWORK_CLASS, WN_CREDENTIAL_CLASS, WN_PRIMARY_AUTHENT_CLASS, and WN_SERVICE_CLASS. Although a provider may support primary authenticator functionality, another means will be used to determine which authenticator is primary. Windows NT/Windows 2000 does not currently support switching primary authenticators, so this value is ignored.
AuthentProviderPath | This is the fully qualified file name for the DLL that exports the Credential Management Functions. This value is useful (but not required) only when the provider is identified as being a CREDENTIAL_CLASS or PRIMARY_AUTHENT_CLASS provider. If this value is not present for a provider of this class, the credential management functions are expected to be exported from the DLL identified by the ProviderPath value. This value is used only if it is desirable to package the network functions and the credential manager functions in separate DLLs.

In addition to the values used to register network providers and credential managers, you can add a value to the registry in order to register a DLL to receive connection notifications. To do so, create a REG_EXPAND_SZ value under the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\NetworkProvider\Notifyees key. This value should specify the path to a DLL that implements the Connection Notification API. The name of this value can be anything you want, as long as it does not conflict with preexisting value names.

Examples

The following example illustrates the registry keys for a system that has two network providers installed: LanmanWorkStation and AnotherNetSvc. AnotherNetSvc is also a credential manager. In the following example, key names are bold and value names are italic. Also, indenting has been used to indicate subkeys and values contained in a key.

HKEY_LOCAL_MACHINE\System\CurrentControlSet\

Control\NetworkProvider\
order

ProviderOrder="LanmanWorkStation,AnotherNetSvc"
Notifyees

MyNotifyApp="c:\connect\connect.dll"

Services\
LanmanWorkStation\

Group="NetworkProvider"
NetworkProvider
Name = "NT LanMan"
ProviderPath = "ntlanman.dll"

Class = 0x00000001 (WN_NETWORK_CLASS)

AnotherNetSvc\

Group ="NetworkProvider"
NetworkProvider
Name = "Another Network"
ProviderPath = "c:\another\anet.dll"

Class = 0x00000003 (WN_NETWORK_CLASS | WN_CREDENTIAL_CLASS)

AuthentProviderPath = "c:\another\anetCM.dll"


LSA Authentication

Purpose

LSA Authentication describes the parts of the Local Security Authority (LSA) that applications can use to authenticate and log users on to the local system. It also describes how to create and call authentication packages and security packages.

Where Applicable

You can use the LSA Authentication functions to write a Graphical Identification and Authentication (GINA) DLL, an authentication package, a subauthentication package, or a combined security support provider/authentication package (SSP/AP).

Developer Audience

The LSA Authentication functions are designed for use by C/C++ programmers. Familiarity with Microsoft® Windows NT®/Windows® 2000 security protocols and procedures is required.

Run-Time Requirements

Applications that use the LSA Authentication functions require Windows NT or Windows 2000. For information on which operating systems are required to use a particular function, see the Requirements section of the documentation for the function.

See Also

LSA Policy, Winlogon and GINA, Client/Server Access Control Functions.

About LSA Authentication

General information about LSA Authentication.

Using LSA Authentication

How to use LSA Authentication to authenticate and log users onto the local system.

LSA Authentication Reference

Documentation of the LSA Authentication interface and functions.

Feedback

Make error reports and feature requests directly to Microsoft.


About LSA Authentication

The Local Security Authority (LSA) is a protected component of the Microsoft® Windows® operating system used to authenticate and log users on to a local or remote system with logon authentication requirements beyond user name and password data.

The following diagram illustrates the place of the LSA in the logon architecture. Components that can be added or changed are highlighted in gray. See the glossary for definitions of Winlogon, GINA, SSP, SSPI, Negotiate, and Authentication Package

The following topics describe LSA authentication:

  • LSA Authentication Model provides an overview of the LSA authentication features.
  • LSA Logon Sessions describes logon sessions.
  • Authentication describes interactive and noninteractive authentication.
  • Authentication Packages describes authentication packages, how they are used, and how they are created.

For information on using only standard user name and password data to log users on to a system, see the LogonUser function provided by the Client/Server Access Control Functions.


LSA Authentication Model

The LSA authentication model has the following features:

  • LSA authentication supports custom authentication packages. This allows end-customers and independent software vendors (ISVs) to customize or replace authentication routines to meet requirements beyond those provided by the standard Microsoft authentication packages. While the authentication packages provided by Microsoft require a user name and password logon data, a custom authentication package can take other forms of logon data, such as ATM card information and a personal identification number. A custom authentication package can also be used to implement a new security protocol.
  • In Windows 2000, the LSA supports custom security packages, which function as security support providers for distributed applications and as authentication packages for applications requiring authentication services. The authentication functionality is accessed using the same interface as a stand-alone authentication package, while the security support provider functionality is accessed using Microsoft Security Support Provider Interface (SSPI). The set of LSA support functions available to custom security packages allows them to supply advanced security features such as token creation and supplemental credentials management.
  • The LSA supports heterogeneous credentials management to interface with non-Microsoft products, such as networks and databases. Because such products often have their own security credentials, the LSA provides functions that authentication packages can use to associate non-Microsoft credentials with Microsoft® Windows NT®/Windows® 2000 processes. Custom authentication packages can provide services for querying these credentials when needed, such as when a network redirector attempts to establish a connection to a remote system.
  • Each class of logon device installed on a system can have its own logon process. Device classes typically include devices such as smart-card readers; however, for the purposes of LSA authentication, connected networks are also treated as devices. By default, Windows NT/Windows 2000 provides the logon process that supports user name/password logons using a keyboard. Developers can add support for other devices, such as smart-card readers.

For more information, see the following documentation.

Information | Documentation
Credentials management | Security Support Provider Interface (SSPI)
Logon device support | Winlogon and GINA
SmartCard and smart card readers | SmartCard


LSA Logon Sessions

A logon session is a computing session that begins when a user authentication is successful and ends when the user logs off of the system.

When a user is successfully authenticated, the authentication package creates a logon session and returns information to the LSA that is used to create a token for the new user. This token includes, among other things, a locally unique identifier (LUID) for the logon session, called the LogonId.

When a token is created, the reference count for the logon session is incremented. The reference count is also incremented whenever copies of the token are created for process creation, impersonation, or other uses. As token uses are completed and copies of the token are deleted, the reference count for the logon session is decremented. When the reference count reaches zero, the logon session is deleted.

Note If authentication is not successful, the authentication package should not create a logon session. If the authentication package must create a logon session before making a final determination about the validity of the user, and if authentication fails, the authentication package must delete the session.


Authentication

The LSA handles user logon and authentication on the local machine, and if the authentication package processing the logon request supports pass-through authentication, the LSA can also log users on to other machines on the network.

The LSA provides access to authentication packages for Graphical Identification and Authentication (GINA) DLLs and Security Support Providers (SSPs). Depending on which of these components calls the LSA, one of the two following types of authentication is performed:

  • Interactive authentication
  • Noninteractive authentication


Interactive Authentication

Authentication is interactive when a user is prompted to supply logon information. The LSA performs an interactive authentication when a user logs on through the GINA user interface. The following diagram shows the components involved in a typical interactive authentication.

A user signals the system to begin the logon sequence by typing the CTRL+ALT+DEL secure attention sequence (SAS). Winlogon receives the SAS and calls the GINA to display a user interface and obtain the user's logon data, such as a user name and password.

After obtaining the logon data, the GINA calls the LsaLogonUser function to authenticate the user, specifying which authentication package must be used to evaluate the logon data.

The LSA calls the specified authentication package and passes the logon data to it. The authentication package examines the data and determines whether or not the authentication is successful. The authentication result is returned to the LSA and from the LSA, to the GINA.

The GINA displays the success or failure of the authentication to the user and returns the result of the authentication to Winlogon. If the authentication succeeds, the user's logon session begins and a set of logon credentials are saved for future reference.

Note In general, a developer who writes a custom GINA to accept specialized logon data, such as a smart card or retinal-scan data, must also write an authentication package responsible for processing that data and determining its authenticity.

For more information about Winlogon and GINAs, see Winlogon and GINA. For more information about authentication packages, see Creating Custom Authentication Packages.


Noninteractive Authentication

Noninteractive authentication can only be used after an interactive authentication has taken place. During noninteractive authentication, the user does not input logon data, instead, previously established credentials are used.

Noninteractive authentication is performed when an application uses the Security Support Provider Interface (SSPI) and a security package to establish a secure network connection. Noninteractive authentication is the mechanism at work when a user connects to multiple machines on a network without having to re-enter logon information for each machine. For example, if an application needs to open a secure folder on a remote machine and the application user is already interactively logged on to a domain account, the application does not require the user to supply logon data again. Instead, the application can request a noninteractive authentication by using SSPI to pass the previously established security information to a security package. The security package then uses LSA functions to check the credentials. The following diagram illustrates this procedure.

In the preceding diagram, the client application initiates a call to SSPI to request an authenticated network connection. SSPI passes the client's request to a security package for processing. The security package authenticates the user by calling the LSA and specifying an authentication package and providing the user's existing credentials.

The authentication result is passed from the authentication package, through the LSA, to the security package, and finally to SSPI. SSPI notifies the client application about the outcome of the request.

For more information about SSPI, see Security Support Provider Interface.


Authentication Packages

Authentication packages are contained in dynamic-link libraries. The LSA loads authentication packages using configuration information stored in the registry. Loading multiple authentication packages permits the LSA to support multiple logon processes and multiple security protocols.

Logon processes use authentication packages to analyze logon data. New logon processes are added to a system by adding a GINA to collect the required logon data and, if needed, by adding a new authentication package to analyze the data.

Security protocols are implemented by authentication packages. An authentication package analyses logon data by following the rules and procedures set forth in a security protocol.

Authentication packages are responsible for the following tasks:

  • Analyzing logon data to determine whether a security principal is allowed to logon to a system.
  • Establishing a new logon session and creating a unique logon identifier for the successfully authenticated principal.
  • Passing security information to the LSA for the principal's security token.

When a user attempts an interactive logon, the LSA calls an authentication package to determine whether to permit the user to log on. MSV1_0, for example, is an authentication package installed with Microsoft Windows NT/Windows 2000. The MSV1_0 package accepts a user name and a hashed password. It looks up the user name and hashed password combination in the Security Accounts Manager (SAM) database. If the logon data matches the stored credentials, the authentication package permits the logon to succeed.

After successfully authenticating a security principal's credentials, an authentication package is responsible for creating a new LSA logon session for the principal and allocating the logon identifier (LUID) that uniquely identifies the logon session. The authentication package may associate credential information with the logon session for subsequent authentication requests. For example, the MSV1_0 authentication package (provided by Microsoft) associates the user account name and a hash of the user's password with each logon session.

The authentication package also provides a set of security identifiers (SIDs) and other information appropriate for inclusion in the security token created by the LSA. This token will represent the principal's security context for access to Windows operations.

After a logon session is created and associated with a principal, subsequent authentication requests made on behalf of the principal are handled differently than the initial logon. The authentication package does not create a new logon session nor return information for creating a token. The authentication package can, however, associate supplemental credentials obtained during a subsequent authentication with the principal's existing logon session. Supplemental credentials are obtained when access to a requested resource requires information beyond the credentials established by the initial logon. For example, when a logged-on user requests a Novell network logon, a Novell-specific authentication package can be called and Novell-specific credentials can be authenticated and associated with the logon session. These credentials can be referenced by a Novell redirector (by way of the Novell authentication package) when the user accesses the Novell network.

The following topics discuss the various types of authentication packages:

  • Windows NT–Style Authentication Packages
  • Security Support Provider/Authentication Packages
  • Microsoft-Provided Authentication Packages
  • Subauthentication Packages


Windows NT-Style Authentication Packages

Platform SDK: Security

Windows NT–Style Authentication Packages

Windows NT–style authentication packages provide authentication services by implementing package-specific functionality for the LsaLogonUser and LsaCallAuthenticationPackage functions provided by the LSA.

MSV1_0 is an example of a Windows NT–style authentication package installed with Microsoft Windows NT/Windows 2000. The MSV1_0 package accepts a user name and a hashed password, which it looks up in the Security Accounts Manager (SAM) database. Depending on the results of the lookup, the MSV1_0 authentication package accepts or rejects the authentication attempt.

Custom development of Windows NT–style authentication packages is supported in Windows NT, beginning with Release 3.51. Windows NT–style packages were the only authentication packages available to support custom authentication prior to Windows 2000.

For a list of the support functions the LSA provides for use by Windows NT–style authentication packages that require system services, see LSA Functions called by Authentication Packages.

Windows NT–style authentication packages must implement a set of functions which are called by the LSA. For the complete list of functions, see Functions Implemented by Authentication Packages.


Security Support Provider/Authentication Packages

Windows 2000 supports authentication using security packages that function as both security support providers and as authentication packages. Security packages provide the logon process support services of a Windows NT–style authentication package and also provide authentication services to applications by implementing a set of functions that are mapped to the Security Support Provider Interface (SSPI).

A security package that functions as an authentication package and implements the functionality required by SSPI is called a security support provider/authentication package (SSP/AP).

For Information on… | See…
Security packages in windows 2000 | Security Packages
Developing custom SSP/APs | Custom Security Packages


Microsoft-Provided Authentication Packages

The following topics describe the authentication packages provided by Microsoft. These packages are installed with the more recent versions of the Microsoft® Windows NT/Windows® 2000 operating systems.

  • MSV1_0 Authentication Package, (Windows NT version 3.51 and later and Windows 2000)
  • Kerberos SSP/AP, (Windows 2000)


MSV1_0 Authentication Package

Microsoft provides the MSV1_0 authentication package for local machine logons that do not require custom authentication. The LSA calls the MSV1_0 authentication package to process logon data collected by the GINA for the Winlogon logon process. The MSV1_0 package checks the local security accounts manager (SAM) database to determine whether the logon data belongs to a valid security principal and then returns the result of the logon attempt to the LSA.

MSV1_0 also supports domain logons. MSV1_0 processes domain logons using pass-through authentication, as illustrated in the following diagram.

In pass-through authentication, the local instance of MSV1_0 uses the Netlogon service to call the instance of MSV1_0 running on the domain controller. The domain controller's instance of MSV1_0 then checks the SAM database of the domain controller and returns the logon result to the instance of MSV1_0 on the local machine. The local version of MSV1_0 forwards the logon result to the instance of the LSA on the local machine.

If the domain controller is not available, and the LSA contains cached credentials for the user, the local instance of MSV1_0 can authenticate the user using the cached logon data.

The MSV1_0 authentication package also supports subauthentication packages. A subauthentication package is a DLL that can replace part of the authentication and validation criteria used by the MSV1_0 authentication package. For more information, see Creating Subauthentication Packages.

MSV1_0 Credential Formats

The MSV1_0 authentication package defines a primary credentials key/string value pair. The primary credentials string holds the credentials derived from the data provided at logon time. It includes the user name and both case-sensitive and case-insensitive forms of the user's password.


Kerberos SSP/AP

Beginning with Windows 2000, Microsoft provides the Kerberos authentication package for logging on to a network; local logons are handled by MSV1_0. When a user logs on using a network account, by default, Kerberos attempts to connect to the Kerberos key distribution center (KDC) on the domain controller and obtain a ticket granting ticket (TGT) using the logon data supplied by the user.

If a Kerberos key distribution center is not available, Windows 2000 uses MSV1_0 and pass-through authentication as described in MSV1_0 Authentication Package.

The Kerberos authentication package supports version 5, revision 6 of the Kerberos Protocol. This protocol is based on Internet RFC 1510. For more information, see the IETF website, http://www.ietf.org/.

For more information about Kerberos, see Overview of the Kerberos Protocol.

Kerberos Credential Formats

The user credentials assigned by the Kerberos authentication package after a successful logon attempt are a ticket and a temporary encryption key, often called a session key. The ticket contains both an encrypted copy of the client's credentials and the session key.


Subauthentication Packages

The authentication packages provided with Windows support customization using subauthentication packages. A subauthentication package is a DLL that supplements or replaces part of the authentication and validation criteria used by the main authentication package. For example, a particular server might supply a subauthentication package that validates a user's password with a different algorithm, or specifies workstation restrictions in a different format.

For more information about subauthentication packages, see Creating Subauthentication Packages and the SubAuth sample installed with the Platform SDK.


Using LSA Authentication

The following topics describe how to use LSA Authentication to authenticate and log users on to the local system. They describe how to write custom authentication, security and subauthentication packages and how to access the LSA from a custom logon application, such as a custom GINA. This information is intended for developers creating applications that define new logon procedures or new security protocols.

Topic | Description
Supporting New Logon Protocols | Describes the custom components you can create to support new types of logon procedures.
Using LSA from a Logon Application | Explains the tasks a logon application such as the GINA can perform using LSA Authentication functions.
Creating Custom Authentication Packages | Describes how to create a custom authentication package to process user logon data from new devices, such as smart card readers and retina scanners.
Registering Custom Authentication Packages | Describes how to install packages.
Using LSA from an Authentication Package | Describes tasks a custom authentication package can perform using LSA.
Creating Subauthentication Packages | Describes how to create a custom subauthentication package that extends the functionality of the MSV1_0 authentication package.

For information on using standard user name and password data to log users on to a system, see the LogonUser topic in Client/Server Access Control Functions.


Supporting New Logon Protocols

You can add new types of logon devices to Windows, such as retina or fingerprint scanners. To support a new logon device and its accompanying authentication procedure, you must provide two components:

  • A GINA DLL
  • A custom authentication package

A custom Graphical Identification and Authentication DLL, or GINA, is the component that Winlogon calls to interact with the user and to collect logon data. For more information about how to write a custom GINA, see Winlogon and GINA.

A custom authentication package analyzes the logon data and determines whether to allow the user to log on to the system. The custom GINA specifies which authentication package will process the logon data. For more information, see Creating Custom Authentication Packages.


Creating Custom Authentication Packages

If you are supporting a system that defines a new type of logon procedure, such as retinal scanning or voice recognition, you must create a custom authentication package to analyze the new logon data and determine whether to accept the user's credentials. You can also create new authentication packages that use standard logon data but implement new security protocols.

The LSA calls the functions implemented by authentication packages when it receives an authentication service request from a logon application. When a user attempts to log on to the system, the authentication package must check the user's logon data against the credentials information on file. The authentication packages provided with Windows NT/Windows 2000 store this information either in the security accounts manager (SAM) database or in the Active Directory™ (depending on the version and configuration of the operating system).

Windows NT/Windows 2000 does not permit applications which are not part of the operating system to access existing credentials data directly; to do so would create a security hole. To work around this restriction, your custom authentication package must call MSV1_0 to access the user's authentication information. Your package calls MSV1_0 to perform the initial authentication and create a logon session. If the initial authentication is successful, your package then performs additional processing to support the new logon protocol or algorithm and sends an authentication result to the LSA. In essence, your custom authentication package wraps MSV1_0, extending its functionality to support the new logon protocol. This is illustrated in the following diagram.

Both the custom authentication package and MSV1_0 support the authentication package interface (see Functions Implemented by Authentication Packages). The LSA calls the authentication package interface functions in the custom package which, in turn, calls the functions in MSV1_0. The custom package must be able to pass the incoming logon information using data structures supported by MSV1_0. In addition, the structures passed to MSV1_0 should be allocated in the address space of the logon process, not the LSA address space.

The MSV1_0 package processes the authentication request and returns a result (and if successful, an LUID) to the custom package. The custom package can then perform additional authentication checks, such as deciding whether the scanned-in fingerprint matches the user account, and return an authentication success or failure back to the LSA. If your custom package revokes a logon allowed by MSV1_0, it must delete the logon session created by MSV1_0 by calling the DeleteLogonSession function.


Creating Subauthentication Packages

Some authentication packages including MSV1_0 (distributed with Windows NT 3.51 and later) and Kerberos (distributed with Windows 2000), support subauthentication packages. A subauthentication package is a DLL that replaces part of the authentication and validation criteria used by the authentication package. For example, a particular server might supply a subauthentication package that validates a user's password with a different algorithm or specifies workstation restrictions in a different format.

The interface a subauthentication package must implement depends on the authentication package it is written for. Subauthentication packages written for MSV1_0 must support the Msv1_0SubAuthenticationRoutine and Msv1_0SubAuthenticationFilter functions. Packages written for Kerberos must support the Msv1_0SubAuthenticationFilter function.

After you write a subauthentication package, you must add it to the registry before you can use it. The details of this registration are authentication package-specific, but typically you register the package by adding a registry key under the authentication package's key. For instructions on adding subauthentication procedures for MSV1_0 or Kerberos, see Registering Subauthentication Packages.

Additional details on creating a subauthentication package for the MSV1_0 authentication package shipped with Windows NT/Windows 2000 can be found in the SubAuth sample shipped with the Platform SDK.

For information about writing subauthentication packages for other authentication packages, see the documentation provided by the creator of the authentication package.


Registering Custom Authentication Packages

The following sections provide the information you need to register custom authentication and subauthentication packages.

  • Registering Windows NT–Style Authentication Packages
  • Registering Subauthentication Packages


Registering Windows NT-Style Authentication Packages

Platform SDK: Security

Registering Windows NT–Style Authentication Packages

Once you have built your custom authentication package, you must register it with the Local Security Authority. To do so, add the name of your authentication package to the following registry value:

\HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Authentication Packages

This registry entry contains a list of the names of installed authentication package DLLs (without the ".dll" extension). The list is a REG_MULTI_SZ data type, so there is a null character ('\0') between each package name. The next time the system starts up, the LSA will check this list and load your authentication package.

Typically, authentication package DLLs are stored in the %systemroot%/system32 directory. If you store the DLL elsewhere, you must specify the complete path to the DLL in the registry entry.


Registering Subauthentication Packages

Each Subauthentication DLL is assigned a DLL number in the range 0 through 255. The DLL number is used to associate the subsystem calling LsaLogonUser with the appropriate Subauthentication DLL. DLL number 0 is reserved for the Domain Controller SubAuthentication Filter. This DLL allows the package to do additional password or logon validation on a domain controller in addition to that normally done by the MSV1_0 or Kerberos packages. DLL numbers 1 through 127 are reserved Microsoft DLL numbers. Numbers 128 through 254 are available to independent software vendors. Software vendors can be assigned a DLL number by Microsoft by sending e-mail to subauth@microsoft.com. Registering a subauthentication package with Microsoft prevents conflict between package IDs when multiple subauthentication packages are installed on a system.

Microsoft will not assign the value of 255 for any subauthentication DLL. If you are developing a subauthentication DLL for use only within your company or facility, subauthentication number 255 is recommended. In this case, it is not necessary to obtain a subauthentication DLL number from Microsoft.

Once the you have a DLL number, you can register the DLL under the related authentication package's registry key.

The registry location for MSV1_0 subauthentication packages is:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0

The registry location for Kerberos subauthentication packages is:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos

If the required key does not exist, you must create it. Under that key, create a registry value named 'AuthN' where 'N' is the DLL number (for example, Auth255).

The 'AuthN' registry value holds REG_SZ data and must specify the name of the subauthentication package DLL. The DLL must be in the default DLL load path.

The authentication package loads the named DLL the first time the subauthentication package is requested.


Using LSA from a Logon Application

The LSA provides several functions that logon processes, such as custom GINAs, can call to authenticate users. They are described in detail in the Logon Functions reference section. In order to call these functions, your process must have the SeTcbPrivilege (trusted computing base) privilege.

Before requesting authentication services, your logon process must establish a connection to the LSA by calling LsaRegisterLogonProcess. This function establishes a connection to the LSA and returns a handle to it to be used in future calls to the LSA. When the connection to the LSA is no longer needed, call LsaDeregisterLogonProcess.

Once you have obtained a handle, you can call LsaLogonUser to attempt to log a user on to a system. During this call, you will need to specify the identifier of an authentication package to handle the logon request. If you know the name of the authentication package, you can look up its identifier by calling the LsaLookupAuthenticationPackage function.

If the user successfully logs on, the LSA returns a token containing the user's security information to your logon process. Your logon process can use this token to check access permissions, to create processes as the user, and for other operations requiring a token. For more information, see Access Control and the CreateProcessAsUser and AccessCheck functions documented in the Platform SDK.

In addition to the standard authentication functions, authentication packages can provide services that are package-specific. Your application can communicate with an authentication package to request a service by calling the LsaCallAuthenticationPackage function. The content and format of the input and output buffers used during a call to LsaCallAuthenticationPackage are specific to the authentication package; the LSA does not interpret the data but simply forwards it to the authentication package. For more information, see the LsaCallAuthenticationPackage reference page.

Note Typically, if you have written a custom GINA to handle non-standard logon data, you must also write a custom authentication package that can interpret that data. For more information, see Creating Custom Authentication Packages. To learn how to write a custom GINA, see Winlogon and GINA.


Using LSA from an Authentication Package

The LSA provides several functions that authentication packages can call to perform various tasks. These functions are described in the LSA Functions Called by Authentication Packages reference section. The following topics describe using the functions.

Topic | Description
Managing Logon Sessions | Describes creating, enumerating, and deleting logon sessions.
Managing User Credentials | Explains assigning, retrieving, and deleting credentials from a logon session.
Exchanging Data with Logon Applications | Describes creating and reading buffers in the logon process's address space.
Returning Data to LSA | Details creating buffers in the LSA process space.


Managing Logon Sessions

One of the responsibilities of an authentication package is to create a logon session whenever a user's initial logon request is authenticated. Your authentication package can do this by calling the CreateLogonSession function. This function returns a logon identifier (LUID) that uniquely identifies the session.

If your authentication package created extraneous logon sessions while authenticating the user, it should delete them by calling DeleteLogonSession. If the authentication fails, your authentication package should delete all related logon sessions. Logon sessions consume kernel memory, so it is important to delete unused or discarded logon sessions.

In Windows Whistler you can enumerate logon sessions and retrieve information about them. See the following topics for more information.

Topic | Description
Enumerating the Logon Sessions | Demonstrates using the LsaEnumerateLogonSessions function.
Retrieving Logon Session Information | Demonstrates using the LsaGetLogonSessionData function.


Enumerating Logon Sessions

[This is preliminary documentation and subject to change.]

The following example calls the LsaEnumerateLogonSessions function to retrieve a list of logon session identifiers, and the number of sessions on the system. This example requires Windows Whistler.

// The following constant may be defined by including NtStatus.h.

#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)

// The LSA authentication functions are available in Unicode only.

#define UNICODE

int _cdecl main(VOID)
{
  PLUID sessions;
  ULONG count;
  NTSTATUS retval;
  int i;

  retval = LsaEnumerateLogonSessions(&count, &sessions);

  if (retval != STATUS_SUCCESS) {
     wprintf (L"LsaEnumerate failed %lu\n",
       LsaNtStatusToWinError(retval));
    return 1;
  }
  wprintf (L"Enumerate sessions received %lu sessions.\n", count);
  // Process the array of session LUIDs…
  for (i =0;i < (int) count; i++) {
    GetSessionData (&sessions[i]);
  }
  // Free the array of session LUIDs allocated by the LSA.
  LsaFreeReturnBuffer(sessions);
  return 0;
}

Remarks

The GetSessionData function, called above, takes a pointer to a valid LUID logon session identifier, and displays detailed information about the session. This function is used for purposes of illustration only; GetSessionData is neither part of nor required by the LSA. For the implementation of this example function, see Retrieving Logon Session Information.

The LsaNtStatusToWinError function converts an NTSTATUS code to a Win32 error code.


Retrieving Logon Session Information

[This is preliminary documentation and subject to change.]

The following example calls the LsaGetLogonSessionData function to retrieve information about a logon session. This example requires Windows Whistler.

// The following constant may be defined by including NtStatus.h.
#define STATUS_SUCCESS  ((NTSTATUS)0x00000000L)
// The LSA authentication functions are available in Unicode only.
#define UNICODE

VOID GetSessionData (PLUID session)
{
  PSECURITY_LOGON_SESSION_DATA sessionData = NULL;
  NTSTATUS retval;
  WCHAR buffer[256];
  WCHAR *usBuffer;
  int usLength;

  // Check for a valid session.
  if (!session ) {
    wprintf(L"Error - Invalid logon session identifier.\n");
    return;
  }
  //Get the session information.
  retval = LsaGetLogonSessionData (session, &sessionData);
  if (retval != STATUS_SUCCESS) {
    // An error occurred. Tell the world.
    wprintf (L"LsaGetLogonSessionData failed %lu \n",
      LsaNtStatusToWinError(retval));
    // If session information was returned, free it.
    if (sessionData) {
      LsaFreeReturnBuffer(sessionData);
    }
    return;
  }
  // Check that there is sesssion data to parse.
  if (!sessionData) { // No data for session.
    wprintf(L"Invalid logon session data. \n");
    LsaFreeReturnBuffer(sessionData);
    return;
  }
  if (sessionData->UserName.Buffer != NULL) {
    // Get the user name.
    usBuffer = (sessionData->UserName).Buffer;
    usLength = (sessionData->UserName).Length;
    lstrcpyn (buffer, usBuffer, usLength);
    lstrcat (buffer,L"");
    wprintf (L"user %s was authenticated ",buffer);
  } else {
    wprintf (L"\nMissing user name.\n");
    LsaFreeReturnBuffer(sessionData);
    return;
  }
  if ((SECURITY_LOGON_TYPE) sessionData->LogonType == Interactive) {
    wprintf(L"interactively ");
  }
  if (sessionData->AuthenticationPackage.Buffer != NULL) {
    // Get the authentication package name.
    usBuffer = (sessionData->AuthenticationPackage).Buffer;
    usLength = (sessionData->AuthenticationPackage).Length;
    lstrcpyn (buffer, usBuffer, usLength);
    lstrcat (buffer,L"");
    wprintf(L"using %s ",buffer);
  } else {
    wprintf (L"\nMissing authentication package.");
    LsaFreeReturnBuffer(sessionData);
    return;
  }
  if (sessionData->LogonDomain.Buffer != NULL) {
    // Get the domain name.
    usBuffer = (sessionData->LogonDomain).Buffer;
    usLength = (sessionData->LogonDomain).Length;
    lstrcpyn (buffer, usBuffer, usLength);
    lstrcat (buffer,L"");
    wprintf(L"in the %s domain.\n",buffer);
  } else {
    wprintf (L"\nMissing authenticating domain information. ");
    LsaFreeReturnBuffer(sessionData);
    return;
  }
  // Free the memory returned by the LSA.
  LsaFreeReturnBuffer(sessionData);
  return;
}

Remarks

The GetSessionData function, defined above, takes a pointer to a valid LUID logon session identifier. For example code that demonstrates obtaining the valid logon session idenifiers available on a system, see Enumerating the Logon Sessions.

The LsaNtStatusToWinError function converts an NTSTATUS code to a Win32 error code.


Managing User Credentials

Credentials are authenticated logon data, such as a password and user name, that identifies a security principal. Associating a principal's authentication data with a unique logon identifier eliminates the need to reenter this data each time the principal accesses a new machine on the network. These credentials are available only to applications that run in kernel mode or that run in-process with the LSA. Because authentication packages and security packages are loaded by the LSA, they have access to this information.

Once a logon session has been created, your authentication package can associate credentials, such as a user name and password, with that session. To do so, call AddCredential.

Your authentication package can enumerate the credentials associated with a logon session by calling GetCredentials, and it can delete credentials from a logon session by calling DeleteCredential.

Windows 2000 SSP/AP security packages may call the UpdateCredentials function to notify other authentication packages when a principal's credentials have changed.

Note The LSA credential management functions, AddCredential, GetCredential, and DeleteCredential, are used only by older Windows NT–style authentication packages, such as MSV1_0. Newer packages, such as Kerberos, do not use them.


Exchanging Data with Logon Applications

Authentication package DLLs run in-process with the LSA. Logon applications, on the other hand, typically run in their own separate process. In order to handle interprocess data exchange between an authentication package and a logon application, an authentication package must be able to allocate and access memory in the logon application's process. The LSA provides several functions that authentication packages can use for this purpose.

An authentication package allocates a buffer in the calling client's process by calling AllocateClientBuffer. This is useful for returning variable sized parameter information. When the returned data is no longer needed, it can be freed either by the authentication package, using FreeClientBuffer, or by the logon application, using LsaFreeReturnBuffer. Note that only buffers allocated by AllocateClientBuffer should be freed by calling FreeClientBuffer.

The LSA also provides methods to copy data between the address space of the authentication package and the address space of the logon application. The authentication package copies data to the logon application's address space by calling CopyToClientBuffer. The target buffer can be, but does not have to be, a buffer allocated by the authentication package. To copy data from the logon application's address space, call CopyFromClientBuffer.


Returning Data to LSA

Information that is returned from an authentication package to the LSA must be allocated using the AllocateLsaHeap function. For example, the ProfileBuffer parameter returned from the authentication package to the LSA as part of the user logon process must be allocated with this function. Your authentication package is free to use this function to allocate buffers for internal use as well.

To deallocate buffers previously allocated by AllocateLsaHeap, call FreeLsaHeap.


LSA Authentication Reference

This reference contains detailed information about the Microsoft® LSA functions, structures, and data types. This information is divided into the following sections:

  • LSA Functions
  • LSA Structures
  • LSA Data Types


LSA Functions

The functions provided by the Local Security Authority and functions implemented by authentication packages, subauthentication packages, and security support provider/authentication packages (SSP/APs) are described in the following topics:

  • Logon Functions details the LSA functions called by a logon application, such as a custom GINA or security support provider. These functions are provided in a local procedure call (LPC) port interface, callable from both user and kernel mode.
  • Functions Implemented by Authentication Packages describes the functions that developers of custom authentication packages must implement. These functions are called by the LSA.
  • LSA Functions Called by Authentication Packages describes LSA functions that can be called by custom authentication packages. When the LSA initializes an authentication package, it passes a dispatch table containing these functions to the authentication package.
  • Subauthentication Functions describes the functions that subauthentication packages implement to supplement the logon authentication protocols used in the MSV1_0 and Kerberos authentication packages.
  • The following topics describe Windows 2000 custom security support provider/authentication packages. These security packages are also supported by and integrated with the LSA. These topics can be found in Custom Security Packages.
  • Functions Implemented by SSP/APs describes the functions that developers of custom SSP/APs must implement. This section includes all functions that execute in-process with the LSA.
  • LSA Functions Called by SSP/APs describes the functions that developers of custom SSP/APs can use to implement authentication and security support services.
  • Functions Implemented by User-Mode SSP/APs describes the functions that developers of custom SSP/APs must implement to support running in-process with applications. This section includes all functions that execute in-process with applications.
  • LSA Functions Called by User-Mode SSP/APs describes the functions that developers of custom SSP/APs can use to implement user-mode functions.


Logon Functions

The following LSA authentication functions authenticate and log on users, and they provide logon session information.

Function | Description
LsaCallAuthenticationPackage | Requests a package-specific service from an authentication package.
LsaConnectUntrusted | Establishes an untrusted connection to the LSA.
LsaDeregisterLogonProcess | Disconnects from the LSA and frees resources allocated to the caller's context.
LsaEnumerateLogonSessions | Retrieves LUIDs for existing logon sessions.
LsaFreeReturnBuffer | Frees memory allocated for a buffer returned to a caller.
LsaGetLogonSessionData | Retrieves information about a specified logon session.
LsaLogonUser | Authenticates user logon data against stored credentials. If successful, it creates a new logon session and returns a user token.
LsaLookupAuthenticationPackage | Obtains the unique identifier of an authentication package.
LsaRegisterLogonProcess | Establishes a trusted connection to the LSA.


LsaCallAuthenticationPackage

The LsaCallAuthenticationPackage function is used by a logon application to communicate with an authentication package. This function is typically used to access services provided by the authentication package.

NTSTATUS LsaCallAuthenticationPackage(
  HANDLE LsaHandle,
  ULONG AuthenticationPackage,
  PVOID ProtocolSubmitBuffer,
  ULONG SubmitBufferLength,
  PVOID* ProtocolReturnBuffer,
  PULONG ReturnBufferLength,
  PNTSTATUS ProtocolStatus
);

Parameters

LsaHandle
[in] Handle obtained from a previous call to LsaRegisterLogonProcess or LsaConnectUntrusted.
AuthenticationPackage
[in] Supplies the identifier of the authentication package. This value is obtained by calling LsaLookupAuthenticationPackage.
ProtocolSubmitBuffer
[in] An authentication package–specific message buffer passed to the authentication package.

The following table lists the buffers used with the MSV1_0 and Kerberos authentication packages.
Input buffer Authentication
package
Use
MSV1_0_LM20_CHALLENGE_REQUEST | MSV1_0 | Processing the first half of an NTLM version 2.0 protocol logon. The structure returned in ProtocolReturnBuffer after this call is input to LsaLogonUser to complete the logon.
MSV1_0_CHANGEPASSWORD_REQUEST | MSV1_0 | Changing an account password.
MSV1_0_SUBAUTH_REQUEST | MSV1_0 | Passing a buffer to an authentication package using subauthentication.
KERB_PURGE_TKT_CACHE_REQUEST | Kerberos | Purging entries from the ticket cache.
KERB_QUERY_TKT_CACHE_REQUEST | Kerberos | Retrieving information about all of the tickets cached for a user logon session.
KERB_RETRIEVE_TKT_REQUEST | Kerberos | Retrieving a ticket. The ticket may be retrieved from the cache of the specified user logon session or may be a new ticket.

For information about the format and content of this buffer with other authentication packages, see the documentation for those packages.

SubmitBufferLength
[in] Indicates the length of the ProtocolSubmitBuffer buffer, in bytes.
ProtocolReturnBuffer
[out] Pointer that receives the address of the buffer returned by the authentication package.

The following table presents information on buffers returned by the MSV1_0 and Kerberos authentication packages.
Output buffer Authentication
package 		Buffer contents
MSV1_0_LM20_CHALLENGE_RESPONSE | MSV1_0 | Buffer to be used as the input buffer in a call to LsaLogonUser to complete the logon. This is done in the first half of an NTLM version 2.0 protocol logon.
MSV1_0_CHANGEPASSWORD_RESPONSE | MSV1_0 | Response from a request to change an account password.
MSV1_0_SUBAUTH_RESPONSE | MSV1_0 | Buffer from an authentication package using subauthentication.
KERB_QUERY_TKT_CACHE_RESPONSE | Kerberos | Information about all of the cached tickets for the specified user logon session.
KERB_RETRIEVE_TKT_RESPONSE | Kerberos | Response to a request for a ticket. The ticket may be retrieved from the cache of the specified user logon session or may be a new ticket.

For information about the format and content of this buffer with other authentication packages, see the documentation for those packages.

This buffer is allocated by this function and must be freed using LsaFreeReturnBuffer when no longer needed.

ReturnBufferLength
[out] Pointer to a ULONG that receives the length of the returned buffer, in bytes.
ProtocolStatus
[out] If the function succeeds, this parameter receives a pointer to an NSTATUS code which indicates the completion status of the authentication package.

The LsaNtStatusToWinError function converts an NTSTATUS code to a Win32 error code.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS. Check the ProtocolStatus parameter to obtain the status returned by the authentication package.

If the function fails, the return value is an NTSTATUS code. The following are possible error codes.

Error code | Description
STATUS_QUOTA_EXCEEDED | The call could not be completed because the client's memory quota is not sufficient to allocate the return buffer.
STATUS_NO_SUCH_PACKAGE | The specified authentication package is not recognized by the LSA.

For more information, see Standard LSA Function Return Values.

The LsaNtStatusToWinError function converts an NTSTATUS code to a Win32 error code.

Remarks

Your logon application can call LsaCallAuthenticationPackage to communicate with an authentication package. There are several reasons why your application may do this:

  • To implement multi-message authentication protocols, such as the NTLM Challenge-Response protocol.
  • To pass state change information to the authentication package. For example, the NTLM might notify the MSV1_0 package that a previously unreachable domain controller is now reachable. The authentication package would then re-logon any users logged on to that domain controller.

Typically, this function is used to exchange information with a custom authentication package. You do not need to call this function if your application is using one of the authentication packages supplied with Windows NT/Windows 2000 (MSV1_0 or Kerberos).

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Ntsecapi.h.
Library: Use Secur32.lib.

See Also

LsaFreeReturnBuffer, LsaLookupAuthenticationPackage, LsaNtStatusToWinError


LsaConnectUntrusted

The LsaConnectUntrusted function establishes an untrusted connection to the LSA server.

NTSTATUS LsaConnectUntrusted(
  PHANDLE LsaHandle
);

Parameters

LsaHandle
[out] Pointer to a handle that receives the connection handle, which must be provided in future authentication services.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code. For more information, see Standard LSA Function Return Values.

The LsaNtStatusToWinError function converts an NTSTATUS code to a Win32 error code.

Remarks

LsaConnectUntrusted returns a handle to an untrusted connection; it does not verify any information about the caller. The handle should be closed using the LsaDeregisterLogonProcess function.

If your application simply needs to query information from authentication packages, you can use the handle returned by this function in calls to LsaCallAuthenticationPackage and LsaLookupAuthenticationPackage.

Applications with the SeTcbPrivilege privilege may create a trusted connection by calling LsaRegisterLogonProcess.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.
Library: Use Secur32.lib.

See Also

LsaCallAuthenticationPackage, LsaDeregisterLogonProcess, LsaLookupAuthenticationPackage, LsaRegisterLogonProcess


LsaDeregisterLogonProcess

The LsaDeregisterLogonProcess function deletes the caller's logon application context and closes the connection to the LSA server.

NTSTATUS LsaDeregisterLogonProcess(
  HANDLE LsaHandle
);

Parameters

LsaHandle
[in] Handle obtained from a LsaRegisterLogonProcess or LsaConnectUntrusted call.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code. For more information, see Standard LSA Function Return Values.

The LsaNtStatusToWinError function converts an NTSTATUS code to a Win32 error code.

Remarks

If your logon application references the connection handle after calling the LsaDeregisterLogonProcess function, unexpected behavior can result.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Ntsecapi.h.
Library: Use Secur32.lib.

See Also

LsaConnectUntrusted, LsaRegisterLogonProcess


LsaEnumerateLogonSessions

[This is preliminary documentation and subject to change.]

The LsaEnumerateLogonSessions function retrieves the set of existing logon session identifiers (LUIDs) and the number of sessions.

NTSTATUS NTAPI LsaEnumerateLogonSessions(
  PULONG  LogonSessionCount,
  PLUID* LogonSessionList
);

Parameters

LogonSessionCount
[out] Pointer to long integer that receives the number of elements returned in the array returned in LogonSessionList parameter.
LogonSessionList
[out] Address of a pointer to a LUID. The pointer receives the first element of an array of logon session identifiers. The memory used by the array is allocated by the LSA. When the array is no longer needed, call the LSAFreeReturnBuffer function to free it.

Return values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code indicating the reason.

Remarks

To retrieve information about the logon sessions returned by LsaEnumerateLogonSessions, call the LsaGetLogonSessionData function.

For an example that demonstrates using this function, see Enumerating Logon Sessions.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Ntsecapi.h.
Library: Use Secur32.lib.


LsaFreeReturnBuffer

The LsaFreeReturnBuffer function frees the memory used by a buffer previously allocated by the LSA.

NTSTATUS LsaFreeReturnBuffer(
  PVOID Buffer
);

Parameters

Buffer
[in] Pointer to the buffer to be freed.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code. For more information, see Standard LSA Function Return Values.

The LsaNtStatusToWinError function converts an NTSTATUS code to a Win32 error code.

Remarks

Some of the LSA authentication functions allocate memory buffers to hold returned information, for example, LsaLogonUser and LsaCallAuthenticationPackage. Your application should call LsaFreeReturnBuffer to free these buffers when they are no longer needed.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Ntsecapi.h.
Library: Use Secur32.lib.

See Also

LsaLogonUser, LsaCallAuthenticationPackage


LsaGetLogonSessionData

[This is preliminary documentation and subject to change.]

The LsaGetLogonSessionData function retrieves information about a specified logon session. To retrieve information about a logon session, the caller must be the owner of the session or a local system administrator.

NTSTATUS NTAPI LsaGetLogonSessionData(
  PLUID LogonId,
  PSECURITY_LOGON_SESSION_DATA* ppLogonSessionData
);

Parameters

LogonId
[in] Specifies a pointer to a LUID that identifies the logon session whose information will be retrieved. For information on valid values for this parameter, see Remarks.
ppLogonSessionData
[out] Address of a pointer to a SECURITY_LOGON_SESSION_DATA structure containing information on the logon session specified by LogonId. This structure is allocated by the LSA. When the information is no longer needed, call the LSAFreeReturnBuffer function to free the memory used by this structure.

Return values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code indicating the reason.

Remarks

To obtain valid logon session identifiers that may be passed to this function's LogonId parameter, call the LsaEnumerateLogonSessions function.

For an example that demonstrates using this function, see Retrieving Logon Session Information.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Ntsecapi.h.
Library: Use Secur32.lib.


LsaLogonUser

The LsaLogonUser function authenticates a security principal's logon data using stored credentials information. If the authentication is successful, this function creates a new logon session and returns a user token.

NTSTATUS LsaLogonUser(
  HANDLE LsaHandle,
  PLSA_STRING OriginName,
  SECURITY_LOGON_TYPE LogonType,
  ULONG AuthenticationPackage,
  PVOID AuthenticationInformation,
  ULONG AuthenticationInformationLength,
  PTOKEN_GROUPS LocalGroups,
  PTOKEN_SOURCE SourceContext,
  PVOID* ProfileBuffer,
  PULONG ProfileBufferLength,
  PLUID LogonId,
  PHANDLE Token,
  PQUOTA_LIMITS Quotas,
  PNTSTATUS SubStatus
);

Parameters

LsaHandle
[in] Handle obtained from a previous call to LsaRegisterLogonProcess.
OriginName
[in] String identifying the origin of the logon attempt. See Remarks.
LogonType
[in] A SECURITY_LOGON_TYPE enumeration value specifying the type of logon requested. If LogonType is Interactive or Batch, a primary token is generated to represent the new user. If LogonType is Network, an impersonation token is generated.
AuthenticationPackage
[in] Identifier of the authentication package to use for the authentication. You can obtain this value by calling LsaLookupAuthenticationPackage.
AuthenticationInformation
[in] Pointer to an input buffer containing authentication information, such as user name and password. The format and content of this buffer are determined by the authentication package.

The following table describes the input buffer structures for the MSV1_0 and Kerberos authentication packages.
Buffer structure Authentication
package 		Use
MSV1_0_INTERACTIVE_LOGON | MSV1_0 | Authenticating an interactive user logon.
KERB_TICKET_LOGON | Kerberos | Authenticating a user on initial network logon or disconnect.
KERB_TICKET_UNLOCK_LOGON | Kerberos | Authenticating a user on ticket refresh, a variation of the normal workstation unlock logon.
MSV1_0_LM20_LOGON MSV1_0 Processing the second half of an NTLM 2.0 protocol logon. The first half of this type of logon is performed by calling LsaCallAuthenticationPackage with the MsV1_0Lm20ChallengeRequest message. For more information, see the description of MsV1_0Lm20ChallengeRequest in MSV1_0_PROTOCOL_MESSAGE_TYPE.

This type of logon can use a subauthentication package.
MSV1_0_SUBAUTH_LOGON | MSV1_0 | Authenticating a user with subauthentication.

For more information about the buffer used by other authentication packages, see the documentation for those authentication packages.

AuthenticationInformationLength
[in] Specifies the length of the AuthenticationInformation buffer, in bytes.
LocalGroups
[in] Optional. Specifies a list of additional group identifiers to add to the authenticated user's token. These group identifiers will be added along with the default group WORLD, and the logon type group (Interactive, Batch, or Network), which are automatically included in every user token.
SourceContext
[in] A TOKEN_SOURCE structure identifying the source component—for example, the session manager—and the context that may be useful to that component. This information is included in the user token and may be retrieved by calling GetTokenInformation.
ProfileBuffer
[out] Pointer to a void pointer that receives the address of an output buffer returning authentication information such as the logon shell and home directory.

The following table describes the output buffer structures for the MSV1_0 and Kerberos authentication packages.
Buffer structure Authentication
package 		Contents
MSV1_0_INTERACTIVE_PROFILE | MSV1_0 | An interactive user's logon profile.
KERB_TICKET_PROFILE | Kerberos | Logon, disconnect, and ticket refresh authentication output.
MSV1_0_LM20_LOGON | MSV1_0 | Output when processing the second half of a NTLM 2.0 protocol logon.
MSV1_0_LM20_LOGON_PROFILE | MSV1_0 | Output when using authentication with subauthentication.

For more information about the buffer used by other authentication packages, see the documentation for that authentication package.

The calling application must free this buffer by calling LsaFreeReturnBuffer when it is no longer needed.

ProfileBufferLength
[out] Pointer to a ULONG that receives the length in bytes of the returned profile buffer.
LogonId
[out] Pointer to a buffer which receives an LUID that uniquely identifies the logon session. This LUID is assigned by the domain controller that authenticated the logon information.
Token
[out] Pointer to a handle that receives the new user token created for this session.
Quotas
[out] When a primary token is returned, this parameter receives a QUOTA_LIMITS structure that contains the process quota limits assigned to the newly logged on user's initial process.
SubStatus
[out] If the logon failed due to account restrictions, this parameter receives information about why the logon failed. This value is set only if the user's account information is valid, but the logon is rejected.

The following table lists the valid SubStatus values for the MSV1_0 authentication package.
Value | Description
STATUS_INVALID_LOGON_HOURS | The user account has time restrictions and cannot be used to log on at this time.
STATUS_INVALID_WORKSTATION | The user account has workstation restrictions and cannot be used to log on from the current workstation.
STATUS_PASSWORD_EXPIRED | The user account's password has expired.
STATUS_ACCOUNT_DISABLED | The user account is currently disabled and cannot be used to log on.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code. The following are possible error codes.

Error code | Description
STATUS_QUOTA_EXCEEDED | The caller's memory quota is insufficient to allocate the output buffer returned by the authentication package.
STATUS_ACCOUNT_RESTRICTION | The user account and password are legitimate, but the user account has some restriction preventing logon at this time. For more information, see the value stored in the SubStatus parameter.
STATUS_BAD_VALIDATION_CLASS | The authentication information provided is not recognized by the authentication package.
STATUS_LOGON_FAILURE | The logon attempt failed. The reason for the failure is not specified, but typical reasons include misspelled user names and misspelled passwords.
STATUS_NO_LOGON_SERVERS | No domain controllers are available to service the authentication request.
STATUS_NO_SUCH_PACKAGE | The specified authentication package is not recognized by the LSA.

For more information, see Standard LSA Function Return Values.

The LsaNtStatusToWinError function converts an NTSTATUS code to a Win32 error code.

Remarks

The OriginName parameter should specify meaningful information. For example it might contain "TTY1" to indicate terminal one or "NTLM - remote node JAZZ" to indicate a network logon using NTLM through a remote node called "JAZZ."

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Ntsecapi.h.
Library: Use Secur32.lib.

See Also

LsaCallAuthenticationPackage, LsaFreeReturnBuffer, LsaLookupAuthenticationPackage


LsaLookupAuthenticationPackage

The LsaLookupAuthenticationPackage function obtains the unique identifier of an authentication package.

NTSTATUS LsaLookupAuthenticationPackage(
  HANDLE LsaHandle,
  PLSA_STRING PackageName,
  PULONG AuthenticationPackage
);

Parameters

LsaHandle
[in] Handle obtained from a previous call to LsaRegisterLogonProcess or LsaConnectUntrusted.
PackageName
[in] Pointer to an LSA_STRING structure that specifies the name of the authentication package. The package name must not exceed 127 bytes in length. The following table lists the names of the Microsoft-provided authentication packages.
String value | Description
MSV1_0_PACKAGE_NAME | ANSI version of the MSV1_0 authentication package name. This package is used with Windows 95 and Windows 98.
MSV1_0_PACKAGE_NAMEW | UNICODE version of the MSV1.0 authentication package name. This package is used with Windows NT and Windows 2000.
MICROSOFT_KERBEROS_NAME_A | ANSI version of the Kerberos authentication package name. Used with Windows 95 and Windows 98.
MICROSOFT_KERBEROS_NAME_W | UNICODE version of the Kerberos authentication package name. Used with Windows NT and Windows 2000.
MICROSOFT_KERBEROS_NAME | Selects the correct version of the Kerberos authentication package name for Windows 95, Windows 98, Windows NT, or Windows 2000.

AuthenticationPackage
[out] Pointer to a ULONG that receives the authentication package identifier.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code. The following are possible error codes.

Error code | Description
STATUS_NO_SUCH_PACKAGE | The specified authentication package is unknown to the LSA.
STATUS_NAME_TOO_LONG | The authentication package name exceeds 127 bytes.

For more information, see Standard LSA Function Return Values.

The LsaNtStatusToWinError function converts an NTSTATUS code to a Win32 error code.

Remarks

The authentication package identifier is used in calls to authentication functions such as LsaLogonUser and LsaCallAuthenticationPackage.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Ntsecapi.h.
Library: Use Secur32.lib.

See Also

LsaLogonUser, LsaCallAuthenticationPackage


LsaRegisterLogonProcess

The LsaRegisterLogonProcess function establishes a connection to the LSA server and verifies that the caller is a logon application.

NTSTATUS LsaRegisterLogonProcess(
  PLSA_STRING LogonProcessName,
  PHANDLE LsaHandle,
  PLSA_OPERATIONAL_MODE SecurityMode
);

Parameters

LogonProcessName
[in] Pointer to an LSA_STRING structure identifying the logon application. This should be a printable name suitable for display to administrators. For example, the windows logon application might use the name: "User32LogonProcess" This name is used by the LSA during auditing. LsaRegisterLogonProcess does not check whether the name is already in use.

This string must not exceed 127 bytes.

LsaHandle
[out] Pointer that receives a handle used in future authentication function calls.
SecurityMode
[out] The value returned is not meaningful and should be ignored.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code. The following are possible error codes.

Error code | Description
STATUS_PRIVILEGE_NOT_HELD | The caller does not have the SeTcbPrivilege privilege, which is required to call this function. You can set this privilege either using Windows NT User Manager or by calling LsaAddAccountRights.
STATUS_NAME_TOO_LONG | The specified logon process name exceeds 127 bytes.

For more information, see Standard LSA Function Return Values.

The LsaNtStatusToWinError function converts an NTSTATUS code to a Win32 error code.

Remarks

This function must be called before a logon process may use any other logon authentication functions provided by the LSA.

LsaRegisterLogonProcess verifies that the application making the function call is a logon process by checking that it has the SeTcbPrivilege privilege set. It also opens the application's process for PROCESS_DUP_HANDLE access in anticipation of future LSA authentication calls. For more information, see DuplicateHandle.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Ntsecapi.h.
Library: Use Secur32.lib.

See Also

LsaDeregisterLogonProcess, LsaAddAccountRights, LsaConnectUntrusted


Functions Implemented by Authentication Packages

Custom authentication packages must implement these functions, which are called by the LSA. These functions are implemented by the MSV1_0 and Kerberos authentication packages provided by Microsoft.

Function | Description
LsaApCallPackage | Called when the authentication package's identifier has been specified in a call to LsaCallAuthenticationPackage by an application using a trusted connection. This function provides a way for logon applications to communicate directly with authentication packages.
LsaApCallPackagePassthrough | Called when the authentication package's identifier has been specified in a call to LsaCallAuthenticationPackage for a passthrough logon request.
LsaApCallPackageUntrusted | Called when the authentication package's identifier has been specified in a call to LsaCallAuthenticationPackage by an application using an untrusted connection. This function is used for communicating with processes that do not have the SeTcbPrivilege privilege.
LsaApInitializePackage | Called during system initialization to permit the authentication package to perform initialization tasks.
LsaApLogonTerminated | Called when a logon session ends to permit the authentication package to free any resources allocated for the logon session.
LsaApLogonUser | Called when the authentication package has been specified in a call to LsaLogonUser. This function authenticates a security principal's logon data.
LsaApLogonUserEx | Identical to LsaApLogonUser except that it returns the workstation name for audit purposes. An authentication package can implement LsaApLogonUser, LsaApLogonUserEx, or LsaApLogonUserEx2. It does not need to implement them all.
LsaApLogonUserEx2 | Identical to LsaApLogonUserEx except that it returns the security principal's primary and supplemental credentials. An authentication package can implement LsaApLogonUser, LsaApLogonUserEx, or LsaApLogonUserEx2. It does not need to implement them all.


LsaApCallPackage

The LsaApCallPackage authentication package function is called by the LSA when a logon application with a trusted connection to the LSA calls the LsaCallAuthenticationPackage function and specifies the authentication package's identifier.

LsaApCallPackage is called for logon applications only; calls from applications that do not have the SeTcbPrivilege privilege are routed to the specified authentication package's LsaApCallPackageUntrusted function instead.

NTSTATUS LsaApCallPackage(
  PLSA_CLIENT_REQUEST ClientRequest,
  PVOID ProtocolSubmitBuffer,
  PVOID ClientBufferBase,
  ULONG SubmitBufferLength,
  PVOID* ProtocolReturnBuffer,
  PULONG ReturnBufferLength,
  PNTSTATUS ProtocolStatus
);

Parameters

ClientRequest
[in] Pointer to an opaque LSA_CLIENT_REQUEST buffer representing the LSA client's request.
ProtocolSubmitBuffer
[in] Supplies a protocol message specific to the authentication package.
ClientBufferBase
[in] Provides the address within the client process of the protocol message. This may be necessary to remap any pointers within the ProtocolSubmitBuffer buffer.
SubmitBufferLength
[in] Specifies the length of the ProtocolSubmitBuffer buffer, in bytes.
ProtocolReturnBuffer
[out] Returns the address of the output buffer within the client process. The authentication package is responsible for calling the AllocateClientBuffer function to allocate the buffer within the client process. The contents of this buffer are specific to the authentication package.
ReturnBufferLength
[out] Pointer to a ULONG that returns the length of the ProtocolReturnBuffer buffer, in bytes.
ProtocolStatus
[out] Pointer to an NTSTATUS value. If the function returns STATUS_SUCCESS, ProtocolStatus returns a completion status set by the authentication package. ProtocolStatus values are authentication package-specific.

More information about NTSTATUS codes can be found in the subauth.h file shipped with the Platform SDK.

Return Values

If the function succeeds, return STATUS_SUCCESS. This return value indicates that the authentication package attempted to provide the requested service; use the ProtocolStatus parameter to return the completion status of the service request.

If the authentication package could not process the request and therefore did not attempt to provide the requested service, return an NTSTATUS code indicating the problem. This code can be the following value or one of the standard LSA function return values.

Value | Description
STATUS_NOT_ENOUGH_QUOTA | The client's memory quota is insufficient to allocate the output buffer.

Remarks

This function must be implemented by authentication packages.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Ntsecpkg.h.

See Also

AllocateClientBuffer, LsaCallAuthenticationPackage, LsaApCallPackageUntrusted


LsaApCallPackagePassthrough

The LsaApCallPackagePassthrough function is the dispatch function for passthrough logon requests sent to the LsaCallAuthenticationPackage function.

NTSTATUS LsaApCallPackagePassthrough (
  PLSA_CLIENT_REQUEST ClientRequest,
  PVOID ProtocolSubmitBuffer,
  PVOID ClientBufferBase,
  ULONG SubmitBufferLength,
  PVOID* ProtocolReturnBuffer,
  PULONG ReturnBufferLength,
  PNTSTATUS ProtocolStatus
);

Parameters

ClientRequest
[in] Pointer to an opaque LSA_CLIENT_REQUEST buffer representing the LSA client's request.
ProtocolSubmitBuffer
[in] Supplies a protocol-specific message to the authentication package.
ClientBufferBase
[in] Provides the address within the client process of the protocol message. This may be necessary to remap pointers within the ProtocolSubmitBuffer.
SubmitBufferLength
[in] Specifies the length of the ProtocolSubmitBuffer buffer, in bytes.
ProtocolReturnBuffer
[out] Returns the address of the output buffer in the client process. The authentication package is responsible for calling the AllocateClientBuffer function to allocate the buffer in the client process. The contents of this buffer are specific to the authentication package.
ReturnBufferLength
[out] Pointer to a ULONG that returns the length of the ProtocolReturnBuffer buffer, in bytes.
ProtocolStatus
[out] Pointer to an NTSTATUS value. If the function returns STATUS_SUCCESS, Protocol Status returns a completion status set by the authentication package. ProtocolStatus values are authentication package-specific.

More information about NTSTATUS codes can be found in the subauth.h file shipped with the Platform SDK.

Return Values

If the function succeeds, return STATUS_SUCCESS. This return value indicates that the authentication package attempted to provide the requested service; use the ProtocolStatus parameter to return the completion status of the service request.

If the authentication package could not process the request and therefore did not attempt to provide the requested service, return an NTSTATUS code indicating the problem. This code can be the following value or one of the standard LSA function return values.

Value | Description
STATUS_NOT_ENOUGH_QUOTA | The client's memory quota is insufficient to allocate the output buffer.

Remarks

This function must be implemented by authentication packages.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

AllocateClientBuffer, LsaCallAuthenticationPackage


LsaApCallPackageUntrusted

The LsaApCallPackageUntrusted authentication package function is called by the LSA when an application with an untrusted connection to the LSA calls the LsaCallAuthenticationPackage function and specifies the authentication package's identifier.

Calls from applications that have the SeTcbPrivilege privilege and a trusted connection are routed to LsaApCallPackage instead.

NTSTATUS LsaApCallPackageUntrusted(
  PLSA_CLIENT_REQUEST ClientRequest,
  PVOID ProtocolSubmitBuffer,
  PVOID ClientBufferBase,
  ULONG SubmitBufferLength,
  PVOID* ProtocolReturnBuffer,
  PULONG ReturnBufferLength,
  PNTSTATUS ProtocolStatus
);

Parameters

ClientRequest
[in] Pointer to an opaque LSA_CLIENT_REQUEST buffer representing the LSA client's request.
ProtocolSubmitBuffer
[in] Pointer to a protocol message specific to the authentication package.
ClientBufferBase
[in] Provides the address within the client process of the protocol message. This may be necessary to remap any pointers within the protocol message buffer.
SubmitBufferLength
[in] Indicates the length of the ProtocolSubmitBuffer buffer, in bytes.
[out] ProtocolReturnBuffer
[out] Returns the address of the output buffer within the client process. The authentication package is responsible for calling the AllocateClientBuffer function to allocate the buffer within the client process. The contents of this buffer are specific to the authentication package.
ReturnBufferLength
[out] Pointer to a ULONG that returns the length of the ProtocolReturnBuffer buffer, in bytes.
ProtocolStatus
[out] Pointer to an NTSTATUS value. If the function returns STATUS_SUCCESS, ProtocolStatus is set to the completion status returned by the specified authentication package. Status values returned are authentication package-specific.

More information about NTSTATUS codes can be found in the subauth.h file shipped with the Platform SDK.

Return Values

If the function succeeds, return STATUS_SUCCESS. This return value indicates that the authentication package attempted to provide the requested service; use the ProtocolStatus parameter to return the completion status of the service request.

If the authentication package could not process the request and therefore did not attempt to provide the requested service, return an NTSTATUS code indicating the problem. This code can be the following value or one of the

standard LSA function return values.

Value | Description
STATUS_NOT_ENOUGH_QUOTA | The client's memory quota is insufficient to allocate the output buffer.

Remarks

This function is similar to LsaApCallPackage but handles untrusted connections. An application should determine what subset of the functionality implemented in LsaApCallPackage should be available to untrusted connections, and it should implement that subset in LsaApCallPackageUntrusted.

For information on establishing an untrusted connection, see LsaConnectUntrusted.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecpkg.h.

See Also

AllocateClientBuffer, LsaCallAuthenticationPackage, LsaApCallPackage


LsaApInitializePackage

The LsaApInitializePackage function is called once by the LSA during system initialization to provide the authentication package a chance to initialize itself.

NTSTATUS LsaApInitializePackage(
  ULONG AuthenticationPackageId,
  PLSA_DISPATCH_TABLE LsaDispatchTable,
  PLSA_STRING Database OPTIONAL,
  PLSA_STRING Confidentiality OPTIONAL,
  PLSA_STRING* AuthenticationPackageName
);

Parameters

AuthenticationPackageId
[in] The identifier the LSA has assigned to the authentication package.
LsaDispatchTable
[in] Pointer to an LSA_DISPATCH_TABLE structure that contains the addresses of LSA functions that can be called by authentication packages. Your custom authentication package should save this information if it requires any of the functions described in LSA Functions Called by Authentication Packages.
Database
[in] This parameter is not used; it is NULL.
Confidentiality
[in] This parameter is not used; it is NULL.
AuthenticationPackageName
[out] Pointer to a pointer to an LSA_STRING structure that receives the name of the authentication package. The authentication package is responsible for allocating the structure and the buffer that contains this string (using the AllocateLsaHeap function) and returning the address of the structure in this parameter. The buffer will be freed by the LSA when it is no longer needed.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS error code. For more information, see Standard LSA Function Return Values.

Remarks

This function must be implemented by authentication packages.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Ntsecpkg.h.

See Also

AllocateLsaHeap


LsaApLogonTerminated

The LsaApLogonTerminated function is used to notify an authentication package when a logon session terminates. A logon session terminates when the last token referencing the logon session is deleted.

VOID
LsaApLogonTerminated(
  PLUID LogonId
);

Parameters

LogonId
[in] Pointer to the logon ID of the session that just ended.

Return Values

This function does not return a value.

Remarks

When LsaApLogonTerminated is called, an authentication package should release any resources held for the logon ID, such as credentials created within the LSA. The LSA does not automatically perform this cleanup.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


LsaApLogonUser

The LsaApLogonUser function authenticates a user's logon credentials. This function is called only for a user's initial logon. Subsequent authentication requests must use LsaCallAuthenticationPackage.

If LsaApLogonUser succeeds, it creates a logon session. It also returns information used to build the token representing the newly logged-on user.

NTSTATUS LsaApLogonUser(
  PLSA_CLIENT_REQUEST ClientRequest,
  SECURITY_LOGON_TYPE LogonType,
  PVOID AuthenticationInformation,
  PVOID ClientAuthenticationBase,
  ULONG AuthenticationInformationLength,
  PVOID* ProfileBuffer,
  PULONG ProfileBufferLength,
  PLUID LogonId,
  PNTSTATUS SubStatus,
  PLSA_TOKEN_INFORMATION_TYPE TokenInformationType,
  PVOID* TokenInformation,
  PLSA_UNICODE_STRING* AccountName,
  PLSA_UNICODE_STRING* AuthenticatingAuthority
);

Parameters

ClientRequest
[in] Pointer to an opaque LSA_CLIENT_REQUEST buffer that represents the LSA client's request. Your authentication package can pass this value into AllocateClientBuffer and FreeClientBuffer in order to identify the client process in which memory should be allocated or freed.
LogonType
[in] A SECURITY_LOGON_TYPE value identifying the type of logon requested.
AuthenticationInformation
[in] Supplies the authentication information specific to the authentication package. The LSA will free this buffer. This is the same input buffer passed into LsaLogonUser.
ClientAuthenticationBase
[in] Provides the address of the authentication information within the client process. This may be necessary to remap any pointers within the AuthenticationInformation buffer.
AuthenticationInformationLength
[in] Indicates the length, in bytes, of the AuthenticationInformation buffer.
ProfileBuffer
[out] Pointer that receives the address of the profile buffer in the client process. The authentication package is responsible for allocating the ProfileBuffer buffer within the client process by calling the AllocateClientBuffer function. However, if the LSA subsequently encounters an error that prevents a successful logon, the LSA will free this buffer.

The contents of this buffer are determined by the authentication package. The LSA does not alter this buffer; it simply returns the value to the LsaLogonUser function.

ProfileBufferLength
[out] Pointer to a ULONG that receives the length of the ProfileBuffer buffer, in bytes.
LogonId
[out] Pointer to an LUID that receives the new logon ID that uniquely identifies this logon session. The authentication package is responsible for allocating this LUID, and creating the logon session for this logon.
SubStatus
[out] Pointer to an NTSTATUS that receives the reason for failures due to account restrictions. The values returned in SubStatus are determined by the authentication package.

The following table lists the SubStatus values for the MSV1_0 and Kerberos authentication packages.
Value | Description
STATUS_INVALID_LOGON_HOURS | The user account has time restrictions; it cannot be used to log on at this time.
STATUS_INVALID_WORKSTATION | The user account has workstation restrictions; it cannot be used to log on to the current workstation.
STATUS_PASSWORD_EXPIRED | The user account password has expired.
STATUS_ACCOUNT_DISABLED | The user account is currently disabled and cannot be used to log on.

More information about NTSTATUS codes can be found in the Subauth.h header file shipped with the Platform SDK.

The LsaNtStatusToWinError function converts an NTSTATUS code to a Win32 error code.

TokenInformationType
[out] Pointer that receives the address of an LSA_TOKEN_INFORMATION_TYPE value that indicates the type of information returned for inclusion in the token to be created. The information is returned in the TokenInformation buffer.
TokenInformation
[out] Pointer that receives information to be included in the token. The format and content of the TokenInformation buffer are indicated by the TokenInformationType parameter. Your authentication package is responsible for allocating the memory used by TokenInformation; however, this memory will be freed by the LSA.
AccountName
[out] Pointer to an LSA_UNICODE_STRING structure that receives the name of the user account. AccountName must always be returned regardless of the success or failure of the call; its string is included in the audit record for an authentication attempt. Your authentication package is responsible for allocating the memory used by AccountName; however, this memory will be freed by the LSA.
AuthenticatingAuthority
[out] Optional. Pointer to an LSA_UNICODE_STRING structure that receives the description of the authenticating authority for the logon. This parameter may be NULL. This string is included in the audit record for an authentication attempt. Your authentication package is responsible for allocating the memory used by AuthenticatingAuthority; however, this memory will be freed by the LSA.

The MSV1_0 authentication package returns the domain name of the domain validating the account. The Kerberos authentication package returns the NetBIOS domain name.

Return Values

If the function succeeds, it should return STATUS_SUCCESS.

If the function fails, it should return an NTSTATUS error code, which can be one of the following values or one of the standard LSA function return values.

Value | Description
STATUS_NOT_ENOUGH_QUOTA | The logon could not be completed because the client's memory quota is insufficient to allocate the return buffer.
STATUS_NO_LOGON_SERVERS | No domain controllers are available to service the authentication request.
STATUS_LOGON_FAILURE | The logon attempt failed. The reason for failure is not specified; typical reasons include misspelled user names and passwords.
STATUS_ACCOUNT_RESTRICTION | The user account and password were legitimate, but user account restrictions prevent logon at this time. For additional information, see the SubStatus parameter.
STATUS_BAD_VALIDATION_CLASS | The authentication information provided is not recognized by the specified authentication package.

Calling applications can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Remarks

Authentication packages must implement one of the following functions: LsaApLogonUser, LsaApLogonUserEx, or LsaApLogonUserEx2.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Ntsecpkg.h.

See Also

LSA_CLIENT_REQUEST, LSA_TOKEN_INFORMATION_TYPE, LSA_UNICODE_STRING, LsaApLogonUserEx, LsaApLogonUserEx2, LsaCallAuthenticationPackage


LsaApLogonUserEx

The LsaApLogonUserEx function authenticates a user's logon credentials. This function is called by the LSA only for a user's initial logon. Subsequent authentication requests must use LsaCallAuthenticationPackage. If LsaApLogonUserEx succeeds, it creates a logon session and returns information used to build the token representing the newly logged on user.

This function differs from LsaApLogonUser in that the machine name is added to the audit record for the logon attempt.

NTSTATUS LsaApLogonUserEx(
  PLSA_CLIENT_REQUEST ClientRequest,
  SECURITY_LOGON_TYPE LogonType,
  PVOID AuthenticationInformation,
  PVOID ClientAuthenticationBase,
  ULONG AuthenticationInformationLength,
  PVOID* ProfileBuffer,
  PULONG ProfileBufferLength,
  PLUID LogonId,
  PNTSTATUS SubStatus,
  PLSA_TOKEN_INFORMATION_TYPE TokenInformationType,
  PVOID* TokenInformation,
  PUNICODE_STRING* AccountName,
  PUNICODE_STRING* AuthenticatingAuthority,
  PUNICODE_STRING* MachineName
);

Parameters

ClientRequest
[in] Pointer to an opaque LSA_CLIENT_REQUEST data type representing the LSA client's request.
LogonType
[in] A SECURITY_LOGON_TYPE structure which identifies the type of logon being attempted.
AuthenticationInformation
[in] Supplies the authentication information specific to the authentication package. the LSA will free this buffer.
ClientAuthenticationBase
[in] Provides the address of the authentication information within the client process. This may be necessary to remap any pointers within the AuthenticationInformation buffer.
AuthenticationInformationLength
[in] Indicates the length of the AuthenticationInformation buffer.
ProfileBuffer
[out] Pointer that receives the address of the profile buffer in the client process. The authentication package is responsible for allocating the ProfileBuffer buffer within the client process by calling the AllocateClientBuffer function. However, if the LSA subsequently encounters an error which prevents a successful logon, then the LSA will take care of freeing this buffer.

The contents of this buffer are determined by the authentication package. The LSA does not alter this buffer; it simply returns the value to the LsaLogonUser function.

ProfileBufferLength
[out] Pointer to a ULONG that receives the length of the ProfileBuffer buffer, in bytes.
LogonId
[out] Pointer to an LUID variable that receives the new logon ID that uniquely identifies this logon session. The authentication package is responsible for allocating this LUID, and creating the LSA logon session for this logon.
SubStatus
[out] Pointer to an NTSTATUS that receives the reason for failures due to account restrictions. The values returned in SubStatus are determined by the authentication package.

The following are SubStatus values for the MSV1_0 and Kerberos authentication packages.
Value | Description
STATUS_INVALID_LOGON_HOURS | The user account has time restrictions and cannot be be used to log on at this time.
STATUS_INVALID_WORKSTATION | The user account has workstation restrictions and cannot be used to log on from the current workstation.
STATUS_PASSWORD_EXPIRED | The user account password has expired.
STATUS_ACCOUNT_DISABLED | The user account is currently disabled and cannot be used to log on.

More information about NTSTATUS codes can be found in the Subauth.h header file shipped with the Platform SDK.

TokenInformationType
[out] Pointer that receives the address of an LSA_TOKEN_INFORMATION_TYPE value that indicates the type of information returned for inclusion in the token to be created. The information is returned by means of the TokenInformation parameter.
TokenInformation
[out] Pointer that receives the address of information to be included in the token. The format and content of TokenInformation are indicated by the TokenInformationType parameter. Your authentication package is responsible for allocating the memory used by TokenInformation; however, this memory will be freed by the LSA.
AccountName
[out] Pointer to an LSA_UNICODE_STRING structure that receives the name of the user account. AccountName must always be returned regardless of the success or failure of the call; its string is included in the audit record for an authentication attempt. Your authentication package is responsible for allocating the memory used by AccountName. It will be freed by the LSA.
AuthenticatingAuthority
[out] Optional. Pointer to an LSA_UNICODE_STRING structure that receives the description of the authenticating authority for the logon. This parameter may be NULL. This string is included in the audit record for an authentication attempt. Your authentication package is responsible for allocating the memory used by AuthenticatingAuthority; however, this memory will be freed by the LSA.

The MSV1_0 authentication package returns the domain name of the domain validating the account. The Kerberos authentication package returns the NetBIOS domain name.

MachineName
[out] Optional. Pointer that receives the address of an LSA_UNICODE_STRING structure containing the name of the client's workstation. This information is included in the audit record for an authentication attempt. Your authentication package is responsible for allocating the memory used by MachineName; however, this memory will be freed by the LSA.

The MSV1_0 authentication package returns the NetBIOS name of the client's workstation.

Return Values

If the function succeeds, it should return STATUS_SUCCESS.

Otherwise, it should return an NTSTATUS error code, which can be one of the following values or one of the standard LSA function return values.

Value | Description
STATUS_NOT_ENOUGH_QUOTA | The logon could not be completed because the client's memory quota is insufficient to allocate the return buffer.
STATUS_NO_LOGON_SERVERS | No domain controllers are available to service the authentication request.
STATUS_LOGON_FAILURE | The logon attempt failed. The reason for failure is not specified; typical reasons include misspelled user names and passwords.
STATUS_ACCOUNT_RESTRICTION | The user account and password are legitimate, but user account restrictions prevent successful logon at this time.
STATUS_BAD_VALIDATION_CLASS | The authentication information provided is recognized by the authentication package.

Calling applications can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Remarks

Authentication packages must implement one of the following functions: LsaApLogonUser, LsaApLogonUserEx, or LsaApLogonUserEx2.

LsaApLogonUserEx was added for C2 certification. C2 is a security classification defined by the United States government.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecpkg.h.

See Also

LSA_CLIENT_REQUEST, LSA_TOKEN_INFORMATION_TYPE, LSA_UNICODE_STRING, LsaApLogonUser, LsaApLogonUserEx2, LsaCallAuthenticationPackage


LsaApLogonUserEx2

The LsaApLogonUserEx2 function is used to authenticate a user logon attempt on the user's initial logon. A new logon session is established for the user, and validation information for the user is returned.

NTSTATUS
LsaApLogonUserEx2 (
   PLSA_CLIENT_REQUEST ClientRequest,
   SECURITY_LOGON_TYPE LogonType,
   PVOID ProtocolSubmitBuffer,
   PVOID ClientBufferBase,
   ULONG SubmitBufferSize,
   PVOID* ProfileBuffer,
   PULONG ProfileBufferSize,
   PLUID LogonId,
   PNTSTATUS SubStatus,
   PLSA_TOKEN_INFORMATION_TYPE TokenInformationType,
   PVOID* TokenInformation,
   PUNICODE_STRING* AccountName,
   PUNICODE_STRING* AuthenticatingAuthority,
   PUNICODE_STRING* MachineName,
   PSECPKG_PRIMARY_CRED PrimaryCredentials,
   PSECPKG_SUPPLEMENTAL_CRED_ARRAY* SupplementalCredentials
);

Parameters

ClientRequest
[in] Pointer to a LSA_CLIENT_REQUEST opaque buffer representing the client's request.
LogonType
[in] SECURITY_LOGON_TYPE value that identifies the type of logon.
ProtocolSubmitBuffer
[in] Buffer that supplies the authentication information specific to the authentication package.
ClientBufferBase
[in] Buffer that provides the address within the client process at which the authentication information was resident. This might be necessary to fix-up any pointers within the authentication information buffer.
SubmitBufferSize
[in] ULONG indicating the size of the authentication information buffer, in bytes.
ProfileBuffer
[out] Pointer that receives the address of the profile buffer in the client process. The authentication package is responsible for allocating ProfileBuffer within the client process by calling the AllocateClientBuffer function. However, if the LSA subsequently encounters an error which prevents a successful logon, then the LSA will take care of freeing this buffer.

The contents of this buffer are determined by the authentication package. The LSA does not alter this buffer; it simply returns the value to the LsaLogonUser function.

ProfileBufferSize
[out] Pointer to a ULONG that receives the size of the ProfileBuffer buffer.
LogonId
[out] Pointer to an LUID variable that receives the new logon ID that uniquely identifies this logon session. The authentication package is responsible for allocating this LUID, and creating the LSA logon session for this logon.
SubStatus
[out] Pointer to an NTSTATUS that receives the reason for failures due to account restrictions. The values returned in SubStatus are determined by the authentication package.

The following table lists the SubStatus values for the MSV1_0 and Kerberos authentication packages.
Value | Description
STATUS_INVALID_LOGON_HOURS | The user account has time restrictions; it cannot be used to log on at this time.
STATUS_INVALID_WORKSTATION | The user account has workstation restrictions; it cannot be used to log on to the current workstation.
STATUS_PASSWORD_EXPIRED | The user account password has expired.
STATUS_ACCOUNT_DISABLED | The user account is currently disabled and cannot be used to log on.

More information about NTSTATUS codes can be found in the Subauth.h header file shipped with the Platform SDK.

The LsaNtStatusToWinError function converts an NTSTATUS code to a Win32 error code.

TokenInformationType
[out] Pointer that receives the address of an LSA_TOKEN_INFORMATION_TYPE value that indicates the type of information returned for inclusion in the token to be created. The information is returned by means of the TokenInformation parameter.
TokenInformation
[out] Pointer that receives the address of information to be included in the token. The format and content of TokenInformation are indicated by the TokenInformationType parameter. Your authentication package is responsible for allocating the memory used by TokenInformation; however, this memory will be freed by the LSA.
AccountName
[out] Pointer to an LSA_UNICODE_STRING structure that receives the name of the user account. AccountName must always be returned regardless of the success or failure of the call; its string is included in the audit record for an authentication attempt. Your authentication package is responsible for allocating the memory used by AccountName; however, this memory will be freed by the LSA.
AuthenticatingAuthority
[out] Optional. Pointer to an LSA_UNICODE_STRING structure that receives the description of the authenticating authority for the logon. This parameter may be NULL. This string is included in the audit record for an authentication attempt. Your authentication package is responsible for allocating the memory used by AuthenticatingAuthority; however, this memory will be freed by the LSA.

The MSV1_0 authentication package returns the domain name of the domain validating the account. The Kerberos authentication package returns the NetBIOS domain name.

MachineName
[out] Optional. Pointer that receives the address of a UNICODE_STRING structure containing the name of the client's computer. This string may optionally be omitted. This string is included in the audit record for this authentication attempt. Your authentication package is responsible for allocating the memory used by MachineName; however, this memory will be freed by the LSA.

The MSV1_0 authentication package returns the NetBIOS name of the client's workstation.

PrimaryCredentials
[out] Pointer to a SECPKG_PRIMARY_CRED structure that returns primary credentials for handing to other packages.
SupplementalCredentials
[out] Pointer to a SECPKG_SUPPLEMENTAL_CRED_ARRAY array of supplemental credentials for other packages.

Return Values

If the function succeeds, it should return STATUS_SUCCESS.

Otherwise, it should return an NTSTATUS error code, which can be one of the following values or one of the standard LSA function return values.

Value | Description
STATUS_QUOTA_EXCEEDED | The logon could not be completed because the client's memory quota is insufficient to allocate the return buffer.
STATUS_NO_LOGON_SERVERS | No domain controllers are available to service the authentication request.
STATUS_LOGON_FAILURE | The logon attempt failed. The reason for failure is not specified; typical reasons include misspelled user names and passwords.
STATUS_ACCOUNT_RESTRICTION | The user account and password were legitimate, but user account restrictions preventing successful logon at this time. For additional information see the SubStatus parameter.
STATUS_BAD_VALIDATION_CLASS | The authentication information provided is not recognized by the authentication package.
STATUS_INVALID_LOGON_CLASS | LogonType was invalid.
STATUS_LOGON_SESSION_COLLISION | The logon ID selected for this logon session (in the LogonId parameter) already exists.
STATUS_NETLOGON_NOT_STARTED | The SAM database or Netlogon service is required, but is not available.
STATUS_NO_MEMORY | The client's virtual memory or pagefile quotas are insufficient to allocate the return buffer.

Calling applications can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Remarks

Authentication packages must implement one of the following functions: LsaApLogonUser, LsaApLogonUserEx, or LsaApLogonUserEx2.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

LSA_CLIENT_REQUEST, LSA_TOKEN_INFORMATION_TYPE, LSA_UNICODE_STRING, LsaApLogonUser, LsaApLogonUserEx, LsaCallAuthenticationPackage


LSA Functions Called by Authentication Packages

The following LSA functions can be called from a custom authentication package. When the LSA calls LsaApInitializePackage to initialize the package it passes a table of support functions. The following functions are in the table.

Function | Description
AddCredential | Associates credentials, such as user name and password, with a logon session.
AllocateClientBuffer | Allocates a buffer within the calling client's process.
AllocateLsaHeap | Allocates buffers that must be returned from the authentication package to the LSA.
CopyFromClientBuffer | Copies the contents of a buffer in the client's address space into a local buffer.
CopyToClientBuffer | Copies the contents of a local buffer into the client's address space.
CreateLogonSession | Used by authentication packages to create a logon session.
DeleteCredential | Removes credentials previously cached by AddCredential.
DeleteLogonSession | Frees extraneous logon sessions created while authenticating a security principal.
FreeClientBuffer | Frees client buffers previously allocated with the AllocateClientBuffer function.
FreeLsaHeap | Frees buffers previously allocated using the AllocateLsaHeap function.
GetCredentials | Retrieves credentials previously cached by AddCredential.


AddCredential

The AddCredential function adds credentials to a logon session. These credentials may later be referenced by through a call to GetCredentials.

Windows 2000: This function is not used by authentication packages, such as Kerberos, provided with Windows 2000.

NTSTATUS AddCredential(
  PLUID LogonId,
  ULONG AuthenticationPackage,
  PLSA_STRING PrimaryKeyValue,
  PLSA_STRING Credentials
);

Parameters

LogonId
[in] Pointer to an LUID containing the session ID of the logon session to which credentials are to be added.
AuthenticationPackage
[in] Specifies the authentication package ID of the calling authentication package. This value is received in the LsaApInitializePackage call during DLL initialization.
PrimaryKeyValue
[in] String containing a value that the authentication package will later need to reference as a primary key of the credential data. This may be used, for example, to keep the name of the domain or server the credentials are related to. The format and meaning of this string are authentication package specific. Note that the string value does not have to be unique, even for the specified logon session. For example, there can be two passwords for the same domain, each with the passwords stored as credentials and the domain name stored as the primary key.
Credentials
[in] String containing data representing the user credentials. The format and meaning of this string are authentication package specific.

Remarks

The body of the credential string must be self relative, containing no pointers to memory outside the credentials. Credentials are copied and any pointers outside the credentials, themselves, will no longer be valid in the copy. In particular, strings referred to in credentials should have both the UNICODE_STRING header and body placed in the credential buffer. Pointers to strings in the body of credentials should be changed to offsets.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code, which can be the following value or one of the standard LSA function return values.

Value | Description
STATUS_NO_SUCH_LOGON_SESSION | The specified logon session could not be found.

The LsaNtStatusToWinError function converts an NTSTATUS code to a Win32 error code.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

GetCredentials


AllocateClientBuffer

The AllocateClientBuffer function allocates a buffer in the client's address space. Buffers allocated in the client's address space are used hold information returned to the client from an authentication package.

NTSTATUS AllocateClientBuffer(
  PLSA_CLIENT_REQUEST ClientRequest,
  ULONG LengthRequired,
  PVOID* ClientBaseAddress
);

Parameters

ClientRequest
[in] Pointer to opaque LSA_CLIENT_REQUEST data containing information about the LSA client's authentication request. A custom authentication package should pass in the value received during the client's call to the function that returns the output parameter, for example, LsaApCallPackage or LsaApLogonUser.
LengthRequired
[in] Length of buffer needed in bytes.
ClientBaseAddress
[out] Pointer that receives the address of the buffer. This address is the virtual address of the buffer within the client process, not in the current process.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code, which can be the following value or one of the standard LSA function return values.

Value | Description
STATUS_NOT_ENOUGH_QUOTA | The client process does not have an adequate memory quota to allocate the buffer.

The LsaNtStatusToWinError function converts an NTSTATUS code to a Win32 error code.

Remarks

This buffer must later be freed either by the authentication package or the client process. The authentication process can free the buffer by using the FreeClientBuffer dispatch routine. The client process can free the buffer by using LsaFreeReturnBuffer.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


AllocateLsaHeap

The AllocateLsaHeap function allocates memory on the heap. Some information passed back to the LSA is expected to be allocated using this function. Memory allocated with this routine must be deallocated with the FreeLsaHeap function.

PVOID AllocateLsaHeap(
  ULONG Length
);

Parameters

Length
[in] Number of bytes to allocate from the heap.

Return Values

This function returns a pointer to the allocated heap memory. If memory could not be allocated, the function returns NULL.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


CopyFromClientBuffer

The CopyFromClientBuffer function copies information from a client process's address space into a buffer in the current process.

NTSTATUS CopyFromClientBuffer(
  PLSA_CLIENT_REQUEST ClientRequest,
  ULONG Length,
  PVOID BufferToCopy,
  PVOID ClientBaseAddress
);

Parameters

ClientRequest
[in] Pointer to an opaque data structure representing the client's logon request.
Length
[in] Length in bytes of the buffer to be copied.
BufferToCopy
[in] Pointer to the local buffer into which the data is to be copied.
ClientBaseAddress
[in] Pointer to the client buffer whose contents are to be copied. This address is the address of the buffer within the client process, not the current process.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code. For more information, see Standard LSA Function Return Values.

The LsaNtStatusToWinError function converts an NTSTATUS code to a Win32 error code.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


CopyToClientBuffer

The CopyToClientBuffer function copies information from a buffer in the current process into a client process's address space.

NTSTATUS CopyToClientBuffer(
  PLSA_CLIENT_REQUEST ClientRequest,
  ULONG Length,
  PVOID ClientBaseAddress,
  PVOID BufferToCopy
);

Parameters

ClientRequest
[in] Pointer to an opaque LSA_CLIENT_REQUEST data type representing a client request.
Length
[in] Length in bytes of the buffer to be copied.
ClientBaseAddress
[in] Pointer to a buffer that receives the data. This address is the address of the buffer within the client process, not the current process.
BufferToCopy
[in] Pointer to the local buffer whose contents are to be copied into the client address space.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code. For more information, see Standard LSA Function Return Values.

The LsaNtStatusToWinError function converts an NTSTATUS code to a Win32 error code.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


CreateLogonSession

The CreateLogonSession function creates logon sessions. The logon session is identified by a unique logon ID (LUID) assigned to the logon session.

NTSTATUS CreateLogonSession(
  IN PLUID LogonId
);

Parameters

LogonId
[in] Pointer to an LUID structure to be assigned to the new logon session. An authentication package calls AllocateLocallyUniqueId in order to generate this ID.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code, which can be the following value or one of the standard LSA function return values.

Value | Description
STATUS_LOGON_SESSION_COLLISION | The specified logon ID is already in use by another logon session.

The LsaNtStatusToWinError function converts an NTSTATUS code to a Win32 error code.

Remarks

If an authentication package creates extraneous logon sessions while determining whether to authenticate the user, it should delete them by calling DeleteLogonSession. If the authentication fails, the authentication package should delete all related logon sessions.

Since logon sessions use memory in the kernel, it is important to delete any unused or discarded logon sessions.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

DeleteLogonSession


DeleteCredential

The DeleteCredential function deletes an existing credential. This function deletes the first credential it finds with a matching logon session ID, authentication package ID, and primary lookup key value. If there are multiple matching credentials, only one of them is deleted.

This function is not used by newer authentication packages provided with Windows 2000, such as Kerberos.

NTSTATUS DeleteCredential(
  PLUID LogonId,
  ULONG AuthenticationPackage,
  PLSA_STRING PrimaryKeyValue
);

Parameters

LogonId
[in] Pointer to an LUID structure containing the session ID of the logon session from which the credential is to be deleted.
AuthenticationPackage
[in] Authentication package ID of the calling authentication package received in the LsaApInitializePackage call during DLL initialization.
PrimaryKeyValue
[in] Contains the primary lookup key of the credential to be deleted.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code, which can be one of the following values or one of the standard LSA function return values.

Value | Description
STATUS_GEN_FAILURE | No matching credential could be found.
STATUS_NO_SUCH_LOGON_SESSION | The specified logon session could not be found.

The LsaNtStatusToWinError function converts an NTSTATUS code to a Win32 error code.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


DeleteLogonSession

The DeleteLogonSession function cleans up any logon sessions created while determining whether a user's authentication information is legitimate. If the authentication fails, the authentication package should delete all related logon sessions.

NTSTATUS DeleteLogonSession(
  PLUID LogonId
);

Parameters

LogonId
[in] Pointer to an LUID structure containing the session ID of logon session to delete.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code, which can be the following value or one of the standard LSA function return values.

Value | Description
STATUS_BAD_LOGON_SESSION_STATE | The specified logon session has a reference count value that prevents it from being deleted. This is a serious problem, caused by both the operating system and authentication package believing they have authority over the logon session.
STATUS_NO_SUCH_LOGON_SESSION | The specified logon session could not be found.

The LsaNtStatusToWinError function converts an NTSTATUS code to a Win32 error code.

Remarks

Since logon sessions use up memory in the kernel, any unused or discarded logon sessions should be deleted. However, logon sessions should not be deleted once a logon ID for the session has been returned to the LSA. Once the LSA has been given a logon ID (for example, as a result of a LsaApLogonUser call), the LSA assumes it is responsible for the logon session and will delete it when the operating system no longer needs it. At this time, the LSA calls LsaApLogonTerminated to notify the authentication package that the session has been deleted.

In contrast, authentication packages are not notified when a logon session is deleted with DeleteLogonSession.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

CreateLogonSession


FreeClientBuffer

The FreeClientBuffer function frees a client buffer previously allocated with the AllocateClientBuffer function.

NTSTATUS FreeClientBuffer(
  PLSA_CLIENT_REQUEST ClientRequest,
  PVOID ClientBaseAddress
);

Parameters

ClientRequest
[in] Pointer to an opaque LSA_CLIENT_REQUEST data type containing information about the LSA client's request.
ClientBaseAddress
[in] Optional. Pointer to the buffer to be freed. This address is the virtual address of the buffer within the client process, not in the current process. If NULL is passed, no memory is freed. This allows the client to pass in a value returned to it by the LSA without knowing whether the LSA actually allocated a buffer.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code. For more information, see Standard LSA Function Return Values.

The LsaNtStatusToWinError function converts an NTSTATUS code to a Win32 error code.

Remarks

Because this function frees pages in the client's process, it must be called with great care. Calling this function with an invalid address can cause the client process to crash.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


FreeLsaHeap

The FreeLsaHeap function deallocates heap memory previously allocated by AllocateLsaHeap.

VOID FreeLsaHeap(
  PVOID Base
);

Parameters

Base
[in] Pointer to the buffer to be freed.

Return Values

This function does not return a value. However, if the function sets Base to NULL, the buffer was freed. If Base is not NULL after the function call ends, the buffer could not be freed.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


GetCredentials

The GetCredentials function retrieves credentials associated with a logon session. This function is not used by newer authentication packages provided with Windows 2000, such as Kerberos.

NTSTATUS GetCredentials(
  PLUID LogonId,
  ULONG AuthenticationPackage,
  PULONG QueryContext,
  BOOLEAN RetrieveAllCredentials,
  PLSA_STRING PrimaryKeyValue,
  PULONG PrimaryKeyLength
  PLSA_STRING Credentials
);

Parameters

LogonId
[in] Pointer to an LUID structure containing the session ID of the logon session from which credentials are to be retrieved.
AuthenticationPackage
[in] Authentication package ID of the calling authentication package. Authentication packages should retrieve only their own credentials.
QueryContext
[in, out] Pointer to an unsigned LONG value used across successive calls to retrieve multiple credentials. The first time this function is used, the value pointed to by this argument should be zero. Thereafter, this value will be updated to allow retrieval to continue where it left off. This value should, therefore, not be changed until all credentials of a given query operation have been retrieved.
RetrieveAllCredentials
[in] Indicates whether all credentials for the specified logon session should be retrieved (TRUE), or only those matching the specified PrimaryKeyValue (FALSE).
PrimaryKeyValue
[in, out] This parameter serves two purposes. If the RetrieveAllCredentials parameter is FALSE, this string contains the value to use as a primary lookup key. In this case, only credentials belonging to the correct logon session with a primary lookup key matching this value will be retrieved.

If RetrieveAllCredentials is TRUE, the value of this string on input is ignored and the primary lookup key of each credential retrieved is returned in this string.

PrimaryKeyLength
[out] If the RetrieveAllCredentials parameter is TRUE, this parameter receives the length needed to store the PrimaryKeyValue string. If this PrimaryKeyLength value is larger than the input length of the PrimaryKeyValue string, the function returns STATUS_MORE_DATA, and no data is copied to the PrimaryKeyValue string.
Credentials
[out] Pointer to a buffer that receives the retrieved credential. Only one credential is retrieved for each call made. The credential is returned in a buffer that the function allocates by calling the AllocateLsaHeap function. It is the caller's responsibility to free the Credentials buffer when it is no longer needed, by calling FreeLsaHeap.

Return Values

If the function succeeds, the function returns the NTSTATUS code, STATUS_SUCCESS, indicating that the credentials were successfully retrieved.

If the function fails, the return value is an NTSTATUS code, which can be one of the following values or one of the standard LSA function return values.

Value | Description
STATUS_GEN_FAILURE | No more credentials are available. If this code is returned on the first call, there are no credentials matching the selection criteria.
STATUS_MORE_DATA | The string provided to receive the PrimaryKeyValue was not large enough to hold the data. In this case, no data is retrieved, and the QueryContext value is not modified. This allows the same call to be made again with a larger string buffer.
STATUS_NO_SUCH_LOGON_SESSION | The specified logon session could not be found.

The LsaNtStatusToWinError function converts an NTSTATUS code to a Win32 error code.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


Subauthentication Functions

The following subauthentication functions can be called by Microsoft-provided authentication packages to provide additional, user-created logon authentication.

  • Msv1_0SubAuthenticationFilter
  • Msv1_0SubAuthenticationRoutine


Msv1_0SubAuthenticationFilter

The Msv1_0SubAuthenticationFilter function performs user logon authentication that is specific to domain controllers. The function receives the user's logon data, and all information found for the user in the domain controller's SAM database.

This function is implemented by custom subauthentication package DLLs for use with the Kerberos and MSV1_0 authentication packages.

NTSTATUS NTAPI Msv1_0SubAuthenticationFilter(
  NETLOGON_LOGON_INFO_CLASS LogonLevel,
  PVOID LogonInformation,
  ULONG Flags,
  PUSER_ALL_INFORMATION UserAll,
  PULONG WhichFields,
  PULONG UserFlags,
  PBOOLEAN Authoritative,
  PLARGE_INTEGER LogoffTime,
  PLARGE_INTEGER KickoffTime
);

Parameters

LogonLevel
[in] Specifies the level of information given in LogonInformation. This parameter is normally set to NetlogonInteractiveInformation.
LogonInformation
[in] Pointer to a NETLOGON_LOGON_IDENTITY_INFO structure. Members of this structure contain information about the user who is logging on. The LogonDomainName member is ignored.
Flags
[in] Optional. Contains flags describing the circumstances of the logon. The following table lists the valid values.
Flag value | Meaning
MSV1_0_PASSTHRU | Pass-through authentication. The user is not connecting to this machine.
MSV1_0_GUEST_LOGON | This is a retry of the logon using the Guest account.

UserAll
[in] Pointer to a USER_ALL_INFORMATION structure containing the description of the user as returned from the SAM database.
WhichFields
[out] Returns the members of the UserAll USER_ALL_INFORMATION structure that need to be written back to the SAM database. These members will be written only if MSV1_0SubAuthenticationFilter returns success. Only the following value is valid.
Value Meaning
USER_ALL_PARAMETERS Write the data contained in the Parameters member of the UserAll structure back to the SAM database.
If the size of the Parameters member's UNICODE_STRING buffer is changed, Msv1_0SubAuthenticationFilter must delete the buffer using the MIDL_user_free function and reallocate it using the MIDL_user_allocate function.

UserFlags
[out] Values to be returned from the LsaLogonUser function in that function's ProfileBuffer parameter. The following table lists the valid values.
Value | Meaning
LOGON_GUEST | This was a guest logon.
LOGON_NOENCRYPTION | The caller did not specify encrypted credentials.

Note By convention, subauthentication packages return bits only in the high order byte of the UserFlags parameter.

Authoritative
[out] Pointer to a Boolean value indicating whether the status returned is an authoritative status that should be returned to the original caller. If the value returned is FALSE, the logon request can be tried again on another domain controller. This parameter should return valid information regardless of the return value of the function call. This parameter is not used with the Kerberos authentication package.
LogoffTime
[out] Pointer to a value that receives the time at which the user should log off the system. This time is used to control the logon lifetime and is specified as a GMT-relative Windows NT system time.
KickoffTime
[out] Pointer to a value that receives the time at which the user should be logged off the system. This time is used to control the logon lifetime and is specified as a GMT-relative system time. If the user is not to be automatically logged off, specify a large positive value, such as:
KickoffTime->HighPart = 0x7FFFFFFF;
KickoffTime->LowPart = 0xFFFFFFFF;

Return Values

This function must return one of the following values.

Return value | Meaning
STATUS_SUCCESS | There was no error.
STATUS_ACCOUNT_DISABLED | The account is disabled.
STATUS_ACCOUNT_EXPIRED | The account has expired.
STATUS_ACCOUNT_LOCKED_OUT | The account is locked out.
STATUS_INVALID_INFO_CLASS | LogonLevel is invalid.
STATUS_INVALID_LOGON_HOURS | The user is not authorized to log on at this time.
STATUS_INVALID_WORKSTATION | The user is not authorized to log on to the specified workstation.
STATUS_NO_SUCH_USER | The specified user has no account.
STATUS_PASSWORD_EXPIRED | The password is expired.
STATUS_PASSWORD_MUST_CHANGE | The password must change on next logon.
STATUS_WRONG_PASSWORD | The password was invalid.

When the Msv1_0SubAuthenticationFilter function is used with the Kerberos authentication package, if the function call returns STATUS_SUCCESS and one of the two parameters LogoffTime or KickoffTime has a nonzero value, this value is used as the ticket lifetime. If, on the other hand, the values of both parameters are nonzero, the smaller of these two values is used.

If the value that is used for the ticket lifetime (the sooner of LogoffTime and KickoffTime) is greater than the default ticket lifetime, then that value will be used as the maximum renewal time for the ticket. Conversely, if the larger of the two values (the later of LogoffTime and KickoffTime) is less than the default ticket lifetime, this value will be used as the ticket lifetime. For more information, see Overview of the Kerberos Protocol.

When used with the Kerberos authentication package, if this function returns an error, the Key Distribution Center (KDC) will return the Kerberos error KDC_ERR_POLICY, with the status value as the extended error code.

Remarks

After the MSV1_0 or Kerberos authentication package has validated a logon, the Msv1_0SubAuthenticationFilter function can perform additional validation to determine whether a user can log on to a network account. This function is called if the subauthentication package DLL is properly registered as 'Auth0' in the domain controller's registry. The registry path is different depending on whether the function is in a MSV1_0 or Kerberos Subauthentication package DLL. For details on registry locations, see Registering Subauthentication Packages.

This filter routine may return STATUS_SUCCESS, indicating that the logon should proceed, or a failure code, indicating that the additional validation failed.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Subauth.h.


Msv1_0SubAuthenticationRoutine

The Msv1_0SubAuthenticationRoutine function performs client/server-specific authentication. The security principal's credentials and information from the Security Accounts Manager (SAM) database are passed to this function for authentication.

This function is implemented by custom subauthentication package DLLs for use with the MSV1_0 authentication package.

The Msv1_0SubAuthenticationRoutine function is called only for a noninteractive authentication, only on the authenticating server where the account resides, and only if a subauthentication DLL is registered under the correct key in the registry.

For details on registry locations, see Registering Subauthentication Packages.

Note The Kerberos authentication package does not call this routine.

NTSTATUS NTAPI Msv1_0SubAuthenticationRoutine(
  NETLOGON_LOGON_INFO_CLASS LogonLevel,
  PVOID LogonInformation,
  ULONG Flags,
  PUSER_ALL_INFORMATION UserAll,
  PULONG WhichFields,
  PULONG UserFlags,
  PBOOLEAN Authoritative,
  PLARGE_INTEGER LogoffTime,
  PLARGE_INTEGER KickoffTime
);

Parameters

LogonLevel
[in] Specifies the level of information given in the LogonInformation parameter. This parameter is normally set to NetlogonInteractiveInformation.
LogonInformation
[in] Pointer to a NETLOGON_LOGON_IDENTITY_INFO structure. Members of this structure contain information about the user who is logging on. The LogonDomainName member of this structure is ignored.
Flags
[in] Optional. Contains flags describing the circumstances of the logon. The following table lists the valid values.
Flag value | Meaning
MSV1_0_PASSTHRU | Pass-through authentication. The user is not connecting to this machine.
MSV1_0_GUEST_LOGON | This is a retry of the logon using the GUEST user account.

UserAll
[in] Pointer to a USER_ALL_INFORMATION structure containing the description of the user as returned from the SAM database.
WhichFields
[out] Returns the members of the USER_ALL_INFORMATION structure that need to be written back to the SAM database. These members will be written only if MSV1_0SubAuthenticationRoutine returns success to the caller. Only the following value is valid.
Value Meaning
USER_ALL_PARAMETERS Write the data contained in the Parameters member of the UserAll structure back to the SAM database.
If the size of the Parameters member's UNICODE_STRING buffer is changed, Msv1_0SubAuthenticationRoutine must delete the buffer using the MIDL_user_free function and reallocate it using the MIDL_user_allocate function.

UserFlags
[out] Values to be returned from the LsaLogonUser function's ProfileBuffer parameter, when it contains a MSV1_0_LM20_LOGON_PROFILE structure. The following values are currently defined for the UserFlags member of the structure.
Value | Meaning
LOGON_GUEST | This is a guest logon.
LOGON_NOENCRYPTION | The caller did not specify encrypted credentials.

Note By convention, subauthentication packages return bits in only the high order byte of UserFlags; however, this convention is not enforced.

Authoritative
[out] Pointer to a Boolean value indicating whether the status returned is an authoritative status that should be returned to the original caller. If the returned value is FALSE, the logon request can be tried again on another domain controller. This parameter should return valid information regardless of the return value of the function call.
LogoffTime
[out] Pointer to a value that receives the time at which the user should log off the system. This time is used to control the logon lifetime and is specified as a GMT-relative system time.
KickoffTime
[out] Pointer to a value that receives the time at which the user should be logged off the system. This time is used to control the logon lifetime and is specified as a GMT-relative system time. If the user is not to be logged off, specify a large positive value, such as:
KickoffTime->HighPart = 0x7FFFFFFF;
KickoffTime->LowPart = 0xFFFFFFFF;

Return Values

This function must return one of the following values.

Return value | Meaning
STATUS_SUCCESS | There was no error.
STATUS_ACCOUNT_DISABLED | The account is disabled.
STATUS_ACCOUNT_EXPIRED | The account has expired.
STATUS_ACCOUNT_LOCKED_OUT | The account is locked out.
STATUS_INVALID_INFO_CLASS | LogonLevel is invalid.
STATUS_INVALID_LOGON_HOURS | The user is not authorized to log on at this time.
STATUS_INVALID_WORKSTATION | The user is not authorized to log on to the specified workstation.
STATUS_NO_SUCH_USER | The specified user has no account.
STATUS_PASSWORD_EXPIRED | The password is expired.
STATUS_PASSWORD_MUST_CHANGE | The account is marked to indicate that the password must be changed on the next logon.
STATUS_WRONG_PASSWORD | The password was invalid.

Remarks

This function is called by the MSV1_0 authentication package if part of the AuthenticationInformation parameter indicates that subauthentication is to be done and if a subauthentication DLL that exports the Msv1_0SubAuthenticationRoutine function is correctly registered on the workstation.

The MSV1_0 authentication package does not support subauthentication for interactive logons, which require the MSV1_0_INTERACTIVE_LOGON structure. Network logons, which require the MSV1_0_LM20_LOGON structure, can use subauthentication.

The Msv1_0SubAuthenticationRoutine function is called after the correct domain controller has been located and all information about the security principal to be authenticated has been retrieved from the SAM database. When subauthentication is used, authentication is the responsibility of the subauthentication DLL and must be done by the Msv1_0SubAuthenticationRoutine function exported by that DLL.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Subauth.h.


LSA Structures

LSA uses the following structures.

Structure | Description
DOMAIN_PASSWORD_INFORMATION | Contains information about a domain's password policy, such as the minimum length for passwords and how unique passwords must be.
KERB_CRYPTO_KEY | Contains information about a Kerberos cryptographic session key.
KERB_EXTERNAL_NAME | Contains information about an external name.
KERB_EXTERNAL_TICKET | Contains information about an external ticket.
KERB_INTERACTIVE_LOGON | Contains information about an interactive logon session.
KERB_INTERACTIVE_PROFILE | Contains information about a interactive logon profile.
KERB_PURGE_TKT_CACHE_REQUEST | Contains information used to purge entries from the ticket cache.
KERB_QUERY_TKT_CACHE_REQUEST | Used to retrieve information about all of the cached tickets for the specified user logon session.
KERB_QUERY_TKT_CACHE_RESPONSE | Contains information used to query the ticket cache.
KERB_QUERY_TKT_CACHE_RESPONSE | Contains the results of querying the ticket cache.
KERB_RETRIEVE_TKT_REQUEST | Contains information used to retrieve a ticket.
KERB_RETRIEVE_TKT_RESPONSE | Contains the response from retrieving a ticket.
KERB_TICKET_CACHE_INFO | Contains information about a cached Kerberos ticket.
KERB_TICKET_LOGON | Contains profile information for a network logon.
KERB_TICKET_PROFILE | Contains information about a interactive logon profile.
KERB_TICKET_UNLOCK_LOGON | Contains information to unlock a workstation.
LSA_DISPATCH_TABLE | A table of pointers to the LSA functions that Windows NT–style authentication packages can call.
LSA_STRING | Contains an ANSI string and its length information.
LSA_TOKEN_INFORMATION_NULL | Used in cases where a non-authenticated system access is needed. This structure has no contents.
LSA_TOKEN_INFORMATION_V1 | Contains information that an authentication package can place in a Version 1 Windows NT token object.
MSV1_0_CHANGEPASSWORD_REQUEST | Contains information about a password change request.
MSV1_0_CHANGEPASSWORD_RESPONSE | Contains the response to a password change request.
MSV1_0_ENUMUSERS_REQUEST | Obsolete.
MSV1_0_ENUMUSERS_RESPONSE | Obsolete.
MSV1_0_GETUSERINFO_REQUEST | Obsolete.
MSV1_0_GETUSERINFO_RESPONSE | Obsolete.
MSV1_0_INTERACTIVE_LOGON | Contains user logon information for an interactive logon.
MSV1_0_INTERACTIVE_PROFILE | Contains information about a interactive logon profile.
MSV1_0_LM20_CHALLENGE_REQUEST | Used to initiate a challenge request, which is the first half of an NTLM version 2.0 protocol logon.
MSV1_0_LM20_CHALLENGE_RESPONSE | Contains the challenge information returned by first half of an NTLM version 2.0 protocol logon.
MSV1_0_LM20_LOGON | Contains logon information used in network logons.
MSV1_0_LM20_LOGON_PROFILE | Contains information about a network logon session.
MSV1_0_SUBAUTH_LOGON | Used by Windows 2000 subauthentication DLLs.
MSV1_0_SUBAUTH_REQUEST | Contains information to pass to a subauthentication package.
MSV1_0_SUBAUTH_RESPONSE | Contains the response from a subauthentication package.
MSV1_0_SUPPLEMENTAL_CREDENTIAL | Used to pass credentials into MSV1_0 from Kerberos or custom authentication packages.
NETLOGON_LOGON_IDENTITY_INFO | Used by the Msv1_0SubAuthenticationRoutine and Msv1_0SubAuthenticationFilter to pass information about a user for logon subauthentication.
QUOTA_LIMITS | Describes the amount of system resources available to a user.
SR_SECURITY_DESCRIPTOR | Contains information on the security privileges of the user.
USER_ALL_INFORMATION | Contains information on the session user. Used with subauthentication packages.


DOMAIN_PASSWORD_INFORMATION

The DOMAIN_PASSWORD_INFORMATION structure contains information about a domain's password policy, such as the minimum length for passwords and how unique passwords must be. It is used in the MSV1_0_CHANGEPASSWORD_RESPONSE structure.

typedef struct _DOMAIN_PASSWORD_INFORMATION {
  USHORT MinPasswordLength;
  USHORT PasswordHistoryLength;
  ULONG PasswordProperties;
#if defined(MIDL_PASS)
  OLD_LARGE_INTEGER MaxPasswordAge;
  OLD_LARGE_INTEGER MinPasswordAge;
#else
  LARGE_INTEGER MaxPasswordAge;
  LARGE_INTEGER MinPasswordAge;
#endif
} DOMAIN_PASSWORD_INFORMATION, *PDOMAIN_PASSWORD_INFORMATION;

Members

MinPasswordLength
Specifies the minimum length, in characters, of a valid password.
PasswordHistoryLength
Indicates the number of previous passwords saved in the history list. A user cannot reuse a password in the history list.
PasswordProperties
Flags that describe the password properties. They can be one or more of the following values.
Value Description
DOMAIN_PASSWORD_COMPLEX
(0x00000001L) 		The password must have a mix of at least two of the following types of characters:
- Upper case characters
- Lower case characters
- Numerals
DOMAIN_PASSWORD_NO_ANON_CHANGE
(0x00000002L) 		The password cannot be changed without logging on. Otherwise, if your password has expired, you can change your password and then log on.
DOMAIN_PASSWORD_NO_CLEAR_CHANGE
(0x00000004L) 		Forces the client to use a protocol that does not allow the domain controller to get the plaintext password.
DOMAIN_LOCKOUT_ADMINS

(0x00000008L)

 Allows the built-in administrator account to be locked out from network logons.
DOMAIN_PASSWORD_STORE_CLEARTEXT
(0x00000010L) 		The directory service is storing a plaintext password for all users instead of a hash function of the password.
DOMAIN_REFUSE_PASSWORD_CHANGE
(0x00000020L) 		Removes the requirement that the machine account password be automatically changed every week.

MaxPasswordAge
Specifies the maximum length of time that a password can remain the same. Passwords older than this must be changed. Because SAM stores relative times as negative values and absolute times as positive numbers, the time is stored as a FILETIME structure with negative values.
MinPasswordAge
Specifies the minimum length of time before a password can be changed. Because SAM stores relative times as negative values and absolute times as positive numbers, the time is stored as a FILETIME structure with negative values.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.


KERB_CRYPTO_KEY

The KERB_CRYPTO_KEY structure contains information about a Kerberos cryptographic session key.

typedef struct KERB_CRYPTO_KEY {
  LONG KeyType;
  ULONG Length;
  PUCHAR Value;
} KERB_CRYPTO_KEY, *PKERB_CRYPTO_KEY;

Members

KeyType
Indicates the type of session key stored in the structure. It can be one of the following values.
Encryption value | Description
KERB_ETYPE_DES_CBC_CRC | Use DES encryption in cipher-block-chaining mode with a CRC-32 checksum.
KERB_ETYPE_DES_CBC_MD4 | Use DES encryption in cipher-block-chaining mode with a MD4 checksum.
KERB_ETYPE_DES_CBC_MD5 | Use DES encryption in cipher-block-chaining mode with a MD5 checksum.
KERB_ETYPE_NULL | Use no encryption.
KERB_ETYPE_RC4_HMAC_NT | Use the RC4 stream cipher with a hash-based MAC.
KERB_ETYPE_RC4_MD4 | Use the RC4 stream cipher with the MD4 hash function.

Values greater than 127 are reserved for local values and may change without notice.

Length
Specifies the length in bytes of the cryptographic session key.
Value
Contains the cryptographic session key.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.


KERB_EXTERNAL_NAME

The KERB_EXTERNAL_NAME structure contains information about an external name. An external name is one used by external users. This structure is used by the KERB_EXTERNAL_TICKET structure.

typedef struct _KERB_EXTERNAL_NAME {
  SHORT NameType;
  USHORT NameCount;
  UNICODE_STRING Names[ANYSIZE_ARRAY];
} KERB_EXTERNAL_NAME, *PKERB_EXTERNAL_NAME;

Members

NameType
Indicates the type of the names stored in this structure.
Value | Description
KRB_NT_UNKNOWN | Unknown name type.
KRB_NT_PRINCIPAL | Name of the user or a Kerberos name type principal in the case of a DCE.
KRB_NT_SRV_INST | Service name and other unique name as instance (krbtgt).
KRB_NT_SRV_HST | Service name with host name as instance (telnet, rcommands).
KRB_NT_SRV_XHST | Service name with host as remaining components.
KRB_NT_UID | Unique ID.
KRB_NT_ENTERPRISE_PRINCIPAL | User principal name (UPN) or service principal name (SPN).
KRB_NT_ENT_PRINCIPAL_AND_ID | UPN and security identifier (SID).
KRB_NT_MS_PRINICPAL | Windows NT 4.0–style name.
KRB_NT_MS_PRINCIPAL_AND_ID | Windows NT 4.0–style name with SID.

NameCount
Indicates the number of names stored in Names.
Names
Array of UNICODE_STRINGS containing the names.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.


KERB_EXTERNAL_TICKET

The KERB_EXTERNAL_TICKET structure contains information about an external ticket. An external ticket is a Kerberos ticket exported to external users. This structure is used by the KERB_RETRIEVE_TKT_RESPONSE structure.

typedef struct _KERB_EXTERNAL_TICKET {
  PKERB_EXTERNAL_NAME ServiceName;
  PKERB_EXTERNAL_NAME TargetName;
  PKERB_EXTERNAL_NAME ClientName;
  UNICODE_STRING DomainName;
  UNICODE_STRING TargetDomainName;
  UNICODE_STRING AltTargetDomainName;
  KERB_CRYPTO_KEY SessionKey;
  ULONG TicketFlags;
  ULONG Flags;
  LARGE_INTEGER KeyExpirationTime;
  LARGE_INTEGER StartTime;
  LARGE_INTEGER EndTime;
  LARGE_INTEGER RenewUntil;
  LARGE_INTEGER TimeSkew;
  ULONG EncodedTicketSize;
  PUCHAR EncodedTicket;
} KERB_EXTERNAL_TICKET, *PKERB_EXTERNAL_TICKET;

Members

ServiceName
KERB_EXTERNAL_NAME structure containing a multipart, canonicalized, returned service name.
TargetName
KERB_EXTERNAL_NAME structure containing the multipart service principal name (SPN).
ClientName
KERB_EXTERNAL_NAME structure containing the client name in the ticket. This name is relative to the current domain.
DomainName
UNICODE_STRING containing the name of the domain corresponding to the ServiceName member. This is the domain that issued the ticket.
TargetDomainName
UNICODE_STRING containing the name of the domain in which the ticket is valid. For an interdomain ticket, this is the destination domain.
AltTargetDomainName
UNICODE_STRING containing a synonym for the destination domain. In Windows 2000, every domain has two names: a DNS and a Netbios name. If the name returned in the ticket is different from the name used to request the ticket(the Kerberos Key Distribution Center (KDC) may do name mapping), this string contains the original name.
SessionKey
KERB_CRYPTO_KEY structure containing the session key for the ticket.
TicketFlags
Ticket flags, as defined in Internet RFC1510. For more information about RFC 1510, see http://www.ietf.org. This can be one or more of the following values.
Value Description
KERB_TICKET_FLAGS_renewable
(0x00800000) 		The ticket is renewable. If this flag is set, the time limit for renewing the ticket is set in RenewTime. A renewable ticket can be used to obtain a replacement ticket that expires at a later date.
KERB_TICKET_FLAGS_initial
(0x00400000) 		The ticket was issued using the Authentication Service protocol instead of being based on a ticket-granting ticket.
KERB_TICKET_FLAGS_invalid
(0x01000000) 		The ticket is invalid.
KERB_TICKET_FLAGS_reserved
(0x80000000) 		Reserved for future use. Do not set this flag.
KERB_TICKET_FLAGS_forwardable
(0x40000000) 		Indicates to the ticket-granting server that it can issue a new ticket-granting ticket with a different network address, based on the presented ticket.
KERB_TICKET_FLAGS_forwarded
(0x20000000) 		The ticket has either been forwarded or was issued based on authentication involving a forwarded ticket-granting ticket.
KERB_TICKET_FLAGS_proxiable
(0x10000000) 		Indicates to the ticket-granting server that only non- ticket-granting tickets may be issued with different network addresses.
KERB_TICKET_FLAGS_proxy
(0x08000000) 		The ticket is a proxy.
KERB_TICKET_FLAGS_may_postdate
(0x04000000) 		Indicates to the ticket-granting server that a postdated ticket may be issued based on this ticket-granting ticket.
KERB_TICKET_FLAGS_postdated
(0x02000000) 		The ticket has been postdated. The end-service can check the ticket's authtime member to see when the original authentication occurred.
KERB_TICKET_FLAGS_pre_authent
(0x00200000) 		During initial authentication, the client was authenticated by the KDC before a ticket was issued. The strength of the preauthentication method is not indicated, but is acceptable to the KDC.
KERB_TICKET_FLAGS_hw_authent
(0x00100000) 		The protocol employed for initial authentication required the use of hardware expected to be possessed solely by the named client. The hardware authentication method is selected by the KDC, and the strength of the method is not indicated.
KERB_TICKET_FLAGS_ok_as_delegate
(0x00040000) 		The target of the ticket is trusted by the directory service for delegation. Thus, the clients may delegate their credentials to the server, which lets the server act as the client when talking to other services.
KERB_TICKET_FLAGS_reserved1
(0x00000001) 		Reserved.

Flags
Reserved for future use. Set this member to 0.
KeyExpirationTime
FILETIME structure containing the time at which the key expires.
StartTime
FILETIME structure containing the time at which the ticket becomes valid.
EndTime
FILETIME structure containing the time at which the ticket expires.
RenewUntil
FILETIME structure containing the latest time a ticket may be renewed. Renewal requests sent after this time will be rejected.
TimeSkew
FILETIME structure containing the measured time difference between the current time on the computer isssuing the ticket and the computer where the ticket will be used.
EncodedTicketSize
Size of the encoded ticket, in bytes.
EncodedTicket
Buffer containing the ASN.1-encoded ticket.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.


KERB_INTERACTIVE_LOGON

The KERB_INTERACTIVE_LOGON structure contains information about an interactive logon session. It is used by LsaLogonUser.

typedef struct _KERB_INTERACTIVE_LOGON {
  KERB_LOGON_SUBMIT_TYPE MessageType;
  UNICODE_STRING LogonDomainName;
  UNICODE_STRING UserName;
  UNICODE_STRING Password;
} KERB_INTERACTIVE_LOGON, *PKERB_INTERACTIVE_LOGON;

Members

MessageType
KERB_LOGON_SUBMIT_TYPE value identifying the type of logon request being made. This member must be set to KerbInteractiveLogon.
LogonDomainName
UNICODE_STRING specifying the name of the target logon domain.
UserName
UNICODE_STRING specifying the user name.
Password
UNICODE_STRING specifying the user password.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.


KERB_INTERACTIVE_PROFILE

The KERB_INTERACTIVE_PROFILE structure contains information about an interactive logon profile. It is used by LsaLogonUser.

typedef struct _KERB_INTERACTIVE_PROFILE {
  KERB_PROFILE_BUFFER_TYPE MessageType;
  USHORT LogonCount;
  USHORT BadPasswordCount;
  LARGE_INTEGER LogonTime;
  LARGE_INTEGER LogoffTime;
  LARGE_INTEGER KickOffTime;
  LARGE_INTEGER PasswordLastSet;
  LARGE_INTEGER PasswordCanChange;
  LARGE_INTEGER PasswordMustChange;
  UNICODE_STRING LogonScript;
  UNICODE_STRING HomeDirectory;
  UNICODE_STRING FullName;
  UNICODE_STRING ProfilePath;
  UNICODE_STRING HomeDirectoryDrive;
  UNICODE_STRING LogonServer;
  ULONG UserFlags;
} KERB_INTERACTIVE_PROFILE, *PKERB_INTERACTIVE_PROFILE;

Members

MessageType
KERB_PROFILE_BUFFER_TYPE value identifying the type of logon request being made. This member can be set to KerbInteractiveProfile.
LogonCount
Number of times the user is currently logged on.
BadPasswordCount
Number of times a bad password was applied to the account since the last successful logon.
LogonTime
Time when the user last logged on. This is an absolute-format standard time value.
LogoffTime
Time when user should log off. This is an absolute-format standard time value.
KickOffTime
Time when system should force user logoff. This is an absolute-format standard time value.
PasswordLastSet
Time and date the password was last set. This is an absolute-format standard time value.
PasswordCanChange
Time and date when the user can change the password. This is an absolute-format standard time value. To prevent a password from ever changing, set this member to a date very far into the future.
PasswordMustChange
Time and date when the user must change the password. If the user can never change the password, this member is undefined. This is an absolute-format standard time value.
LogonScript
UNICODE_STRING containing the relative path to the account's logon script.
HomeDirectory
UNICODE_STRING containing the user's home directory.
FullName
UNICODE_STRING containing the user's full name.
ProfilePath
UNICODE_STRING containing the path to a user's roaming profile. This is used only if the user has a roaming profile.
HomeDirectoryDrive
UNICODE_STRING containing the drive containing the user's home directory.
LogonServer
UNICODE_STRING containing the name of the server that processed the logon request.
UserFlags
Specifies how this user established the session. This can be one or more of the following flags.
Flag | Description
LOGON_EXTRA_SIDS | The user logged on using extra security identifiers (SIDs).
LOGON_RESOURCE_GROUPS | The user logged on using a domain local group.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.


KERB_PURGE_TKT_CACHE_REQUEST

The KERB_PURGE_TKT_CACHE_REQUEST structure contains information used to purge entries from the ticket cache. It is used by LsaCallAuthenticationPackage.

typedef struct _KERB_PURGE_TKT_CACHE_REQUEST {
  KERB_PROTOCOL_MESSAGE_TYPE MessageType;
  LUID LogonId;
  UNICODE_STRING ServerName;
  UNICODE_STRING RealmName;
} KERB_PURGE_TKT_CACHE_REQUEST, *PKERB_PURGE_TKT_CACHE_REQUEST;

Members

MessageType
KERB_PROTOCOL_MESSAGE_TYPE value identifying the type of request being made. This member must be set to KerbPurgeTicketCacheMessage.
LogonId
LUID structure containing the logon session identifier. This can be zero for the current user's logon session. If not zero, the caller must have the SeTcbPrivilege privilege set. If this fails, the Kerberos authentication package sets the ProtocolStatus parameter of LsaCallAuthenticationPackage to STATUS_ACCESS_DENIED.
ServerName
UNICODE_STRING containing the name of the service whose tickets should be deleted from the cache.
RealmName
UNICODE STRING containing the name of the realm whose tickets should be deleted from the cache.

Remarks

If both ServerName and RealmName are of zero length, LsaCallAuthenticationPackage will delete all tickets for the logon session identified by LogonId. Otherwise, LsaCallAuthenticationPackage will search the cache tickets for ServerName@RealmName, and will delete all such tickets.

LsaCallAuthenticationPackage does not return this buffer. It returns STATUS_SUCCESS if one or more tickets are purged. If no tickets are found, the function returns SEC_E_NO_CREDENTIALS.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.


KERB_QUERY_TKT_CACHE_REQUEST

The KERB_QUERY_TKT_CACHE_REQUEST structure contains information used to query the ticket cache. It is used by LsaCallAuthenticationPackage.

typedef struct _KERB_QUERY_TKT_CACHE_REQUEST {
  KERB_PROTOCOL_MESSAGE_TYPE MessageType;
  LUID LogonId;
} KERB_QUERY_TKT_CACHE_REQUEST, *PKERB_QUERY_TKT_CACHE_REQUEST;

Members

MessageType
KERB_PROTOCOL_MESSAGE_TYPE value identifying the type of request being made. This member must be set to KerbQueryTicketCacheMessage or KerbRetrieveTicketMessage.

If this member is set to KerbQueryTicketCacheMessage, the request is for information about all of the cached tickets for the specified user logon session. If it is set to KerbRetrieveTicketMessage, the request is for the ticket granting ticket from the ticket cache of the specified user logon session.

LogonId
LUID structure containing the logon session identifier. This can be zero for the current user's logon session. If not zero, the caller must have the SeTcbPrivilege privilege set. If this fails, the Kerberos authentication package sets the ProtocolStatus parameter of LsaCallAuthenticationPackage to STATUS_ACCESS_DENIED.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.


KERB_QUERY_TKT_CACHE_RESPONSE

The KERB_QUERY_TKT_CACHE_RESPONSE structure contains the results of querying the ticket cache. It is used by LsaCallAuthenticationPackage.

typedef struct _KERB_QUERY_TKT_CACHE_RESPONSE {
  KERB_PROTOCOL_MESSAGE_TYPE MessageType;
  ULONG CountOfTickets;
  KERB_TICKET_CACHE_INFO Tickets[ANYSIZE_ARRAY];
} KERB_QUERY_TKT_CACHE_RESPONSE, *PKERB_QUERY_TKT_CACHE_RESPONSE;

Members

MessageType
KERB_PROTOCOL_MESSAGE_TYPE value identifying the type of request being made. This member must be set to KerbQueryTicketCacheMessage.
CountOfTickets
Number of tickets in Tickets array. This can be zero if no tickets are available for the specified logon session.
Tickets
Array of length CountOfTickets of KERB_TICKET_CACHE_INFO structures.

Remarks

This buffer is allocated by the Kerberos authentication package and should be deleted by the application that called LsaCallAuthenticationPackage, using LsaFreeReturnBuffer.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.


KERB_RETRIEVE_TKT_REQUEST

The KERB_RETRIEVE_TKT_REQUEST structure contains information used to retrieve a ticket. It is used by LsaCallAuthenticationPackage.

typedef struct _KERB_RETRIEVE_TKT_REQUEST {
  KERB_PROTOCOL_MESSAGE_TYPE MessageType;
  LUID LogonId;
  UNICODE_STRING TargetName;
  ULONG TicketFlags;
  ULONG CacheOptions;
  LONG EncryptionType;
  SecHandle CredentialsHandle;
} KERB_RETRIEVE_TKT_REQUEST, *PKERB_RETRIEVE_TKT_REQUEST;

Members

MessageType
KERB_PROTOCOL_MESSAGE_TYPE value indicating the type of request being made. This member must be set to KerbRetrieveEncodedTicketMessage.
LogonId
LUID structure containing the logon session identifier. This can be zero for the current user's logon session. If not zero, the caller must have the SeTcbPrivilege privilege set. If this fails, the Kerberos authentication package sets the ProtocolStatus parameter of LsaCallAuthenticationPackage to STATUS_ACCESS_DENIED.
TargetName
UNICODE_STRING containing the name of the target service.
TicketFlags
Contains flags specifying uses for the retrieved ticket. If TicketFlags is set to 0 and if there is a matching ticket found in the cache, then that ticket will be returned, regardless of its flag values. If there is no match in the cache, a new ticket with the default flag values will be requested.

If this member is not set to 0, the returned ticket will not be cached.

CacheOptions
Indicates options for searching the cache. Set this member to 0 to indicate that the cache should be searched and if no ticket if found, a new ticket should be requested.

If this member is not set to 0, the returned ticket will not be cached.

CacheOptions can contain the following values.
Value | Description
KERB_RETRIEVE_TICKET_DONT_USE_CACHE Always request a new ticket; do not search the cache.

If a ticket is obtained, the Kerberos authentication package returns STATUS_SUCCESS in the ProtocolStatus parameter of the LsaCallAuthenticationPackage function.
KERB_RETRIEVE_TICKET_USE_CREDHANDLE | Use the CredentialsHandle member instead of LogonId to identify the logon session.
KERB_RETRIEVE_TICKET_USE_CACHE_ONLY Return only a previously cached ticket.

If such a ticket is not found, the Kerberos authentication package returns STATUS_OBJECT_NAME_NOT_FOUND in the ProtocolStatus parameter of the LsaCallAuthenticationPackage function.

EncryptionType
Specifies the type of encryption to use for the requested ticket. If this member is not set to zero (0), the returned ticket will not be cached.

This member can have one of the following values.
Encryption Value | Description
KERB_ETYPE_DES_CBC_CRC | Use DES encryption in cipher-block-chaining mode with a CRC-32 checksum.
KERB_ETYPE_DES_CBC_MD4 | Use DES encryption in cipher-block-chaining mode with a MD4 checksum.
KERB_ETYPE_DES_CBC_MD5 | Use DES encryption in cipher-block-chaining mode with a MD5 checksum.
KERB_ETYPE_NULL | Use no encryption.
KERB_ETYPE_RC4_HMAC_NT | Use the RC4 stream cipher with a hash-based MAC, as used by Windows NT.
KERB_ETYPE_RC4_MD4 | Use the RC4 stream cipher with the MD4 hash function.
>127 | Values greater than 127 are reserved for local values and may change without notice.

CredentialsHandle
An SSPI credentials handle used in place of a logon session identifier.

Remarks

The returned ticket will not be placed in the cache unless TicketFlags, CacheOption and EncryptionType are all set to 0. Setting these members to 0 produces the behavior required by most applications.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.


KERB_RETRIEVE_TKT_RESPONSE

The KERB_RETRIEVE_TKT_RESPONSE structure contains the response from retrieving a ticket. It is used by LsaCallAuthenticationPackage.

typedef struct _KERB_RETRIEVE_TKT_RESPONSE {
  KERB_EXTERNAL_TICKET Ticket;
} KERB_RETRIEVE_TKT_RESPONSE, *PKERB_RETRIEVE_TKT_RESPONSE;

Members

Ticket
KERB_EXTERNAL_TICKET structure containing the requested ticket.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.


KERB_TICKET_CACHE_INFO

The KERB_TICKET_CACHE_INFO structure contains information about a cached Kerberos ticket. It can be used both for retrieving tickets and querying the ticket cache. The KERB_QUERY_TKT_CACHE_RESPONSE structure uses this structure.

typedef struct _KERB_TICKET_CACHE_INFO {
  UNICODE_STRING ServerName;
  UNICODE_STRING RealmName;
  LARGE_INTEGER StartTime;
  LARGE_INTEGER EndTime;
  LARGE_INTEGER RenewTime;
  LONG EncryptionType;
  ULONG TicketFlags;
} KERB_TICKET_CACHE_INFO, *PKERB_TICKET_CACHE_INFO;

Members

ServerName
UNICODE_STRING containing the name of the server the ticket applies to. This name is combined with the RealmName value in order to create the full name ServerName@RealmName.
RealmName
UNICODE_STRING containing the name of the realm the ticket applies to.
StartTime
FILETIME structure containing the time at which the ticket becomes valid. If the starttime member of the ticket is not set, this value defaults to the time when the ticket was initially authenticated, authtime. The starttime member of a ticket is optional.
EndTime
FILETIME structure containing the time when the ticket expires.
RenewTime
If KERB_TICKET_FLAGS_renewable is set in TicketFlags, this member is a FILETIME structure containing the time beyond which the ticket cannot be renewed.
EncryptionType
The type of encryption used in the ticket.
TicketFlags
The ticket flags, as defined in Internet RFC1510. For more information about RFC 1510, see http://www.ietf.org. These flags can be one or more of the following values.
Value Description
KERB_TICKET_FLAGS_renewable
(0x00800000) 		The ticket is renewable. If this flag is set, the time limit for renewing the ticket is set in RenewTime. A renewable ticket can be used to obtain a replacement ticket that expires at a later date.
KERB_TICKET_FLAGS_initial
(0x00400000) 		The ticket was issued using the Authentication Service protocol instead of being based on a ticket-granting ticket.
KERB_TICKET_FLAGS_invalid
(0x01000000) 		The ticket is invalid.
KERB_TICKET_FLAGS_reserved
(0x80000000) 		Reserved for future use. Do not set this flag.
KERB_TICKET_FLAGS_forwardable
(0x40000000) 		Indicates to the ticket-granting server that it can issue a new ticket- granting ticket with a different network address based on the presented ticket.
KERB_TICKET_FLAGS_forwarded
(0x20000000) 		The ticket has either been forwarded or was issued based on authentication involving a forwarded ticket-granting ticket.
KERB_TICKET_FLAGS_proxiable
(0x10000000) 		Indicates to the ticket-granting server that only non-ticket-granting tickets may be issued based on this ticket but with a different network addresses.
KERB_TICKET_FLAGS_proxy
(0x08000000) 		The ticket is a proxy.
KERB_TICKET_FLAGS_may_postdate
(0x04000000) 		Indicates to the ticket-granting server that a postdated ticket may be issued based on this ticket-granting ticket.
KERB_TICKET_FLAGS_postdated
(0x02000000) 		The ticket has been postdated. The end-service can check the ticket's authtime member to see when the original authentication occurred.
KERB_TICKET_FLAGS_pre_authent
(0x00200000) 		During initial authentication, the client was authenticated by the KDC before a ticket was issued. The strength of the preauthentication method is not indicated, but is acceptable to the KDC.
KERB_TICKET_FLAGS_hw_authent
(0x00100000) 		The protocol employed for initial authentication required the use of hardware expected to be possessed solely by the named client. The hardware authentication method is selected by the KDC and the strength of the method is not indicated.
KERB_TICKET_FLAGS_ok_as_delegate
(0x00040000) 		The target of the ticket is trusted by the directory service for delegation. Thus, clients may delegate their credentials to the server, which lets the server act as the client when talking to other services.
KERB_TICKET_FLAGS_reserved1
(0x00000001) 		Reserved.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.


KERB_TICKET_LOGON

The KERB_TICKET_LOGON structure contains profile information for a network logon. It is used by the LsaLogonUser function.

typedef struct _KERB_TICKET_LOGON {
  KERB_LOGON_SUBMIT_TYPE MessageType;
  ULONG Flags;
  ULONG ServiceTicketLength;
  ULONG TicketGrantingTicketLength;
  PUCHAR ServiceTicket;
  PUCHAR TicketGrantingTicket;
} KERB_TICKET_LOGON, *PKERB_TICKET_LOGON;

Members

MessageType
KERB_LOGON_SUBMIT_TYPE value identifying the type of logon request being made. This member must be set to KerbTicketLogon
Flags
ULONG that can be set to KERB_LOGON_FLAG_ALLOW_EXPIRED_TICKET to allow a locked workstation to re-logon with expired ticket. Other values are ignored.
ServiceTicketLength
Indicates the length of the ServiceTicket buffer.
TicketGrantingTicketLength
Indicates the length of the TicketGrantingTicket buffer. Must be set to 0 for an empty buffer.
ServiceTicket
Required ticket for service "host" or the computer account service principal name (SPN) in the form of an ASN.1 encoded Kerberos ticket. Expired tickets are acceptable if the Flags member is set to KERB_LOGON_FLAG_ALLOW_EXPIRED_TICKET.
TicketGrantingTicket
Optional buffer containing an ASN.1-encoded KERB_CRED message containing the user's Kerberos ticket-granting ticket (KRBTGT) to be used to initialize the credential cache. The ticket must have the "forwarded" flag set in the ticket options.

Remarks

The service ticket must be for the host SPN of the computer. For example host/hostname.dns.com@DNS.COM. If the ticket includes a Windows Privilege Attribute Certificate (PAC), it will be used to construct the user's logon token. Otherwise, an anonymous token will be created using the client principal name in the ticket.

If a ticket-granting ticket (TGT) is supplied as a KERB_CRED message, it is placed in the logon session's credentials cache. If the TGT is omitted, the logon will be only for the local machine.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.


KERB_TICKET_PROFILE

The KERB_TICKET_PROFILE structure contains information about a interactive logon profile. This structure is returned by LsaLogonUser.

typedef struct _KERB_TICKET_PROFILE {
  KERB_INTERACTIVE_PROFILE Profile;
  KERB_CRYPTO_KEY SessionKey;
} KERB_TICKET_PROFILE, *PKERB_TICKET_PROFILE;

Members

Profile
KERB_INTERACTIVE_PROFILE structure containing logon information.
SessionKey
KERB_CRYPTO_KEY structure containing the session key for the Kerberos ticket.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.


KERB_TICKET_UNLOCK_LOGON

The KERB_TICKET_UNLOCK_LOGON structure contains information to unlock a workstation. It is used by LsaLogonUser.

typedef struct _KERB_TICKET_UNLOCK_LOGON {
  KERB_TICKET_LOGON Logon;
  LUID LogonId;
} KERB_TICKET_UNLOCK_LOGON, *PKERB_TICKET_UNLOCK_LOGON;

Members

Logon
KERB_TICKET_LOGON structure. All members of the structure must be the same as the structure used in the original logon except the KERB_LOGON_SUBMIT_TYPE member, which must be set to KerbTicketUnlockLogon.
LogonId
LUID structure containing the logon identifier of the current logon session. This ID was previously returned from the initial logon by LsaLogonUser.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.


LSA_DISPATCH_TABLE

The LSA_DISPATCH_TABLE structure contains pointers to the LSA functions that Windows NT–style authentication packages can call. The LSA passes this structure to an authentication package when it calls the package's LsaApInitializePackage function.

typedef struct _LSA_DISPATCH_TABLE {
  PLSA_CREATE_LOGON_SESSION    CreateLogonSession;
  PLSA_DELETE_LOGON_SESSION    DeleteLogonSession;
  PLSA_ADD_CREDENTIAL          AddCredential;
  PLSA_GET_CREDENTIALS         GetCredentials;
  PLSA_DELETE_CREDENTIAL       DeleteCredential;
  PLSA_ALLOCATE_LSA_HEAP       AllocateLsaHeap;
  PLSA_FREE_LSA_HEAP           FreeLsaHeap;
  PLSA_ALLOCATE_CLIENT_BUFFER  AllocateClientBuffer;
  PLSA_FREE_CLIENT_BUFFER      FreeClientBuffer;
  PLSA_COPY_TO_CLIENT_BUFFER   CopyToClientBuffer;
  PLSA_COPY_FROM_CLIENT_BUFFER CopyFromClientBuffer;
} LSA_DISPATCH_TABLE, *PLSA_DISPATCH_TABLE;

Members

For descriptions of the dispatch functions pointed to by the members of this structure, see LSA Functions Called by Authentication Packages.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Ntsecpkg.h.


LSA_STRING

The LSA_STRING structure is used by LSA functions to specify an ANSI string.

typedef struct _LSA_STRING {
  USHORT Length;
  USHORT MaximumLength;
  PCHAR  Buffer;
} LSA_STRING, *PLSA_STRING;

Members

Length
Specifies the length, in bytes, of the string in Buffer. This value does not include the terminating null character, if any.
MaximumLength
Specifies the total size, in bytes, of Buffer. Up to MaximumLength bytes may be written into the buffer without trampling memory.
Buffer
Pointer to an array of characters. Note that strings returned by the LSA may not be null terminated.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.


LSA_TOKEN_INFORMATION_NULL

The LSA_TOKEN_INFORMATION_NULL structure is used in cases where a non-authenticated system access is needed. For example, a non-authentication network circuit (such as a null session) can be given NULL information. This results in an anonymous token being generated for the logon. An anonymous token gives the user no ability to access protected system resources, but does allow access to non-protected system resources.

typedef struct _LSA_TOKEN_INFORMATION_NULL {
  LARGE_INTEGER ExpirationTime;
  PTOKEN_GROUPS Groups;
} LSA_TOKEN_INFORMATION_NULL, *PLSA_TOKEN_INFORMATION_NULL;

Members

ExpirationTime
Time at which the security context becomes invalid. Use a value in the distant future if the context never expires.
Groups
TOKEN_GROUPS structure containing the security identifiers (SIDs) of groups the user is to be made a member of. This should not include WORLD or other SIDs defined and assigned by the system.

Each SID is expected to be in a separately allocated block of memory. The TOKEN_GROUPS structure is also expected to be in a separately allocated block of memory.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Ntsecpkg.h.


LSA_TOKEN_INFORMATION_V1

The LSA_TOKEN_INFORMATION_V1 structure contains information an authentication package can place in a Version 1 Windows NT token object. The version 1 token information is used in most logons.

A Version 1 Windows NT token object stores all the information needed to build a token from the authentication package to the LSA. The LSA passes this information into the kernel to create a token object and to return a handle to that token object to the caller of LsaLogonUser.

typedef struct _LSA_TOKEN_INFORMATION_V1 {
  LARGE_INTEGER ExpirationTime;
  TOKEN_USER User;
  PTOKEN_GROUPS Groups;
  TOKEN_PRIMARY_GROUP PrimaryGroup;
  PTOKEN_PRIVILEGES Privileges;
  TOKEN_OWNER Owner;
  TOKEN_DEFAULT_DACL DefaultDacl;
} LSA_TOKEN_INFORMATION_V1, *PLSA_TOKEN_INFORMATION_V1;

Members

ExpirationTime
Time at which the security context becomes invalid. Use a value in the distant future if the context never expires. The current version of the operating system kernel does not enforce this expiration time.
User
TOKEN_USER structure that contains the SID of the user logging on. The security identifier SID value is in a separately allocated block of memory.
Groups
TOKEN_GROUPS structure that contains the SID(s) of groups the user is a member of. This should not include WORLD or other system-defined and system-assigned SIDs. These will be added automatically by the LSA.

Each SID is expected to be in a separately allocated block of memory. The TOKEN_GROUPS structure is also expected to be in a separately allocated block of memory.

PrimaryGroup
TOKEN_PRIMARY_GROUP structure that is used to establish the primary group of the user. This value does not have to correspond to one of the SIDs assigned to the user.

The SID pointed to by this structure is expected to be in a separately allocated block of memory.

This member is mandatory and must be filled in.

Privileges
TOKEN_PRIVILEGES structure that contains the privileges assigned to the user. This list of privileges will be augmented or overridden by any local security policy assigned privileges.

Each privilege is expected to be in a separately allocated block of memory. The TOKEN_PRIVILEGES structure is also expected to be in a separately allocated block of memory.

If there are no privileges to assign to the user, this member may be set to NULL.

Owner
TOKEN_OWNER structure. This member may be used to establish an explicit default owner. Normally, the user ID is used as the default owner. If another value is desired, it must be specified here.

The Owner.Sid member may be set to NULL to indicate there is no alternate default owner value.

DefaultDacl
TOKEN_DEFAULT_DACL structure. This member may be used to establish a default protection for the user. If no value is provided, a default protection that grants everyone all access will be established.

The DefaultDacl.DefaultDacl member may be set to NULL to indicate there is no default protection.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Ntsecpkg.h.


MSV1_0_CHANGEPASSWORD_REQUEST

The MSV1_0_CHANGEPASSWORD_REQUEST structure contains information about a password change request. It is used by LsaCallAuthenticationPackage.

typedef struct _MSV1_0_CHANGEPASSWORD_REQUEST {
  MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType;
  UNICODE_STRING DomainName;
  UNICODE_STRING AccountName;
  UNICODE_STRING OldPassword;
  UNICODE_STRING NewPassword;
  BOOLEAN Impersonating;
} MSV1_0_CHANGEPASSWORD_REQUEST, *PMSV1_0_CHANGEPASSWORD_REQUEST;

Members

MessageType
MSV1_0_PROTOCOL_MESSAGE_TYPE value identifying the type of request being made. This member must be set to MsV1_0ChangePassword.
DomainName
UNICODE_STRING specifying the domain containing the account for which the password is to be changed. The domain name can be either a domain name or, to change the password on a specific machine, a server name with UNC marks, for example "\\SomeServer."
AccountName
UNICODE_STRING specifying the logon account that will have its password changed.
OldPassword
UNICODE_STRING containing the old password.
NewPassword
UNICODE_STRING containing the new password.
Impersonating
Indicates whether the request is being made by a process impersonating a principal.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.


MSV1_0_CHANGEPASSWORD_RESPONSE

The MSV1_0_CHANGEPASSWORD_RESPONSE structure contains the response to a password change request. It is used by LsaCallAuthenticationPackage

typedef struct _MSV1_0_CHANGEPASSWORD_RESPONSE {
  MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType;
  BOOLEAN PasswordInfoValid;
  DOMAIN_PASSWORD_INFORMATION DomainPasswordInfo;
} MSV1_0_CHANGEPASSWORD_RESPONSE, *PMSV1_0_CHANGEPASSWORD_RESPONSE;

Members

MessageType
MSV1_0_PROTOCOL_MESSAGE_TYPE value identifying the type of request being made. This member must be set to MsV1_0ChangePassword or MsV1_0ChangeCachedPassword.
PasswordInfoValid
Indicates whether the password information sent in the request was valid. PasswordInfoValid is set to TRUE if DomainPasswordInfo returns information on the password change.

For more information about the information sent into a password change request, see MSV1_0_CHANGEPASSWORD_REQUEST.

DomainPasswordInfo
DOMAIN_PASSWORD_INFORMATION structure containing information about the password policy for the domain.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.


MSV1_0_ENUMUSERS_REQUEST

The MSV1_0_ENUMUSERS_REQUEST structure is obsolete.

For retrieving information about logged on users, see the NetWkstaUserEnum function.


MSV1_0_ENUMUSERS_RESPONSE

The MSV1_0_ENUMUSERS_RESPONSE structure is obsolete.

For retrieving information about logged on users, see the NetWkstaUserEnum function.


MSV1_0_GETUSERINFO_REQUEST

The MSV1_0_GETUSERINFO_REQUEST structure is obsolete.

For retrieving information about the workstation user, see the NetWkstaUserGetInfo function.


MSV1_0_GETUSERINFO_RESPONSE

The MSV1_0_GETUSERINFO_RESPONSE structure is obsolete.

For retrieving information about the workstation user, see the NetWkstaUserGetInfo function.


MSV1_0_INTERACTIVE_LOGON

The MSV1_0_INTERACTIVE_LOGON structure contains information about an interactive logon. It is used by the LsaLogonUser function.

typedef struct _MSV1_0_INTERACTIVE_LOGON {
  MSV1_0_LOGON_SUBMIT_TYPE MessageType;
  UNICODE_STRING LogonDomainName;
  UNICODE_STRING UserName;
  UNICODE_STRING Password;
} MSV1_0_INTERACTIVE_LOGON;

Members

MessageType
MSV1_0_LOGON_SUBMIT_TYPE value specifying the type of logon being requested. This member must be set to MsV1_0InteractiveLogon.
LogonDomainName
UNICODE_STRING containing the name of the logon domain. The specified domain name must be a Windows NT/Windows 2000 domain or mixed domain that is trusted by this machine.
UserName
UNICODE_STRING representing the user's account name. The name can be up to 255 bytes long. The name is treated as case-insensitive. The specified UserName must have an account in domain LogonDomainName.
Password
UNICODE_STRING containing the user's plaintext password. The password may be up to 255 bytes long and contain any UNICODE value.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

MSV1_0_LOGON_SUBMIT_TYPE


MSV1_0_INTERACTIVE_PROFILE

The MSV1_0_INTERACTIVE_PROFILE structure contains information about a interactive logon profile. It is used by LsaLogonUser.

typedef struct _MSV1_0_INTERACTIVE_PROFILE {
  MSV1_0_PROFILE_BUFFER_TYPE MessageType;
  USHORT LogonCount;
  USHORT BadPasswordCount;
  LARGE_INTEGER LogonTime;
  LARGE_INTEGER LogoffTime;
  LARGE_INTEGER KickOffTime;
  LARGE_INTEGER PasswordLastSet;
  LARGE_INTEGER PasswordCanChange;
  LARGE_INTEGER PasswordMustChange;
  UNICODE_STRING LogonScript;
  UNICODE_STRING HomeDirectory;
  UNICODE_STRING FullName;
  UNICODE_STRING ProfilePath;
  UNICODE_STRING HomeDirectoryDrive;
  UNICODE_STRING LogonServer;
  ULONG UserFlags;
} MSV1_0_INTERACTIVE_PROFILE, *PMSV1_0_INTERACTIVE_PROFILE;

Members

MessageType
MSV1_0_PROFILE_BUFFER_TYPE value identifying the type of profile data being returned. This member must be set to MsV1_0InteractiveProfile.
LogonCount
Number of times the user is currently logged on.

Note This value is not guaranteed to be accurate because the domain controller is not notified of all logons and logoffs.

BadPasswordCount
Number of times a invalid password was applied to the account since the last successful logon.
LogonTime
Time when the user last logged on. This is an absolute-format Windows NT/Windows 2000 standard time value.

Windows NT 4.0: This value will be 0x7fffffff,0xffffffff unless the user has logon hours restrictions.

LogoffTime
Time when user should log off. This is an absolute-format Windows NT/Windows 2000 standard time value.
KickOffTime
Time when system should force the user to log off. This is an absolute-format Windows NT/Windows 2000 standard time value. Note that in Windows NT/Windows 2000, users are not forced to log off interactively; however, their network connections may be closed.
PasswordLastSet
Time and date the password was last changed. This is an absolute format Windows NT/Windows 2000 standard time value.
PasswordCanChange
Time and date when the user should be reminded to change passwords. This is an absolute-format Windows NT/Windows 2000 standard time value. This member is used by the GINA to display the prompt asking whether the user wants to change the current password.
PasswordMustChange
Time and date when the user must change the password. If the user can never change the password, this member is undefined. This is an absolute-format, Windows NT/Windows 2000, standard time value.
LogonScript
UNICODE_STRING containing the relative path to the account's logon script.
HomeDirectory
UNICODE_STRING containing the home directory for the user.
FullName
UNICODE_STRING containing the full name of the user.
ProfilePath
UNICODE_STRING specifying the path to the user's roaming profile if the user has a roaming profile. For example: \\SomeServer\SomeShare\MyUserName
HomeDirectoryDrive
UNICODE_STRING containing the drive letter (for example, C:\ or D:\) of the home directory.
LogonServer
UNICODE_STRING containing the name of the server that processed the logon request.
UserFlags
Specifies how this user established the session. This can be the following flag.
Flag | Description
LOGON_EXTRA_SIDS | Windows 2000: The user logged on using extra SIDs.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

MSV1_0_PROFILE_BUFFER_TYPE


MSV1_0_LM20_CHALLENGE_REQUEST

The MSV1_0_LM20_CHALLENGE_REQUEST structure is used to initiate a challenge request, which is the first half of an NTLM version 2.0 protocol logon. It is used by LsaCallAuthenticationPackage.

typedef struct _MSV1_0_LM20_CHALLENGE_REQUEST {
  MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType;
} MSV1_0_LM20_CHALLENGE_REQUEST, *PMSV1_0_LM20_CHALLENGE_REQUEST;

Members

MessageType
MSV1_0_PROTOCOL_MESSAGE_TYPE value identifying the type of request being made. This member must be set to MsV1_0Lm20ChallengeRequest.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.


MSV1_0_LM20_CHALLENGE_RESPONSE

The MSV1_0_LM20_CHALLENGE_RESPONSE structure contains the challenge information returned by first half of an NTLM version 2.0 protocol logon. It is used by LsaCallAuthenticationPackage.

typedef struct _MSV1_0_LM20_CHALLENGE_RESPONSE {
  MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType;
  UCHAR ChallengeToClient[MSV1_0_CHALLENGE_LENGTH];
} MSV1_0_LM20_CHALLENGE_RESPONSE, *PMSV1_0_LM20_CHALLENGE_RESPONSE;

Members

MessageType
MSV1_0_PROTOCOL_MESSAGE_TYPE value identifying the type of request being made. This member must be set to MsV1_0Lm20ChallengeResponse.
ChallengeToClient
Contains the challenge to be sent to the client.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.


MSV1_0_LM20_LOGON

The MSV1_0_LM20_LOGON structure contains logon information used in network logons. It is used by LsaLogonUser.

typedef struct _MSV1_0_LM20_LOGON {
  MSV1_0_LOGON_SUBMIT_TYPE MessageType;
  UNICODE_STRING LogonDomainName;
  UNICODE_STRING UserName;
  UNICODE_STRING Workstation;
  UCHAR ChallengeToClient[MSV1_0_CHALLENGE_LENGTH];
  STRING CaseSensitiveChallengeResponse;
  STRING CaseInsensitiveChallengeResponse;
  ULONG ParameterControl;
} MSV1_0_LM20_LOGON, *PMSV1_0_LM20_LOGON;

Members

MessageType
MSV1_0_LOGON_SUBMIT_TYPE value that specifies the type of logon being requested. This member must be set to MsV1_0Lm20Logon or MsV1_0NetworkLogon.

If this member is set to MsV1_0Lm20Logon, the MSV1_0 package ignores the ParameterControl member.

LogonDomainName
UNICODE_STRING containing the name of the logon domain. The specified domain name must be a Windows NT/Windows 2000 domain (or mixed domain) that is in the trusted domain list of this machine. If the logon domain name is not known (for example, for clients that don't supply this information), this member should be passed in as a zero length string. This domain is the authenticating authority.
UserName
UNICODE_STRING representing the user's account name. The name may be up to 255 bytes long. The name is treated as case insensitive.
Workstation
UNICODE_STRING containing the computer name of the client workstation from which the user logon request was initiated.
ChallengeToClient
Contains the challenge returned from a previous call to LsaCallAuthenticationPackage, when MsV1_0Lm20ChallengeRequest was specified as the message type. For more information, see the description of MsV1_0Lm20ChallengeRequest in MSV1_0_PROTOCOL_MESSAGE_TYPE. This enables the authentication package to determine if the challenge response is correct or not.
CaseSensitiveChallengeResponse
Contains some function of the client's case-sensitive UNICODE password. Typically, it will be the ChallengeToClient member encrypted by a case-sensitive version of the password.

Some clients will simply supply the plaintext case-sensitive Unicode password. In that case, this member points to that plaintext password. The MSV1_0 Authentication Package may accept this non-encrypted form depending on a configuration option.

Some clients do not support case-sensitive Unicode passwords. In that case, this member should be contain a zero length string.

CaseInsensitiveChallengeResponse
Contains some function of the client's case-insensitive multi-byte character set (MBCS) password. Typically, it will be the ChallengeToClient member encrypted by a case-insensitive version of the password.

Windows 95 and clients which only support MBCS and not Unicode, simply supply the plaintext case-insensitive multi-byte character set (MBCS) password. In that case, this member points to that plaintext password. The MSV1_0 authentication package will accept this non-encrypted form depending on a configuration option.

ParameterControl
Specifies attributes of the other parameters. This can be one or more of the following flags.
Value | Description
MSV1_0_CLEARTEXT_PASSWORD_ALLOWED LanMan1.0 or LanMan2.0 used in older versions of Windows NT sent a plaintext password instead of a challenge response. An application must supply this flag to allow plaintext passwords to be used in the NetworkLogon message.

This flag is required if the user is logging on using a version of Windows NT earlier than Windows NT 4.0.
MSV1_0_UPDATE_LOGON_STATISTICS | Update the logon statistics for the account. If this flag is not set, the bad password count is set to zero upon successful logon.
MSV1_0_RETURN_USER_PARAMETERS | If this flag is specified, the UserParameters member of the MSV1_0_LM20_LOGON_PROFILE return buffer is valid.
MSV1_0_DONT_TRY_GUEST_ACCOUNT | Prevents the user from logging on with a guest account.
MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | If this flag is set, domain controller accounts can be used for authentication. Otherwise, only user accounts can be used.
MSV1_0_RETURN_PASSWORD_EXPIRY | Causes the password expiration time to be returned in the LogoffTime member of the MSV1_0_LM20_LOGON_PROFILE structure returned in the output buffer.
MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT | Windows 2000: Permits remote-boot clients to logon using a machine account.
MSV1_0_TRY_GUEST_ACCOUNT_ONLY | Causes the user to logon using the guest account.
MSV1_0_RETURN_PROFILE_PATH | Returns the profile path for Encrypted File System (EFS). The profile path is used by EFS to locate the user's profile and find the user's keys for encrypting and decrypting files. This information is not returned to the caller; it is stored within the LSA and used by internal processes.
MSV1_0_TRY_SPECIFIED_DOMAIN_ONLY Windows 2000:

In normal operation, the LogonDomainName member is used as a suggestion. The package (using the NetLogon service) will continue passing the logon request to domain controllers higher in the trusted domain path until one authoritatively rejects the logon.

This flag overrides that behavior so that only the specified domain controller will attempt to process the logon. If LogonDomainName is blank, the logon will not be attempted.

This flag is new for Windows 2000. If Windows NT 4 domain controllers are along the logon path, they will attempt to process the logon, regardless of whether MSV1_0_TRY_SPECIFIED_DOMAIN_ONLY is set.

Remarks

If the UserName, CaseSensitiveChallengeResponse and CaseInsensitiveChallengeResponse all contain zero-length strings, an anonymous token will be generated for the logon. This anonymous token gives the user no ability to access protected system resources but does allow access to non-protected system resources. The server uses this method to support a NULL session.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LsaCallAuthenticationPackage, LsaLogonUser, MSV1_0_LM20_LOGON_PROFILE, MSV1_0_LOGON_SUBMIT_TYPE, MSV1_0_PROTOCOL_MESSAGE_TYPE


MSV1_0_LM20_LOGON_PROFILE

The MSV1_0_LM20_LOGON_PROFILE structure contains information about a network logon session. It is used by LsaLogonUser.

typedef struct _MSV1_0_LM20_LOGON_PROFILE {
  MSV1_0_PROFILE_BUFFER_TYPE MessageType;
  LARGE_INTEGER KickOffTime;
  LARGE_INTEGER LogoffTime;
  ULONG UserFlags;
  UCHAR UserSessionKey[MSV1_0_USER_SESSION_KEY_LENGTH];
  UNICODE_STRING LogonDomainName;
  UCHAR LanmanSessionKey[MSV1_0_LANMAN_SESSION_KEY_LENGTH];
  UNICODE_STRING LogonServer;
  UNICODE_STRING UserParameters;
} MSV1_0_LM20_LOGON_PROFILE, * PMSV1_0_LM20_LOGON_PROFILE;

Members

MessageType
MSV1_0_PROFILE_BUFFER_TYPE value identifying the type of logon requested. The type of logon determines the format and content of the profile data returned. This member must be set to MsV1_0LM20LogonProfile.
KickOffTime
Time when system should force user logoff. This is an absolute-format Windows NT/Windows 2000 standard time value.
LogOffTime
Time when user should log off. This is an absolute-format Windows NT/Windows 2000 standard time value.
UserFlags
Specifies the way the user established the session. UserFlags can contain one or more of the following values.
Flag | Description
LOGON_GUEST | The user logged onto a guest account.
LOGON_NOENCRYPTION | The user logged on without using password encryption.
LOGON_CACHED_ACCOUNT | Windows 2000: The user logged on using cached credentials.
LOGON_USED_LM_PASSWORD Windows 2000: The user logged on using an LM password instead of a Windows NT/Windows 2000 password. An LM password is the hashed version of the MBCS upper-cased password. It is typically used by down-level clients, such as Windows 95.

The Windows NT/Windows 2000 password is the hashed version of the Unicode password.

The caller may need to know which type of password was used to determine the corresponding session key (LanmanSessionKey or UserSessionKey ).
LOGON_EXTRA_SIDS | Windows 2000: SIDs from a domain other than the user's logon domain were sent back from the user's domain controller. This information is used internally by the LSA.
LOGON_SUBAUTH_SESSION_KEY | Windows 2000: The user logged on using a subauthentication session key.
LOGON_SERVER_TRUST_ACCOUNT | Windows 2000: The user logged on using a trusted server account.
LOGON_PROFILE_PATH_RETURNED | Windows 2000: The profile path in the profile in the UserParameters member is valid.
LOGON_RESOURCE_GROUPS | Windows 2000: The user logged on using resource groups.

Note The high order byte of UserFlags is reserved for return flags from subauthentication packages. The flags returned by a subauthentication package are package specific. For more information, see the documentation for the subauthentication package.

UserSessionKey
Contains a session key specific to the session and user. This session key can be used to encrypt and decrypt information sent between the client and server. This string is MSV1_0_USER_SESSION_KEY_LENGTH characters long. The array is not null terminated and can contain embedded null characters.
LogonDomainName
UNICODE_STRING containing the name of the logon domain.
LanmanSessionKey
Contains the Lanman session key. This string is MSV1_0_LANMAN_SESSION_KEY_LENGTH characters long. It is not null terminated and can contain embedded null characters.
LogonServer
UNICODE_STRING containing the name of the server that processed the logon request.
UserParameters
UNICODE_STRING containing user parameters. These parameters are primarily used by RAS to store RAS dial-in permissions for the user. In general, applications developers should not tamper with this member.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LsaLogonUser, MSV1_0_PROFILE_BUFFER_TYPE


MSV1_0_SUBAUTH_LOGON

The MSV1_0_SUBAUTH_LOGON structure is used by Windows 2000 subauthentication DLLs.

typedef struct _MSV1_0_SUBAUTH_LOGON{
  MSV1_0_LOGON_SUBMIT_TYPE MessageType;
  UNICODE_STRING LogonDomainName;
  UNICODE_STRING UserName;
  UNICODE_STRING Workstation;
  UCHAR ChallengeToClient[MSV1_0_CHALLENGE_LENGTH];
  STRING AuthenticationInfo1;
  STRING AuthenticationInfo2;
  ULONG ParameterControl;
  ULONG SubAuthPackageId;
} MSV1_0_SUBAUTH_LOGON, * PMSV1_0_SUBAUTH_LOGON;

Members

MessageType
MSV1_0_LOGON_SUBMIT_TYPE value that indicates the type of logon being requested. This value must be set to MsV1_0SubAuthLogon.
LogonDomainName
UNICODE_STRING containing the name of the logon domain. The specified domain name must be a Windows NT/Windows 2000 domain or a mixed domain that is trusted by this machine. If the logon domain name is not known (for example, for clients that don't supply this information), this member should be passed in as a zero-length string. This is the authenticating authority.
UserName
UNICODE_STRING containing the user's account name. The name may be up to 255 bytes long. The name is treated as case insensitive.
Workstation
UNICODE_STRING containing the computer name of the workstation where the user logon request was initiated.
ChallengeToClient
Contains the challenge returned from a previous call to LsaCallAuthenticationPackage, when MsV1_0Lm20ChallengeRequest was specified as the message type. For more information, see the description of MsV1_0Lm20ChallengeRequest in MSV1_0_PROTOCOL_MESSAGE_TYPE. This enables the authentication package to determine whether or not the challenge response is correct.
AuthenticationInfo1
Contains subauthentication package–specific information. For more information, see the subauthentication package documentation.
AuthenticationInfo2
Contains subauthentication package-specific information. For more information, see the subauthentication package documentation.
ParameterControl
Specifies additional information about how the logon should be processed. This member can contain one or more of the following values.
Value | Description
MSV1_0_CLEARTEXT_PASSWORD_ALLOWED | Required if the user is logging on using a version of Windows NT earlier than Windows NT 4.0.
MSV1_0_UPDATE_LOGON_STATISTICS | Update the logon statistics for the account. If this flag is not set, the bad password count is set to zero upon successful logon.
MSV1_0_RETURN_USER_PARAMETERS | Causes the user parameters to be returned in the HomeDirectoryDrive member of the MSV1_0_INTERACTIVE_PROFILE structure.
MSV1_0_DONT_TRY_GUEST_ACCOUNT | Prevents the user from logging with a guest account.
MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | If this flag is set, domain controller accounts can be used for authentication. Otherwise, only user accounts can be used.
MSV1_0_RETURN_PASSWORD_EXPIRY | Causes the password expiration time to be returned in the LogoffTime member of the MSV1_0_LM20_LOGON_PROFILE structure returned in the output buffer.
MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT | Windows 2000: Permits remote-boot clients to logon using a machine account.
MSV1_0_TRY_GUEST_ACCOUNT_ONLY | Causes the user to logon using the guest account.
MSV1_0_RETURN_PROFILE_PATH | Returns the profile path associated with the logged on user.
MSV1_0_TRY_SPECIFIED_DOMAIN_ONLY | Windows 2000 domain controllers: Only a domain controller associated with the specified domain will attempt to validate the logon request.

SubAuthPackageId
Contains the subauthentication package identifier. This value is set by the subauthentication package vendor.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.

See Also

LsaCallAuthenticationPackage, MSV1_0_INTERACTIVE_PROFILE, MSV1_0_LM20_LOGON_PROFILE, MSV1_0_LOGON_SUBMIT_TYPE, MSV1_0_PROTOCOL_MESSAGE_TYPE


MSV1_0_SUBAUTH_REQUEST

The MSV1_0_SUBAUTH_REQUEST structure contains information to pass to an subauthentication package. It is used by LsaCallAuthenticationPackage.

typedef struct _MSV1_0_SUBAUTH_REQUEST{
  MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType;
  ULONG SubAuthPackageId;
  ULONG SubAuthInfoLength;
  PUCHAR SubAuthSubmitBuffer;
} MSV1_0_SUBAUTH_REQUEST, *PMSV1_0_SUBAUTH_REQUEST;

Members

MessageType
MSV1_0_PROTOCOL_MESSAGE_TYPE value identifying the type of request being made. This member should be set to MsV1_0SubAuth for local subauthentication and MsV1_0GenericPassThrough for subauthentication on the domain controller.
SubAuthPackageId
Contains a subauthentication package identifier. The value of subauthentication package identifiers is established by the creator of the subauthentication package.
SubAuthInfoLength
Indicates the length, in bytes, of the buffer passed to the subauthentication package in SubAuthSubmitBuffer.
SubAuthSubmitBuffer
Containing the data to pass to the subauthentication package. The format and content of this data is specific to the subauthentication package. For more information, see the documentation for specific subauthentication packages.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.


MSV1_0_SUBAUTH_RESPONSE

The MSV1_0_SUBAUTH_RESPONSE structure contains the response from a subauthentication package. It is used by LsaCallAuthenticationPackage.

typedef struct _MSV1_0_SUBAUTH_RESPONSE{
  MSV1_0_PROTOCOL_MESSAGE_TYPE MessageType;
  ULONG SubAuthInfoLength;
  PUCHAR SubAuthReturnBuffer;
} MSV1_0_SUBAUTH_RESPONSE, *PMSV1_0_SUBAUTH_RESPONSE;

Members

MessageType
MSV1_0_PROTOCOL_MESSAGE_TYPE value identifying the type of request being made. This member must be set to MsV1_0SubAuth.
SubAuthInfoLength
Indicates the length, in bytes, of the buffer returned by SubAuthReturnBuffer.
SubAuthReturnBuffer
Contains the subauthentication package response. The format and content of this biffer is specific to the subauthentication package. For more information, see the documentation for specific subauthentication packages.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.


MSV1_0_SUPPLEMENTAL_CREDENTIAL

The MSV1_0_SUPPLEMENTAL_CREDENTIAL structure is used to pass credentials into MSV1_0 from Kerberos or custom authentication packages.

typedef struct _MSV1_0_SUPPLEMENTAL_CREDENTIAL {
  ULONG Version;
  ULONG Flags;
  UCHAR LmPassword[MSV1_0_OWF_PASSWORD_LENGTH];
  UCHAR NtPassword[MSV1_0_OWF_PASSWORD_LENGTH];
} MSV1_0_SUPPLEMENTAL_CREDENTIAL, *PMSV1_0_SUPPLEMENTAL_CREDENTIAL;

Members

Version
Specifies the version number of the credential structure and related credential content.
Flags
Describes the credential. This can contain one or more of the following values.
Value | Description
MSV1_0_CRED_LM_PRESENT | The credential contains an LM password stored in the LmPassword member.
MSV1_0_CRED_NT_PRESENT | The credential contains a Windows NT password stored in the NtPassword member.
MSV1_0_CRED_VERSION | Version information is included and is stored in the Version member.

LmPassword
Contains the LAN Manager (LM) password. The size of this array is defined by the constant MSV1_0_OWF_PASSWORD_LENGTH.
NtPassword
STRING containing the Windows NT password. The size of this array is defined by the constant MSV1_0_OWF_PASSWORD_LENGTH.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.


NETLOGON_LOGON_IDENTITY_INFO

The NETLOGON_LOGON_IDENTITY_INFO structure is used to pass information about a user for logon subauthentication. It is used by Msv1_0SubAuthenticationRoutine and Msv1_0SubAuthenticationFilter.

typedef struct _NETLOGON_LOGON_IDENTITY_INFO {
  UNICODE_STRING LogonDomainName;
  ULONG ParameterControl;
  OLD_LARGE_INTEGER LogonId;
  UNICODE_STRING UserName;
  UNICODE_STRING Workstation;
} NETLOGON_LOGON_IDENTITY_INFO,
 *PNETLOGON_LOGON_IDENTITY_INFO;

Members

LogonDomainName
Pointer to a UNICODE_STRING containing the name of the logon domain. The specified domain name must be a domain that is trusted by this machine. If the logon domain is unknown, such as a down-level client that does not supply this information, this member should be NULL. The member should never be NULL on calls to I_NetLogonSamLogoff.
ParameterControl
Specifies attributes of the other function parameters.
Flag Value | Meaning
CLEARTEXT_PASSWORD_ALLOWED | Specifies that CaseSensitiveChallengeResponse and CaseInsensitiveChallengeResponse are allowed to be the user's cleartext password.

LogonId
Uniquely identifies the logon session
UserName
Pointer to a UNICODE_STRING identifying the account name of the user attempting to log on.
Workstation
Pointer to a UNICODE_STRING identifying the workstation from which the user is attempting to log on. NULL indicates that the workstation identity is unknown.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Subauth.h.


QUOTA_LIMITS

The QUOTA_LIMITS structure describes the amount of system resources available to a user.

typedef struct _QUOTA_LIMITS {
  SIZE_T PagedPoolLimit;
  SIZE_T NonPagedPoolLimit;
  SIZE_T MinimumWorkingSetSize;
  SIZE_T MaximumWorkingSetSize;
  SIZE_T PagefileLimit;
  LARGE_INTEGER TimeLimit;
} QUOTA_LIMITS;
typedef QUOTA_LIMITS *PQUOTA_LIMITS;

Members

PagedPoolLimit
Specifies the amount of paged pool memory assigned to the user. The paged pool is an area of system memory (physical memory used by the operating system) for objects that can be written to disk when they are not being used.

The value set in this member is not enforced by the LSA. You should set this member to 0, which causes the default value to be used.

NonPagedPoolLimit
Specifies the amount of nonpaged pool memory assigned to the user. The nonpaged pool is an area of system memory (physical memory used by the operating system) for objects that cannot be written to disk but must remain in physical memory as long as they are allocated.

The value set in this member is not enforced by the LSA. You should set this member to 0, which causes the default value to be used.

MinimumWorkingSetSize
Specifies the minimum set size assigned to the user. The "working set" of a process is the set of memory pages currently visible to the process in physical RAM memory. These pages are present in memory when the application is running and available for an application to use without triggering a page fault.

The value set in this member is not enforced by the LSA. You should set this member to NULL, which causes the default value to be used.

MaximumWorkingSetSize
Specifies the maxium set size assigned to the user.

The value set in this member is not enforced by the LSA. You should set this member to 0, which causes the default value to be used.

PagefileLimit
Specifies the maximum size, in bytes, of the paging file, which is a reserved space on disk that backs up committed physical memory on the computer.

The value set in this member is not enforced by the LSA. You should set this member to 0, which causes the default value to be used.

TimeLimit
Indicates the maximum amount of time the process can run.

The value set in this member is not enforced by the LSA. You should set this member to NULL, which causes the default value to be used.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Winnt.h.


SECURITY_LOGON_SESSION_DATA

[This is preliminary documentation and subject to change.]

The SECURITY_LOGON_SESSION_DATA structure contains information about a logon session. This structure is used by the LsaGetLogonSessionData function.

typedef struct _SECURITY_LOGON_SESSION_DATA {
  ULONG               Size;
  LUID                LogonId;
  LSA_UNICODE_STRING  UserName;
  LSA_UNICODE_STRING  LogonDomain;
  LSA_UNICODE_STRING  AuthenticationPackage;
  ULONG               LogonType;
  ULONG               Session;
  PSID                Sid;
  LARGE_INTEGER       LogonTime;
} SECURITY_LOGON_SESSION_DATA, * PSECURITY_LOGON_SESSION_DATA;

Members

Size
The size of the structure, in bytes.
LogonId
A locally unique identifier (LUID) that identifies a logon session.
UserName
An LSA_UNICODE_STRING structure containing the account name of the security principal that owns the logon session.
LogonDomain
An LSA_UNICODE_STRING structure containing the name of the domain used to authenticate the owner of the logon session.
AuthenticationPackage
An LSA_UNICODE_STRING structure containing the name of the authentication package used to authenticate the owner of the logon session.
LogonType
A SECURITY_LOGON_TYPE value that identifies the logon method.
Session
A Terminal Services session identifier. This member may be zero.
Sid
Pointer to the user's security descriptor.
LogonTime
The time the session owner logged on.

Remarks

This structure is allocated by the LSA. When the structure is no longer required, free it using the LSAFreeReturnBuffer function.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Ntsecapi.h.


SR_SECURITY_DESCRIPTOR

The SR_SECURITY_DESCRIPTOR structure contains information about the security privileges of the user.

typedef struct _SR_SECURITY_DESCRIPTOR {
  ULONG Length;
  PUCHAR SecurityDescriptor;
} SR_SECURITY_DESCRIPTOR, *PSR_SECURITY_DESCRIPTOR;

Members

Length
Indicates the size in bytes of the structure.
SecurityDescriptor
Indicates the user's security privileges.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Subauth.h.


USER_ALL_INFORMATION

The USER_ALL_INFORMATION structure contains information on the session user. It is used with subauthentication functions.

typedef struct _USER_ALL_INFORMATION {
  LARGE_INTEGER LastLogon;
  LARGE_INTEGER LastLogoff;
  LARGE_INTEGER PasswordLastSet;
  LARGE_INTEGER AccountExpires;
  LARGE_INTEGER PasswordCanChange;
  LARGE_INTEGER PasswordMustChange;
  UNICODE_STRING UserName;
  UNICODE_STRING FullName;
  UNICODE_STRING HomeDirectory;
  UNICODE_STRING HomeDirectoryDrive;
  UNICODE_STRING ScriptPath;
  UNICODE_STRING ProfilePath;
  UNICODE_STRING AdminComment;
  UNICODE_STRING WorkStations;
  UNICODE_STRING UserComment;
  UNICODE_STRING Parameters;
  UNICODE_STRING LmPassword;
  UNICODE_STRING NtPassword;
  UNICODE_STRING PrivateData;
  SR_SECURITY_DESCRIPTOR SecurityDescriptor;
  ULONG UserId;
  ULONG PrimaryGroupId;
  ULONG UserAccountControl;
  ULONG WhichFields;
  LOGON_HOURS LogonHours;
  USHORT BadPasswordCount;
  USHORT LogonCount;
  USHORT CountryCode;
  USHORT CodePage;
  BOOLEAN LmPasswordPresent;
  BOOLEAN NtPasswordPresent;
  BOOLEAN PasswordExpired;
  BOOLEAN PrivateDataSensitive;
} USER_ALL_INFORMATION, *PUSER_ALL_INFORMATION;

Members

LastLogon
Indicates the date and time of the last logon.
LastLogoff
Indicates the date and time of the last logoff.
PasswordLastSet
Indicates the date and time when the password was set or last changed.
AccountExpires
Indicates the date and time when the account will expire.
PasswordCanChange
Indicates the date and time when the password can be changed.
PasswordMustChange
Indicates the date and time that the password must change.
UserName
Pointer to a UNICODE_STRING containing the name of the user account.
FullName
Pointer to a UNICODE_STRING containing the full name of the user or account.
HomeDirectory
Pointer to a UNICODE_STRING containing the home directory of the user.
HomeDirectoryDrive
Pointer to a UNICODE_STRING containing the home drive designation.
ScriptPath
Pointer to a UNICODE_STRING containing the path to any logon script.
ProfilePath
Pointer to a UNICODE_STRING containing the path to the user's profile.
AdminComment
Pointer to a UNICODE_STRING containing a comment associated with the user account. This string can be a null string, or it can have any number of characters before the terminating null character.
WorkStations
Pointer to a UNICODE_STRING containing the name of the workstation in use by the account.
UserComment
Pointer to a UNICODE_STRING containing a user comment. This string can be a null string, or it can have any number of characters before the terminating null character.
Parameters
Pointer to a UNICODE_STRING reserved for use by applications. This string can be a null string, or it can have any number of characters before the terminating null character. Microsoft products use this member to store user configuration information. Do not modify this information
LmPassword
Pointer to a UNICODE_STRING containing a hash of the user's local machine password.
NtPassword
Pointer to a UNICODE_STRING containing a hash of the user's Windows NT/Windows 2000 domain password.
PrivateData
Pointer to a UNICODE_STRING containing supplemental private data associated with the user account. If PrivateDataSensitive is TRUE, this data is encrypted.
SecurityDescriptor
SR_SECURITY_DESCRIPTOR indicating the security privileges of the account.
UserId
Contains the user ID from the account relative identifier (RID). This ID is used by the posix subsystem.
PrimaryGroupId
Indicates the account's primary group. This ID is used by the posix subsystem.
UserAccountControl
Contains flags defined in subauth.h.
WhichFields
Contains flags defined in subauth.h.
LogonHours
Indicates the hours when the user can logon.
BadPasswordCount
Indicates the number of times the user tried to log on to this account using an incorrect password.
LogonCount
Indicates the number of logons by the user.
CountryCode
Used for localization. If not equal to zero, value is the country/region code for the user's language of choice.
CodePage
Used for localization. If not equal to zero, the values is the code page for the user's language of choice.
LmPasswordPresent
Indicates whether there is a local machine password.
NtPasswordPresent
Indicates whether there is an Windows NT/Windows 2000 domain password.
PasswordExpired
Indicates whether the password has expired.
PrivateDataSensitive
When set to TRUE, indicates that the PrivateData member is encrypted. A value of FALSE indicates that the PrivateData is in plaintext.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Subauth.h.


LSA Data Types

The LSA uses the following data and enumerated types:

Data Type or Enumeration | Description
KERB_LOGON_SUBMIT_TYPE | Lists the type of logon being requested.
KERB_PROFILE_BUFFER_TYPE | Lists the type of logon profile returned.
KERB_PROTOCOL_MESSAGE_TYPE | Lists the types of messages which can be sent to the Kerberos authentication package by calling LsaCallAuthenticationPackage.
LSA_TOKEN_INFORMATION_TYPE | Specifies the levels of information that can be included in a logon token.
MSV1_0_LOGON_SUBMIT_TYPE | Lists the kind of logon being requested.
MSV1_0_PROFILE_BUFFER_TYPE | Lists the kind of logon profile returned.
MSV1_0_PROTOCOL_MESSAGE_TYPE | Lists the types of messages which can be sent to the MSV1_0 Authentication Package by calling LsaCallAuthenticationPackage.
PLSA_CLIENT_REQUEST | An opaque data type used internally by the LSA to maintain client information related to individual requests.
SECURITY_LOGON_TYPE | Indicates the type of logon requested by a logon process.


KERB_LOGON_SUBMIT_TYPE

The KERB_LOGON_SUBMIT_TYPE enumeration lists the type of logon being requested.

typedef enum _KERB_LOGON_SUBMIT_TYPE {
  KerbInteractiveLogon = 2,
  KerbTicketLogon = 10,
  KerbTicketUnlockLogon = 11
} KERB_LOGON_SUBMIT_TYPE, *PKERB_LOGON_SUBMIT_TYPE;

Enumerated Values

KerbInteractiveLogon
Perform an interactive logon.
KerbTicketLogon
Logon using a valid Kerberos ticket as a credential.
KerbTicketUnlockLogon
Unlock a workstation by using a Kerberos ticket.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.


KERB_PROFILE_BUFFER_TYPE

The KERB_PROFILE_BUFFER_TYPE enumeration lists the type of logon profile returned.

typedef enum _KERB_PROFILE_BUFFER_TYPE {
  KerbInteractiveProfile = 2,
  KerbTicketProfile = 6
} KERB_PROFILE_BUFFER_TYPE, *PKERB_PROFILE_BUFFER_TYPE;

Enumerated Values

KerbInteractiveProfile
The buffer contains information about an interactive logon session.
KerbTicketProfile
The buffer contains information about a Kerberos logon session.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.


KERB_PROTOCOL_MESSAGE_TYPE

The KERB_PROTOCOL_MESSAGE_TYPE enumeration lists the types of messages which can be sent to the Kerberos authentication package by calling LsaCallAuthenticationPackage. Each message corresponds to a dispatch routine and causes the Kerberos authentication package to perform a different task.

typedef enum _KERB_PROTOCOL_MESSAGE_TYPE {
  KerbDebugRequestMessage = 0,
  KerbQueryTicketCacheMessage,
  KerbChangeMachinePasswordMessage,
  KerbVerifyPacMessage,
  KerbRetrieveTicketMessage,
  KerbUpdateAddressesMessage,
  KerbPurgeTicketCacheMessage,
  KerbChangePasswordMessage,
  KerbRetrieveEncodedTicketMessage,
  KerbDecryptDataMessage,
  KerbAddBindingCacheEntryMessage,
  KerbSetPasswordMessage
} KERB_PROTOCOL_MESSAGE_TYPE, *PKERB_PROTOCOL_MESSAGE_TYPE;

Enumerated Values

KerbDebugRequestMessage
Reserved.
KerbQueryTicketCacheMessage
This dispatch routine returns information about all of the cached tickets for the specified user logon session.
KerbChangeMachinePasswordMessage
Reserved.
KerbVerifyPacMessage
Reserved.
KerbRetrieveTicketMessage
This dispatch routine retrieves the ticket-granting ticket from the ticket cache of the specified user logon session.
KerbUpdateAddressesMessage
Reserved.
KerbPurgeTicketCacheMessage
This dispatch routine allows selected tickets to be removed from the user logon session's ticket cache. It can also remove all cached tickets.
KerbChangePasswordMessage
This message causes the use of Kerberos Password Change Protocol to change the user's password in a Windows NT/Windows 2000 domain or configured MIT realm that supports this service. The caller must know the current password in order to change the password for an account.

When changing the password of an account in an MIT realm, the local computer's registry is consulted to locate the Kerberos password service for the requested domain name.

KerbRetrieveEncodedTicketMessage
This message retrieves the specified ticket, either from the cache, if it is already there, or by requesting it from the Kerberos key distribution center (KDC).
KerbDecryptDataMessage
Reserved.
KerbAddBindingCacheEntryMessage
Reserved.
KerbSetPasswordMessage
This message uses a modified Kerberos Password Change Protocol to change the user's password in the domain or configured MIT realm that supports this service. The password may be changed on any account if the caller knows the current password for the account.

When changing the password for an account in an MIT realm, the local computer registry is used to locate the Kerberos password service for the requested domain name.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.


LSA_TOKEN_INFORMATION_TYPE

The LSA_TOKEN_INFORMATION_TYPE enumeration specifies the levels of information that can be included in a logon token. When the LSA calls either LsaApLogonUser, LsaApLogonUserEx, or LsaApLogonUserEx2 the authentication package is expected to return one of the following enumeration values to indicate the type of token information structure returned.

typedef enum _LSA_TOKEN_INFORMATION_TYPE {
  LsaTokenInformationNull,
  LsaTokenInformationV1
} LSA_TOKEN_INFORMATION_TYPE, *PLSA_TOKEN_INFORMATION_TYPE;

Enumerated Values

LsaTokenInformationNull
The token information is stored in an LSA_TOKEN_INFORMATION_NULL structure.

This token information type is used for anonymous logons or null sessions, where a token is needed but the client's identity is unknown.

For example, a non-authenticated network circuit (such as a domain controller's null session) can be given NULL information. In this case an anonymous token is generated for the logon. An anonymous token does not permit access protected system resources, but does allow access to unprotected system resources.

LsaTokenInformationV1
The token information is stored in a LSA_TOKEN_INFORMATION_V1 structure. This structure contains information that an authentication package can place in a Version 1 Windows NT token object. A Version 1 Windows NT token object stores all the information needed to build a token and is used in most logon cases. The LSA creates the token object, and returns a handle to that token object to the caller of LsaLogonUser.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Ntsecpkg.h.


MSV1_0_LOGON_SUBMIT_TYPE

The MSV1_0_LOGON_SUBMIT_TYPE enumeration indicates the kind of logon being requested.

typedef enum _MSV1_0_LOGON_SUBMIT_TYPE {
  MsV1_0InteractiveLogon = 2,
  MsV1_0Lm20Logon,
  MsV1_0NetworkLogon,
  MsV1_0SubAuthLogon
} MSV1_0_LOGON_SUBMIT_TYPE, *PMSV1_0_LOGON_SUBMIT_TYPE;

Enumerated Values

MsV1_0InteractiveLogon
Requests an interactive user logon. This dispatch routine handles NTLM interactive logons initiated by LsaLogonUser or LogonUser.
MsV1_0Lm20Logon
Requests the second half of a NTLM 2.0 protocol logon. The first half of this type of logon is performed by calling LsaCallAuthenticationPackage with the MsV1_0Lm20ChallengeRequest message. For more information see, MSV1_0_PROTOCOL_MESSAGE_TYPE.
MsV1_0NetworkLogon
Requests a network logon. The only difference between this dispatch routine and MsV1_0Lm20Logon is that MsV1_0NetworkLogon uses a ParameterControl member.
MsV1_0SubAuthLogon
Windows 2000: Requests the second half of a NTLM 2.0 protocol logon using a subauthentication package. When MSV1_0 initializes itself, it checks a registry key to determine if it should load a subauthentication package. For more information about subauthentication packages used with MSV1_0, see the subauth sample included in the Platform SDK.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LogonUser, LsaCallAuthenticationPackage, LsaLogonUser, MSV1_0_PROTOCOL_MESSAGE_TYPE


MSV1_0_PROFILE_BUFFER_TYPE

The MSV1_0_PROFILE_BUFFER_TYPE enumeration lists the kind of logon profile returned.

typedef enum _MSV1_0_PROFILE_BUFFER_TYPE {
  MsV1_0InteractiveProfile = 2,
  MsV1_0Lm20LogonProfile,
  MsV1_0SmartCardProfile
} MSV1_0_PROFILE_TYPE, *PMSV1_0_PROFILE_BUFFER_TYPE;

Enumerated Values

MsV1_0InteractiveProfile
The profile describes an interactive logon session.
MsV1_0Lm20LogonProfile
The profile describes a network logon session.
MsV1_0SmartCardProfile
The profile describes a smart card logon session.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.


MSV1_0_PROTOCOL_MESSAGE_TYPE

The MSV1_0_PROTOCOL_MESSAGE_TYPE enumeration lists the types of messages which can be sent to the MSV1_0 Authentication Package by calling the LsaCallAuthenticationPackage function. Each message corresponds to a dispatch routine and causes the MSV1_0 authentication package to perform a different task.

typedef enum _MSV1_0_PROTOCOL_MESSAGE_TYPE {
  MsV1_0Lm20ChallengeRequest = 0,
  MsV1_0Lm20GetChallengeResponse,
  MsV1_0EnumerateUsers,
  MsV1_0GetUserInfo,
  MsV1_0ReLogonUsers,
  MsV1_0ChangePassword,
  MsV1_0ChangeCachedPassword,
  MsV1_0GenericPassthrough,
  MsV1_0CacheLogon,
  MsV1_0SubAuth,
} MSV1_0_PROTOCOL_MESSAGE_TYPE, *PMSV1_0_PROTOCOL_MESSAGE_TYPE;

Enumerated Values

MsV1_0Lm20ChallengeRequest
This dispatch routine serves as the first half of an NTLM version 2.0 protocol logon. The challenge returned by this call may be delivered to the initiating NTLM 2.0 node. When that node responds with a challenge response, a MsV1_0Lm20Logon message to the LsaLogonUser function is used to complete the logon. For more information see MSV1_0_LOGON_SUBMIT_TYPE.
MsV1_0Lm20GetChallengeResponse
This dispatch routine is used by the NTLM redirector to determine the challenge response to pass to a server when trying to establish a connection to the server.

This routine is passed a challenge from the server. It then encrypts the challenge with either the specified password or with the password implied by the specified logon identifier. Two challenge responses are returned. One is based on the Unicode password as given to the authentication package. The other is based on that password converted to a multibyte character set (for example, ASCII) and uppercased. The redirector should use either (or both) formats of challenge responses as it needs them. The redirector should use the returned challenge responses exactly as returned. No zero byte should be added. A challenge response is binary data and might contain zero bytes within the string.

This routine may indicate that a NULL session is to be used. If the redirector specifies all the RETURN_PRIMARY_DOMAINNAME, RETURN_PRIMARY_USERNAME and the USE_PRIMARY_PASSWORD flags, and the LogonId does not correspond to any interactive logon session, this function returns an empty string for the UserName and both challenge responses.

MsV1_0EnumerateUsers
This value is obsolete.
MsV1_0GetUserInfo
This value is obsolete.
MsV1_0ReLogonUsers
This value is not used.
MsV1_0ChangePassword
This dispatch routine changes the password of an account.
MsV1_0ChangeCachedPassword
Windows 2000: This dispatch routine changes a password in the logon cache. This is used when the password is changed on the domain controller using some other mechanism, and the locally cached version needs to be updated to match the new value. For example, RAS handles changing the passwords on the domain, but then needs to update the cached copy so the user can still access servers.
MsV1_0GenericPassthrough
Windows 2000: This dispatch routine passes any of the other dispatch routines to the domain controller. The authentication package on the domain controller may choose to reject certain dispatch requests.
MsV1_0CacheLogon
Windows 2000: This dispatch routine caches logon information in the logon cache.
MsV1_0SubAuth
Windows 2000: This dispatch routine is called to submit a buffer to a subauthentication package. If the subauthentication is local, use this dispatch routine. If the subauthentication needs to be processed on the domain controller, use the MsV1_0GenericPassthrough dispatch routine with MSV1_0_SUBAUTH_REQUEST and MSV1_0_SUBAUTH_RESPONSE buffers.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.


PLSA_CLIENT_REQUEST

The PLSA_CLIENT_REQUEST data type is an opaque data type. The LSA uses it internally to maintain client information related to individual requests.

typedef PVOID *PLSA_CLIENT_REQUEST;

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Ntsecpkg.h.


SECURITY_LOGON_TYPE

The SECURITY_LOGON_TYPE enumeration indicates the type of logon requested by a logon process.

typedef enum _SECURITY_LOGON_TYPE {
  Interactive = 2,
  Network,
  Batch,
  Service,
  Proxy,
  Unlock
} SECURITY_LOGON_TYPE, *PSECURITY_LOGON_TYPE;

Logon type | Description
Interactive | The security principal is logging on interactively.
Network | The security principal is logging using a network.
Batch | The logon is for a batch process.
Service | The logon is for a service account.
Proxy | Not supported.
Unlock | The logon is an attempt to unlock a workstation.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Ntsecapi.h.


Security Packages

Security packages are software implementations of security protocols. A security protocol defines, and a security package implements, functionality that safeguards system integrity and privacy, such as:

  • Authenticating logon data provided by a user
  • Managing access to the credentials of security principals
  • Establishing the authenticity of a client or server
  • Protecting messages exchanged between a client and server

A security package may define some security mechanisms and not others. For example, the default network security package distributed with Windows NT 4.0 is Microsoft LanManager (NTLM), which uses the MSV1_0 authentication package to handle interactive authentication. In Windows 2000, the default network security package is the Kerberos security package, which includes functionality to handle interactive authentication.

Each security package, in addition to implementing a security protocol, also provides functions that allow a potential package user to determine whether or not the implemented protocol can provide the security services that are required.

Section | Contents
Security Support Provider Interface | Client/server applications use this interface to establish authenticated connections. Once established, the connections may then be used to exchange messages that require privacy and integrity verification.
Microsoft Security Packages | Covers security packages shipped with the Microsoft® Windows® family of operating systems.
Custom Security Packages | Developers use this application programmer's interface to create custom security packages that implement new security protocols.


Security Support Provider Interface

Purpose

Security Support Provider Interface (SSPI) provides the means for networked applications to call one of several security support providers (SSP) to establish authenticated connections and to exchange data securely over those connections.

Where Applicable

The SSPI interface is available both in kernel mode and user mode. SSPI kernel mode functionality requires the Windows IFS kit to provide the necessary files and libraries. The calling model remains the same. Kernel mode considerations are noted on function reference pages.

About SSPI

General information about Security Support Provider Interface (SSPI).

SSPI Reference

Documentation of SSPI functions, structures, and constants.

Feedback

Make error reports and feature requests directly to Microsoft.


About SSPI

Security Support Provider Interface (SSPI) provides a common interface between transport-level applications such as remote procedure call (RPC), and security support providers (SSPs) such as Windows Distributed Security. SSPI allows a transport application to call one of several security packages within an SSP to obtain an authenticated connection. These calls do not require extensive knowledge of the security protocol's details.

This documentation contains the following sections:

  • SSPI Fundamentals
  • Context Semantics
  • Overview of the Kerberos Protocol


SSPI Fundamentals

This section presents introductory information about Security Support Provider Interface (SSPI). Topics include the following:

  • SSPI Model
  • SSPI Options for Distributed Applications
  • Extended Error Information


SSPI Model

SSPI allows an application to use various security models available on a computer or network without changing the interface to the security system. SSPI does not establish logon credentials because that is generally a privileged operation handled by the operating system.

A security support provider (SSP) is contained in a dynamic-link library (DLL) that implements SSPI by making one or more security packages available to applications. Each security package provides mappings between an application's SSPI function calls and an actual security model's functions. Security packages support security protocols such as Kerberos authentication and the Microsoft® LAN Manager.

The SSPI interface is available in kernel mode as well as user mode. To use SSPI functionality in kernel mode requires the Windows IFS kit to provide the necessary files and libraries. The calling model remains the same, but kernel mode considerations are noted on function reference pages. For more information, see SSPI Functions.


SSPI Options for Distributed Applications

Developers have many options for building distributed applications. SSPI provides an abstraction layer between application-level protocols and security protocols. Applications can take advantage of SSPI's security protocols in several ways:

  • Call SSPI routines directly (for traditional, socket-based applications).

    The routines use request/response messages to implement the application protocol that carries SSPI security-related data.

  • Use COM to call security options that are implemented using authenticated RPC and SSPI at lower levels.

    These applications do not call SSPI functions directly.

  • Use Windows Sockets 2.0 (WinSock) with the extended WinSock interface to allow transport providers to use security features.

    This approach integrates the SSP into the network stack and provides both security and transport services through a common interface.

  • Use Windows Internet Extensions API (WinInet) and an interface designed to support Internet security protocols such as the Secure Sockets Layer (SSL) protocol.

    Applications use the SSPI interface to the Secure Channel security provider to implement WinInet security. The Secure Channel is the Microsoft® Windows NT/Microsoft® Windows 2000 implementation of SSL.

Several SSPI functions return timestamps representing the lifespan of various objects. A security package is free to maintain time and provide timestamps in any fashion, but using local time simplifies the work of applications using SSPI functions.


Extended Error Information

Some security packages support extended error messages that allow the sides of a communication link to communicate any reasons for a failure. For example, the Kerberos protocol could fail because of a time discrepancy between the time of request for a Kerberos ticket and the ticket's time of issue. With information from returned extended error information, a client can resynchronize its clock and generate a new connection message.

A security package setting the SECPKG_FLAG_EXTENDED_ERROR flag in the fCapabilities member of a SecPkgInfo structure indicates that the security package supports extended error messages.

Client applications requiring extended error messages specify the ISC_REQ_EXTENDED_ERROR flag when calling the InitializeSecurityContext function. Server applications requiring extended error messages set the ASC_REQ_EXTENDED_ERROR flag when calling AcceptSecurityContext.


Context Semantics

A secuirty context is the set of security attributes and rules in effect during a communication session. This includes such information as the identities of the principal and information on the keys, ciphers, and algorithms being used. For Security Support Provider Interface (SSPI), a security context is an opaque structure created through an exchange involving the InitializeSecurityContext function and the AcceptSecurityContext function.

For more information about the context attributes, see Context Requirements.

The SSPI model supports three types of security contexts.

Type | Description
Connection | A connection-oriented context is the most common security context, and the simplest to use. The caller is responsible for the overall message format and for the location of the data in the message. The caller is also responsible for the location of the security-relevant fields within a message, such as the location of the signature data.
Datagram | A datagram-oriented context has extra support for DCE-style datagram communication. It can also be used generically for a datagram-oriented transport application.
Stream | A stream-oriented context is responsible for the blocking and message formatting within the security package. The caller is not interested in formatting, but rather a raw stream of data.


Context Requirements

Context requirements are expressed as a combination of bit flags passed to either the InitializeSecurityContext or AcceptSecurityContext function. These flags affect the context in a number of ways. Not all flags apply to all contexts. Some are valid only for the server, others only for the client.

The caller uses the fContextReq parameter of the InitializeSecurityContext or AcceptSecurityContext call to specify a set of flags that indicate the required capabilities. When the function returns, the pfContextAttr parameter indicates the attributes of the established context. The caller determines whether the final context attributes are acceptable.

Flags requested from or returned by InitializeSecurityContext are prefixed by ISC. Those requested from or returned by AcceptSecurityContext are prefixed by ASC. Flags passed into a function include REQ, while returned flags include RET. For example, a request flag for delegation passed to InitializeSecurityContext is ISC_REQ_DELEGATE. A server requesting mutual authentication passes ASC_REQ_MUTUAL_AUTH to AcceptSecurityContext. If mutual authentication is achieved, InitalizeSecurityContext returns ISC_RET_MUTUAL_AUTH and AcceptSecurityContext returns ASC_RET_MUTUAL_AUTH. If the caller requests mutual authentication, but the security package indicates that it cannot be performed, the caller must decide whether to cancel the context or continue.

The following table describes the various context requirement flags.

Flag | Description
DELEGATE | The server in the transport application can build new security contexts impersonating the client that will be accepted by other servers as the client's contexts. DELEGATE is currently only supported by Kerberos. Further, Kerberos will only delegate to a server that has the flag TRUSTED_FOR_DELEGATION.
MUTUAL_AUTH | The communicating parties must authenticate their identities to each other. Without MUTUAL_AUTH, the client authenticates its identity to the server. With MUTUAL_AUTH, the server also must authenticate its identity to the client.
REPLAY_DETECT | The security package detects replayed packets and notifies the caller if a packet has been replayed. The use of this flag implies all of the conditions specified by the INTEGRITY flag.
SEQUENCE_DETECT | The context must be allowed to detect out-of-order delivery of packets later through the message support functions. Use of this flag implies all of the conditions specified by the INTEGRITY flag.
CONFIDENTIALITY | The context can protect data while in transit using the EncryptMessage and DecryptMessage functions. CONFIDENTIALITY is directly supported in Microsoft® Windows® 2000 and later and Microsoft® Windows® ME. It can be supported for NTLM with Microsoft® Windows NT® version 4.0, SP4 by loading the EncryptMessage and DecryptMessage functions from security.dll. These functions are also available for NTLM and SSL for Windows 95 and Windows 98 using Directory Service Client ( dsclient )..
USE_SESSION_KEY | A new session key must be negotiated.
PROMPT_FOR_CREDS | If the client is an interactive user, the security package must, if possible, prompt the user for the appropriate credentials.
USE_SUPPLIED_CREDS | Package-specific credential information is available in the input buffer. The security package can use these credentials to authenticate the connection.
SAVE_SUPPLIED_CREDS | The supplied credentials should be cached wit the supplemenatal credentials.
ALLOCATE_MEMORY | The security package must allocate memory. The caller must eventually call the FreeContextBuffer function to free memory allocated by the security package.
USE_DCE_STYLE | The caller expects a three-leg authentication transaction.
DATAGRAM | Datagram semantics must be used. For more information, see Datagram Contexts.
CONNECTION | Connection semantics must be used. For more information, see Connection-oriented Contexts.
STREAM | Stream semantics must be used. For more information, see Stream Contexts.
EXTENDED_ERROR | Error reply messages for the peer must be generated if the context fails.
INTEGRITY | Buffer integrity can be verified but no sequencing or reply detection is enabled.
IDENTIFY | When a server impersonates a context that has this flag set, that impersonation yields extremely limited access. Impersonation with IDENTIFY set is used to verify the client's identity.


Connection-Oriented Contexts

With a connection-oriented context, the function's caller is responsible for formatting messages. The caller relies on the security package to authenticate connections and to ensure the integrity of specific parts of the message.

Most context options are available to connection-oriented contexts. These options include mutual authentication, replay detection, and sequence detection, as described in Context Requirements.

A security package sets the SECPKG_FLAG_CONNECTION flag to indicate that it supports connection-oriented semantics.


Datagram Contexts

The semantics for datagram, or connectionless, contexts differ slightly from those for connection-oriented contexts. In a datagram's connectionless context, a server cannot determine when the client has shut down or otherwise terminated the connection. In other words, no termination notice is passed from the transport application to the server as would occur in a connection-oriented context.

To use a datagram context, a client sets the ISC_REQ_DATAGRAM flag in its call to the InitializeSecurityContext function.

To better support some models, particularly DCE-style RPC, the following rules apply when the client uses a datagram context:

  • The security package does not produce an authentication BLOB (binary large object) on the first call to InitializeSecurityContext. However, the client can use the returned security context in a call to the MakeSignature function to generate a signature for a message.
  • The security package must allow for the context to be re-established multiple times to allow the server to drop the connection without notice. This implies that any keys used in the MakeSignature and VerifySignature functions can be reset to a consistent state.
  • The security package allows the caller to specify sequence information, and provides that sequence information at the receiver side. This is in addition to any sequence information maintained by the package.

A security package sets the SECPKG_FLAG_DATAGRAM flag to indicate that it supports datagram semantics.


Stream Contexts

Stream contexts handle the secure stream-oriented protocols such as SSL or PCT. In the interest of sharing the same interface and similar credential management, SSPI provides support for stream contexts. The security protocol incorporates both the stream authentication scheme and record formats.

To provide stream-oriented protocols, security packages that support stream contexts have the following process characteristics:

  1. The package sets the SECPKG_FLAG_STREAM flag to indicate that it supports stream semantics.
  2. Transport applications requests stream semantics by setting the ISC_REQ_STREAM and ASC_REQ_STREAM flags in the calls to the InitializeSecurityContext and AcceptSecurityContext functions.
  3. The application calls the QueryContextAttributes function with a SecPkgContext_StreamSizes structure to query the security context for the number of buffers to provide and the sizes to reserve for headers or trailers.
  4. The application provides buffer descriptors to spare during the actual processing of the data. By specifying stream semantics, the caller indicates willingness to do extra processing so that the security package can handle the blocking of the messages. In essence, for the MakeSignature and VerifySignature functions, the caller passes in a list of buffers. When a message is received from a channel that is stream-oriented (such as a TCP port), the caller passes in a buffer list as follows.
    Buffer | Length | Buffer type
    1 | Message Length | SECBUFFER_DATA
    2 | 0 | SECBUFFER_EMPTY
    3 | 0 | SECBUFFER_EMPTY
    4 | 0 | SECBUFFER_EMPTY
    5 | 0 | SECBUFFER_EMPTY

    The security package then works on the BLOB. If the function returns successfully, the buffer list looks like the following.
    Buffer | Length | Buffer type
    1 | Header Length | SECBUFFER_STREAM_HEADER
    2 | Data Length | SECBUFFER_DATA
    3 | Trailer Length | SECBUFFER_STREAM_TRAILER
    4 | 0 | SECBUFFER_EMPTY
    5 | 0 | SECBUFFER_EMPTY

    The package could have also returned buffer #4 with length x and buffer type SECBUFFER_EXTRA indicating that the data in this buffer is part of the next record and has not yet been processed. Conversely, if the message function returns the SEC_E_INCOMPLETE_MESSAGE error code, the returned buffer list would look like the following.
    Buffer | Length | Buffer type
    1 | x | SECBUFFER_MISSING

    This indicates that more data was needed to process the record. Unlike most errors returned from a message function, this buffer type does not indicate that the context has been compromised. Instead, it indicates that more data is needed. Security packages must not update their state in this condition.

    Similarly, on the sender side of the communication, the caller can call the MakeSignature function. The security package may need to reallocate the buffer or copy things around. The caller can be more efficient by providing a buffer list as follows.
    Buffer | Length | Type
    1 | Header Length | SECBUFFER_STREAM_HEADER
    2 | Data Length | SECBUFFER_DATA
    3 | Trailer Length | SECBUFFER_STREAM_TRAILER

    This allows the caller to use the buffers more efficiently. By calling the QueryContextAttributes function to determine the amount of space to reserve before calling MakeSignature, the operation is more efficient for the application and the security package.


Overview of the Kerberos Protocol

The Kerberos protocol defines how clients interact with a network authentication service. Clients obtain tickets from the Kerberos Key Distribution Center (KDC), and they present these tickets to servers when connections are established. Kerberos tickets represent the client's network credentials.

Information in this section provides theoretical background on the use of the Kerberos protocol in an authentication process. This is background information that can add to a developer's understanding of what is happening behind the scenes in an SSPI process that uses the Kerberos Version 5 protocol.

The Kerberos authentication protocol provides a mechanism for mutual authentication between entities before a secure network connection is established. Throughout this documentation, the two entities are called the client and the server even though secure network connections can be made between servers. Both client and server can also be referred to as security principals.

The Kerberos protocol assumes that transactions between clients and servers take place on an open network where most clients and many servers are not physically secure, and packets traveling along the network can be monitored and modified at will. The assumed environment is like today's Internet where an attacker can easily pose as either a client or a server, and can readily eavesdrop on or tamper with communications between legitimate clients and servers.

This section provides the following information:

  • Basic Authentication Concepts
  • Kerberos Subprotocols
  • Kerberos Components in Windows 2000
  • SSPI/Kerberos Interoperability with GSSAPI


Basic Authentication Concepts

In a client/server application model, clients are programs acting on behalf of users who need something done. This might be opening and using a file, accessing a mailbox, querying a database, or printing a document. Servers are programs providing services to clients such as file storage, mail handling, query processing, and print spooling. Clients initiate action, servers respond. Typically, a server listens at a communications port waiting for clients to connect and ask for service.

In the Kerberos protocol model, every client/server connection begins with authentication. Client and server, in turn, step through a sequence of actions designed to verify to the party on each end of the connection that the party on the other end is genuine. If authentication is successful, session setup completes and a secure client/server session is established.

The Kerberos protocol makes use of:

  • Key authentication
  • Authenticator messages
  • Key distribution
  • Session tickets
  • Ticket-granting tickets


Key Authentication

Many forms of authentication are based on the idea that an entity can prove its identity if it can prove it knows a key, such as a password, that only it can know.

Authentication techniques that rely on a secret, such as a password, need to have a way to keep the secret from becoming public knowledge. A password owner cannot walk up to a door and give the password. Someone besides the doorkeeper might be listening; or it might be the wrong door. In order to keep a secret, there must be a way to prove a user knows the password without revealing the password. That is the idea behind secret key authentication, a method of verification used throughout the Kerberos protocol.

Notice that the "secret" in secret key authentication is that the authentication process takes place "in secret;" that is, without ever actually revealing the content of the key.

For secret key authentication to work, the two parties to a transaction must share a cryptographic session key which is also secret, known only to them and to no others. The key is symmetric; that is, it is a single key used for both encryption and decryption. One party in the authentication process proves its knowledge of the key by encrypting a message. The other party proves its knowledge of the key by decrypting the message.


Authenticator Messages

In a simple protocol using secret key authentication, a client presents an authenticator message in the form of a piece of information encrypted in the session key. The information in the authenticator message must be different each time the authentication protocol is executed, or an encrypted authenticator message could be reused by an unauthorized entity.

On receiving the authenticator message, the server decrypts it and can tell from the contents of the decrypted message whether decryption was successful. If the decrypted message is not gibberish, the server knows that the client presenting the authenticator message used the correct key to encrypt the message. Only two entities have access to the session key and if the server is one of those, the client who encrypted the authenticator message must be the other.

For mutual authentication, a similar protocol is executed. The server extracts part of the information from the decrypted, original authenticator message, encrypts it with the shared session key, and sends the encrypted message to the client. The client decrypts the message and compares the result with the original. If the decrypted message matches the correct part of the original message, the client knows that the server was able to decrypt the original message with the shared secret session key and was able to re-encrypt a portion of that message with that same shared secret session key.


Key Distribution

The secret key authentication technique does not explain how the client and server get the secret session key to use in sessions with each other. If they are people, they could meet in secret and agree on the key. But if the client is a program running on a workstation and the server is a service running on a network server, that method will not work.

A client will want to communicate with many servers and will need different keys for each of them. A server communicates with many clients and needs different keys for each of them, as well. If each client needs a different key for every server, and each server needs a different key for every client, key distribution becomes a problem. In addition, the need to store and protect many keys on many computers creates an enormous security risk.

The name of the Kerberos protocol suggests its solution to the problem of key distribution. Kerberos (or Cerberus) was a figure in classical Greek mythology—a fierce, three-headed dog who kept living intruders from entering the Underworld. Like the mythical guard, the Kerberos protocol has three heads: a client, a server, and a trusted third party to mediate between them. The trusted intermediary in this protocol is the Key Distribution Center (KDC).

The KDC is a service running on a physically secure server. It maintains a database with account information for all security principals in its realm. A realm is the Kerberos equivalent of a domain in Microsoft® Windows®.

Along with other information about each security principal, the KDC stores a cryptographic key known only to the principal and the KDC. This is the master key used in exchanges between each security principal and the KDC. In most implementations of the Kerberos protocol, this master key is derived using a hash function from a security principal's password.

When a client wants to create a secure connection with a server, the client begins by sending a request to the KDC, not to the server that it wants to reach. The KDC creates and sends to the client a unique session key for the client and a server to use to authenticate each other. The KDC has access to both the client's master key and the server's master key. The KDC encrypts the server's copy of the session key using the server's master key, and the client's copy using the client's master key.

The KDC could fulfill its role as trusted intermediary by sending the session key directly to each of the security principals involved, but in practice this procedure will not work, for a number of reasons. Instead, the KDC sends both encrypted session keys to the client. The session key for the server is included in a session ticket.


Session Tickets

Instead of sending the encrypted session keys to both of the principals, the KDC sends both the client's and the server's copies of the session key to the client. The client's copy of the session key is encrypted with the client's master key and therefore cannot be decrypted by any other entity. The server's copy of the session key is embedded, along with authorization data about the client, in a data structure called a ticket. The ticket is entirely encrypted with the server's master key and therefore cannot be read or changed by the client or any other entity that does not have access to the server's master key. It is the responsibility of the client to store the ticket safely until contact with the server.

Note The KDC only provides a ticket-granting service. The client and server are responsible for keeping their respective master keys secure.

When the client receives the KDC's response, it extracts the ticket and its own copy of the session key, putting both aside in a secure cache. To establish a secure session with the server, it sends the server a message consisting of the ticket, still encrypted with the server's master key, and an authenticator message encrypted with the session key. Together, the ticket and authenticator message are the client's credentials to the server.

When the server receives credentials from a client, it decrypts the ticket with its master key, extracts the session key, and uses the session key to decrypt the client's authenticator message. If everything checks out, the server knows that the client's credentials were issued by the KDC, a trusted authority. For mutual authentication, the server responds by encrypting the timestamp from the client's authenticator message using the session key. This encrypted message is sent to the client. The client then decrypts the message. If the returned message is the same as the timestamp in the original authenticator message, the server is authenticated.

As an added benefit, the server does not need to store the session keys it uses with its clients. It is each client's responsibility to manage the ticket for the server in its ticket cache and to present that ticket each time it accesses the server. Whenever the server receives a ticket from a client, it uses its master key to decrypt the ticket and extract the session key. When the server no longer needs the session key, the key is purged.

The client does not need to access the KDC each time it wants access to this particular server. Tickets can be reused. As a precaution against the possibility of ticket theft, tickets have an expiration time, specified by the KDC in the ticket structure. How long a ticket is valid depends on Kerberos policy for the realm. Typically, tickets are good for no longer than eight hours, about the length of a normal logon session. When the user at a client workstation logs off, the client ticket cache is flushed and all tickets and client session keys are destroyed.


Ticket-Granting Tickets

As the Kerberos protocol was originally designed, a master key for a user was derived from a password provided by the user. When a user logged on, the Kerberos client on the user's workstation accepted the password from the user and converted it into an encryption key by passing the text through a one-way hash function. The resulting hash was the user's master key. The client used this master key to decrypt session keys received from KDC.

The problem with the original Kerberos design is the client needs the user's master key each time it decrypts a session key from the KDC. That means either the client must ask the user for the password at the beginning of every client/server exchange, or the client must store the user's key on the workstation. Frequent interruptions of the user are too intrusive. Storing the key on the workstation risks compromising a key derived from the user password which is a long term key.

The Kerberos protocol's solution to this problem is for the client to get a temporary key from the KDC. This temporary key is good only for this logon session. When a user logs on, the client requests a ticket for the KDC just as it would request a ticket for any other service. The KDC responds by creating a logon session key and a ticket for a special server, the KDC's full ticket-granting service. One copy of the logon session key is embedded in the ticket, and the ticket is encrypted with the KDC's master key. Another copy of the logon session key is encrypted with the user's master key derived from the user's logon password. Both the ticket and the encrypted session key are sent to the client.

When the client gets the KDC's reply, it decrypts the logon session key with the user's master key derived from the user's password. The client no longer needs the key derived from the user's password because the client will now use the logon session key to decrypt its copy of any server session key it gets from the KDC. The client stores the logon session key in its ticket cache along with its ticket for the KDC's full ticket-granting service.

The ticket for the full ticket-granting service is called a ticket-granting ticket (TGT). When the client asks the KDC for a ticket to a server, it presents credentials in the form of an authenticator message and a ticket — in this case a TGT — just as it would present credentials to any other service. The ticket-granting service opens the TGT with its master key, extracts the logon session key for this client, and uses the logon session key to encrypt the client's copy of a session key for the server.


Kerberos Subprotocols

The Kerberos protocol is composed of three subprotocols.

Subprotocol | Meaning
Authentication Service (AS) Exchange | In this subprotocol, the KDC gives the client a logon session key and a TGT.
Ticket-Granting Service (TGS) Exchange | In this subprotocol, the KDC distributes a service session key and a ticket for the service.
Client/server (CS) Exchange | In this subprotocol, the client presents the ticket for admission to a service.


Authentication Service (AS) Exchange

The user begins logging on to the network by typing a logon name and password. The Kerberos client on the user's workstation converts the password to an encryption key and saves the result in a program variable.

The client then requests credentials for the KDC's ticket-granting service by sending the KDC's authentication service a message of type KRB_AS_REQ (Kerberos Authentication Service Request). The first part of this message identifies the user and the TGS service being requested. The second part of the message contains pre-authentication data intended to prove that user knows the password. This is simply an authenticator message encrypted with the master key derived from the user's logon password.

When the KDC receives KRB_AS_REQ, it looks up the user in its database, gets the associated user's master key, decrypts the pre-authentication data, and evaluates the timestamp inside. If the timestamp is valid, the KDC can be assured that the pre-authentication data was encrypted with the user's master key and thus that the client is genuine.

Once it has verified the user's identity, the KDC creates credentials that the client can present to the ticket-granting service.

  1. It invents a logon session key and encrypts a copy with the user's master key.
  2. It embeds another copy of the logon session key and the user's authorization data in a TGT, and encrypts the TGT with the KDC's own master key.
  3. The KDC sends these credentials back to the client by replying with a message of type KRB_AS_REP (Kerberos Authentication Service Reply).
  4. When the client receives the reply, it uses the key derived from the user's password to decrypt the new logon session key.
  5. The client stores the new key in its ticket cache.
  6. The client extracts the TGT from the message and stores that in its ticket cache as well.


Ticket-Granting Service (TGS) Exchange

To request a ticket for another service from the KDC, the following process is used.

  1. The Kerberos client on the user's workstation requests credentials for the service by sending a message of type KRB_TGS_REQ (Kerberos Ticket-Granting Service Request). This message consists of the identity of the service for which the client is requesting credentials, an authenticator message encrypted with the user's new logon session key, and the TGT obtained from the Authentication Service (AS) Exchange.
  2. When it receives a KRB_TGS_REQ, the KDC decrypts the TGT with its secret key and extracts the user's logon session key.
  3. The KDC uses the logon session key to decrypt the user's authenticator message and evaluates that. If the authenticator passes the test, the KDC extracts the user's authorization data from the TGT and invents a session key for the user to share with the desired server
  4. The KDC encrypts one copy of the service session key with the user's logon session key.
  5. The KDC embeds another copy of the service session key in a ticket, along with the user's authorization data, and encrypts the ticket with the server's master key.
  6. The KDC sends these credentials back to the client by replying with a message of type KRB_TGS_REP (Kerberos Ticket-Granting Service Reply).
  7. When the client receives the reply, it decrypts the service session key with the user's logon session key, and stores the service session key in its ticket cache.
  8. The client extracts the ticket to the server and stores that in its ticket cache.


Client/Server (CS) Exchange

Once a user has a ticket to a server, the workstation client can establish a secure communications session with that server. This is done using the following steps.

  1. The client sends the server a message of type KRB_AP_REQ (Kerberos Application Request). This message contains an authenticator message encrypted with the key sent by the KDC for the session with the server. the ticket for sessions with the server, and a flag indicating whether the client requests mutual authentication. Setting of the flag requesting mutual authentication is one of the options in configuring Kerberos. The user is never asked whether mutual authentication should be used or not.
  2. The server receives KRB_AP_REQ, decrypts the ticket, and extracts user's authorization data and the session key.
  3. The server uses the session key from the ticket to decrypt the user's authenticator message and evaluates the timestamp inside.
  4. If the authenticator message is valid, the server checks the mutual authentication flag in the client's request.
  5. If the mutual authentication flag is set, the server uses the session key to encrypt the time from the user's authenticator message and returns the result in a message of type KRB_AP_REP (Kerberos Application Reply).
  6. When the client receives KRB_AP_REP, it decrypts the server's authenticator message with the session key it shares with the server, and compares the time sent back by the service with the time in its original authenticator message. If they match, the client is assured that the service is genuine, and the connection proceeds.


Kerberos Components in Windows 2000

The following are the Kerberos components used with Windows 2000:

  • Key Distribution Center
  • Account Database
  • Kerberos Policy


Key Distribution Center

Windows 2000 implements the Key Distribution Center (KDC) as a domain service. It uses the Active Directory as its account database and the Global Catalog for directing referrals to KDCs in other domains.

As in other implementations of the Kerberos protocol, the KDC is a single process that provides two services:

  • Authentication Service (AS)

    This service issues ticket-granting tickets (TGTs) for connection to the ticket-granting service in its own domain or in any trusted domain. Before a client can ask for a ticket to another computer, it must request a TGT from the authentication service in the client's account domain. The authentication service returns a TGT for the ticket-granting service in the target computer's domain. The TGT can be reused until it expires, but the first access to any domain's ticket-granting service always requires a trip to the authentication service in the client's account domain.

  • Ticket-Granting Service (TGS)

    This service issues tickets for connection to computers in its own domain. When clients want access to a computer, they contact the ticket-granting service in the target computer's domain, present a TGT, and ask for a ticket to the computer. The ticket can be reused until it expires, but the first access to any computer always requires a trip to the ticket-granting service in the target computer's account domain.

The KDC for a domain is located on a domain controller, as is the Active Directory for the domain. Both services are started automatically by the domain controller's Local Security Authority (LSA) and run as part of the LSA's process. Neither service can be stopped. If the KDC is unavailable to network clients, then the Active Directory is also unavailable—and the domain controller is no longer controlling the domain. Windows 2000 ensures availability of these and other domain services by allowing each domain to have several domain controllers, all peers. Any domain controller can accept authentication requests and ticket-granting requests addressed to the domain's KDC.

The security principal name used by the KDC in any Windows 2000 domain is krbtgt, as specified by RFC 1510. An account for this security principal is created automatically when a new Windows 2000 domain is created. The account cannot be deleted, nor can the name be changed. A password is assigned to the account automatically and is changed on a regular schedule, as are the passwords assigned to domain trust accounts. The password for the KDC's account is used to derive a cryptographic key for encrypting and decrypting the TGTs that it issues. The password for a domain trust account is used to derive an inter-realm key for encrypting referral tickets.

All instances of the KDC within a domain use the domain account for the security principal krbtgt. Clients address messages to a domain's KDC by including both the service's principal name, krbtgt, and the name of the domain. Both items of information are also used in tickets to identify the issuing authority. For information on name forms and addressing conventions, see RFC 1510.


Account Database

The Active Directory provides the account database that the KDC uses to obtain information about security principals in the domain. Each principal is represented by an account object in the directory. The encryption key used in communicating with a user, computer, or service is stored as an attribute of that security principal's account object.

Only domain controllers are Active Directory servers. Each domain controller keeps a writable copy of the directory, so accounts can be created, passwords reset, and group membership modified at any domain controller. Changes made to one replica of the directory are automatically propagated to all other replicas. Microsoft® Windows NT® does not, however, implement the Kerberos replication protocol. Instead, it replicates the information store for the Active Directory using a proprietary multimaster replication protocol over a secure channel between replication partners.

Physical storage of account data is managed by the Directory System Agent (DSA), a protected process integrated with the LSA on the domain controller. Clients of the directory service are never given direct access to the data store. Any client wanting access to directory information must use one of the supported Active Directory Service Interfaces (ADSI) to connect to the DSA and then search for, read, and write directory objects and their attributes.

Requests to access an object or attribute in the directory are subject to validation by Windows NT access control mechanisms. Like file and folder objects in the Windows NT File System (NTFS), objects in the Active Directory are protected by Access-Control Lists (ACLs) that specify who can access the object and in what way. Unlike files and folders, however, Active Directory objects have an ACL for each of their attributes. Thus attributes for sensitive account information can be protected by more restrictive permissions than those granted for other attributes of the account.

The most sensitive information about an account is of course its password. Although an account object's password attribute stores an encryption key derived from a password, not the password itself, this key is just as useful to an intruder. Therefore, access to an account object's password attribute is granted only to the account holder, never to anyone else, not even administrators. Only processes with Trusted Computing Base privilege—processes running in the security context of the LSA—are allowed to read or change password information.

To hinder an offline attack by someone with access to a domain controller's backup tape, an account object's password attribute is further protected by a second encryption using a system key. This encryption key can be stored on removable media so that it can be safeguarded separately, or it can be stored on the domain controller but protected by a dispersal mechanism. Administrators are given the option to choose where the system key is stored and which of several algorithms is used to encrypt password attributes.


Kerberos Policy

In Windows 2000, Kerberos ticket policy is defined at the domain level and implemented by the domain's KDC. Kerberos policy is stored in the Active Directory as a subset of the attributes of domain security policy. By default, policy options can be set only by members of the Domain Administrators group. Domain policy includes options to:

  • Allow postdated tickets
  • Allow forwardable tickets
  • Allow renewable tickets
  • Set maximum ticket age
  • Set maximum renewal age
  • Set maximum proxy ticket age
  • Forcibly log off users when tickets expire

Although Kerberos policy for a domain may permit delegated authentication by allowing tickets to be forwarded, that aspect of policy need not apply to all users or all computers. An attribute of an individual user account can be set to disable forwarding of that user's credentials by any server. An attribute of an individual computer's account can be set to disable forwarding of credentials from any user. In both cases, delegation can be disabled by creating a group policy to apply to all users or all computers in an organizational unit of the Active Directory.


SSPI/Kerberos Interoperability with GSSAPI

Care must be taken when using the Kerberos SSP if interoperability with GSSAPI is a requirement. The following coding conventions allow interoperability with GSSAPI-based applications:

  • Windows 2000 compatible names
  • Authentication
  • Message Integrity and Privacy

Sample code can be found in the Platform SDK under Samples\Winbase\Security\Win200\Gss. In addition, the equivalent Unix sample is distributed in the MIT and Heimdal Kerberos distributions, gss client and server.

Windows 2000 Compatible Names

GSSAPI functions use a name format known as gss_nt_service_name as specified in the RFC. Note in the GSSAPI name, 'nt' does not stand for 'NT.' sample@host.dom.com is an example of a name that can be used in a GSSAPI based application. Windows 2000 does not recognize the gss_nt_service_name format, and the full service principal name, for example sample/host.dom.com@REALM, must be used.

Authentication

Authentication is usually handled when a connection is first set up between a client and server. In this example, the client is using SSPI and the server is using GSSAPI.

In the SSPI client:

  1. Get outbound credentials using AcquireCredentialsHandle.
  2. Create service name with gss_import_name() and get inbound credentials using gss_aquire_cred.
  3. Get authentication token to send to server using InitializeSecurityContext.
  4. Send token to server.

In the GSSAPI server:

  1. Parse message from client to extract security token. Use gss_accept_sec_context passing token as argument.
  2. Parse message from server to extract security token. Pass to InitializeSecurityContext.
  3. Send response token to client.

    gss_accept_sec_context can return a token to send back to the client.

  4. If continue needed, send token to server; otherwise connection is completed
  5. If continue needed, wait for next token from client; otherwise connection is completed

Message Integrity and Privacy

Most GSSAPI-based applications use GSS_Wrap to sign a message before sending it. Conversely, GSS_Unwrap verifies the signature. GSS_Wrap is a new part of the API (v2) and is now widely used and specified in Internet standards that describe using the GSSAPI for adding security to protocols. Earlier, the GSS SignMessage and SealMessage functions were used for message integrity and privacy. GSS_Wrap and GSS_Unwrap are used for both integrity and privacy with the use of privacy controlled by the value of the "conf_flag" argument.

If a GSSAPI-based protocol is specified to use gss_get_mic and gss_verify_mic, the correct SSPI functions would be MakeSignature and VerifySignature. Be aware that MakeSignature and VerifySignature will not interoperate with gss_wrap with conf_flag set to zero or with gss_unwrap. The same is true for mixing EncryptMessage set for signature only and gss_verify_mic.

Note Do not use the MakeSignature or VerifySignature functions when GSS_Wrap and GSS_Unwrap are called for.

The SSPI equivalent to GSS_Wrap is EncryptMessage for both integrity and privacy.

The following code sample shows using EncryptMessage to sign data that will be verified by GSS_Unwrap.

In the SSPI client:

// Need 3 descriptors - 2 for the SSP and one to hold the application data
in_buf_desc.cBuffers = 3;
in_buf_desc.pBuffers = wrap_bufs;
in_buf_desc.ulVersion = SECBUFFER_VERSION;
wrap_bufs[0].cbBuffer = sizes.cbSecurityTrailer;
wrap_bufs[0].BufferType = SECBUFFER_TOKEN;
wrap_bufs[0].pvBuffer = malloc(sizes.cbSecurityTrailer);
// This buffer holds the application data
wrap_bufs[1].BufferType = SECBUFFER_DATA;
wrap_bufs[1].cbBuffer = in_buf.cbBuffer;
wrap_bufs[1].pvBuffer = malloc(wrap_bufs[1].cbBuffer);
memcpy(wrap_bufs[1].pvBuffer, in_buf.pvBuffer, in_buf.cbBuffer);
wrap_bufs[2].BufferType = SECBUFFER_PADDING;
wrap_bufs[2].cbBuffer = sizes.cbBlockSize;
wrap_bufs[2].pvBuffer = malloc(wrap_bufs[2].cbBuffer);
maj_stat = EncryptMessage(&context,
SignOnly ? KERB_WRAP_NO_ENCRYPT : 0,
&in_buf_desc, 0);

// Send message to server

In the GSSAPI server:

// Received message is in recv_buf
maj_stat = gss_unwrap(&min_stat, context, &recv_buf, &msg_buf, &conf_state, (gss_qop_t *) NULL);
(void) gss_release_buffer(&min_stat, &recv_buf);
// Original message is in msg_buf

The SSPI equivalent to GSS_Unwrap is DecryptMessage. Here is a code sample that shows how to use DecryptMessage to decrypt data that was encrypted by GSS_Wrap.

In the GSSAPI server:

// Seal the message
send_buf.value = msg;
send_buf.length = msglen;
// If encrypt_flag = 1, privacy; encrypt_flag = 0, integrity
maj_stat = gss_wrap(&min_stat, context, encrypt_flag, GSS_C_QOP_DEFAULT,
&send_buf, &state, &msg_buf);
// The message to send is in msg_buf

In the SSPI client:

wrap_buf_desc.cBuffers = 2;
wrap_buf_desc.pBuffers = wrap_bufs;
wrap_buf_desc.ulVersion = SECBUFFER_VERSION;
// This buf is for SSPI
wrap_bufs[0].BufferType = SECBUFFER_STREAM;
wrap_bufs[0].pvBuffer = xmit_buf.pvBuffer;
wrap_bufs[0].cbBuffer = xmit_buf.cbBuffer;
// This buf holds the application data
wrap_bufs[1].BufferType = SECBUFFER_DATA;
wrap_bufs[1].cbBuffer = 0;
wrap_bufs[1].pvBuffer = NULL;
maj_stat = DecryptMessage(
&context,
&wrap_buf_desc,
0, // no sequence number
&qop
);
// This is where the data is
msg_buf = wrap_bufs[1];
// Check QOP of received message.
// if qop is KERB_WRAP_NO_ENCRYPT, the message is signed only,
// otherwise it is encrypted.


Using SSPI

This section presents procedures and example code demonstrating SSPI functions and tasks. The code uses function calls and structures described in the SSPI Reference section. The following topics are presented:

  • Procedures Used with Most Security Packages and Protocols
  • Sample SSPI Code


Procedures Used with Most Security Packages and Protocols

The Security Support Provider Interface (SSPI) model provides a single interface for a client/server transport application using the various security packages available on a computer or network. SSPI allows an application to use a security package without dealing with the underlying security protocols of the package. At the same time, SSPI also allows sophisticated, security-aware applications to take advantage of the advanced capabilities of specific security packages.

Applications initialize SSPI using the following steps to secure a network connection for most security packages:

  • Using SecBufferDesc and SecBuffer
  • Initializing SSPI
  • Establishing a Secure Connection with Authentication
  • Ensuring Communication Integrity During Message Exchange
  • Ending an SSPI Session


Using SecBufferDesc and SecBuffer

Communication often involves potentially large amounts of data or data of unknown length. Sending and receiving data is done in similar or identical fashion in both of these cases. To deal with unknown length and potentially large amounts of data, SSPI communication is done using two structures, SecBufferDesc and SecBuffer.

A SecBufferDesc structure is a container for an array of SecBuffer structures. A SecBufferDesc structure has the following members:

  • A version number
  • The number of SecBuffer elements
  • The address of the array of SecBuffer structures

A SecBuffer structure contains the following three members:

  • A number indication of the number of bytes to be used
  • Information on the type information contained in the data item
  • The bytes themselves

A whole SSPI message often consists of an array of SecBuffer structures.

The following buffer data types are defined as follows.

Buffer type | Meaning
SECBUFFER_EMPTY | Undefined, replaced by the security package function
SECBUFFER_DATA | Packet data
SECBUFFER_TOKEN | Security token
SECBUFFER_PKG_PARAMS | Package-specific parameters
SECBUFFER_MISSING | Missing data indicator
SECBUFFER_EXTRA | Extra data
SECBUFFER_STREAM | Security stream data
SECBUFFER_STREAM_TRAILER | Security stream trailer
SECBUFFER_STREAM_HEADER | Security stream header

The buffer types above can be combined using a bitwise-OR operation with either of the following buffer types.

Buffer type | Meaning
SECBUFFER_ATTRMASK | Mask security attributes by separating the attribute flags from the buffer type.
SECBUFFER_READONLY | Buffer is read-only

Before each call to an SSPI API that requires a SecBufferDesc parameter, one or more SecBuffer arrays are declared and initialized. For example, there can be two security buffers: one that contains input message data and the other for the output opaque security token returned by the security package. The order of security buffers in the security buffer descriptor is not important, but each buffer must be tagged with its appropriate type. A read-only tag can be used with any input buffer that must not be modified by the security package.

The size of the output buffer that is expected to contain the security token is important. An application can find the maximum token size for a security package during initial setup. The call to EnumerateSecurityPackages returns an array of pointers to security package information. The security package information structure contains the maximum token size for each package. In the example code, the information is in the cbMaxToken member of the SecPkgInfo structure. The same information can be obtained later using QuerySecurityPackageInfo.

The application initializes the buffer pointers and sizes in the buffer description to indicate where message data and other information can be found.

For details, see SecBuffer and SecBufferDesc Example Code.


Initializing SSPI

The client and server use the same sequence of operations to initialize SSPI, and select a security package.

The following steps initialize SSPI:

  • Loading the Security Support Provider DLL
  • Initializing the Security Package
  • Getting Information About Security Packages
  • Using Security Packages


Loading the Security Support Provider DLL

To use SSPI with Microsoft® Windows NT®/Microsoft® Windows® 2000, both the client and server components of a transport application call the LoadLibrary function to load Secur32.dll, a security support provider (SSP). This SSP supports all security packages available on the system, including:

  • Kerberos package
  • NTLM package
  • MSN package
  • Negotiate and Negotiate2 packages

The Kerberos package is available only with Windows 2000 or later.

For code using LoadLibrary, see the InitPackage function in Using SSPI with a Windows Sockets Client or Using SSPI with a Windows Sockets Server.


Writing and Installing a Security Support Provider

The design of SSPI enables additional SSPs to be written and added to the system. An SSP specific to a security model can be developed with relative ease or great complexity, depending on the level of integration with the operating system. A client SSP that allows connections to a new type of server could be developed very quickly, whereas a full SSP that provides local impersonation would require more effort.

SSPs are installed by updating a value in the registry, located as follows:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control
SecurityProviders
SecurityProviders = REG_SZ provider1.dll, provider2.dll,...

A single DLL can contain multiple SSPs.


Initializing the Security Package

After the DLL has been loaded, additional setup steps enable SSPI for the rest of the application.

Note Beginning with Windows 2000, a special Negotiate package can be used where agreement between client and server about which security package to use is done behind the scenes. If the Negotiate package is not used, the client and server must agree on the specific security package to use before performing the additional setup steps below.

These steps are necessary before using SSPI:

  1. A pointer to the initialization function must be acquired.

    Both the client and server call GetProcAddress to get a pointer to the initialization function, InitSecurityInterface.

  2. The initialization function must be called to obtain the address of the security function table.

    The client and server use the pointer returned by GetProcAddress to call InitSecurityInterface for a pointer to a SecurityFunctionTable dispatch table. This table contains pointers to callback functions declared in Sspi.h. These pointers provide access to the DLL's implementations of the various SSPI functions.

  3. Information must be obtained about the supported security packages.

    While most applications use security packages that support default or common capabilities, security packages can have unique capabilities of interest to the application. An application needing special capabilities can use a package that offers those capabilities. For more information, see Getting Information About Security Packages.

At this point, the application has successfully initialized an SSP and chosen a security package with sufficient capabilities.


Getting Information About Security Packages

When a client begins, it selects a security package for its transactions with a server and then contacts that server. A server selects one or more security packages and waits for a client connection.

For specific information about the SSPI security packages available with a particular SSP, the EnumerateSecurityPackages function can be called to retrieve a SecPkgInfo structure.

To retrieve the output structure, the caller passes to the function the address of a pointer to the type of the return structure. The function allocates memory and returns the data to the caller by assigning the address of the return data buffer to the argument. The SSPI convention is that the functions allocates memory for the structure and the calling application frees that memory using FreeContextBuffer.

Calling the QuerySecurityPackageInfo function retrieves the attributes of a security package. Both server and client can call QuerySecurityPackageInfo to get the maximum length of the security token from the cbMaxToken member of the SecPkgInfo structure. See the example in the InitPackage function in Using SSPI with a Windows Sockets Client or Using SSPI with a Windows Sockets Server.

For more information on package functions, see Package Management.


Using Security Packages

This section presents specifics about using Security Support Provider Interface (SSPI) with the following security packages:

  • NTLM
  • Kerberos

The Kerberos and NTLM protocols are implemented as security packages from the Secur32.dll SSP supplied with the Windows 2000 operating system. By default, support for both Kerberos and NTLM authentication are loaded by the local security authority (LSA) on a computer running Windows 2000 when the system boots. In Windows 2000 domains, either package can be used to authenticate network logons and client/server connections. Which one is used depends on the capabilities of the computer on the other side of the connection. The Kerberos protocol is always the first choice if available.

After a security context for an interactive user has been established, another instance of the Kerberos or NTLM package can be loaded by a process running in the user's security context to support the exchanging, signing, and verifying of messages. Windows 2000 also allows encrypting and decrypting messages. But no process other than the LSA is ever permitted access to session keys or tickets in the credentials cache.

System services and transport-level applications access a security support provider (SSP) through SSPI which provides functions for enumerating the security packages available on a system, selecting a packages, and using that package to obtain an authenticated connection.

The methods in SSPI are generic, black-box routines that developers can use without knowing the details of a particular security protocol. For example, when a client/server connection is authenticated, the application on the client's side of the connection sends credentials to the server using the SSPI function InitializeSecurityContext. The application on the server's side of the connection responds with the SSPI function AcceptSecurityContext. Once the connection has been authenticated, the LSA on the server uses information from the client to build an access token. The server can then call the SSPI function ImpersonateSecurityContext to attach the access token to an impersonation thread for the service.

NTLM Security Package

The NTLM security package is based on the NTLM authentication protocol. NTLM ships with the following products:

  • Microsoft® Windows NT® version 3.5 and later
  • Microsoft® Windows® 95 and later
  • The RPC SDK for Windows 3.1, MS-DOS®, and Macintosh platforms

Kerberos Security Package

The Kerberos security package is based on the Kerberos authentication protocol.

If the Kerberos protocol is being used to authenticate a client/server connection, InitializeSecurityContext generates a GSSAPI message that includes a KRB_AP_REQ message from the client. AcceptSecurityContext then generates a GSSAPI message that includes a KRB_AP_REP message from the server.

For background information on the steps that take place behind the scenes in the implementation of a Kerberos protocol, see Overview of the Kerberos Protocol.

All distributed services in Windows 2000 use SSPI to access the Kerberos protocol. A partial list of the ways in which the Kerberos protocol is used for authentication includes:

  • Print spooler services
  • CIFS/SMB remote file access
  • LDAP queries to the Active Directory
  • Distributed file system management and referrals
  • IPSec host-to-host security authority authentication
  • Reservation requests for network Quality of Service
  • Intranet authentication to Internet Information Services
  • Remote server or workstation management using authenticated RPC
  • Certificate requests to Certificate Services for domain users and computers


Establishing a Secure Connection with Authentication

In a client/server application protocol, a server binds to a communication port such as a socket or an RPC interface. The server then waits for a client to connect and request service. The role of security at connection setup is two-fold in the case of mutual authentication:

  • Client authentication by the server.
  • Server authentication by the client.

The client and server components of a transport application use a security package to establish a secure connection for transmitting messages. The first step in establishing a secure connection is to create a security context; that is, an opaque data structure that contains the security data relevant to a connection, such as a session key and the duration of the session.

A security context is essentially a message from the security package associated with the client to the security package associated with the server. Consequently, creating a security context typically requires both client and server to make calls to their respective security packages. For more information on context functions, see Context Management.

The protocol used to establish a secure, authenticated connection involves the exchange of one or more "security tokens" between the client and the server/. These tokens are sent as opaque messages by the two sides along with any other application protocol-specific information. As an opaque message, the token is received from a security package function by the client, which cannot interpret or change it, and forwarded as a message to the server. The token is also opaque to the server, which can neither interpret nor change the token. The server forwards the opaque token to its security package for interpretation. The package then informs the server of the client authentication or failure to authenticate.

The client receives the server's token in a message, retrieves the token from the received message, and uses that token in a call to its security package. The client then calls the security package again indicating whether a secure connection has been established or whether further exchanges are needed before a secure connection is ready. Theoretically, there is no limit to the number of exchanges of security tokens needed. In practice, only a limited number of exchanges is required. NTLM authentication is based on the challenge/response scheme, and uses three legs to authenticate a client to the server. The Kerberos version 5.0 protocol can require additional message exchanges.


Client Context Initialization

To establish a secure connection, the client acquires an outbound credentials handle before sending an authentication request to the server. The server creates a security context for the client from the authentication request. There are two client-side SSPI functions involved in authentication setup:

  • AcquireCredentialsHandle obtains a reference to previously obtained logon credentials.
  • InitializeSecurityContext creates the initial authentication request security tokens.

Code for this process can be seen in the GenClientContext function in Using SSPI with a Windows Sockets Client.

If a client program needs to use credentials in addition to its own logon credentials, such as a different user name, domain name, and password, it provides them in the AcquireCredentialsHandle call with a SEC_WINNT_AUTH_IDENTITY structure specifying the additional credentials. For more information on credentials functions, see Credential Management.

Note The Flags member of the SEC_WINNT_AUTH_IDENTITY structure can be set to SEC_WINNT_AUTH_IDENTITY_ANSI when strings in the structure are ASCI or OEM. ANSI strings can be used with the Flags member of the SEC_WINNT_AUTH_IDENTITY structure set to SEC_WINNT_AUTH_IDENTITY_UNICODEif they are first converted to Unicode using the MultByteToWideChar function. .

The following code uses the GenClientContext function to acquire alternate credentials. This example uses the Negotiate package that is the preferred package for use with Windows 2000; however, note that the Negotiate package is not supported on any earlier platform.

//--------------------------------------------------------------------
// This code fills in any additional credentials. The string
// UserName holds the name of the user for whom the additional
// credentials are being acquired. DomainName and Password are strings
// with the domain name and the password associated with the user.

SEC_WINNT_AUTH_IDENTITY AdditionalCredentials;

CredHand ClientCredentials;
TimeStamp Expiration;
AdditionalCredentials.User = UserName;
AdditionalCredentials.UserLength = strlen(UserName);
AdditionalCredentials.Domain = DomainName;
AdditionalCredentials.DomainLength=strlen(DomainName);
AdditionalCredentials.Password = Password;
AdditionalCredentials.PasswordLength = strlen(Password);

#ifdef UNICODE
AdditionalCredentials.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE
#else
AdditionalCredentials.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI
#endif

SecStatus = AcquireCredentialsHandle(
    NULL,                       // no principal name
    "negotiate",                // package name
    SECPKG_CRED_OUTBOUND,       // credential use flag
    NULL,                       // no logon identifier
    &AdditionalCredentials      // the address of the
                                // data structure containing
                                // the alternative credentials.
    NULL,                       // no GetKey function
    NULL,                       // no GetKey function argument
    &ClientCredential,          // receives the new credential
    &Expiration);

To initiate the first leg of the authentication, the client calls InitializeSecurityContext to obtain an initial security token to be sent in a connection request message to the server.

The client uses the security token information received in the output buffer descriptor to generate a message to send to the server. The construction of the message, in terms of placement of various buffers and so forth, is part of the application protocol and must be understood by both parties.

The client checks the return status from InitializeSecurityContext to see if authentication will complete in a single call. A return status of SEC_I_CONTINUE_NEEDED indicates that the security protocol requires multiple authentication messages. For more information on context functions, see Context Management.


Client Continuation

Some protocols require multiple authentication messages. In this case, the client parses the response from the server and calls InitializeSecurityContext again using the continue status from the previous call. The client checks the return status from this call and might be required to continue for additional legs. It uses the information in OutputBufferDescriptor to construct a message and send it to the server.


Server Context Initialization

Like the client, the server also acquires a credentials handle to be ready to respond to an incoming authentication request from the client. Server credentials are used to authenticate the server to the client in security protocols that support server authentication or mutual authentication. The server obtains a handle to its credentials defined by the service account used to start the server. It does so by calling AcquireCredentialsHandle.

The server can acquire its credentials handle and then go into a listen state, or it can wait in a listen state until a connection request arrives and then acquire an inbound credentials handle. For more information on credentials functions, see Credential Management.

When the server receives a connection request message from a client, it creates a local security context for the client using AcceptSecurityContext. The server uses this local security context to carry out future requests by the same client. For more information on context functions, see Context Management.

The server checks the return status and output buffer descriptor to ensure there are no errors so far, and can reject the connection request if there are errors. If there is information in the output buffer returned by AcceptSecurityContext, it bundles that buffer into a response message to the client.

Any output buffer from AcceptSecurityContext must be sent back to the client. In addition, if the return status requires the protocol to continue (SEC_I_CONTINUE_NEEDED or SEC_I_COMPLETE_AND_CONTINUE), another message exchange with the client is required.

For additional legs, the server waits for the client to respond with another message. This wait can be timed out so as to avoid a denial of service attack where a client purposely never responds, thus hanging a server thread so that soon all server threads will hang.


Server Continuation

Based on the return code from a previous call to AcceptSecurityContext, the server can wait for a response from the client and can participate in additional exchanges with the client. To continue the authentication protocol, the server repeats calls to AcceptSecurityContext.

The status returned by AcceptSecurityContext is checked to see if the server needs to wait for additional messages from the client. In most authentication protocols, there is the maximum number of exchanges even for mutual authentication. Currently, both the NTLM and Kerberos protocols do mutual authentication with three exchanges.


Ensuring Communication Integrity During Message Exchange

After a security context is established, the application can use the message support functions to transmit tamper-resistant messages.

The client or server passes the security context and a message to the MakeSignature function to generate a secure signature that prevents the message from being modified while in transit. The receiver of the message calls the VerifySignature function. VerifySignature uses the information in the signature to verify that the message received was not modified during transmission. The client and server can also exchange encrypted messages using EncryptMessage and DecryptMessage.

The server in an authenticated connection can also make connections with other remote computers in the name of the client after calling ImpersonateSecurityContext.


Ending an SSPI Session

After the client and server have finished communicating, both sides call the DeleteSecurityContext function with their respective context handles. The client must also call the FreeCredentialsHandle function when it has finished communicating with any server or has finished using the additional credentials passed to the AcquireCredentialsHandle function. The server must call DeleteSecurityContext when it is ready to shut down, but before unloading the DLL.


Sample SSPI Code

This section includes two complete programs:

  • Using SSPI with a Windows Sockets Client
  • Using SSPI with a Windows Sockets Server

Both of these programs use functions that are defined in Utility Functions for Windows Sockets Client and Server.

The following example code is also included.

  • SecBuffer and SecBufferDesc Example Code
  • Using Message Support


Using SSPI with a Windows Sockets Client

This sample program works with the server program Using SSPI with a Windows Sockets Server. Both this program and the server program call some identical utility functions that are included in Utility Functions for Windows Sockets Client and Server. This program includes calls to functions in Ws2_32.lib, which must be included among the link libraries.

This program demonstrates the following:

  • Establishing a Windows Sockets connection with a server.
  • Initializing an SSPI session.
  • Connecting with a server and establishing a secure communication session
  • Receiving a message from the server within the secure session.

This sample code uses limited error handling.

//--------------------------------------------------------------------
//      Client-side program to establish an SSPI socket connection
//      with a server and exchange messages.

//--------------------------------------------------------------------
//     Define macros and constants.

#define SEC_SUCCESS(Status) ((Status) >= 0)
// Change the following define statement to use "Kerberos"
// For Windows 2000, it could also be "Negotiate" to choose the best
// possible package available to both client and server.
#define PACKAGE_NAME "NTLM"
#define NT_DLL_NAME "security.dll"
// secur32.dll could also be used.
#define TOKEN_SOURCE_NAME       "AuthSamp"
#define SECURITY_WIN32
#define SERVER_NAME "SampleServer1"
#define wVerRequested 0x0101

//--------------------------------------------------------------------
//     Include header files.

#include <windows.h>
#include <winsock.h>
#include <stdio.h>
#include <stdlib.h>
#include "sspi.h"

//--------------------------------------------------------------------
//     Declare and initialize global structures and variables

typedef struct _AUTH_SEQ {
    BOOL _fNewConversation;
    CredHandle _hcred;
    BOOL _fHaveCredHandle;
    BOOL _fHaveCtxtHandle;
    SecHandle  _hctxt;
} AUTH_SEQ, *PAUTH_SEQ;

static PAUTH_SEQ pAS;
static HINSTANCE g_hLib;
static DWORD g_cbMaxToken;
static PSecurityFunctionTable g_pFuncs;
static PBYTE g_pInBuf = NULL;
static PBYTE g_pOutBuf = NULL;
static DWORD g_cbMaxMessage = 0;
static unsigned short g_usPort = 2000;

//--------------------------------------------------------------------
//     Declare function prototypes.

BOOL ConnectAuthSocket(LPCSTR szServer, SOCKET *s);
BOOL CloseAuthSocket(SOCKET s);
BOOL DoAuthentication(SOCKET s);
BOOL GenClientContext (DWORD dwKey, BYTE *pIn, DWORD cbIn, BYTE *pOut,
        DWORD *pcbOut, BOOL *pfDone);
BOOL InitPackage (DWORD *pcbMaxMessage) ;
BOOL InitSession ();
BOOL SendMsg(SOCKET s, PBYTE pBuf, DWORD cbBuf) ;
BOOL ReceiveMsg(SOCKET s, PBYTE pBuf, DWORD cbBuf, DWORD *pcbRead) ;
BOOL SendBytes(SOCKET s, PBYTE pBuf, DWORD cbBuf) ;
BOOL ReceiveBytes(SOCKET s, PBYTE pBuf, DWORD cbBuf, DWORD *pcbRead) ;
void HandleError(char *s);
void UseSession(SOCKET s, SecHandle phContext);

//--------------------------------------------------------------------
//      Define main()

void main()
{
//--------------------------------------------------------------------
//     Declare and initialize local variables.

SOCKET s;
WSADATA wsaData;

//--------------------------------------------------------------------
//      Initialize Windows Sockets

WSAStartup (wVerRequested, &wsaData);

//--------------------------------------------------------------------
//      Initialize the SSPI security package.

if (!(InitPackage (&g_cbMaxMessage)))
{
     HandleError("The security package could not be initialized.");
}

//--------------------------------------------------------------------
//      Allocate memory for the input and output message buffers.

g_pInBuf = (BYTE *) malloc (g_cbMaxMessage+512);
g_pOutBuf = (BYTE *) malloc (g_cbMaxMessage+512);

//--------------------------------------------------------------------
//      Connect to server

if (!(ConnectAuthSocket (SERVER_NAME, &s)))
{
     HandleError("Could not connect to the socket.");
}

//--------------------------------------------------------------------
//      Make this an authenticated connection

if (!(InitSession ()) )
{
     HandleError("The connection could not be initialized.");
}

if (!(DoAuthentication (s)))
{
     HandleError("The connection could not be authenticated.");
}
//--------------------------------------------------------------------
//     Do some processing in the secure connection.

UseSession(s, pAS->_hctxt);

//--------------------------------------------------------------------
//     Clean up and terminate

g_pFuncs->DeleteSecurityContext (&pAS->_hctxt);
g_pFuncs->FreeCredentialHandle (&pAS->_hcred);
free (pAS);
shutdown (s, 2);
closesocket (s);
FreeLibrary (g_hLib);
WSACleanup ();
free (g_pInBuf);
free (g_pOutBuf);
printf("Program ran to completion.\n");
} // End of main

//--------------------------------------------------------------------
//     Define ConnectAuthSocket()
//     Connect to the Windows Sockets server.

BOOL ConnectAuthSocket (
          LPCSTR szServer,  // server name.
          SOCKET *s)        // pointer to the socket.
{
//--------------------------------------------------------------------
//     Declare and initialize local variables.

SOCKET sockServer;
unsigned long ulAddress;
struct hostent *pHost;
SOCKADDR_IN sin;

//--------------------------------------------------------------------
//      Look up the address for the server name

ulAddress = inet_addr (szServer);
if(pHost = gethostbyname (szServer))
{
     memcpy((char FAR *)&ulAddress, pHost->h_addr, pHost->h_length);
}
else
{
     HandleError("Unable to resolve host name.");
}

//--------------------------------------------------------------------
//      Create the socket

if(!(sockServer = socket (
     PF_INET,
     SOCK_STREAM,
     0)))
{
     HandleError("Unable to create socket.");
}

sin.sin_family = AF_INET;
sin.sin_addr.s_addr = ulAddress;
sin.sin_port = htons (g_usPort);

//--------------------------------------------------------------------
//      Connect to remote endpoint

if (connect (
     sockServer,
     (LPSOCKADDR) &sin,
     sizeof (sin)))
{
     HandleError("connect failed:");
}

*s = sockServer;
return(TRUE);
} // End ConnectAuthSocket

//--------------------------------------------------------------------
//     Define DoAuthentication().
//     Manage the authentication conversation with the server via the
//     supplied socket handle.

BOOL DoAuthentication (SOCKET s)
{
//--------------------------------------------------------------------
//     Declare and initialize local variables.

BOOL fDone = FALSE;
DWORD cbOut, cbIn;

cbOut = g_cbMaxMessage;
if (!(GenClientContext (
     s,
     NULL,
     0,
     g_pOutBuf,
     &cbOut,
     &fDone)))
{
     HandleError("Client context could not be generated.");
}

if (!(SendMsg (
     s,
     g_pOutBuf,
     cbOut)))
{
     HandleError("Message could not be sent.");
}

while(!fDone)
{
     if (!(ReceiveMsg(
          s,
          g_pInBuf,
          g_cbMaxMessage,
          &cbIn)))
     {
          HandleError("Message not received.");
     }
     cbOut = g_cbMaxMessage;
     GenClientContext (
          s,
          g_pInBuf,
          cbIn,
          g_pOutBuf,
          &cbOut,
          &fDone);
     if (!(SendMsg (
          s,
          g_pOutBuf,
          cbOut)))
     {
          HandleError("Message not sent.");
     }
} // End of while loop
return(fDone);
} // End of DoAuthentication

//--------------------------------------------------------------------
//      Handle communication with the security package.

//--------------------------------------------------------------------
//     Define InitPackage()

BOOL InitPackage (DWORD *pcbMaxMessage)
{
//--------------------------------------------------------------------
//     Declare and initialize local variables.

FARPROC pInit;
SECURITY_STATUS ss;
PSecPkgInfo pkgInfo;
ULONG cPackages, i;
SecPkgInfo *ppPackageInfo;

//--------------------------------------------------------------------
//     Load and initialize an security package library

if(!(g_hLib = LoadLibrary (NT_DLL_NAME)))
{
     HandleError("Could not load DLL.");
}

if(!(pInit = GetProcAddress (g_hLib, SECURITY_ENTRYPOINT)))
{
     HandleError("Could not get sec init routine.");
}

if(!(g_pFuncs = (PSecurityFunctionTable) pInit ()))
{
     HandleError("Could not initialize the security package");
}

//--------------------------------------------------------------------
// List the available packages

ss = g_pFuncs->EnumerateSecurityPackages(
  &cPackages,
  &ppPackageInfo  );
if( SEC_SUCCESS(ss))
{
     printf("The names of the available packages are:\n");
     for(i=0;i<cPackages;i++)
     {
          printf("%s \n",ppPackageInfo[i].Name);
     }
}
else
{
     HandleError("Listing the packages failed.");
}

//--------------------------------------------------------------------
//  Query one of the packages for the maximum token length.

ss = g_pFuncs->QuerySecurityPackageInfo (PACKAGE_NAME, &pkgInfo);
if (!SEC_SUCCESS(ss))
{
     HandleError("Could not query package information.");
}

g_cbMaxToken = pkgInfo->cbMaxToken;
g_pFuncs->FreeContextBuffer (pkgInfo);
*pcbMaxMessage = g_cbMaxToken;
return TRUE;
}

//--------------------------------------------------------------------
//     Define GenClientContext().

BOOL GenClientContext (
DWORD dwKey,
BYTE *pIn,
DWORD cbIn,
BYTE *pOut,
DWORD *pcbOut,
BOOL *pfDone)
{
//--------------------------------------------------------------------
//     Declare and initialize local variables.

SECURITY_STATUS ss;
TimeStamp Lifetime;
SecBufferDesc OutBuffDesc;
SecBufferDesc InBuffDesc;
SecBuffer OutSecBuff;
SecBuffer InSecBuff;
ULONG ContextAttributes;

if (pAS->_fNewConversation)
{
     ss = g_pFuncs->AcquireCredentialsHandle (
        NULL,           // use the default principal
        PACKAGE_NAME,
        SECPKG_CRED_OUTBOUND,
        NULL,          // use the default LOGON id
        NULL,          // no authentication data
        NULL,          // no callback function needed to get a key
        NULL,          // no callback function arguments needed
        &pAS->_hcred,
        &Lifetime);
     if (SEC_SUCCESS (ss))
     {
         pAS->_fHaveCredHandle = TRUE;
     }
     else
     {
          HandleError("AcquireCreds failed.");
     }
}

//--------------------------------------------------------------------
//      Prepare buffers
//
OutBuffDesc.ulVersion = 0;
OutBuffDesc.cBuffers = 1;
OutBuffDesc.pBuffers = &OutSecBuff;

OutSecBuff.cbBuffer = *pcbOut;
OutSecBuff.BufferType = SECBUFFER_TOKEN;
OutSecBuff.pvBuffer = pOut;

if (!pAS->_fNewConversation)
{
     InBuffDesc.ulVersion = 0;
     InBuffDesc.cBuffers = 1;
     InBuffDesc.pBuffers = &InSecBuff;

     InSecBuff.cbBuffer = cbIn;
     InSecBuff.BufferType = SECBUFFER_TOKEN;
     InSecBuff.pvBuffer = pIn;
}

ss = g_pFuncs->InitializeSecurityContext(
     &pAS->_hcred,
     pAS->_fNewConversation ? NULL : &pAS->_hctxt,
     TOKEN_SOURCE_NAME,
     0,// context requirements
     0,// reserved1
     SECURITY_NATIVE_DREP,
     pAS->_fNewConversation ? NULL : &InBuffDesc,
     0,// reserved2
     &pAS->_hctxt,
     &OutBuffDesc,
     &ContextAttributes,
     &Lifetime
);

if (!SEC_SUCCESS (ss))
{
     HandleError("init context failed.");
}
pAS->_fHaveCtxtHandle = TRUE;

//--------------------------------------------------------------------
//      Complete token -- if applicable
//
if ((SEC_I_COMPLETE_NEEDED == ss) || (SEC_I_COMPLETE_AND_CONTINUE == ss))
{
     if (g_pFuncs->CompleteAuthToken)
     {
          ss = g_pFuncs->CompleteAuthToken (
               &pAS->_hctxt,
               &OutBuffDesc);
          if (!SEC_SUCCESS(ss))
          {
               HandleError("Complete failed.");
          }
     }
     else
     {
          HandleError("Complete not supported.");
     }
}
*pcbOut = OutSecBuff.cbBuffer;
pAS->_fNewConversation = FALSE;
*pfDone = !((SEC_I_CONTINUE_NEEDED == ss) ||
     (SEC_I_COMPLETE_AND_CONTINUE == ss));
return TRUE;
} // end GenClientContext

//--------------------------------------------------------------------
//     Define InitSession(),

BOOL InitSession ()
{

pAS = (PAUTH_SEQ) malloc (sizeof (AUTH_SEQ));
if (NULL == pAS)
{
     return(FALSE);
}

pAS->_fNewConversation = TRUE;
pAS->_fHaveCredHandle = FALSE;
pAS->_fHaveCtxtHandle = FALSE;

return(TRUE);
} // end InitSession

//--------------------------------------------------------------------
//     Define UseSession().
void UseSession(SOCKET s, SecHandle phContext)
{
//--------------------------------------------------------------------
//     Declare and initialize local variables.

int cbRead;
char achData[BUFSIZ];

if (ReceiveMsg(
     s,
     (BYTE *) achData,
     g_cbMaxMessage,
     (unsigned long *)&cbRead))
{
     printf ("First read: %d %s\n", cbRead, achData);
}
else
{
     HandleError("Message not received.");
}

if (ReceiveMsg (
     s,
     (BYTE *) achData,
     g_cbMaxMessage,
     (unsigned long *)&cbRead))
{
     printf ("Second read: %d %s\n", cbRead, achData);
}
else
{
     HandleError("Message not received.");
}
} // end of UseSession.


Using SSPI with a Windows Sockets Server

This sample program works with the client program Using SSPI with a Windows Sockets Client. Both this program and the client program call some identical utility functions that are included in Utility Functions for Windows Sockets Client and Server. This program includes calls to functions in Ws2_32.lib, which must be included among the link libraries.

This program demonstrates the following:

  • Establishing a Windows Sockets connection with a client.
  • Initializing an SSPI session.
  • Connecting with a client and establishing a secure communication session
  • Receiving a message from the client within the secure session

This sample code uses limited error handling.

//--------------------------------------------------------------------
//     Server-side SSPI Windows Sockets program.

#define SEC_SUCCESS(Status) ((Status) >= 0)
#define SECURITY_WIN32
// Change the following define statement to use "Kerberos"
// For Windows 2000, it could also be "Negotiate" to choose the best
// possible package available to both client and server.
##define PACKAGE_NAME "NTLM"
#define NT_DLL_NAME "secur32.dll"
#define TOKEN_SOURCE_NAME       "AuthSamp"
#define wVerRequested 0x0101
//--------------------------------------------------------------------
//     Include header files

#include <windows.h>
#include <winsock.h>
#include <stdio.h>
#include <stdlib.h>
#include "comm.h"
#include "security.h"
#include "sspi.h"

//--------------------------------------------------------------------
//      Declare and initialize structures and global variables

typedef struct _AUTH_SEQ {
    BOOL _fNewConversation;
    CredHandle _hcred;
    BOOL _fHaveCredHandle;
    BOOL _fHaveCtxtHandle;
    SecHandle  _hctxt;
} AUTH_SEQ, *PAUTH_SEQ;

static PAUTH_SEQ pAS;
static PBYTE g_pInBuf = NULL;
static PBYTE g_pOutBuf = NULL;
static DWORD g_cbMaxMessage = 0;
static unsigned short g_usPort = 2000;
static HINSTANCE g_hLib;
static DWORD g_cbMaxToken;
static PSecurityFunctionTable g_pFuncs;

//--------------------------------------------------------------------
//     Declare function prototypes

BOOL AcceptAuthSocket (SOCKET *s);
BOOL CloseAuthSocket(SOCKET s);
BOOL DoAuthentication(SOCKET s);
BOOL InitWinsock() ;
BOOL SendMsg(SOCKET s, PBYTE pBuf, DWORD cbBuf) ;
BOOL ReceiveMsg(SOCKET s, PBYTE pBuf, DWORD cbBuf, DWORD *pcbRead)
BOOL SendBytes(SOCKET s, PBYTE pBuf, DWORD cbBuf) ;
BOOL ReceiveBytes(SOCKET s, PBYTE pBuf, DWORD cbBuf, DWORD *pcbRead) ;
void HandleError(char *s);
void UseSession(SOCKET s, SecHandle phContext);

//--------------------------------------------------------------------
//     Begin main()

void main ()
{
SOCKET s;
WSADATA wsaData;

//--------------------------------------------------------------------
//      Initialize the Windows socket

WSAStartup (wVerRequested, &wsaData);

if (!(InitPackage (&g_cbMaxMessage)))
{
     HandleError("Security package not initialized.\n");
}

g_pOutBuf = (PBYTE) malloc (g_cbMaxMessage);
g_pInBuf = (PBYTE) malloc (g_cbMaxMessage);

//--------------------------------------------------------------------
//      Make an authenticated connection with client

if (!(AcceptAuthSocket (&s)))
{
     HandleError("AcceptAuthSocket failed.\n");
}

//--------------------------------------------------------------------
//     Do processing in the SSPI authenticated secure connection

UseSession(s, pAS->hctxt);

//--------------------------------------------------------------------
//      Terminate the session and clean-up.

if (pAS->_fHaveCredHandle)
{
     g_pFuncs->FreeCredentialHandle (&pAS->_hcred);
}
free (pAS);
shutdown (s, 2);
closesocket (s);
FreeLibrary (g_hLib);
WSACleanup ();
free (g_pInBuf);
free (g_pOutBuf);
printf("The server-side program ran to completion without error.");
} // end of main

//--------------------------------------------------------------------
//     Define AcceptAuthSocket.

BOOL AcceptAuthSocket (SOCKET *s)
{
SOCKET sockListen;
SOCKET sockClient;
SOCKADDR_IN sin;
int nRes;

//--------------------------------------------------------------------
//      Create listening socket
//
printf("Listening ");

sockListen = socket (PF_INET, SOCK_STREAM, 0);
if (INVALID_SOCKET == sockListen)
{
     HandleError("Failed to create socket.");
}

sin.sin_family = AF_INET;
sin.sin_addr.s_addr = 0;
sin.sin_port = htons(g_usPort);
nRes = bind (sockListen, (LPSOCKADDR) &sin, sizeof (sin));
if (SOCKET_ERROR == nRes)
{
     HandleError("bind failed: \n");
}

if (SOCKET_ERROR == listen (sockListen, 1))
{
     HandleError("listen failed");
}

sockClient = accept (sockListen, NULL, NULL);
if (INVALID_SOCKET == sockClient)
{
     HandleError("accept failed: ");
}

closesocket (sockListen);

if (!(InitSession (sockClient)))
{
     HandleError("Session not initalized.\n");
}

if (!(DoAuthentication (sockClient)))
{
     HandleError("Authentication did not work.");
}

//--------------------------------------------------------------------
//      Set value of *s to the returned socket.

*s = sockClient;
return(TRUE);
}

//--------------------------------------------------------------------
//      Define DoAuthentication()
//      Manage the authentication conversation with the client by the
//      supplied socket handle.

BOOL DoAuthentication (SOCKET s)
{
DWORD cbIn, cbOut;
BOOL fDone = FALSE;

while(!fDone);
{
     if (!(ReceiveMsg (
          s,
          g_pInBuf,
          g_cbMaxMessage,
          &cbIn)))
     {
          HandleError("ReceiveMsg failed in DoAuthentication.");
     }
     cbOut = g_cbMaxMessage;

     if (!(GenServerContext (
          s,
          g_pInBuf,
          cbIn,
          g_pOutBuf,
          &cbOut,
          &fDone)))
     {
          HandleError("GenServerContext failed.\n");
     }
    if(!fDone)
    {
         if (!(SendMsg (
              s,
              g_pOutBuf,
              cbOut)))
          {
              HandleError("Message not sent from DoAuthentication.");
           }
     }
}  // end while loop.
return(TRUE);
}

//--------------------------------------------------------------------
//      Handle communication with the security package.

//--------------------------------------------------------------------
//     Define InitPackage()
//     Find, load, and initialize the security package
//     Return TRUE is successful, otherwise FALSE.

BOOL InitPackage (DWORD *pcbMaxMessage)
{
FARPROC pInit;
SECURITY_STATUS ss;
PSecPkgInfo pkgInfo;
ULONG cPackages, i;
SecPkgInfo *ppPackageInfo;

//--------------------------------------------------------------------
//     Load the SSPI Library
       Load and initialize a security package.

if(!(g_hLib = LoadLibrary (NT_DLL_NAME)))
{
     HandleError("Could not load the dll.");
}

if(!(pInit = GetProcAddress (g_hLib, SECURITY_ENTRYPOINT)))
{
     HandleError("Could not get security initialization routine.");
}

if(!(g_pFuncs = (PSecurityFunctionTable) pInit ()))
{
     HandleError("Could not initialize the security package.");
}

//--------------------------------------------------------------------
//      List the available security packages.

ss = g_pFuncs->EnumerateSecurityPackages(
     &cPackages,
     &ppPackageInfo  );
if( SEC_SUCCESS(ss))
{
     printf("The security packages available are:\n");
     for(i=0;i<cPackages;i++)
     {
          printf("%s \n",ppPackageInfo[i].Name);
     }
}
else
{
     HandleError("Could not list available security packages.");
}

//--------------------------------------------------------------------
//      Query the security package for the maximum token length..

ss = g_pFuncs->QuerySecurityPackageInfo (PACKAGE_NAME, &pkgInfo);
if (!(SEC_SUCCESS(ss)))
{
     HandleError("Could not query selected package information.");
}

g_cbMaxToken = pkgInfo->cbMaxToken;
g_pFuncs->FreeContextBuffer (pkgInfo);
*pcbMaxMessage = g_cbMaxToken;
return TRUE;
}

//--------------------------------------------------------------------
//     Define GenServerContext()
//    Take an input buffer coming from the client and return a buffer
//    to be sent to the client. Also returns an indication of whether
//    or not the context is complete.

BOOL GenServerContext (
DWORD dwKey,
BYTE *pIn,
DWORD cbIn,
BYTE *pOut,
DWORD *pcbOut,
BOOL *pfDone)
{
SECURITY_STATUS ss;
TimeStamp Lifetime;
SecBufferDesc OutBuffDesc;
SecBuffer OutSecBuff;
SecBufferDesc InBuffDesc;
SecBuffer InSecBuff;
ULONG ContextAttributes;

if (pAS->_fNewConversation)
{
     ss = g_pFuncs->AcquireCredentialsHandle (
          NULL,              // Use the default principal
          PACKAGE_NAME,
          SECPKG_CRED_INBOUND,
          NULL,              // Use the current LOGON id
          NULL,
          NULL,
          NULL,
          &pAS->_hcred,
          &Lifetime );
     if (SEC_SUCCESS (ss))
     {
          pAS->_fHaveCredHandle = TRUE;
     }
     else
     {
           HandleError("AcquireCreds failed.");
     }
}
//--------------------------------------------------------------------
//      Prepare input and output buffers

OutBuffDesc.ulVersion = 0;
OutBuffDesc.cBuffers = 1;
OutBuffDesc.pBuffers = &OutSecBuff;

OutSecBuff.cbBuffer = *pcbOut;
OutSecBuff.BufferType = SECBUFFER_TOKEN;
OutSecBuff.pvBuffer = pOut;

InBuffDesc.ulVersion = 0;
InBuffDesc.cBuffers = 1;
InBuffDesc.pBuffers = &InSecBuff;

InSecBuff.cbBuffer = cbIn;
InSecBuff.BufferType = SECBUFFER_TOKEN;
InSecBuff.pvBuffer = pIn;

ss = g_pFuncs->AcceptSecurityContext (
          &pAS->_hcred,
          pAS->_fNewConversation ? NULL : &pAS->_hctxt,
          &InBuffDesc,
          0,
          SECURITY_NATIVE_DREP,
          &pAS->_hctxt,
          &OutBuffDesc,
          &ContextAttributes,
           &Lifetime
);
if (!SEC_SUCCESS (ss))
{
     HandleError("Accept context failed.");
}

pAS->_fHaveCtxtHandle = TRUE;

//--------------------------------------------------------------------
//      Complete token -- if needed

if ((SEC_I_COMPLETE_NEEDED == ss)
          || (SEC_I_COMPLETE_AND_CONTINUE == ss))
{
     if (g_pFuncs->CompleteAuthToken)
     {
          ss = g_pFuncs->CompleteAuthToken (
               &pAS->_hctxt,
               &OutBuffDesc);
          if (!SEC_SUCCESS(ss))
          {
               HandleError("Complete failed.");
          }
     }
    else
     {
          HandleError("Complete not supported.");
     }
}

*pcbOut = OutSecBuff.cbBuffer;

pAS->_fNewConversation = FALSE;
*pfDone = !((SEC_I_CONTINUE_NEEDED == ss) ||
          (SEC_I_COMPLETE_AND_CONTINUE == ss));
return TRUE;
}  // end GenServerContext

//--------------------------------------------------------------------
//     Define ImpersonateContext()

BOOL ImpersonateContext (DWORD dwKey)
{
SECURITY_STATUS ss;

ss = (g_pFuncs->ImpersonateSecurityContext) (&pAS->_hctxt);
if (!(SEC_SUCCESS(ss)))
{
     HandleError("Impersonation failed.");
}
return(TRUE);
} // end ImpersonateContext.

//--------------------------------------------------------------------
//      Define RevertContext.
//      Revert to the original server context.
//      Return TRUE is successful, otherwise, FALSE.

BOOL RevertContext (DWORD dwKey)
{
SECURITY_STATUS ss;

ss = g_pFuncs->RevertSecurityContext (&pAS->_hctxt);
if (!(SEC_SUCCESS(ss)))
{
     HandleError("Revert to original context failed.");
}
return(TRUE);
} end ReverContext.

//--------------------------------------------------------------------
//      Define InitSession.
//      Initialize the server's context.
//      Return TRUE if successful; otherwise, FALSE.

BOOL InitSession (DWORD dwKey)
{

if(!(pAS = (PAUTH_SEQ) malloc (sizeof (AUTH_SEQ))))
{
     HandleError("Memory allocation error in InitSession.");
}

pAS->_fNewConversation = TRUE;
pAS->_fHaveCredHandle = FALSE;
pAS->_fHaveCtxtHandle = FALSE;

return(TRUE);
}

//--------------------------------------------------------------------
//     Define UseSession.

void UseSession(SOCKET s, SecHandle phContext)
{
char szUser[80];
DWORD cbUser = 80;

//--------------------------------------------------------------------
//      Impersonate the client

ImpersonateContext (s);

//--------------------------------------------------------------------
//      Get the user name of the impersonated client.

if (GetUserName (szUser, &cbUser))
{
     printf("The impersonated user name is %s",szUser);
}
else
{
     HandleError("GetUserName failed.\n");
}

//--------------------------------------------------------------------
//     Revert to self

if (!(RevertContext (s)))
{
     HandleError("Could not revert to security context.\n");
}
printf("Sending the message 'Testing. This message is sent to check the connection.'\n");
if (!(SendMsg(
          s,
          (PBYTE)"Testing. This message is sent to check the connection.",
          60))
{
     HandleError("User Message not sent.\n");
}

printf("Sending the user name.\n");
if (!(SendMsg(
      s,
     (PBYTE)szUser,
      cbUser)))
{
     HandleError("User name not sent.\n");
}
} // end of UseSession.


Utility Functions for Windows Sockets Client and Server

This section contains the code for functions that are used in the sample Windows Sockets client and server SSPI programs. The functions included are:

  • Example Code: SendMsg
  • Example Code: ReceiveMsg
  • Example Code: SendBytes
  • Example Code: ReceiveBytes
  • Example Code: HandleError

These functions depend upon the #define, the #include, and global variables from the client and server sample programs.


Example Code: SendMsg

//--------------------------------------------------------------------
//Define SendMsg()
//     Send a message over the socket by first sending a DWORD that
//     represents the size of the message followed by the message
//     itself.
//     Return TRUE if successful; otherwise, FALSE.

BOOL SendMsg (SOCKET s, PBYTE pBuf, DWORD cbBuf)
{

//--------------------------------------------------------------------
//      Send the size of the message

if (!(SendBytes (
     s,
     (PBYTE)&cbBuf,
     sizeof (cbBuf))))
{
     HandleError("Error sending number of bytes in SendMsg.");
}

//--------------------------------------------------------------------
//      Send the body of the message

if (!(SendBytes (
     s,
     pBuf,
     cbBuf)))
{
     HandleError("Message body not sent.\n");
}
return(TRUE);
} // end of SendMsg


Example Code: ReceiveMsg

//--------------------------------------------------------------------
//     Define ReceiveMsg()
//     Receives a message over the socket. The first DWORD in the
//     message will be the message size. The remainder of the bytes
//     will be the actual message.

BOOL ReceiveMsg (SOCKET s, PBYTE pBuf, DWORD cbBuf, DWORD *pcbRead)
{
DWORD cbRead;
DWORD cbData;

//--------------------------------------------------------------------
//      Find the length of the message

if (!(ReceiveBytes (
     s,
     (PBYTE)&cbData,
     sizeof(cbData),
     &cbRead)))
{
     HandleError("Did not receive bytes from ReceiveBytes.");
}

//--------------------------------------------------------------------
//      Receive the full message

if (!(ReceiveBytes (
     s,
     pBuf,
     cbData,
     &cbRead)))
{
     HandleError("Did not read the message.");
}

if (cbRead == cbData)
{
     *pcbRead = cbRead;
}
else
{
     HandleError("Message not read corretly.");
}
return(TRUE);
} // end ReceiveMsg


Example Code: SendBytes

//--------------------------------------------------------------------
//     Define SendBytes()

BOOL SendBytes (SOCKET s, PBYTE pBuf, DWORD cbBuf)
{
PBYTE pTemp = pBuf;
int eNumber;
int cbSent;
int cbRemaining = cbBuf;

if (cbBuf< 1)
{
     return(TRUE);
}

while (cbRemaining)
{
     cbSent = send(
          s,
          (const char *)pTemp,
          cbRemaining,
          0);
     if (SOCKET_ERROR == cbSent)
     {
          eNumber = WSAGetLastError();
          if(eNumber == WSAENETRESET)
               printf("1 net reset.\n");
          else
               if(eNumber == WSAENOBUFS)
                    printf("2 no buffs.\n");
               else
                    if(eNumber == WSAENOTCONN)
                         printf("3not conn .\n");
          printf("socket error %d.\n ",eNumber);
          HandleError("send failed.");
     }
     pTemp += cbSent;
     cbRemaining -= cbSent;
} // end while.
return TRUE;
} // End SendBytes


Example Code: ReceiveBytes

//--------------------------------------------------------------------
//     Define ReceiveBytes()

BOOL ReceiveBytes (SOCKET s, PBYTE pBuf, DWORD cbBuf, DWORD *pcbRead)
{
PBYTE pTemp = pBuf;
int cbRead =1;
int cbRemaining = cbBuf;

while(cbRemaining && cbRead >0 )
{
     if(cbRead = recv(
          s,
          (char *)pTemp,
          cbRemaining,
          0))
     {
          if (SOCKET_ERROR == cbRead)
          {
               HandleError("Recv failed.");
          }
          cbRemaining -= cbRead;
          pTemp += cbRead;
          *pcbRead = cbBuf - cbRemaining;
     } // end if
} // end while

return TRUE;
} // end ReceiveBytes


Example Code: HandleError

//--------------------------------------------------------------
//     Define HandleError()

void HandleError(char *s)
{
     printf("An error occurred in running the program.\n");
     printf("%s \n",s);
     printf("Last error was %d \n",WSAGetLastError);
     exit(1);
} //End of HandleError


SecBuffer and SecBufferDesc Example Code

This example code demonstrates initializing an array of security buffers. It shows input security buffers initialized by the server side of a connection to prepare for a call to AcceptSecurityContext. Note that the last buffer contains the opaque security token received by the client and that the SECBUFFER_READONLY flag is set on SecBuffer.

SecBuffer  Buffers[3];
SecBufferDesc BufferDesc;
BYTE *pHeader;
BYTE *pMessage;
BYTE *pTrailer;

//--------------------------------------------------------------------
// pHeader, pMessage, and pTrailer are BYTE strings.
// In a working program, they would be assigned string values.

BufferDesc.ulVersion = SECBUFFER_VERSION;
BufferDesc.cBuffers = 3;
BufferDesc.pBuffers = Buffers;

Buffers[0].cbBuffer = sizeof(Protocol_Header);
Buffers[0].BufferType = SECBUFFER_READONLY | SECBUFFER_DATA;
Buffers[0].pvBuffer = pHeader;

Buffers[1].cbBuffer = pHeader->MessageSize;
Buffers[1].BufferType = SECBUFFER_DATA;
Buffers[1].pvBuffer = pMessage;

Buffers[2].cbBuffer = pHeader->TrailerSize;
Buffers[2].BufferType = SECBUFFER_READONLY | SECBUFFER_TOKEN;
Buffers[2].pvBuffer = pSecurityTrailer;


Using Message Support

Once a handshake has been completed and a secure connection has been established, an application can use the MakeSignature, EncryptMessage, VerifySignature, and DecryptMessage functions to exchange signed or encrypted application data with the remote computer.

Example code using these functions after a security context has been established is demonstrated in the following sections:

  • Signing a Message
  • Verifying a Message
  • Encrypting a Message
  • Decrypting a Message


Signing a Message

When a client and server finish setting up the security context, message support functions can be used. The client and server use the security context token created when the session was established to call MakeSignature and VerifySignature functions. The context token can be used with EncryptMessage and DecryptMessage for communications privacy.

The following example code shows the client side generating a signed message to send to the server. Before calling MakeSignature, the client calls QueryContextAttributes with a SecPkgContext_Sizes structure to determine the length of the buffer needed to hold the message signature. If the cbMaxSignature member is zero, the security package does not support signing messages. Otherwise, this member indicates the size of the buffer to allocate to receive the signature.

The example assumes that a SecHandle variable named phContext and a SOCKET structure named s are initialized. For the declarations and initiations of these variables, see Using SSPI with a Windows Sockets Client and Using SSPI with a Windows Sockets Server. This code also uses the function SendMsg and HandleError. Code for these functions can be seen in Utility Functions for Windows Sockets Client and Server.

//--------------------------------------------------------------------
//   Declare and initialize local variables.

SecPkgContext_Sizes ContextSizes;
char *MessageBuffer = "This is a sample buffer to be signed.";
DWORD MessageBufferSize = strlen(MessageBuffer);
SecBufferDesc InputBufferDescriptor;
SecBuffer InputSecurityToken[2];

ss=g_pFuncs->QueryContextAttributes(
    &phContext,
    SECPKG_ATTR_SIZES,
    &ContextSizes
    );
if(ContextSizes.cbMaxSignature == 0)
{
     HandleError("This session does not support message signing.");
}
//--------------------------------------------------------------------
// The message as a byte string is in the variable
// MessageBuffer, and its length is in MessageBufferSize.

//--------------------------------------------------------------------
// Build the buffer descriptor and the buffers
// to pass to the MakeSignature call.

InputBufferDescriptor.cBuffers = 2;
InputBufferDescriptor.pBuffers = InputSecurityToken;
InputBufferDescriptor.ulVersion = SECBUFFER_VERSION;

//--------------------------------------------------------------------
// Build a security buffer for the message itself. If
// the SECBUFFER_READONLY attribute is set, the buffer will not be
// signed.

InputSecurityToken[0].BufferType = SECBUFFER_DATA;
InputSecurityToken[0].cbBuffer = MessageBufferSize;
InputSecurityToken[0].pvBuffer = MessageBuffer;

//--------------------------------------------------------------------
// Allocate and build a security buffer for the message
// signature.

InputSecurityToken[1].BufferType = SECBUFFER_TOKEN;
InputSecurityToken[1].cbBuffer = ContextSizes.cbMaxSignature;
InputSecurityToken[1].pvBuffer =
        (void *)malloc(ContextSizes.cbMaxSignature);

//--------------------------------------------------------------------
// Call MakeSignature
// For the NTLM package, the sequence number need not be specified
// because the package provides sequencing.
// The quality of service parameter is ignored.

ss=g_pFuncs->MakeSignature(
    &phContext,
    0,                       // no quality of service
    &InputBufferDescriptor,  // input message descriptor
    0                        // no sequence number
    );
if (SEC_SUCCESS(ss))
{
     printf("Have made a signature.\n");
}
else
{
    HandleError("MakeSignature Failed.");
}

//--------------------------------------------------------------------
//  Send the message.

if(!SendMsg(
    s,
    (BYTE *)InputSecurityToken[0].pvBuffer,
    InputSecurityToken[0].cbBuffer))
{
     HandleError("The message was not sent.");
}

//--------------------------------------------------------------------
//   Send the signature.

if(!SendMsg(
     s,
    (BYTE *)InputSecurityToken[1].pvBuffer,
    InputSecurityToken[1].cbBuffer ))
{
     HandleError("The signature was not sent.");
}

MakeSignature returns TRUE if the context is set up to allow signing messages and if the input buffer descriptor is correctly formatted. After the message is signed, the message and the signature with their lengths are sent to the remote computer.

Note The data contents of the SecBuffer structures are sent, not the SecBuffer structures themselves nor the SecBufferDesc structure. New SecBuffer structures and a new SecBufferDesc structure are created by the receiving application to verify the signature.


Verifying a Message

The following example shows code to receive and verify a signed message. The example receives the signature buffer and its size are in SignatureBuffer and SignatureBufferSize, and the message buffer and its size in MessageBuffer and MessageBufferSize.

The example assumes that a SecHandle variable named phContext and a SOCKET structure named s are initialized. For the declarations and initiations of these variables, see Using SSPI with a Windows Sockets Client and Using SSPI with a Windows Sockets Server. This code also uses the function ReceiveMsg and HandleError. Code for these functions can be seen in Utility Functions for Windows Sockets Client and Server.

//--------------------------------------------------------------------
//  Declare and initialize local variables.

#define MaxMessageLength 1024
#define BUFSIZ 512
BYTE MessageBuffer[BUFSIZ];
BYTE SignatureBuffer[BUFSIZ];
DWORD MessageBufferSize;
DWORD SignatureBufferSize;
SECURITY_STATUS SecStatus;
SecBufferDesc InputBufferDescriptor;
SecBuffer InputSecurityToken[2];
ULONG fQOP;

//------------------------------------------------------------------
//    Receive the message

if(!(ReceiveMsg(
     s,
     MessageBuffer,
     MaxMessageLength,
     &MessageBufferSize)))
{
     HandleError("Error. Message not received.");
}

//------------------------------------------------------------------
//    Receive the signature.

if(!(ReceiveMsg(
     s,
     SignatureBuffer,
     MaxMessageLength,
     &SignatureBufferSize)))
{
     HandleError("Error. Signature not received.");
}

//------------------------------------------------------------------
// Build the input buffer descriptor.

InputBufferDescriptor.cBuffers = 2;
InputBufferDescriptor.pBuffers = InputSecurityToken;
InputBufferDescriptor.ulVersion = SECBUFFER_VERSION;

//-------------------------------------------------------------------
// Build the security buffer for the message

InputSecurityToken[0].BufferType = SECBUFFER_DATA;
InputSecurityToken[0].cbBuffer = MessageBufferSize;
InputSecurityToken[0].pvBuffer = MessageBuffer;

//-------------------------------------------------------------------
// Build the security buffer for the signature.

InputSecurityToken[1].BufferType = SECBUFFER_TOKEN;
InputSecurityToken[1].cbBuffer = SignatureBufferSize;
InputSecurityToken[1].pvBuffer = SignatureBuffer;

//--------------------------------------------------------------------
// Call VerifySignature.

SecStatus =g_pFuncs->VerifySignature(
      &phContext,
      &InputBufferDescriptor,  // input message descriptor
      0,                       // no sequence number
      &fQOP                    // Quality of protection
      );
if(SecStatus == SEC_E_OK)
{
     printf("The signature verified the message.\n");
}
else
     if(SecStatus == SEC_E_MESSAGE_ALTERED)
     {
          printf("The message was altered in transit.\n");
     }
     else
          if(SecStatus == SEC_E_OUT_OF_SEQUENCE )
          {
              printf("The message is out of sequence.\n");
          }
          else
          {
              printf("An unknown error occurred in VerifyMessage.\n");
          }


Encrypting a Message

The following example code shows a message being encrypted before it is sent to a remote computer over the secure connection.

The example assumes that a SecHandle variable named phContext and a SOCKET named s are initialized. For the declarations and initiations of these variables, see Using SSPI with a Windows Sockets Client and Using SSPI with a Windows Sockets Server. This code also uses the function SendMsg and HandleError. Code for these functions can be seen in Utility Functions for Windows Sockets Client and Server.

SSPI functions are shown as available through the global SecurityFunctionTable structure g_SecurityFunc.

//--------------------------------------------------------------------
//   Declare and initialize local variables.

SecPkgContext_StreamSizes  Sizes;
SECURITY_STATUS            scRet;
SecBufferDesc              Message;
SecBuffer                  Buffers[4];
SecBuffer                  *pDataBuffer;

PBYTE                       pbIoBuffer;
DWORD                       cbIoBuffer;
DWORD                       cbIoBufferLength;
PBYTE                       pbMessage;
DWORD                       cbMessage;

//--------------------------------------------------------------------
// Get the stream encryption sizes. This needs to
// be done once per connection.
// phContext must have been initialized during the handshake process.

scRet = g_SecurityFunc.QueryContextAttributes(
            phContext,
            SECPKG_ATTR_STREAM_SIZES,
            &Sizes);

if(FAILED(scRet))
{
    HandleError("Error reading SECPKG_ATTR_STREAM_SIZES");
}

//--------------------------------------------------------------------
// Allocate a working buffer. The plaintext sent to EncryptMessage
// can never be more than 'Sizes.cbMaximumMessage', so a buffer
// size of Sizes.cbMaximunMessage plus the header and trailer sizes
// is sufficient for the longest message.

cbIoBufferLength = Sizes.cbHeader +
                   Sizes.cbMaximumMessage +
                   Sizes.cbTrailer;

if(!(pbIoBuffer = malloc((BYTE *), cbIoBufferLength)))
{
    HandleError("Out of memory");
}

//--------------------------------------------------------------------
// Create a plaintext message to be encrypted offset into the data
// buffer by "header size" bytes. This allows encryption in place.

pbMessage = pbIoBuffer + Sizes.cbHeader;

sprintf(pbMessage, "This is the plaintext message.");
cbMessage = strlen(pbMessage);

//--------------------------------------------------------------------
// Encrypt the plaintext message.

Buffers[0].pvBuffer     = pbIoBuffer;
Buffers[0].cbBuffer     = Sizes.cbHeader;
Buffers[0].BufferType   = SECBUFFER_STREAM_HEADER;

Buffers[1].pvBuffer     = pbMessage;
Buffers[1].cbBuffer     = cbMessage;
Buffers[1].BufferType   = SECBUFFER_DATA;

Buffers[2].pvBuffer     = pbMessage + cbMessage;
Buffers[2].cbBuffer     = Sizes.cbTrailer;
Buffers[2].BufferType   = SECBUFFER_STREAM_TRAILER;

Buffers[3].BufferType   = SECBUFFER_EMPTY;

Message.ulVersion       = SECBUFFER_VERSION;
Message.cBuffers        = 4;
Message.pBuffers        = Buffers;

scRet = g_SecurityFunc.EncryptMessage(phContext, 0, &Message, 0);

if(FAILED(scRet))
{
    HandleError("Error returned by EncryptMessage.");
}

//--------------------------------------------------------------------
// Send the encrypted data.

if(!(SendMsg(
     s,
     pbIoBuffer,
     Buffers[0].cbBuffer + Buffers[1].cbBuffer +
           Buffers[2].cbBuffer)))
{
     HandleError("SendMsg failed.");
}


Decrypting a Message

The following example code shows an encrypted message being received and decrypted.

The example assumes that a SecHandle variable named phContext and a SOCKET structure named s are initialized. For the declarations and initiations of these variables, see Using SSPI with a Windows Sockets Client and Using SSPI with a Windows Sockets Server. This code also uses the function ReceiveMsg and HandleError. Code for these functions can be seen in Utility Functions for Windows Sockets Client and Server.

SSPI functions are shown as available through the global SecurityFunctionTable structure g_SecurityFunc.

SecPkgContext_StreamSizes   Sizes;
SECURITY_STATUS             scRet;
SecBufferDesc               Message;
SecBuffer                   Buffers[4];
SecBuffer                   *pDataBuffer;
SecBuffer                   *pExtraBuffer;
SecBuffer                    ExtraBuffer;

PBYTE                        pbIoBuffer;
DWORD                        cbIoBuffer;
DWORD                        cbIoBufferLength;

//--------------------------------------------------------------------
// Get stream encryption properties.

scRet = g_SecurityFunc.QueryContextAttributes(
       phContext,
       SECPKG_ATTR_STREAM_SIZES,
       &Sizes);

if(scRet != SEC_E_OK)
{
    HandleError("Error reading SECPKG_ATTR_STREAM_SIZES\n");
}

//--------------------------------------------------------------------
// Allocate a working buffer. The plaintext sent to EncryptMessage
// should never be more than 'Sizes.cbMaximumMessage', so a buffer
// size of this plus the header and trailer sizes should be safe.

cbIoBufferLength = Sizes.cbHeader +
                   Sizes.cbMaximumMessage +
                   Sizes.cbTrailer;

pbIoBuffer = LocalAlloc(LMEM_FIXED, cbIoBufferLength);
if(pbIoBuffer == NULL)
{
    HandleError("Error: Out of memory");
}

//--------------------------------------------------------------------
// Attempt to decrypt the data in the i/o buffer.

Buffers[0].pvBuffer     = pbIoBuffer;
Buffers[0].cbBuffer     = cbIoBuffer;
Buffers[0].BufferType   = SECBUFFER_DATA;

Buffers[1].BufferType   = SECBUFFER_EMPTY;
Buffers[2].BufferType   = SECBUFFER_EMPTY;
Buffers[3].BufferType   = SECBUFFER_EMPTY;

Message.ulVersion       = SECBUFFER_VERSION;
Message.cBuffers        = 4;
Message.pBuffers        = Buffers;

scRet = g_SecurityFunc.DecryptMessage(
     phContext,
     &Message,
     0,
     NULL);

if(scRet == SEC_E_INCOMPLETE_MESSAGE)
{
//--------------------------------------------------------------------
// The input buffer contains only a fragment of an
// encrypted record. Read some more data from the server
// and then try the decryption again.
     continue;
}

if(scRet != SEC_E_OK && scRet != SEC_I_RENEGOTIATE)
{
    HandleError("Error returned by DecryptMessage");
}

//--------------------------------------------------------------------
// Locate data.

pDataBuffer  = NULL;
pExtraBuffer = NULL;
while(!pDataBuffer && i < 4)
{
    if(Buffers[i].BufferType == SECBUFFER_DATA)
    {
        pDataBuffer = &Buffers[i];
    }
    i++;
}

if(pDataBuffer)
{
//--------------------------------------------------------------------
// Display or otherwise process the decrypted data.
//        ...
}


SSPI Reference

The SSPI Reference contains the following sections:

  • SSPI Functions
  • SSPI Structures
  • SSPI Types, Handles, and Status Codes


SSPI Functions

The Security Support Provider Interface (SSPI) functions fall into the following major categories.

Function category | Description
Package management | These functions list the security packages available and select a package.
Credential management | These functions create and work with handles to the credentials of principals.
Context management | These functions use credentials handles to create a security context.
Message support | These functions use security contexts to ensure message integrity and privacy during message exchanges over the secured connection. Integrity is achieved through message signing and signature verification. Privacy is achieved through message encryption and decryption.


Package Management

SSPI package management functions initiate a security package, enumerate available packages, and query the attributes of a security package.

The following SSPI functions provide management services for security packages.

Function | Description
EnumerateSecurityPackages | Lists available security packages and their capabilities.
InitSecurityInterface | Retrieves a pointer to a security support provider (SSP) dispatch table.
QuerySecurityPackageInfo | Queries an individual security package for its capabilities, including authentication, transport, and message integrity/privacy-related capabilities.


EnumerateSecurityPackages

The EnumerateSecurityPackages function returns an array of SecPkgInfo structures that describe the security packages available to the client.

SECURITY_STATUS EnumerateSecurityPackages(
  PULONG pcPackages,          // receives the number of packages
  PSecPkgInfo *ppPackageInfo  // receives array of information
);

Parameters

pcPackages
[in] Pointer to a ULONG variable that receives the number of packages returned.
ppPackageInfo
[in] Pointer to a variable that receives a pointer to an array of SecPkgInfo structures. Each structure contains information from the SSP describing a security package available within that SSP.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value is a nonzero error code.

Remarks

The SecPkgInfo structures provide information that the caller can use to determine which security package best satisfies the requirements of the caller.

The caller can use the Name member of a SecPkgInfo structure to specify a security package in a call to the AcquireCredentialsHandle function.

The caller must assume that the SSP includes all available security packages in the single call to EnumerateSecurityPackages.

The caller must call the FreeContextBuffer function to free the buffer returned in ppPackageInfo.

The prototype for this function can be found in Sspi.h.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

AcquireCredentialsHandle, EnumerateSecurityPackages, FreeContextBuffer, SecPkgInfo


InitSecurityInterface

The InitSecurityInterface function returns a pointer to a SSPI dispatch table. This function enables clients to use SSPI without binding directly to an implementation of the interface.

PSecurityFunctionTable InitSecurityInterface(VOID)

Return Values

If the function succeeds, the return value is a pointer to a SecurityFunctionTable structure.

If the function fails, the return value is NULL.

Remarks

The prototype for this function can be found in Sspi.h.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

SecurityFunctionTable


QuerySecurityPackageInfo

The QuerySecurityPackageInfo function retrieves information about a specified security package. This information includes the bounds on sizes of authentication information, credentials, and contexts.

SECURITY_STATUS QuerySecurityPackageInfo(
  SEC_CHAR *pszPackageName,    // name of package
  PSecPkgInfo *ppPackageInfo   // receives package information
);

Parameters

pszPackageName
[in] Pointer to a NULL-terminated string that specifies the name of the security package.
ppPackageInfo
[out] Pointer to a variable that receives a pointer to a SecPkgInfo structure containing information about the specified security package.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value is a nonzero error code.

Remarks

The caller must call the FreeContextBuffer function to free the buffer returned in ppPackageInfo.

The prototype for this function can be found in Sspi.h.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

FreeContextBuffer, SecPkgInfo


Credential Management

SSPI credential management functions provide a credentials handle, a reference to an opaque security object, for accessing a principal. The security object is opaque because the application has access only to the handle and not to the actual contents of the structure.

All references to the contents of a credential context are through the object's handle and the security package de-references the handle to access the specifics of credentials. A credential handle is a 64-bit value between {0x00000000, 0x0000000} and {0xFFFFFFFF, 0xFFFFFFFE}.

Applications use the credentials handle with context management functions to create a security context.

Credential management functions also release credential handles and query the attributes of credentials. At present, the name associated with a credential is the only attribute that can be queried.

The following functions are used with credentials management.

Function | Description
AcquireCredentialsHandle | Acquires a handle to the pre-existing credentials of a specified principal.
ExportSecurityContext | Exports a security context into a context buffer.
FreeCredentialsHandle | Releases a credential handle and associated resources.
ImportSecurityContext | Imports a security context exported by using ExportSecurityContext into the current process.
QueryCredentialsAttributes | Queries a credential handle for the name associated with the credential.


AcquireCredentialsHandle

The AcquireCredentialsHandle function acquires a handle to pre-existing credentials associated with the user on whose behalf the call is made. These pre-existing credentials are established through a system logon that is not described here.

Note This is not a "log on to the network" and does not imply gathering of credentials.

SECURITY_STATUS AcquireCredentialsHandle(
  SEC_CHAR *pszPrincipal,   // name of principal
  SEC_CHAR *pszPackage,     // name of package
  ULONG fCredentialUse,     // flags indicating use
  PLUID pvLogonID,          // pointer to logon identifier
  PVOID pAuthData,          // package-specific data
  SEC_GET_KEY_FN pGetKeyFn,          // pointer to GetKey function
  PVOID pvGetKeyArgument,   // value to pass to GetKey
  PCredHandle phCredential, // credential handle
  PTimeStamp ptsExpiry      // lifetime of the returned credentials
);

Parameters

pszPrincipal
[in] Pointer to a NULL-terminated string that specifies the name of the principal whose credentials the handle will reference.

Note If the process requesting the handle does not have access to the credentials, the function returns an error. A null string indicates that the process requires a handle to the credentials of the user under whose security context it is executing.

pszPackage
[in] Pointer to a NULL-terminated string specifying the name of the security package with which these credentials will be used. This is a security package name returned in the Name member of a SecPkgInfo structure returned by the EnumerateSecurityPackages function. After a context is established, QueryContextAttributes can be called with ulAttribute set to SECPKG_ATTR_PACKAGE_INFO to return information on the security package in use.
fCredentialUse
[in] Flag indicating how these credentials will be used. This parameter can be one of the following values.
Value | Meaning
SECPKG_CRED_INBOUND | Used to validate an incoming credential. Inbound credentials might be validated using an authenticating authority when InitializeSecurityContext or AcceptSecurityContext is called. If such an authority is not available the function will fail returning SEC_E_NO_AUTHENTICATING_AUTHORITY. Validation is package specific. Windows 95 and Windows 98 using NTLM require the Client for Microsoft Networks be set to "user level' access control.
SECPKG_CRED_OUTBOUND | Use to use a local credential to prepare an outgoing token.
SECPKG_CRED_BOTH | Validate an incoming credential or use a local credential to prepare an outgoing token. This flag enables both other flags.

pvLogonID
[in] Pointer to a Microsoft® Windows NT®/Microsoft® Windows® 2000–style locally unique identifier (LUID) used to identify the user. This parameter is provided for file-system processes such as network redirectors. This parameter can be NULL.
pAuthData
[in] Pointer to package-specific data. This parameter can be NULL, indicating that the default credentials for that package must be used. To use supplied credentials, pass a SEC_WINNT_AUTH_IDENTITY structure that includes those credentials in this parameter. The RPC run time passes whatever was provided in RpcBindingSetAuthInfo.
pGetKeyFn
[in] Pointer to a SEC_GET_KEY_FN function that retrieves the key for the function. The security package can call this function, as provided by the RPC run-time transport application. This parameter can be NULL if the transport application does not support callbacks to retrieve credentials.
pvGetKeyArgument
[in] Specifies the pointer argument that the security package must pass to the GetKey function. This parameter can be NULL.
phCredential
[out] Pointer to a CredHandle structure that receives the credential handle.
ptsExpiry
[out] Pointer to a TimeStamp structure that receives the time at which the returned credentials expire. The value returned in this TimeStamp structure depends on the security package. The security package must return this value in local time.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value can be one of the following error codes.

Value | Meaning
SEC_E_UNKNOWN_CREDENTIALS | The credentials supplied to the package were not recognized.
SEC_E_NO_CREDENTIALS | No credentials are available in the security package.
SEC_E_NOT_OWNER | The caller of the function does not have the necessary credentials.
SEC_E_INSUFFICIENT_MEMORY | Not enough memory is available to complete the request.
SEC_E_INTERNAL_ERROR | The Local Security Authority (LSA) cannot be contacted.
SEC_E_SECPKG_NOT_FOUND | The requested security package does not exist.

Remarks

The AcquireCredentialsHandle function returns a handle to the credentials of a principal (such as a user or client), as used by a specific security package. This can be the handle to pre-existing credentials or the function can create a new set of credentials and return it. This handle can be used in subsequent calls to the AcceptSecurityContext and InitializeSecurityContext functions.

In general, AcquireCredentialsHandle does not allow a process to obtain a handle to the credentials of other users logged on to the same computer. However, a caller with SE_TCB_NAME privilege has the option of specifying the logon identifier (LUID) of any existing logon session token to get a handle to that session's credentials. Typically, this is used by kernel-mode components that must act on the behalf of a logged-on user.

A package may call the function in pGetKeyFn provided by the RPC run-time transport. If the transport does not support the notion of callback to retrieve credentials, this parameter must be NULL.

For kernel mode callers, the following differences must be noted: The two string parameters are Unicode strings, and the buffer values must be allocated in process virtual memory, not from the pool.

When you no longer need the returned credentials, call the FreeCredentialsHandle function to free the memory used by the credentials.

The prototype for this function can be found in Sspi.h.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

AcceptSecurityContext, InitializeSecurityContext, FreeCredentialsHandle


ExportSecurityContext

The ExportSecurityContext function exports a security context into a context buffer for later use by ImportSecurityContext.

SECURITY_STATUS SEC_Entry ExportSecurityContext(
  PCtxtHandle phContext,
  Ulong fFlags,
  PSecBuffer pPackedContext,
  void SEC_FAR *pToken
);

Parameters

phContext
[in] Handle of the security context to be exported.
fFlags
[in] Only the SECPKG_CONTEXT_EXPORT_DELETE_OLD flag is currently used. If this flag is set, the old context is deleted after the export copy of the credentials is created.
pPackedContext
[out] Pointer to a buffer that receives the serialized security context. This context must be freed by the application with FreeContextBuffer.
pToken
[out, optional] Optional pointer to receive the handle of the context's token.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value can be one of the following error codes.

Value | Meaning
SEC_E_UNKNOWN_CREDENTIALS | The credentials supplied to the package were not recognized.
SEC_E_NO_CREDENTIALS | No credentials are available in the security package.
SEC_E_NOT_OWNER | The caller of the function does not have the necessary credentials.
SEC_E_INSUFFICIENT_MEMORY | Not enough memory is available to complete the request.
SEC_E_INTERNAL_ERROR | The Local Security Authority (LSA) cannot be contacted.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.

See Also

ImportSecurityContext, FreeContextBuffer


FreeCredentialsHandle

The FreeCredentialsHandle function notifies the security system that the credentials are no longer needed. An application calls this function to free the credential handle acquired in the call to the AcquireCredentialsHandle function. When all references to this credential set have been removed, the credentials themselves can be removed.

SECURITY_STATUS FreeCredentialsHandle(
  PCredHandle phCredential  // handle to free
);

Parameters

phCredential
[in] Pointer to the credential handle obtained by using the AcquireCredentialsHandle function.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value may be the following error code.

Value | Meaning
SEC_E_INVALID_HANDLE | The handle passed to the function is invalid.

Remarks

The FreeCredentialsHandle function allows the security system to free any resources associated with the credential handle.

The prototype for this function can be found in Sspi.h.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.

See Also

AcquireCredentialsHandle


ImportSecurityContext

The ImportSecurityContext function imports a security context exported into the current process by ExportSecurityContext.

SECURITY_STATUS SEC_Entry ImportSecurityContext(
  PSECURITY_STRING *pszPackage,
  PSecBuffer pPackedContext,
  void SEC_FAR *pToken,
  PCtxtHandle phContext
);

Parameters

pszPackage
[in] String containing the name of the security package where the credential was exported.
pPackedContext
[in] Pointer to a buffer that contains the serialized security context created by ExportSecurityContext. This context must be freed by the application with FreeContextBuffer.
pToken
[in, optional] Optional pointer to a handle of the context's token.
phContext
[out] Handle of the new security context created from pPackedContext.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value can be one of the following error codes.

Value | Meaning
SEC_E_UNKNOWN_CREDENTIALS | The credentials supplied to the package were not recognized.
SEC_E_NO_CREDENTIALS | No credentials are available in the security package.
SEC_E_NOT_OWNER | The caller of the function does not have the necessary credentials.
SEC_E_INSUFFICIENT_MEMORY | Not enough memory is available to complete the request.
SEC_E_INTERNAL_ERROR | The Local Security Authority (LSA) cannot be contacted.

Remarks

The prototype for this function can be found in sspi.h.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

ExportSecurityContext, FreeContextBuffer


QueryCredentialsAttributes

The QueryCredentialsAttributes function retrieves the attributes of a credential, such as the name associated with the credential.

SECURITY_STATUS QueryCredentialsAttributes(
  PCredHandle phCredential,  // credential to query
  ULONG ulAttribute,         // attribute to query
  PVOID pBuffer              // buffer that receives attributes
);

Parameters

phCredential
[in] Handle of the credentials to be queried.
ulAttribute
[in] Specifies the attribute to query. This parameter can be any of the following attributes.
Attribute | pBuffer type | Header required
SECPKG_CRED_ATTR_NAMES | SecPkgCredentials_Names | Sspi.h
SECPKG_ATTR_SUPPORTED_ALGS | SecPkgCred_SupportedAlgs | Schnlsp.h
SECPKG_ATTR_CIPHER_STRENGTHS | SecPkgCred_CipherStrengths | Schnlsp.h
SECPKG_ATTR_SUPPORTED_PROTOCOLS | SecPkgCred_SupportedProtocols | Schnlsp.h

pBuffer
[out] Pointer to a buffer that receives the requested attribute. See the table above.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value may be one of the following error codes.

Value | Meaning
SEC_E_INVALID_HANDLE | The handle passed to the function is invalid.
SEC_E_INSUFFICIENT_MEMORY | Not enough memory is available to complete the request.

Remarks

The QueryCredentialsAttributes function allows an application to determine several characteristics of a credential, including the name associated with the specified credentials.

Querying the SECPKG_ATTR_CIPHER_STRENGTHS attribute returns a SecPkgCred_CipherStrengths structure. The cipher strength in this structure is the same as the cipher strength in the SCHANNEL_CRED structure used when a credential was created.

Note An application can find the system default cipher strength by querying this attribute with a default credential. A default credential is created by calling AcquireCredentialsHandle with a NULL pAuthData parameter.

Querying the SECPKG_ATTR_SUPPORTED_ALGS attribute returns a SecPkgCred_SupportedAlgs structure. The algorithms in this structure are compatible with those indicated in the SCHANNEL_CRED structure used when a credential was created.

Querying the SECPKG_ATTR_SUPPORTED_PROTOCOLS attribute returns a SecPkgCred_SupportedProtocols structure that contains a bit array compatible with the grbitEnabledProtocols field of the SCHANNEL_CRED structure.

The caller must allocate the structure pointed to by the pBuffer parameter. The security package allocates the buffer for any pointer returned in the pBuffer structure. The caller can call the FreeContextBuffer function to free any pointers allocated by the security package.

The prototype for this function can be found in Sspi.h.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

AcquireCredentialsHandle, FreeContextBuffer, SCHANNEL_CRED, SecPkgCred_CipherStrengths, SecPkgCred_SupportedAlgs, SecPkgCred_SupportedProtocols, SecPkgCredentials_Names


Context Management

SSPI context management functions create and use security contexts.

In a communication link, the client and server cooperate to create a shared security context. The client and server both use the security context with message support functions to ensure message integrity and privacy during the connection.

Security contexts are opaque security objects. Information in the security context is not available to the application. Context management functions create and use context handles and the security package de-references the context handle to access its security content.

A context handle is a 64 bit value between {0x00000000, 0x0000000} and {0xFFFFFFFF, 0xFFFFFFFE}.

The following functions are used with context management.

Function | Description
AcceptSecurityContext | Used by a server to creates a security context based on an opaque message received from a client.
ApplyControlToken | Applies a supplemental security message to an existing security context.
CompleteAuthToken | Completes an authentication token. This function is used by protocols such as DCE that need to revise the security information after the transport application has updated some message parameters.
DeleteSecurityContext | Frees a security context and associated resources.
FreeContextBuffer | Frees a memory buffer allocated by a security package.
ImpersonateSecurityContext | Impersonates the security context to appear as the client to the system.
InitializeSecurityContext | Used by a client to initiates a security context by generating an opaque message to be passed to a server.
QueryContextAttributes | Queries the attributes of a security context.
QuerySecurityContextToken | Obtains the impersonation token for a security context for direct manipulation.
RevertSecurityContext | Ceases impersonating a security context.


AcceptSecurityContext

The AcceptSecurityContext function enables the server component of a transport application to establish a security context between the server and a remote client. The remote client uses the InitializeSecurityContext function to start the process of establishing a security context. The server can require one or more reply tokens from the remote client to complete establishing the security context.

SECURITY_STATUS AcceptSecurityContext(
  PCredHandle phCredential,  // handle to the credentials
  PCtxtHandle phContext,     // handle of partially formed context
  PSecBufferDesc pInput,     // pointer to the input buffers
  ULONG fContextReq,         // required context attributes
  ULONG TargetDataRep,       // data representation on the target
  PCtxtHandle phNewContext,  // receives the new context handle
  PSecBufferDesc pOutput,    // pointer to the output buffers
  PULONG pfContextAttr,      // receives the context attributes
  PTimeStamp ptsTimeStamp    // receives the life span of the security context
);

Parameters

phCredential
[in] Handle to the server's credentials. The server calls the AcquireCredentialsHandle function with the INBOUND flag set to retrieve this handle.
phContext
[in/out] Pointer to a CtxtHandle structure. On the first call to AcceptSecurityContext, this pointer is NULL. On subsequent calls, phContext is the handle to the partially formed context that was returned in the phNewContext parameter by the first call.
pInput
[in] Pointer to a SecBufferDesc structure generated by a client call to InitializeSecurityContext that contains the input buffer descriptor.
fContextReq
[in] Bit flags that specify the attributes required by the server to establish the context. Bit flags can be combined using bitwise-OR operations. For possible attribute flags and their meanings, see Context Requirements. Flags used for this parameter are prefixed with ASC_REQ, such as ASC_REQ_DELEGATE.
TargetDataRep
[in] Indicates the data representation, such as byte ordering, on the target. Can be either SECURITY_NATIVE_DREP or SECURITY_NETWORK_DREP.
phNewContext
[in/out] Pointer to a CtxtHandle structure. On the first call to AcceptSecurityContext, this pointer receives the new context handle. On subsequent calls, phNewContext can be the same as the handle specified in the phContext parameter.
pOutput
[in/out] Pointer to a SecBufferDesc structure that contains the output buffer descriptor. This buffer is sent to the client for input into additional calls to InitializeSecurityContext. An output buffer may be generated even if the function returns SEC_E_OK. Any buffer generated must be sent back to the client application.
pfContextAttr
[out] Pointer to a variable that receives a set of bit flags indicating the attributes of the established context. For a description of the various attributes, see Context Requirements. Flags used for this parameter are prefixed with ASC_RET, such as ASC_RET_DELEGATE.
ptsTimeStamp
[out] Pointer to a TimeStamp structure that receives the expiration time of the context. It is recommended that the security package always return this value in local time.

Note Until the last call of the authentication process, the expiration time for the context can be incorrect because more information will be provided during later stages of the negotiation dialog. Therefore, ptsTimeStamp must be NULL until the last call to the function.

Return Values

If the function succeeds, the return value is one of the following.

Value | Meaning
SEC_E_OK | The security context received from the client was accepted. If an output token was generated by the function, it must be sent to the client process.
SEC_I_CONTINUE_NEEDED | The server must send the output token to the client and wait for a returned token. The returned token should be passed in pInput for another call to AcceptSecurityContext.
SEC_I_COMPLETE_NEEDED | The server must finish building the message from the client, then call the CompleteAuthToken function.
SEC_I_COMPLETE_AND_CONTINUE | The server must call CompleteAuthToken, then pass the output token to the client. The server then waits for a return token from the client, and makes another call to AcceptSecurityContext.

If the function fails, the return value is one of the following.

Value | Meaning
SEC_E_INVALID_TOKEN | The token passed to the function is invalid.
SEC_E_INVALID_HANDLE | The handle passed to the function is invalid.
SEC_E_LOGON_DENIED | The logon failed.
SEC_E_INTERNAL_ERROR | An error occurred that did not map to an SSPI error code.
SEC_E_NO_AUTHENTICATING_AUTHORITY | No authority could be contacted for authentication. This could be due to the domain name of the authenticating party being wrong, the domain being unreachable, or to a trust relationship failure.
SEC_E_INSUFFICIENT_MEMORY | One or more of the SecBufferDesc structures passed as an OUT parameter has a buffer that is too small.

Remarks

The AcceptSecurityContext function is the server counterpart to the InitializeSecurityContext function.

When the server receives a request from a client, the server uses the fContextReq parameter to specify what it requires of the session. In this fashion, a server can specify that clients must be capable of using a confidential or integrity-checked session, and it can reject clients that cannot meet that demand. Alternatively, a server can require nothing, and whatever the client can provide or requires is returned in the pfContextAttr parameter.

For a package that supports multi-leg authentication such as mutual authentication, the calling sequence is as follows:

  1. The client transmits a token to the server.
  2. The server calls AcceptSecurityContext the first time, generating a reply token which is sent to the client.
  3. The client receives the token and passes it to InitializeSecurityContext. If InitializeSecurityContext returns SS_E_OK, mutual authentication has been completed and a secure session can begin. If InitializeSecurityContext returns an error code, the mutual authentication dialog ends. Otherwise, the security token returned by InitializeSecurityContext is sent to the client and steps 2 and 3 are repeated.

The fContextReq and pfContextAttributes parameters are bit masks representing various context attributes. For a description of the various attributes, see Context Requirements. The pfContextAttributes parameter is valid on any successful return, but only on the final successful return should you examine the flags pertaining to security aspects of the context. Intermediate returns can set, for example, the ISC_RET_ALLOCATED_MEMORY flag

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.

See Also

InitializeSecurityContext


ApplyControlToken

The ApplyControlToken function provides a way to apply a control token to a security context. A token can be received when the security context is being established by a call to InitializeSecurityContext or with a per-message security service such as verify or unseal.

This function allows additional or replacement tokens to be applied to a context.

SECURITY_STATUS ApplyControlToken(
  PCtxtHandle phContext, // handle of the context to modify
  PSecBufferDesc pInput  // input token to apply
);

Parameters

phContext
[in] Handle to the context to which the token is applied.
pInput
[in] Pointer to a SecBufferDesc structure with a pointer to a SecBuffer structure that contains the input token to apply to the context.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value is a nonzero error code.

Remarks

The ApplyControlToken function can modify the context based on this token.

The prototype for this function can be found in Sspi.h.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.

See Also

ImpersonateSecurityContext, InitializeSecurityContext, SecBuffer, SecBufferDesc


CompleteAuthToken

The CompleteAuthToken function completes an authentication token. This function is used by protocols such as DCE that need to revise the security information after the transport application has updated some message parameters.

SECURITY_STATUS CompleteAuthToken(
  PCtxtHandle phContext, // handle of the context to complete
  PSecBufferDesc pToken  // token to complete
);

Parameters

phContext
[in] Handle of the context that needs to be completed.
pToken
[in] Pointer to a SecBufferDesc structure that contains the buffer descriptor for the entire message.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value can be one of the following error codes.

Value | Meaning
SEC_E_INVALID_HANDLE | The handle passed to the function is invalid.
SEC_E_INVALID_TOKEN | The token passed to the function is invalid.
SEC_E_INTERNAL_ERROR | An unidentified internal error has occurred.

Remarks

The client of a transport application calls the CompleteAuthToken function to allow the security package to update a checksum or similar operation after all the protocol headers have been updated by the transport application. The client calls this function only if the InitializeSecurityContext call returned SEC_I_COMPLETE_NEEDED or SEC_I_COMPLETE_AND_CONTINUE.

The prototype for this function can be found in Sspi.h.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.

See Also

InitializeSecurityContext, SecBufferDesc


DeleteSecurityContext

The DeleteSecurityContext function deletes the local data structures associated with the specified security context.

SECURITY_STATUS DeleteSecurityContext(
  PCtxtHandle phContext  // handle of the context to delete
);

Parameters

phContext
[in] Handle of the security context to delete.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value can be the following error code.

Value | Meaning
SEC_E_INVALID_HANDLE | The handle passed to the function is invalid.

Remarks

The DeleteSecurityContext function terminates a security context. No further use of the context is permitted once it is terminated.

The prototype for this function can be found in Sspi.h.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.


FreeContextBuffer

The FreeContextBuffer function enables callers of security package functions to free a memory buffer allocated by the security package. For example, the InitializeSecurityContext function may allocate a buffer for returning the outbound context token.

SECURITY_STATUS FreeContextBuffer(
  PVOID pvContextBuffer  // buffer to free
);

Parameters

pvContextBuffer
[in] Pointer to memory allocated by the security package.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value is a nonzero error code.

Remarks

The FreeContextBuffer function can free any memory allocated by a security package.

The prototype for this function can be found in Sspi.h.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.

See Also

InitializeSecurityContext


ImpersonateSecurityContext

The ImpersonateSecurityContext function allows security packages to impersonate the caller. This function allows the application server to act as the client, and thus all necessary access controls are enforced.

SECURITY_STATUS ImpersonateSecurityContext(
  PCtxtHandle phContext  // handle of context to impersonate
);

Parameters

phContext
[in] Handle of the context to impersonate. This handle must have been obtained in a call to the AcceptSecurityContext function.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value can be the following error code.

Value | Meaning
SEC_E_INVALID_HANDLE | The handle passed to the function is invalid.

Remarks

The security package or application server calls the ImpersonateSecurityContext function when it needs to impersonate the caller. Before doing so, the server must have obtained a valid context handle. To obtain the context handle, the server must call AcceptSecurityContext to submit the client's incoming security token to the security system. The server gets a context handle if the inbound context is validated. The function creates an impersonation token and allows the thread or process to run with the impersonation context.

The application server must call the RevertSecurityContext function when it finishes or when it needs to restore its own security context.

ImpersonateSecurityContext is not available with all security packages on all platforms. Typically, it is implemented only on platforms and with security packages for which a call to the QuerySecurityPackageInfo function indicates impersonation support. The caller must also specify ASC_REQ_DELEGATE in the AcceptSecurityContext function.

The prototype for this function can be found in Sspi.h.

Warning If the ImpersonateSecurityContext function fails, the client is not impersonated, and all subsequent client requests are made in the security context of the process that called the function. If the calling process is running as a privileged account, it can perform actions that the client would not be allowed to perform. To avoid security risks, the calling process should always check the return value. If the return value indicates that the function call failed, no client requests should be executed.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.

See Also

AcceptSecurityContext, QuerySecurityPackageInfo, RevertSecurityContext


InitializeSecurityContext

The InitializeSecurityContext function initiates the outbound security context from a credential handle. The function is used to build a security context between the client application and a remote peer. InitializeSecurityContext returns a token that the client must pass to the remote peer, which the peer in turn submits to the local security implementation through the AcceptSecurityContext call. The token generated should be considered opaque by all callers.

SECURITY_STATUS InitializeSecurityContext(
  PCredHandle phCredential,  // handle to the credentials
  PCtxtHandle phContext,     // handle of partially formed context
  SEC_CHAR *pszTargetName,   // name of the target of the context
  ULONG fContextReq,         // required context attributes
  ULONG Reserved1,           // reserved; must be zero
  ULONG TargetDataRep,       // data representation on the target
  PSecBufferDesc pInput,     // pointer to the input buffers
  ULONG Reserved2,           // reserved; must be zero
  PCtxtHandle phNewContext,  // receives the new context handle
  PSecBufferDesc pOutput,    // pointer to the output buffers
  PULONG pfContextAttr,      // receives the context attributes
  PTimeStamp ptsExpiry       // receives the life span of the security context
);

Parameters

phCredential
[in] Handle to the credentials returned by AcquireCredentialsHandle used to build the security context. Using InitializeSecurityContext requires at least OUTBOUND credentials.
phContext
[in/out] Pointer to a CtxtHandle structure. On the first call to InitializeSecurityContext, this pointer is NULL. On the second call, this parameter is a pointer to the handle to the partially formed context returned in the phNewContext parameter by the first call.
pszTargetName
[in] Pointer to a NULL-terminated string that indicates the target of the context. The string contents are security-package specific, as described in the following table. This list is not exhaustive. Additional system SSPs and third party SSPs can be added to a system.
Security Package | String Contents
Kerberos or Negotiate | Service principal name (SPN) or the security context of the destination server.
NTLM | Not needed by the package; must be set to NULL.
SSL | SPN for the first call to InitializeSecurityContext.

fContextReq
[in] Bit flags indicating the requirements of the context. Not all packages can support all requirements. Flags used for this parameter are prefixed with ISC_REQ_, such as ISC_REQ_DELEGATE. For a description of the various attributes, see Context Requirements.
Reserved1
[reserved] Reserved value; must be zero.
TargetDataRep
[in] Indicates the data representation, such as byte ordering, on the target. Can be either SECURITY_NATIVE_DREP or SECURITY_NETWORK_DREP.
pInput
[in/out] Pointer to a SecBufferDesc structure that contains pointers to the buffers supplied as input to the package. The pointer must be NULL on the first call to the function. On subsequent calls to the function, it is a pointer a buffer allocated with enough memory to the token returned by the remote peer. If the buffer is not large enough to hold the returned token, the function will fail returning SEC_E_INSUFFICIENT_MEMORY.
Reserved2
[reserved] Reserved value; must be zero.
phNewContext
[in/out] Pointer to a CtxtHandle structure. On the first call to InitializeSecurityContext, this pointer receives the new context handle. On the second call, phNewContext can be the same as the handle specified in the phContext parameter.
pOutput
[out] Pointer to a SecBufferDesc structure that contains pointers to the SecBuffer structure that receives the output data. If a buffer was typed as SEC_READWRITE in the input, it will be there on output. The system will allocate a buffer for the security token if requested (through ISC_REQ_ALLOCATE_MEMORY) and fill in the address in the buffer descriptor for the security token.
pfContextAttr
[out] Pointer to a variable to receive a set of bit flags indicating the attributes of the established context. For a description of the various attributes, see Context Requirements. Flags used for this parameter are prefixed with ISC_RET, such as ISC_RET_DELEGATE.

Note Particular context attributes can change during a negotiation dialog with a remote peer.

ptsExpiry
[out] Pointer to a TimeStamp structure that receives the expiration time of the context. It is recommended that the security package always return this value in local time. This parameter is optional and NULL should be passed for short-lived clients.

Return Values

If the function succeeds, the return value is one of the following success codes.

Value | Meaning
SEC_E_OK | The security context was successfully initialized. There is no need for another InitializeSecurityContext call. If the function returns an output token, that is, if the SECBUFFER_TOKEN in pOutput is of non-zero length, that token must be sent to the server.
SEC_I_CONTINUE_NEEDED | The client must send the output token to the server, and wait for a return token. The returned token is then passed in another call to InitializeSecurityContext.
SEC_I_COMPLETE_NEEDED | The client must finish building the message, then call the CompleteAuthToken function.
SEC_I_COMPLETE_AND_CONTINUE | The client must call CompleteAuthToken, then pass the output to the server. The client then waits for a returned token and passes it in another call to InitializeSecurityContext.
SEC_E_INCOMPLET_MESSAGE | Use with SSL. Data for the whole message was not read from the wire.

If the function fails, the return value is one of the following error codes.

Value | Meaning
SEC_E_INVALID_HANDLE | The handle passed to the function is invalid.
SEC_E_TARGET_UNKNOWN | The target was not recognized.
SEC_E_LOGON_DENIED | The logon failed.
SEC_E_INTERNAL_ERROR | The Local Security Authority cannot be contacted.
SEC_E_NO_CREDENTIALS | No credentials are available in the security package.
SEC_E_NO_AUTHENTICATING_AUTHORITY | No authority could be contacted for authentication. The domain name of the authenticating party could be wrong, the domain could be unreachable, or there might have been a trust relationship failure.
SEC_E_INSUFFICIENT_MEMORY | One or more of the SecBufferDesc structures passed as an OUT parameter has a buffer that is too small.
SEC_E-INVALID_TOKEN | The error is due to a malformed input token, such as a token corrupted in transit, a token of incorrect size, or a token passed into the wrong security package. Passing a token to the wrong package can happen if client and server did not negotiate the proper security package.

Remarks

The InitializeSecurityContext function is used by a client to initialize an outbound context.

For a two-leg security package, the calling sequence is as follows:

  1. The client calls the function with phContext set to NULL and fills in the buffer descriptor with the input message.
  2. The security package examines the parameters and constructs an opaque token, placing it in the TOKEN element in the buffer array. If the fContextReq parameter includes the ISC_REQ_ALLOCATE_MEMORY flag, the security package allocates the memory and returns the pointer in the TOKEN element.
  3. The client sends the token returned in the pOutput buffer to the target server. The server then passes the token as an input argument in a call to the AcceptSecurityContext function.
  4. AcceptSecurityContext may return a token, which the server sends to the client for a second call to InitializeSecurityContext if the first call returned SEC_I_CONTINUE_NEEDED..

For multi-leg security packages such as mutual authentication, the calling sequence is as follows:

  1. The client calls the function as described earlier, but the package returns the SEC_I_CONTINUE_NEEDED success code.
  2. The client sends the output token to the server and waits for the server's reply.
  3. Upon receipt of the server's response, the client calls InitializeSecurityContext again, with phContext set to the handle that was returned from the last call. The token received from the server is supplied in the pInput parameter. If the server has successfully responded, the security package returns SEC_E_OK and a secure session is established. If the function returns one of the error responses, the server's response is not accepted and the session is not established. If the function returns SEC_I_CONTINUE_NEEDED, SEC_I_COMPLETE_NEEDED, or SEC_I_COMPLETE_AND_CONTINUE, steps 2 and 3 are repeated.

To initialize a security context, more than one call to this function may be required, depending on the underlying authentication mechanism as well as the choices specified in the fContextReq parameter.

The fContextReq and pfContextAttributes paramaters are bit masks representing various context attributes. For a description of the various attributes, see Context Requirements. The pfContextAttributes parameter is valid on any successful return, but only on the final successful return should you examine the flags pertaining to security aspects of the context. Intermediate returns can set, for example, the ISC_RET_ALLOCATED_MEMORY flag.

The caller is responsible for determining whether the final context attributes are sufficient. If, for example, confidentiality was requested, but could not be established, some applications may choose to shut down the connection immediately.

When the ISC_REQ_PROMPT_FOR_CREDS flag is set, the security package attempts to prompt the user for the credentials to use for the connection. If the caller is not an interactive user (for example, a non-interactive service), this flag is ignored. During the prompt, the package might inquire if the supplied credentials must be retained. If retention of the supplied credentials is indicated, the package can store them for future use relieving the user of having to re-enter the credentials.

If the ISC_REQ_USE_SUPPLIED_CREDS flag is set, the security package must look for a SECBUFFER_PKG_PARAMS buffer type in the pInput input buffer. This is not a generic solution, but it allows for a strong pairing of security package and application when appropriate.

If ISC_REQ_ALLOCATE_MEMORY was specified, the caller must free the memory by calling the FreeContextBuffer function.

For example, the input token could be the challenge from a LAN Manager or Windows NT/Windows 2000 file server. In this case, the output token would be the NTLM-encrypted response to the challenge.

The action the client takes depends on the return code from this function. If the return code is SEC_E_OK, there will be no second InitializeSecurityContext call, and no response from the server is expected. If the return code is SEC_I_CONTINUE_NEEDED, the client expects a token in response from the server, and passes it in a second call to InitializeSecurityContext. The SEC_I_COMPLETE_NEEDED return code indicates that the client must finish building the message and call the CompleteAuthToken function. The SEC_I_COMPLETE_AND_CONTINUE code incorporates both of these actions.

If the connection is rejected by the server, the client must call the DeleteSecurityContext function at that time to free any resources.

The client may call InitializeSecurityContext again after it has completed successfully. This indicates to the security package that a re-authentication is desired.

Kernel mode callers have the following differences: the target name is a Unicode string and must be allocated in virtual memory using VirtualAlloc, not from the pool. Buffers passed and supplied in pInput and pOutput must be in virtual memory, not in the pool.

The prototype for this function can be found in Sspi.h.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

AcceptSecurityContext, AcquireCredentialsHandle, CompleteAuthToken, DeleteSecurityContext, FreeContextBuffer, SecBuffer, SecBufferDesc


QueryContextAttributes

The QueryContextAttributes function enables a transport application to query a security package for certain attributes of a security context.

SECURITY_STATUS QueryContextAttributes(
  PCtxtHandle phContext,   // handle of the context to query
  ULONG ulAttribute,       // attribute to query
  PVOID pBuffer            // buffer for attributes
);

Parameters

phContext
[in] Handle to the security context to be queried.
ulAttribute
[in] Specifies the attribute of the context to be returned. This parameter can be one of the following values.
Value | Meaning | pBuffer type
SECPKG_ATTR_SIZES | Queries the sizes of the structures used in the per-message functions. | SecPkgContext_Sizes structure
SECPKG_ATTR_NAMES | Queries the name associated with the context. | SecPkgContext_Names structure
SECPKG_ATTR_LIFESPAN | Queries the life span of the context. | SecPkgContext_Lifespan structure
SECPKG_ATTR_DCE_INFO | Queries for authorization data used by DCE services. | SecPkgContext_DceInfo structure
SECPKG_ATTR_STREAM_SIZES | Queries the sizes of the various stream components used in the per-message functions. | SecPkgContext_StreamSizes structure
SECPKG_ATTR_AUTHORITY | Queries the name of the authenticating authority. | SecPkgContext_Authority structure
SECPKG_ATTR_KEY_INFO | Queries information about the keys used in a security context. | SecPkgContext_KeyInfo structure
SECPKG_ATTR_REMOTE_CERT_CONTEXT | Finds a certificate context containing the end certificate supplied by the server. | PCCERT_CONTEXT
SECPKG_ATTR_LOCAL_CERT_CONTEXT | Finds a certificate context containing a local end certificate. | PCCERT_CONTEXT
SECPKG_ATTR_ROOT_STORE | Finds a certificate context containing a certificate supplied by the Root store. | HCERTCONTEXT
SECPKG_ATTR_ISSUER_LIST_EX | Returns a list of certificate issuers acceptable by the server. | SecPkgContext_IssuerListInfoEx structure
SECPKG_ATTR_CONNECTION_INFO | Returns detailed information on the established connection. | SecPkgContext_ConnectionInfo structure
SECPKG_ATTR_PACKAGE_INFO | Returns information on the SSP in use. | SecPkgContext_PackageInfo
SECPKG_ATTR_NEGOTIATION_INFO | Returns information on the security package to be used using the negotiation process and the current state of the negotiation for the use of that package. | SecPkgContext_NegotiationInfo

pBuffer
[out] Pointer to a structure that receives the attributes. The type of structure pointed to depends on the value specified in the ulAttribute parameter.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value is a nonzero error code.

Remarks

The structure pointed to by the pBuffer parameter varies depending on the attribute being queried. The caller must allocate the structure itself, but the package allocates other pointers that are returned in the structure. Any pointers allocated by the package can be freed by calling the FreeContextBuffer function.

After the SECPKG_ATTR_REMOTE_CERT_CONTEXT or SECPKG_ATTR_LOCAL_CERT_CONTEXT value has been read, the hStore member will be set to a handle to a certificate store containing the intermediate certificates, if any. Also, the application is responsible for calling CertFreeCertificateContext to release the memory used by the certificate context.

The prototype for this function can be found in Sspi.h.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

CERT_CONTEXT, FreeContextBuffer, SecPkgContext_Authority, SecPkgContext_ConnectionInfo, SecPkgContext_DceInfo, SecPkgContext_IssuerListInfoEx, SecPkgContext_KeyInfo, SecPkgContext_Lifespan, SecPkgContext_Names, SecPkgContext_Sizes, SecPkgContext_StreamSizes


QuerySecurityContextToken

The QuerySecurityContextToken function obtains the Windows NT/Windows 2000 access token for a client security context and uses it directly.

SECURITY_STATUS QuerySecurityContextToken(
  PCtxtHandle phContext,
  HANDLE *phToken
);

Parameters

phContext
[in] Handle of the context to query.
phToken
[out] Returned handle to the access token.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value is a nonzero error code. One possible error code return is SEC_E_INVALID_HANDLE.

Remarks

This function is called by a security package or application to control impersonation outside the SSPI layer, such as when launching a child process. The handle returned must be closed with CloseHandle when the handle is no longer needed.

The prototype for this function can be found in Sspi.h.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.


RevertSecurityContext

The RevertSecurityContext function allows a security package to discontinue the impersonation of the caller and restore its own security context.

SECURITY_STATUS RevertSecurityContext(
  PCtxtHandle phContext  // handle of the context being impersonated
);

Parameters

phContext
[in] Handle of the security context being impersonated. This handle must have been obtained in the call to the AcceptSecurityContext function and used in the call to the ImpersonateSecurityContext function.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value can be the following error code.

Value | Meaning
SEC_E_INVALID_HANDLE | The handle passed to the function is invalid.

Remarks

The security package or an application server calls the RevertSecurityContext function when it needs to stop impersonating the caller. The server must have used this handle in the ImpersonateSecurityContext function.

RevertSecurityContext is not available with all security packages on all platforms. Typically, it is implemented only on platforms and with security packages for which a call to the QuerySecurityPackageInfo function indicates impersonation support.

The prototype for this function can be found in Sspi.h.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.

See Also

AcceptSecurityContext, ImpersonateSecurityContext


Message Support

SSPI message support functions enable an application to transmit and receive tamper-resistant messages and to encrypt and decrypt messages. These functions work with one or more buffers containing a message and with a security context created by the context management functions. The functions' behavior differs based on whether a connection, datagram, or stream context is in use. For a description of these differences, see Context Semantics.

The following functions provide security support for messages.

Function | Description
DecryptMessage | Decrypts an encrypted message using the session key from a security context.
EncryptMessage | Encrypts a message using the session key from a security context.
MakeSignature | Generates a secure signature based on a message and a security context.
VerifySignature | Verifies that a signature matches a received message.


DecryptMessage

The DecryptMessage function decrypts a message. Some packages do not have messages to encrypt/decrypt, but rather an integrity hash to be provided and checked.

SECURITY_STATUS DecryptMessage(
  PCtxtHandle phContext,     // context to use
  PSecBufferDesc pMessage,   // buffer containing the message to decrypt
  ULONG MessageSeqNo,        // expected sequence number
  PULONG pfQOP               // quality of protection
);

Parameters

phContext
[in] Handle to the security context to be used to decrypt the message.
pMessage
[in/out] Pointer to a SecBufferDesc structure. On input, the structure references one or more SecBuffer structures. One of these may be of type SECBUFFER_DATA. That buffer contains the encrypted message. The encrypted message is decrypted in place, overwriting the original contents of its buffer.
MessageSeqNo
[in] Specifies the sequence number expected by the transport application, if any. If the transport application does not maintain sequence numbers, this parameter must be set to zero.
pfQOP
[out] Pointer to a ULONG variable that receives package-specific flags indicating the quality of protection.

The following flag is defined for use with the Kerberos protocol.
Flag | Description
KERB_WRAP_NO_ENCRYPT | Message was not encrypted, but a header/trailer was produced.

Return Values

If the function verifies that the message was received in the correct sequence, the return value is SEC_E_OK.

If the function fails to decrypt the message, the return value can be one of the following error codes.

Value | Meaning
SEC_E_OUT_OF_SEQUENCE | The message was not received in the correct sequence.
SEC_E_INCOMPLETE_MESSAGE | The data in the input buffer is incomplete. The application needs to read more data from the server and call DecryptMessage again.
SEC_I_RENEGOTIATE | The remote party requires a new handshake sequence or the application has just initiated a shutdown. Return to the negotiation loop and call AcceptSecurityContext or InitializeSecurityContext, passing empty input buffers.
SEC_E_CONTEXT_EXPIRED | The remote party closed the connection. Call EncryptMessage with an empty input buffer, send the output data (if any) to the remote party, and delete the security context.

Remarks

Sometimes an application will read data from the remote party, attempt to decrypt it with DecryptMessage, and discover that DecryptMessage succeeded but the output buffers are empty. This is normal behavior, and applications must be able to deal with it.

This function is directly supported in Microsoft® Windows® 2000 and later and in Microsoft® Windows® ME. It can be loaded for NTLM with Microsoft® Windows NT® version 4.0, SP4 from security.dll. This function is also available for NTLM and SSL for Windows 95 and Windows 98 using Directory Service Client ( dsclient ).

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.

See Also

EncryptMessage, SecBuffer, SecBufferDesc


EncryptMessage

The EncryptMessage function encrypts a message to provide privacy. EncryptMessage allows the application to choose among cryptographic algorithms supported by the chosen mechanism. The EncryptMessage function uses the security context referenced by the context handle. Some packages do not have messages to be encrypted/decrypted, but rather an integrity hash to be provided and checked.

SECURITY_STATUS EncryptMessage(
  PCtxtHandle phContext,     // context to use
  ULONG fQOP,                // quality of protection
  PSecBufferDesc pMessage,   // message to encrypt
  ULONG MessageSeqNo         // message sequence number
);

Parameters

phContext
[in] Handle to the security context to be used to encrypt the message.
fQOP
[in] Specifies package-specific flags that indicate the quality of protection. A security package can use this parameter to enable the selection of cryptographic algorithms.

The following flag is defined for use with the Kerberos protocol.
Flag | Description
KERB_WRAP_NO_ENCRYPT | Message is not to be encrypted, but a header/trailer is to be produced.

pMessage
[in/out] Pointer to a SecBufferDesc structure. On input, the structure references one or more SecBuffer structures. Only one of these can be of type SECBUFFER_DATA. That buffer contains the message to be encrypted. The function does not process buffers with the SECBUFFER_READONLY attribute.

The message in SecBuffer is encrypted in place; that is, the encrypted message overwrites the original data in the structure. Only one SecBuffer structure of type SECBUFFER_DATA is permitted.

The length of the SecBuffer structure that contains the message must be no greater than cbMaximumMessage, which is obtained from the QueryContextAttributes (SECPKG_ATTR_STREAM_SIZES) function.

MessageSeqNo
[in] Specifies a sequence number that the transport application assigned to the message. If the transport application does not maintain sequence numbers, this parameter must be zero.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value is a nonzero error code.

This function can return the error code SEC_I_RENEGOTIATE, indicating that the remote party requires a new handshake sequence or that the application has just initiated a shutdown. Return to the negotiation loop and call AcceptSecurityContext or InitializeSecurityContext again. An empty input buffer is passed in the first call.

Remarks

The EncryptMessage function encrypts a message based on the message and the session key from a security context.

If the transport application created the security context to support sequence detection and the caller provides a sequence number, the function includes this information with the encrypted message. Including this information protects against replay, insertion, and suppression of messages. The security package incorporates the sequence number passed down from the transport application.

This function is directly supported in Microsoft® Windows® 2000 and later and in Microsoft® Windows® ME. It can be loaded for NTLM with Microsoft® Windows NT® version 4.0, SP4 from security.dll. This function is also available for NTLM and SSL for Windows 95 and Windows 98 using Directory Service Client ( dsclient ).

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.

See Also

AcceptSecurityContext, DecryptMessage, InitializeSecurityContext, QueryContextAttributes, SecBuffer, SecBufferDesc


MakeSignature

The MakeSignature function generates a cryptographic checksum of the message, and also includes sequencing information to prevent message loss or insertion. MakeSignature allows the application to choose between several cryptographic algorithms, if supported by the chosen mechanism. The MakeSignature function uses the security context referenced by the context handle.

SECURITY_STATUS MakeSignature(
  PCtxtHandle phContext,     // context to use
  ULONG fQOP,                // quality of protection
  PSecBufferDesc pMessage,   // message to sign
  ULONG MessageSeqNo         // message sequence number
);

Parameters

phContext
[in] Handle to the security context to use to sign the message.
fQOP
[in] Specifies package-specific flags that indicate the quality of protection. A security package can use this parameter to enable the selection of cryptographic algorithms.
pMessage
[in/out] Pointer to a SecBufferDesc structure. On input, the structure references one or more SecBuffer structures that contain the message to be signed. The function does not process buffers with the SECBUFFER_READONLY attribute.

The SecBufferDesc structure also references a SecBuffer structure of type SECBUFFER_TOKEN that receives the signature.

MessageSeqNo
[in] Specifies a sequence number that the transport application assigned to the message. If the transport application does not maintain sequence numbers, this parameter is zero.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value is a nonzero error code.

Remarks

The MakeSignature function generates a signature that is based on the message and the session key for the context.

If the transport application created the security context to support sequence detection and the caller provides a sequence number, the function includes this information in the signature. This protects against reply, insertion, and suppression of messages. The security package incorporates the sequence number passed down from the transport application.

The prototype for this function can be found in Sspi.h.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.

See Also

SecBuffer, SecBufferDesc, VerifySignature


VerifySignature

The VerifySignature function verifies the signature of a message received.

SECURITY_STATUS VerifySignature(
  PCtxtHandle phContext,    // context to use
  PSecBufferDesc pMessage,  // message to verify
  ULONG MessageSeqNo,       // sequence number
  PULONG pfQOP              // quality of protection
);

Parameters

phContext
[in] Handle to the security context to use for the message.
pMessage
[in] Pointer to a SecBufferDesc structure that references a set of SecBuffer structures that contain the message and signature to verify. The signature is in a SecBuffer structure of type SECBUFFER_TOKEN.
MessageSeqNo
[in] Specifies the sequence number expected by the transport application, if any. If the transport application does not maintain sequence numbers, this parameter is zero.
pfQOP
[out] Pointer to a ULONG variable that receives package-specific flags that indicate the quality of protection.

Return Values

If the function verifies that the message was received in the correct sequence and has not been modified, the return value is SEC_E_OK.

If the function determines that the message is not correct according to the information in the signature, the return value can be one of the following error codes.

Value | Meaning
SEC_E_OUT_OF_SEQUENCE | The message was not received in the correct sequence.
SEC_E_MESSAGE_ALTERED | The message has been altered.

Remarks

The VerifySignature function verifies that the message received was correct according to the information in the signature.

The prototype for this function can be found in Sspi.h.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.

See Also

MakeSignature, SecBuffer


SSPI Structures

The following structures are used in SSPI. These structures are defined in Sspi.h.

  • SEC_WINNT_AUTH_IDENTITY
  • SEC_WINNT_AUTH_IDENTITY_EX
  • SecBuffer
  • SecBufferDesc
  • SecPkgContext_ConnectionInfo
  • SecPkgContext_DceInfo
  • SecPkgContext_IssuerListInfoEx
  • SecPkgContext_Lifespan
  • SecPkgContext_Names
  • SecPkgContext_NegotiationInfo
  • SecPkgContext_PackageInfo
  • SecPkgContext_Sizes
  • SecPkgContext_StreamSizes
  • SecPkgCredentials_Names
  • SecPkgInfo
  • SecurityFunctionTable


SEC_WINNT_AUTH_IDENTITY

The SEC_WINNT_AUTH_IDENTITY structure allows you to pass a particular user name and password to the run-time library for the purpose of authentication.

typedef struct _SEC_WINNT_AUTH_IDENTITY
{
  unsigned short __RPC_FAR *User;
  unsigned long UserLength;
  unsigned short __RPC_FAR *Domain;
  unsigned long DomainLength;
  unsigned short __RPC_FAR *Password;
  unsigned long PasswordLength;
  unsigned long Flags;
} SEC_WINNT_AUTH_IDENTITY, *PSEC_WINNT_AUTH_IDENTITY;

Members

User
String containing the user name.
UserLength
The length of the user string in characters, not including the terminating Null.
Domain
String containing the domain name or the workgroup name.
DomainLength
The length of the domain string in characters, not including the terminating Null.
Password
String containing the user's password in the domain or workgroup.
PasswordLength
The length of the password string in characters, not including the terminating Null.
Flags
The following values are valid flags for this member of the SEC_WINNT_AUTH_IDENTITY structure.
Value | Description
SEC_WINNT_AUTH_IDENTITY_ANSI | The strings in this structure are in ANSI format.
SEC_WINNT_AUTH_IDENTITY_UNICODE | The strings in this structure are in Unicode format.

Remarks

Note that this structure must remain valid for the lifetime of the binding handle.

For Windows 95, the strings are ANSI; for Windows NT/Windows 2000, the strings may be ANSI or Unicode, depending on the value you assign to the Flags member.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Rpcdce.h.


SEC_WINNT_AUTH_IDENTITY_EX

The SEC_WINNT_AUTH_IDENTITY_EX structure contains information about a user. Both an ASCI and Unicode form of this structure are provided.

typedef struct _SEC_WINNT_AUTH_IDENTITY_EX {
  unsigned long Version;
  unsigned long Length;
  LPTSTR User;
  unsigned long UserLength;
  LPTSTR Domain;
  unsigned long DomainLength;
  LPTSTR Password;
  unsigned long PasswordLength;
  unsigned long Flags;
  LPTSTR PackageList;
  unsigned long PackageListLength;
} SEC_WINNT_AUTH_IDENTITY_EX, *PSEC_WINNT_AUTH_IDENTITY_EX;

Members

Version
Unsigned long indicating the version number of the structure.
Length
Unsigned long indicating the length of the structure in bytes.
User
Unicode or ANSI string with the name of the user account.
UserLength
Unsigned long indicating the length of the user name string.
Domain
Unicode or ANSI string with the name of the domain for the user account.
DomainLength
Unsigned long indicating the length of the domain name string.
Password;
Unicode or ANSI string with the user password in plaintext.
PasswordLength
Unsigned long indicating the length of the password string.
Flags
Unsigned long flag indicating the type used by negotiable security packages.
Flag value | Meaning
SEC_WINNT_AUTH_IDENTITY_MARSHALLED | All data is in one buffer.
SEC_WINNT_AUTH_IDENTITY_ONLY | Used with the Kerberos SSP. Credentials are for identity only. The Kerberos package is directed to not include authorization data in the ticket.
SEC_WINNT_AUTH_IDENTITY_ANSI | Credentials are in ANSI form.
SEC_WINNT_AUTH_IDENTITY_UNICODE | Credentials are in Unicode form.

PackageList
Unicode or ANSI string comma separated list of names of security packages to use.
PackageListLength
Unsigned long indicating the length of the package list string.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Sspi.h; include Security.h.


SecBuffer

The SecBuffer structure describes a buffer allocated by a transport application to pass to a security package.

typedef struct _SecBuffer {
  ULONG        cbBuffer;
  ULONG        BufferType;
  PVOID        pvBuffer;
} SecBuffer, *PSecBuffer;

Members

cbBuffer
Specifies the size, in bytes, of the buffer pointed to by the pvBuffer member.
BufferType
Bit flags that indicate the type of buffer. BufferType must be one of the following flags.
Flag | Meaning
SECBUFFER_EMPTY | This is a placeholder in the buffer array. The caller can supply several such entries in the array, and the security package can return information in them. For more information, see Context Semantics.
SECBUFFER_DATA | Used for common data. The security package can read and write this data, for example, to encrypt some or all of it.
SECBUFFER_TOKEN | This buffer is used to indicate the security token portion of the message. This is read-only for input parameters or read/write for output parameters.
SECBUFFER_PKG_PARAMS | These are transport-to-package–specific parameters. For example, the Netware redirector may supply the server object identifier, while DCE RPC can supply an association UUID, and so on.
SECBUFFER_MISSING | The security package uses this value to indicate the number of missing bytes in a particular message. The pvBuffer member is ignored in this type.
SECBUFFER_EXTRA | The security package uses this value to indicate the number of extra or unprocessed bytes in a message.
SECBUFFER_STREAM_TRAILER | Indicates a protocol-specific trailer for a particular record. Not usually of interest to callers.
SECBUFFER_STREAM_HEADER | Indicates a protocol-specific header for a particular record. Not usually of interest to callers.

In addition, BufferType can combine the following flag with any of the flags in the preceding table using a bitwise OR operation.
Flag | Meaning
SECBUFFER_READONLY | The buffer is read-only. This flag is intended for sending header information to the security package for computing the checksum or the like. The package can read this buffer, but cannot modify it.

pvBuffer
Pointer to a buffer.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.

See Also

SecBufferDesc


SecBufferDesc

The SecBufferDesc structure describes an array of SecBuffer structures to pass from a transport application to a security package.

typedef struct _SecBufferDesc {
  ULONG        ulVersion;
  ULONG        cBuffers;
  PSecBuffer   pBuffers;
} SecBufferDesc, * PSecBufferDesc;

Members

ulVersion
Specifies the version number of this structure. This member must be SECBUFFER_VERSION.
cBuffers
Indicates the number of SecBuffer structures in the pBuffers array.
pBuffers
Pointer to an array of SecBuffer structures.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.

See Also

SecBuffer


SecPkgContext_DceInfo

The SecPkgContext_DceInfo structure contains authorization data used by DCE services. The QueryContextAttributes function uses this structure.

typedef struct _SecPkgContex_DceInfo {
  ULONG  AuthzSvc;
  PVOID  pPac;
} SecPkgContext_DceInfo, * PSecPkgContext_DceInfo;

Members

AuthzSvc
Specifies the authorization service used. For DCE use only.
pPac
Pointer to package-specific authorization data.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.

See Also

QueryContextAttributes


SecPkgContext_Lifespan

The SecPkgContext_Lifespan structure indicates the life span of a security context. The QueryContextAttributes function uses this structure.

typedef struct _SecPkgContext_Lifespan {
  TimeStamp      tsStart;
  TimeStamp      tsExpiry;
} SecPkgContext_Lifespan, * PSecPkgContext_Lifespan;

Members

tsStart
Time at which the context was established.
tsExpiry
Time at which the context will expire.

Remarks

It is recommended that the security package always return these values in local time.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.

See Also

QueryContextAttributes


SecPkgContext_Names

The SecPkgContext_Names structure indicates the name of the user associated with a security context. The QueryContextAttributes function uses this structure.

typedef struct _SecPkgContext_Names {
  SEC_CHAR *  sUserName;
} SecPkgContext_Names, * pSecPkgContext_Names;

Members

sUserName
Pointer to a NULL-terminated string containing the name of the user represented by the context. If the security package has set the SECPKG_FLAG_ACCEPT_WIN32_NAME flag, this name can be used in other Win32® calls.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Unicode: Declared as Unicode and ANSI structures.

See Also

QueryContextAttributes


SecPkgContext_NegotiationInfo

The SecPkgContext_NegotiationInfo structure contains information on the security package that is being set up or has been set up, and also gives the status on the negotiation to set up the security package.

typedef struct _SecPkgContext_NegotiationInfo
{
  PSecPkgInfo     PackageInfo ;
  unsigned long   NegotiationState ;
} SecPkgContext_NegotiationInfo, *PSecPkgContext_NegotiationInfo;

Members

PackageInfo
Pointer to a SecPkgInfo structure that provides general information about the security package chosen in the negotiate process, such as the name and capabilities of the package.
NegotiationState
Indicator of the state of the negotiation for the security package identified in the PackageInfo member. This attribute can be queried from the context handle before the setup is complete, such as when ISC returns SEC_I_CONTINUE_NEEDED

The following table shows values returned in this member:
Value | Meaning
SECPKG_NEGOTIATION_COMPLETE | Negotiation has been completed.
SECPKG_NEGOTIATION_OPTIMISTIC | Negotiations not yet completed.
SECPKG_NEGOTIATION_IN_PROGRESS | Negotiations in progress.
SECPKG_NEGOTIATION_DIRECT | Negotiations in progress

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Unicode: Declared as Unicode and ANSI structures.


SecPkgContext_PackageInfo

The SecPkgContext_PackageInfo structure contains the name of a security support provider (SSP). This structure is returned by the QueryContextAttributes function. It would most often be used when the SSP in use was established using the Negotiate security package.

typedef struct _SecPkgContext_PackageInfo{
  PSecPkgInfo PackageInfo;
} SecPkgContext_PackageInfo, * PSecPkgContext_PackageInfo;

Members

PackageInfo
Pointer to a SecPkgInfo structure containing the name of the SSP in use.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Sspi.h; include Security.h.

See Also

QueryContextAttributes, SecPkgInfo


SecPkgContext_Sizes

The SecPkgContext_Sizes structure indicates the sizes of important structures used in the message support functions. The QueryContextAttributes function uses this structure.

typedef struct _SecPkgContext_Sizes {
  ULONG    cbMaxToken;
  ULONG    cbMaxSignature;
  ULONG    cbBlockSize;
  ULONG    cbSecurityTrailer;
} SecPkgContext_Sizes, * PSecPkgContext_Sizes;

Members

cbMaxToken
Specifies the maximum size of the security token used in the authentication exchanges.
cbMaxSignature
Specifies the maximum size of the signature created by the MakeSignature function. This member must be zero if integrity services are not requested or available.
cbBlockSize
Specifies the preferred integral size of the messages. F or example, 8 indicates that messages should be of size 0 mod 8 for optimal performance. Messages other than this block size can be padded.
cbSecurityTrailer
Size of the security trailer to be appended to messages. This member should be zero if the relevant services are not requested or available.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.

See Also

MakeSignature, QueryContextAttributes


SecPkgContext_StreamSizes

The SecPkgContext_StreamSizes structure indicates the sizes of the various stream components for use with the message support functions. The QueryContextAttributes function uses this structure.

typedef struct _SecPkgContext_StreamSizes {
  ULONG        cbHeader;
  ULONG        cbTrailer;
  ULONG        cbMaximumMessage;
  ULONG        cBuffers;
  ULONG        cbBlockSize;
} SecPkgContext_StreamSizes, * PSecPkgContext_StreamSizes;

Members

cbHeader
Specifies the size, in bytes, of the header portion. If zero, no header is used.
cbTrailer
Specifies the size, in bytes, of the trailer portion. If zero, no trailer is used.
cbMaximumMessage
Specifies the size, in bytes, of the largest message that can be encapsulated.
cBuffers
Specifies the number of buffers to pass.
cbBlockSize
Specifies the preferred integral size of the messages. F or example, 8 indicates that messages should be of size 0 mod 8 for optimal performance. Messages other than this block size can be padded.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.

See Also

QueryContextAttributes


SecPkgCredentials_Names

The SecPkgCredentials_Names structure holds the name of the user associated with a context. The QueryCredentialsAttributes function uses this structure.

typedef struct _SecPkgCredentials_Names {
  SEC_CHAR *  sUserName;
} SecPkgCredentials_Names, * PSecPkgCredentials_Names;

Members

sUserName
Pointer to a NULL-terminated string containing the name of the user represented by the credential. If the security package sets the SECPKG_FLAG_ACCEPT_WIN32_NAME flag to indicate that it can process Win32 names, this name can be used in other Win32 calls.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Unicode: Declared as Unicode and ANSI structures.

See Also

QueryCredentialsAttributes


SecPkgInfo

The SecPkgInfo structure provides general information about a security package, such as its name and capabilities.

typedef struct _SecPkgInfo {
  ULONG fCapabilities;  // capability of bit mask
  USHORT wVersion;      // version of driver
  USHORT wRPCID;        // identifier for RPC run time
  ULONG cbMaxToken;     // size of authentication token
  SEC_CHAR * Name;      // text name
  SEC_CHAR * Comment;   // comment
} SecPkgInfo, * PSecPkgInfo;

Members

fCapabilities
Set of bit flags that describes the capabilities of the security package. This member can be a combination of the following flags.
Value | Meaning
SECPKG_FLAG_INTEGRITY | Verifies that all messages exchanged have not been tampered with or exchanged out of sequence.
SECPKG_FLAG_PRIVACY | All messages are tamper proof and are not passed in plaintext. Reserved for future use.
SECPKG_FLAG_TOKEN_ONLY | The package is interested only in the security-token portion of messages, and will ignore any other buffers. This is a performance-related issue.
SECPKG_FLAG_DATAGRAM | Supports datagram-style authentication. For more information, see Context Semantics.
SECPKG_FLAG_CONNECTION | Supports connection-oriented style authentication. For more information, see Context Semantics.
SECPKG_FLAG_MULTI_REQUIRED | Multiple legs are required for authentication.
SECPKG_FLAG_CLIENT_ONLY | Server authentication support is not provided.
SECPKG_FLAG_EXTENDED_ERROR | Supports extended error handling. For more information, see Extended Error Information.
SECPKG_FLAG_IMPERSONATION | Supports Win32 impersonation in server contexts.
SECPKG_FLAG_ACCEPT_WIN32_NAME | Understands Win32 principal and target names.
SECPKG_FLAG_STREAM | Supports stream semantics. For more information, see Context Semantics.

wVersion
Specifies the version of the package protocol. Must be 1.
wRPCID
Specifies a DCE RPC identifier, if appropriate. If the package does not implement one of the DCE registered security systems, the reserved value SECPKG_ID_NONE is used.
cbMaxToken
Specifies the maximum size, in bytes, of the token.
Name
Pointer to a NULL-terminated string that contains the name of the security package.
Comment
Pointer to a NULL-terminated string. This can be any additional string passed back by the package.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Unicode: Declared as Unicode and ANSI structures.

See Also

EnumerateSecurityPackages, QuerySecurityPackageInfo


SecurityFunctionTable

The SecurityFunctionTable structure is a dispatch table that contains pointers to the functions defined in SSPI.

typedef struct _SECURITY_FUNCTION_TABLE {
  unsigned long                     dwVersion;
  ENUMERATE_SECURITY_PACKAGES_FN    EnumerateSecurityPackages;
  void SEC_FAR *                    Reserved1;
  QUERY_CREDENTIAL_ATTRIBUTES_FN_W  QueryCredentialsAttributesW;
  ACQUIRE_CREDENTIALS_HANDLE_FN     AcquireCredentialsHandle;
  FREE_CREDENTIALS_HANDLE_FN        FreeCredentialHandle;
  void SEC_FAR *                    Reserved2;
  INITIALIZE_SECURITY_CONTEXT_FN    InitializeSecurityContextA;
  ACCEPT_SECURITY_CONTEXT_FN        AcceptSecurityContext;
  COMPLETE_AUTH_TOKEN_FN            CompleteAuthToken;
  DELETE_SECURITY_CONTEXT_FN        DeleteSecurityContext;
  APPLY_CONTROL_TOKEN_FN            ApplyControlToken;
  QUERY_CONTEXT_ATTRIBUTES_FN       QueryContextAttributesA;
  IMPERSONATE_SECURITY_CONTEXT_FN   ImpersonateSecurityContext;
  REVERT_SECURITY_CONTEXT_FN        RevertSecurityContext;
  MAKE_SIGNATURE_FN                 MakeSignature;
  VERIFY_SIGNATURE_FN               VerifySignature;
  FREE_CONTEXT_BUFFER_FN            FreeContextBuffer;
  QUERY_SECURITY_PACKAGE_INFO_FN    QuerySecurityPackageInfoA;
  void SEC_FAR *                    Reserved3;
  void SEC_FAR *                    Reserved4;
} SecurityFunctionTable, * PSecurityFunctionTable;

#define SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Unicode: Declared as Unicode and ANSI structures.

See Also

InitSecurityInterface


SSPI Types, Handles, and Status Codes

This section presents the following defined types, handles, and status codes:

  • SECURITY_INTEGER
  • TimeStamp
  • SSPI Handles
  • SSPI Status Codes


SECURITY_INTEGER

SECURITY_INTEGER is a defined type that holds a numeric value. It is used in defining other types.

typedef struct _SECURITY_INTEGER {
  unsigned long      LowPart;
  long               HighPart;
} SECURITY_INTEGER;

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.


TimeStamp

A TimeStamp time defined type holds information on time validity of security tokens. The type declarations for TimeStamp and PTimeStamp differ between the Microsoft® Win32® system and older Win16 or MS-DOS systems.

// For Win32 systems:

typedef SECURITY_INTEGER      TimeStamp, * PTimeStamp;

// For Win16 and MS-DOS systems

typedef unsigned long      TimeStamp, __far * PTimeStamp;


SSPI Handles

SSPI uses the following handle types and pointer to these handles:

  • SecHandle and PSecHandle
  • CredHandle and PCredHandle
  • CtxtHandle and PCtxtHandle

These handle types and pointers to these handle types are defined as follows:

typedef struct _SecHandle {
  unsigned long      dwLower;
  unsigned long      dwUpper;
} SecHandle, * PSecHandle;

typedef SecHandle    CredHandle;
typedef PSecHandle   PCredHandle;

typedef SecHandle    CtxtHandle;
typedef PSecHandle   PCtxtHandle;

Note For 16-bit environments, the PSecHandle type is actually a __far pointer.


SSPI Status Codes

The following status codes are used in SSPI applications.

Status code | Meaning
SEC_E_NOT_OWNER | The caller of the function does not own the credentials.
SEC_E_CANNOT_INSTALL | The security package cannot initialize successfully, and should not be installed.
SEC_I_PACKAGE_INSTALLED | Informational return indicating that the package installed itself successfully.
SEC_E_INVALID_HANDLE | The handle passed to the function is invalid.
SEC_E_CANNOT_PACK | The package is unable to pack the context.
SEC_E_INVALID_TOKEN | The token passed to the function is invalid.
SEC_E_NOT_SUPPORTED | The request is not supported.
SEC_E_QOP_NOT_SUPPORTED | The quality of protection attribute is not supported by this package.
SEC_E_NO_TOKEN | The context does not possess an impersonation token.
SEC_E_TARGET_UNKNOWN | The target was not recognized.
SEC_E_SECPKG_NOT_FOUND | The security package was not recognized.
SEC_E_NO_IMPERSONATION | No impersonation is allowed for this context.
SEC_E_LOGON_DENIED | This status code is obsolete.
SEC_E_UNKNOWN_CREDENTIALS | The credentials provided were not recognized.
SEC_E_NO_CREDENTIALS | No credentials are available.
SEC_E_MESSAGE_ALTERED | The message supplied for verification has been altered.
SEC_E_OUT_OF_SEQUENCE | The message supplied for verification is out of sequence.
SEC_E_NO_AUTHENTICATING_AUTHORITY | No authority could be contacted for authentication.
SEC_E_BAD_PKGID | The requested package identifier does not exist.
SEC_E_CONTEXT_EXPIRED | The context has expired and can no longer be used.
SEC_E_INCOMPLETE_MESSAGE | The message supplied was incomplete. The signature was not verified.
SEC_I_CONTINUE_NEEDED | The function completed successfully, but you must call this function again to complete the context.
SEC_I_COMPLETE_NEEDED | The function completed successfully, but you must call the CompleteAuthToken function on the final message.
SEC_I_COMPLETE_AND_CONTINUE | The function completed successfully, but the application must call both CompleteAuthToken and then either InitializeSecurityContext or AcceptSecurityContext again to complete the context.
SEC_E_INSUFFICIENT_MEMORY | One or more of the SecBufferDesc structures passed to a function as an OUT parameter has a buffer that is too small.


Microsoft Security Packages

The following topics contain information on security packages provided by Microsoft.

Security package | Description
Microsoft Digest Security Support Provider | A security support provider that supplies a light-weight authentication protocol for Hypertext Transfer Protocol (HTTP) or Simple Authentication Security Layer (SASL) based communications.
Microsoft NTLM | NTLM is a network authentication protocol used on Windows NT systems.
Microsoft Schannel | Schannel implements the TLS, SSL and PCT security protocols, and provides a means for securing communications that rely on the HTTP protocol.
Microsoft Kerberos | Kerberos is the network authentication protocol of choice for Windows 2000 systems.


Microsoft Digest

Microsoft Digest Start Page

Microsoft Digest Security Support Provider

Purpose

Microsoft Digest is a security support provider (SSP) that implements the Digest Access protocol, a light-weight authentication protocol for parties involved in Hypertext Transfer Protocol (HTTP) or Simple Authentication Security Layer (SASL) based communications.

Where Applicable

Microsoft Digest provides a simple challenge response mechanism for authenticating clients. This SSP is intended for use by client/server applications using HTTP or SASL based communications.

Developer Audience

The Microsoft Digest SSP is designed for use by C/C++ programmers and requires a familiarity with the Security Support Provider Interface.

Run-Time Requirements

Microsoft Digest SSP requires the Whistler release of the Microsoft® Windows® 2000 operating system.

See Also

Security Support Provider Interface

About Microsoft Digest SSP

General information about Microsoft Digest SSP.

Using SSPI with Microsoft Digest SSP

Using Microsoft security support provider interface (SSPI) functions to access the Microsoft Digest SSP.

Microsoft Digest Reference

SSPI functions used when authenticating a client with Microsoft Digest SSP.

Feedback

Make error reports and feature requests directly to Microsoft.


About Microsoft Digest SSP

[This is preliminary documentation and subject to change.]

Microsoft Digest is a security support provider (SSP) available in the Whistler beta release of the Windows 2000 operating system.

Microsoft Digest is the Microsoft implementation of Digest Access, a light-weight authentication protocol for parties involved in Hypertext Transfer Protocol (HTTP) or Simple Authentication Security Layer (SASL) based communications. Microsoft Digest implements and extends the following specifications:

  • HTTP Authentication: Basic and Digest Access Authentication (http://www.ietf.org/rfc/rfc2617.txt)
  • Using Digest Authentication as a SASL Mechanism (http://www.ietf.org/rfc/rfc2831.txt)

Digest Access authentication employs a challenge-response mechanism that relies on a secret known by both parties. The secret, which is used as the basis for identification, is never communicated in clear text. For this reason Digest Access is a more secure authentication scheme than Basic Access, the scheme included in the HTTP/1.0 specification. Basic Access requires the client to supply user credentials; however those credentials are not encrypted and can be compromised during transit.

Microsoft Digest is intended for use in situations where the bandwidth and overhead required by more robust protocols such as Schannel and Kerberos make them unfeasible. Microsoft Digest is currently used by LDAP, IIS, Windows Media Player, and to support wireless remote devices requiring Internet access to secure resources, such as e-mail, tasks and appointments stored on Microsoft Exchange servers.


The Digest Access Protocol

[This is preliminary documentation and subject to change.]

The Digest Access protocol specified by RFC2617 is implemented by the Microsoft Digest security support provider (SSP). The implementation consists of a set of Microsoft Security Support Provider Interface (SSPI) functions which client/server applications call to:

  • Establish a security context for message exchange
  • Obtain data objects required by the Digest SSP, such as credentials and context handles
  • Access message integrity and confidentiality mechanisms

Digest Access authentication takes place within paired request/response transactions, with requests originating on the client and responses originating on the server. A successful Digest Access authentication requires two request/response pairs.

When the Digest SSP is used for HTTP authentication, there is no connection maintained between the first and second request/response pair. In other words, the server does not wait for the second request after it sends the first response.

The following diagram illustrates the steps taken by a client and server to complete an authentication using the Digest SSP.

The process starts with the client requesting an access-protected resource from the server by sending HTTP Request 1.

The server receives HTTP Request 1 and determines that the resource requires authentication information that was not included in the request. The server generates a challenge for the client as follows:

The server obtains its credentials by calling the AcquireCredentialsHandle function.

The server generates the Digest challenge by calling the AcceptSecurityContext function.

The server sends a WWW-Authenticate header as its response to the client's request (shown as HTTP Response 1). The header contains the Digest challenge and an opaque directive which contains a reference to a partial security context established for the client. The header is sent with a 401 status code indicating that the client request generated an unauthorized access error. For additional information on the Digest challenge, see Contents of a Digest Challenge and Generating the Digest Challenge.

The client receives HTTP Response 1, extracts the Digest challenge sent by the server, and generates a Digest challenge response as follows:

The user's credentials are obtained either by calling the AcquireCredentialsHandle function, or by interactively prompting the user for credentials.

The challenge and credentials information are passed to the InitializeSecurityContext function, which generates the Digest challenge response.

The client sends an Authorization header containing the challenge response to the server (shown as HTTP Request 2). For additional information on the Digest challenge response, see Contents of a Digest Challenge Response and Generating the Digest Challenge Response.

The server receives HTTP Request 2, extracts the challenge response sent by the client, and authenticates the information by calling the AcceptSecurityContext function. For details on the authentication process, see Initial Authentication using Microsoft Digest.

The server sends HTTP Response 2 back to the client as the second and final response required by the Digest Access protocol. If the authentication is successful, this response contains the requested resource.


Contents of a Digest Challenge

[This is preliminary documentation and subject to change.]

The size of a Digest Access challenge must be less than 2048 bytes. Following is an example challenge assigned to the character string szChallenge:

szChallenge = "realm=\"Microsoft_Example_Forest\", algorithm = \"MD5-sess\", qop=\"auth\", nonce=\"0123456789abcdef\"";

Note The challenge string is enclosed in double quotes and contains embedded double quotes. Embedded double quotes must be preceded (escaped) with a backslash (\).

The following table describes the directives that make up a Digest challenge.

Directive | Description
realm | An implementation-defined hint to the client as to which credentials are required. The client should display this information to the user if prompting for credentials.
algorithm | Microsoft Digest supports MD5 and MD5-Sess. For optimal performance use MD5-Sess.
qop | Can specify "auth", "auth-int" or "auth-conf". For more information, see Quality of Protection and Ciphers.
nonce | A unique encoded value generated by the server for each challenge. This value must not be altered by the client.
opaque | Contains a reference for the security context that is being established. For more information see Maintaining the Security Context Between Connections.
(SASL only) cipher | The list of ciphers that the server supports. This element can be present in a Digest SASL challenge only if the qop directive specifies "auth-conf". For more information, see Quality of Protection and Ciphers.

Microsoft Digest generates the Digest challenge string for server applications. For details, see Generating the Digest Challenge.


Contents of a Digest Challenge Response

[This is preliminary documentation and subject to change.]

The client must send the server a Digest challenge response when it receives a Digest challenge in response to a request for a resource. The client must send the request again, supplying an Authorization header with the challenge response. The following table describes the directives that make up a Digest challenge response.

Directive | Description
username | The account name of the security principal requesting the resource.
realm | The name of the domain that contains the account indicated by username.
nonce | The nonce received in the Digest challenge.
uri | The Universal Resource Identifier (URI) of the requested resource.
qop | The quality of protection.
nc | The nonce count. The number of times the client has sent a challenge response using the nonce. See the nonce directive.
cnonce | A unique encoded value generated by the client for each challenge response.
response | A value computed according to the Digest Access specification (RFC 2617). An accurate response is conclusive proof that the user's password is known on the client side.
algorithm | The algorithm received in the Digest challenge.
opaque | The opaque value received in the Digest challenge.
(SASL only) cipher | One of the cipher values received in the Digest challenge. For cipher details, see Quality of Protection and Ciphers.

Microsoft Digest generates the Digest challenge response string for client applications. For details, see Generating the Digest Challenge Response.


Quality of Protection and Ciphers

[This is preliminary documentation and subject to change.]

The quality of protection determines the level of security that is used when sending and receiving messages. Microsoft Digest selects a level based on the requirements of the client and server.

When using Digest as a SASL mechanism, applications can specify that messages be kept confidential using encryption. The server specifies the ciphers it supports for encrypted messages, and the client selects a cipher from this list.

The following topics discuss these security mechanisms in detail:

  • Quality of Protection
  • Ciphers


Quality of Protection

[This is preliminary documentation and subject to change.]

The quality of protection, identified by the qop directive, is first specified by the server in the Digest challenge, and then confirmed by the client in the challenge response. If the client requires a quality of protection that the server does not support, the client must terminate the authentication.

The possible values for the qop directive are described in the following table.

qop value | Description
"auth" | Authentication only.
"auth-int" | Authentication and integrity checking using signatures.
(SASL only) "auth-conf" | Authentication, integrity and confidentiality checking using signatures and encryption. See Ciphers.

Quality of protection is determined by context requirement flags passed to the Microsoft Digest SSP. The following table lists the flags related to quality of protection, and the resulting value of the qop directive.

Flag | qop value
XXX_REQ_CONFIDENTIALITY | "auth-conf" (SASL only)
XXX_REQ_REPLAY_DETECT | "auth-int"
XXX_REQ_SEQUENCE_DETECT | "auth-int"
XXX_REQ_INTEGRITY | "auth-int"
(none) | "auth"

Note Context requirement flags specified by server applications have a prefix of ASC, and those specified by clients are prefixed with ISC. To determine the flag values used by your application, substitute one of these prefixes for XXX.

For additional server-related information, see Generating the Digest Challenge.

For additional client-related information, see Generating the Digest Challenge Response.


Ciphers

[This is preliminary documentation and subject to change.]

The following material is valid only when Digest is used as a SASL mechanism. Ciphers and encryption are not available for HTTP authentication using Microsoft Digest.

A Digest SASL challenge's cipher directive contains a list of the ciphers supported by a server that requires confidential communications. The cipher directive can only be included if the qop directive is set to "auth-conf". The ciphers recognized by Microsoft Digest are listed in the following table, in order from strongest to weakest.

Cipher value | Description
"rc4" | The RC4 cipher with a 128 bit key.
"3des" | The triple DES cipher in CBC mode with EDE with the same key for each E stage (two keys mode). Total key length is 112 bits.
"rc4-40" | The RC4 cipher with a 40 bit key.
"rc4-56" | The RC4 cipher with a 56 bit key.
"des" | The Data Encryption Standard (DES) cipher in cipher block chaining (CBC) mode with a 56 bit key.

When a server application requests confidentiality (qop="auth-conf") Microsoft Digest will generate a challenge that offers the client all of the ciphers installed on the server and supported by Digest. The Digest client will select the strongest available cipher. For details on specifying confidentiality, see Generating the Digest Challenge.


Microsoft Digest Authentication

Microsoft Digest performs an initial authentication when the server receives the first challenge response from a client. The server verifies that the client has not been authenticated and then performs the initial authentication by accessing the services of a domain controller. For a detailed description of this procedure, see Initial Authentication using Microsoft Digest.

When the initial authentication is successful the server receives a Digest session key. The server caches this key and uses it to authenticate subsequent requests for resources from the client. This authentication is local, that is, it does not require access to a domain controller. For a detailed description of this procedure see Authenticating Subsequent Requests using Microsoft Digest.

When using HTTP, there is no connection maintained between client and server. To reduce domain controller traffic and improve performance, Microsoft Digest caches information received after successful authentication. For information about this process, see Maintaining the Security Context Between Connections.


Initial Authentication Using Microsoft Digest

[This is preliminary documentation and subject to change.]

The initial authentication takes place when the server receives a challenge response from a client. Authenticating a challenge response typically involves a minimum of two servers:

  • The originating server—receives the request from the client and issues a challenge, and then receives the challenge response from the client which must be authenticated.
  • The authenticating server—receives authorization information from the originating server, and performs the authentication. This server is typically a domain controller that supports multiple originating servers.

When the originating server receives a request with an Authorization header containing a Digest challenge response, the authentication proceeds as follows:

  • The identity of the originating server is checked against the server encoded in the challenge's nonce.
  • The time stamp encoded in the nonce is checked. If the nonce has expired and the user name/password information is valid, the originating server ends the authentication by issuing a new Digest challenge with the stale directive set to "true". This indicates that only the nonce was "stale" and the client can respond to the new challenge using the password it used in the previous response. If the client receives a new challenge after sending the challenge response for the stale challenge, the client must generate a new challenge response.
  • If replay detection is enforced, the nc directive (nonce count) is checked against the nonce session database maintained by the server.
  • The authenticating server is identified and sent the client's authorization information.
  • The authenticating server checks the identity of the server encoded in the nonce against the identity of the originating server.
  • The authenticating server, which is a domain controller, retrieves the user's password.
  • Using the authorization information, password, and originating server identification, the authenticating server computes the value that the client should have supplied in the challenge response's response directive. The authenticating server compares the computed value to the client's response to determine the success or failure of the authentication.

If authentication is successful, the user's security context and a Digest session key are returned to the originating server. If authentication fails, the originating server must generate an error response. After a successful authentication the originating server returns the requested resource to the client.

The Digest session key returned by the authenticating server is cached by the originating server for use in authenticating future requests. For more information, see Authenticating Subsequent Requests using Microsoft Digest.


Authenticating Subsequent Requests Using Microsoft Digest

[This is preliminary documentation and subject to change.]

The server sends the client a reference to their shared security context using the opaque directive of the Digest challenge. After a successful authentication, the client must specify this value in subsequent requests to the target server. Including the opaque value in requests for resources that are accessible using the existing security context eliminates the need to re-authenticate at the domain controller. Such requests are re-authenticated at the server, using the Digest session key cached after the initial authentication.

The following diagram illustrates the steps taken by client and server during a subsequent request for access-protected resources.

To request additional resources after a successful authentication, the client calls the Microsoft Digest MakeSignature function to generate a Digest challenge response. The opaque value is included in the opaque directive of the challenge response sent to the server as an Authorization header (shown as HTTP Request).

The server calls the AcceptSecurityContext function to determine whether there is an existing security context for the client. When an existing context is found, the function returns SEC_E_COMPLETE_NEEDED to indicate the server must then call the CompleteAuthToken function. This function performs the client authentication using the Digest session key cached during the initial authentication instead of re-authenticating at the domain controller.


Maintaining the Security Context Between Connections

[This is preliminary documentation and subject to change.]

To reduce domain controller traffic and improve performance, the client-side of Microsoft Digest caches information received after successful authentication with a server. Client applications need only cache the handle to the security context that has been established. The following table describes information cached by the security package.

Information | Description
Server name | The server that has successfully created a security context for the user.
Realm/Domain | The domain name used in the successful authentication.
Nonce | A server nonce that is associated with the successful authentication.
Nonce count | The number of times the client has included the nonce in requests to the server. This is used for replay-detection.
Opaque value | The value returned for the opaque directive after a successful authentication. This value contains a reference to the security context of the user.

When a client sends a message to a server, the server must determine whether or not the client has an existing security context. To do this, the server passes each client request to the AcceptSecurityContext function. This function extracts the value of the opaque directive from the request, if present, and uses it to look up the client's security context. If the security context is found, the handle of the context is returned to the server. For related information, see Authenticating Subsequent Requests.

As a means of detecting spoofing and replay attacks, the client calls the MakeSignature function which uses a security context to sign a message. When messages are protected using the MakeSignature function, the server uses the VerifySignature function with the cached context to verify the message's origin and integrity. For more information, see Protecting Messages.


Delegation Extensions to Digest Authentication

[This is preliminary documentation and subject to change.]

Resources requested by a client may require multiple accesses to one or more machines containing secured data. Additionally, satisfying a request may involve accessing secured information that is not specified in the original request.

The Microsoft Digest SSP implementation of the Digest Access protocol permits a server to issue requests to other servers on behalf of the client. The digest created by the client is called the original digest, and the digest created by the server working on behalf of the client is called the delegated digest.

Delegation of authority requires that authentication of the client has been successful.


IETF Specifications - Microsoft Digest SSP

Platform SDK: Security

IETF Specifications—Microsoft Digest SSP

[This is preliminary documentation and subject to change.]

HTTP Authentication: Basic and Digest Access Authentication (RFC 2617) is available at http://www.ietf.org/rfc/rfc2617.txt.

Using Digest as a SASL Mechanism Internet draft is available at http://www.ietf.org/rfc/rfc2831.txt.

For additional information on SASL, also see the Simple Authentication and Security Layer specification (RFC 2222) available at http://www.ietf.org/rfc/rfc2222.txt.


Using SSPI with Microsoft Digest SSP

Client/server applications access Microsoft Digest by calling Microsoft Security Support Provider Interface (SSPI) functions. The Microsoft Digest security package is automatically loaded by the SSPI security library. Access the security library by linking your application to Secur32.lib or Security.lib (Windows 9x). These files are shipped and installed with the Platform SDK.

The following topics demonstrate using Microsoft Digest:

Obtaining Microsoft Digest SSP Credentials

Generating the Digest Challenge (Servers only)

Generating the Digest Challenge Response (Clients only)

Protecting Messages Using Microsoft Digest

Querying Digest Security Context Attributes


Obtaining Microsoft Digest SSP Credentials

[This is preliminary documentation and subject to change.]

User credentials are required by Microsoft Digest; both client and server must present valid credentials before they can establish a security context for message exchange. Credentials handles are used to obtain and present credentials.

Because the credential handle is used to store configuration information, the same handle cannot be used for both client-side and server-side operations. This means that applications that support both client and server connections must obtain a minimum of two credentials handles.

To get a handle to the credentials required by Microsoft Digest, call the AcquireCredentialsHandle function.

The following C language examples demonstrate obtaining credentials.

  • Obtaining Default Digest Credentials
  • Obtaining Alternate Digest Credentials


Obtaining Default Digest Credentials

[This is preliminary documentation and subject to change.]

Both clients and servers must obtain credentials before they can establish a security context for message exchange. The default behavior of the AcquireCredentialsHandle function is to provide credentials for the security principal associated with the current logon session.

The following example demonstrates a server-side call to obtain the default credentials.

SECURITY_STATUS SecStatus;
TimeStamp tsLifetime;
CredHandle hCred;
SecStatus = AcquireCredentialsHandle (
       NULL,                  // Default principal.
       MICROSOFT_DIGEST_NAME, // Microsoft Digest SSP.
       SECPKG_CRED_INBOUND,   // Server will use the credentials.
       NULL,                  // Use the current LOGON id.
       NULL,                  // Default credentials.
       NULL,                  // Not used with Digest SSP.
       NULL,                  // Not used with Digest SSP.
       &hCred,                // Receives the credential handle.
       &tsLifetime            // Receives the credential time limit.
);

The client-side call for default credentials is identical, except the third parameter must specify SECPKG_CRED_OUTBOUND to indicate that the client will use the credentials handle returned by the function.

For an example that demonstrates obtaining credentials for a security principal other than the logged on user, see Obtaining Alternate Credentials.


Obtaining Alternate Digest Credentials

[This is preliminary documentation and subject to change.]

To obtain credentials other than those associated with the current logon session, populate a SEC_WINNT_AUTH_IDENTITY structure with information for the alternate security principal. Pass the structure to the AcquireCredentialsHandle function using the pAuthData parameter.

The following table describes the members of the SEC_WINNT_AUTH_IDENTITY structure.

Member | Description
User | Null-terminated string containing the name of the security principal whose credentials will be used to establish a security context.
UserLength | The length of the User member, in characters. Omit the terminating null.
Domain | Null-terminated string that identifies the domain containing the account of the security principal.
DomainLength | The length of the Domain member, in characters. Omit the terminating null.
Password | Null-terminated string containing the password of the security principal.
PasswordLength | The length of the Password member, in characters. Omit the terminating null.
Flags | Indicates whether the string members are in ANSI or Unicode format.

The following table lists the valid values for the Flags member of the structure.

Constant | Description
SEC_WINNT_AUTH_IDENTITY_ANSI | Strings in this structure are in ANSI format.
SEC_WINNT_AUTH_IDENTITY_UNICODE | Strings in this structure are in Unicode format.

The structure and constants are declared in the rpcedce.h header file distributed with the Platform SDK.

The following example demonstrates a client-side call to obtain Digest credentials for a specific user account.

SECURITY_STATUS SecStatus;
TimeStamp tsLifetime;
CredHandle hCred;
SEC_WINNT_AUTH_IDENTITY ClientAuthID;
LPTSTR UserName = TEXT("ASecurityPrinciple");
LPTSTR DomainName = TEXT("AnAuthenticatingDomain");
LPTSTR Password = TEXT("Secret");

// Initialize the memory.
ZeroMemory( &ClientAuthID, sizeof(ClientAuthID) );

// Specify string format for the ClientAuthID structure.
#ifdef UNICODE
  ClientAuthID.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
#else
  ClientAuthID.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
#endif

// Specify an alternate user, domain and password.
  ClientAuthID.User = UserName;
  ClientAuthID.UserLength = _tcslen(UserName);

  ClientAuthID.Domain = DomainName;
  ClientAuthID.DomainLength = _tcslen(DomainName);

  ClientAuthID.Password = Password;
  ClientAuthID.PasswordLength = _tcslen(Password);

// Get the client side credential handle.
SecStatus = AcquireCredentialsHandle (
  NULL,                  // Default principal.
  MICROSOFT_DIGEST_NAME, // The Digest SSP.
  SECPKG_CRED_OUTBOUND,  // Client will use the credentials.
  NULL,                  // Don't specify LOGON id.
  &ClientAuthID,         // User information.
  NULL,                  // Not used with Digest SSP.
  NULL,                  // Not used with Digest SSP.
  &hCred,                // Receives the credential handle.
  &tsLifetime            // Receives the credential time limit.
);

The constant MICROSOFT_DIGEST_NAME is defined in the NTSecapi.h header file shipped with the Platform SDK.

The _tcslen function returns the string length in characters, not including the terminating null character.

If your application can use the credentials established at logon, see Obtaining Default Digest Credentials.


Generating the Digest Challenge

[This is preliminary documentation and subject to change.]

The Microsoft Digest challenge is generated by the server's initial call to the AcceptSecurityContext function. This function call generates a nonce, which is a unique value containing information that can be used to detect security violations. This call also generates a partial security context which is used to maintain state information. When calling AcceptSecurityContext you specify context requirements flags to control the behavior of Microsoft Digest and to set the quality of protection. See Digest Challenge Context Requirements for more information.

The output from the initial call to the AcceptSecurityContext function is a security buffer containing a token that sent to the client with an HTTP 401 response (Access Denied).

Note Calls to AcceptSecurityContext without information in the input buffers, return a Digest challenge.

Digest Challenge Context Requirements

Context requirements are flags that determine:

  • Whether Microsoft Digest functions as a SASL mechanism or HTTP authentication protocol.
  • The quality of protection supported by the security context shared by the client and server.

By default, Microsoft Digest functions as a SASL mechanism. To use it for HTTP authentication, the ASC_REQ_HTTP ( 0x10000000) flag must be set by the server.

Context requirements are specified as flags passed to the fContextReq parameter of the AcceptSecurityContext function. The flags affect the security context's quality of protection by controlling the qop directive in the challenge.

By default, the qop directive is set to "auth". To generate a challenge that sets qop to "auth-int", the server must specify one or more of the following flags:

  • ASC_REQ_INTEGRITY
  • ASC_REQ_REPLAY_DETECT
  • ASC_REQ_SEQUENCE_DETECT

SASL only: Generate a challenge with the qop directive set to "auth-conf" by specifying the ASC_REQ_CONFIDENTIALITY context requirement flag. Because this flag is not valid for HTTP authentication, it cannot be used with the ASC_REQ_HTTP flag.

For additional information on the qop directive, see Quality of Protection and Ciphers.

For more information on challenges, see Contents of a Digest Challenge.


Generating the Digest Challenge Response

[This is preliminary documentation and subject to change.]

After receiving a challenge from the server, the client creates the Digest challenge response by calling the InitializeSecurityContext function. This function generates an MD5 hash fingerprint using information about the requested resource and data from the challenge, and outputs a security token representing a partial security context. To complete the authentication the client must return the token to the server that issued the challenge.

The following table describes the parameters of the InitializeSecurityContext function, and the values to supply when constructing a Digest challenge response.

InitializeSecurityContext Parameter | Description
fContextReq | Specifies the security context attributes requested by the client. For more information, see Context Requirements, below.
pszTargetName | HTTP: Null-terminated string specifying the target URL. SASL:Null-terminated string specifying the DNS/SPN target.
pInput | Buffers containing information required by the Digest SSP. For more information, see Input Buffers for the Digest Challenge Response.
pfContextAttr | Receives the attributes supported by the returned security context. For more information, see Context Requirements, below.
pOutput | Address of a SECBUFFER_TOKEN type buffer that receives a security token to send back to the server.

Digest Challenge Response Context Requirements

Context requirements are flags that determine:

  • Whether Microsoft Digest functions as a SASL mechanism or HTTP authentication protocol.
  • The quality of protection supported by the security context shared by the client and server.

By default, Microsoft Digest functions as a SASL mechanism. To request it for HTTP authentication, the ISC_REQ_HTTP context requirement flag must be set by the client.

Context requirements are specified as flags passed to the fContextReq parameter of the InitializeSecurityContext function. The flags affect the security context's quality of protection by controlling the qop directive in the challenge response.

By default, the qop directive is set to "auth". To generate a challenge response that sets qop to "auth-int", the following must occur:

  1. The Digest challenge must have had a qop directive set to "auth-int".
  2. The client must specify one or more of the following flags:
    • ISC_REQ_INTEGRITY
    • ISC_REQ_REPLAY_DETECT
    • ISC_REQ_SEQUENCE_DETECT

SASL only: Generate a challenge response with the qop directive set to "auth-conf" by specifying the ISC_REQ_CONFIDENTIALITY flag. Because this flag is not valid for HTTP authentication, it cannot be used with the ISC_REQ_HTTP flag.

Verifying the Quality of Protection

The client must examine the security context attributes flags returned in the InitializeSecurityContext function's pfContextAttr parameter. The client should send the challenge response to the server only if the quality of protection indicated by the flags is sufficient for its purposes. The relevant flags can be any combination of the following:

  • ISC_RET_INTEGRITY
  • ISC_RET_REPLAY_DETECT
  • ISC_RET_SEQUENCE_DETECT
  • ISC_RET_CONFIDENTIALITY (SASL contexts only)

For additional information on the qop directive, see Quality of Protection and Ciphers.

For more information on challenge response directives, see Contents of a Digest Challenge Response.


Input Buffers for the Digest Challenge Response

[This is preliminary documentation and subject to change.]

HTTP authentication using Microsoft Digest requires three input buffers to generate a challenge response. The following table summarizes these buffers.

Buffer Number | Contains | Buffer Type
0 | Challenge received from Server | SECBUFFER_TOKEN
1 | HTTP Method | SECBUFFER_PARAMS
2 | H(Entity) | SECBUFFER_PARAMS

Buffer 0 contains the Digest challenge received from the server in response to the initial request for an access-protected resource.

Buffer 1 contains the string representation of the method, such as "GET" or "POST". The method is used in the calculation of A2, as described in RFC 2617.

Buffer 2 is the MD-5 hash of the message's entity-body as described in RFC 2617.

The following example demonstrates using CryptoAPI to compute the MD-5 hash of some data. This example performs the computation on the contents of a file specified at run-time.

// Compute the MD5 hash of a file using CryptoAPI.
#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>

#define  BUFSIZE 1024
#define  MD5LEN  16

DWORD main(int argc, char *argv[])
{
  DWORD           dwStatus    = 0;
  HCRYPTPROV      hProv       = 0;
  HCRYPTHASH      hHash       = 0;
  HANDLE          hFile       = 0;
  BYTE            rgbFile [BUFSIZE];
  DWORD           cbRead;
  BYTE            rgbHash [MD5LEN];
  DWORD           cbHash      = MD5LEN;
  DWORD           i;
  CHAR            rgbDigits[] = "0123456789abcdef";

  // Argument list = progname filename.
  if (argc != 2)
  {
      goto end;
  }
  // Open the file to be hashed.

  hFile = CreateFile  ( argv[1],                  // File name
         GENERIC_READ,             // Access mode
         FILE_SHARE_READ,          // Share mode
         NULL,                     // Not inheritable
         OPEN_EXISTING,            // Create flags
         FILE_FLAG_SEQUENTIAL_SCAN,// Attributes
         NULL);                    // Template handle
  if ( INVALID_HANDLE_VALUE == hFile )
  {
   dwStatus = GetLastError ();
   printf("Can\'t open file %s, error : 0x%x\n", argv[1], dwStatus);
   hFile = 0;
   goto end;
  }

    // Get a handle to the CSP that will be used for the hash function
    //

    if ( !CryptAcquireContext( &hProv,
                               NULL,
                               NULL,
                               PROV_RSA_FULL,
                               CRYPT_VERIFYCONTEXT ))
    {
        dwStatus = GetLastError ();
        printf("CryptAcquireContext() failed : 0x%x\n", dwStatus);
        hProv = 0;
        goto end;
    }
    // Create a MD5 hash.
    if ( !CryptCreateHash( hProv,
                           CALG_MD5,
                           0,
                           0,
                           &hHash ) )
    {
        dwStatus = GetLastError ();
        printf("CryptCreateHash() failed : 0x%x\n", dwStatus);
        hHash = 0;
        goto end;
    }
    // Read the file and hash the data.
    while ( ReadFile( hFile,
                      rgbFile,
                      BUFSIZE,
                      &cbRead,
                      NULL ))
    {
        if ( 0 == cbRead )
        {
            break;
        }
        if ( !CryptHashData( hHash,
                             rgbFile,
                             cbRead,
                             0 ))
        {
            dwStatus = GetLastError ();
            printf("CryptHashData() failed : 0x%x\n", dwStatus);
            goto end;
        }
    }
    // Get the hash.
    cbHash = MD5LEN;
    if ( !CryptGetHashParam( hHash,
                             HP_HASHVAL,
                             rgbHash,
                             &cbHash,
                             0 ) )
    {
        dwStatus = GetLastError ();
        printf("CryptGetHashParam() failed : 0x%x\n", dwStatus);
        goto end;
    }
    // Print out the hash.
    printf("MD5 hash of file %s is : ", argv[1]);
    for (i = 0;
         i < cbHash;
         ++i)
    {
        printf("%c%c", rgbDigits[rgbHash[i] >> 4],
            rgbDigits[rgbHash[i] & 0xf]);
    }
    printf("\n");
end:
    // Clean up.
    if ( hFile )
    {
        CloseHandle ( hFile );
    }

    if ( hHash )
    {
        if ( !CryptDestroyHash ( hHash ) )
        {
            dwStatus = GetLastError ();
            printf("CryptDestroyHash() failed : 0x%lx\n", dwStatus);
        }
    }
    if ( hProv )
    {
        if ( !CryptReleaseContext ( hProv, 0 ) )
        {
            dwStatus = GetLastError();
            printf("CryptRelease() failed : 0x%lx\n", dwStatus);
        }
    }
    return dwStatus;
}

Input Buffers for SASL

Supply Buffer 0 only. For compatibility with other SSPs, you may call InitializeSecurityContext without a valid server challenge. In this case the pInput parameter should be set to NULL.


Protecting Messages Using Microsoft Digest

[This is preliminary documentation and subject to change.]

HTTP and SASL

As a means of detecting certain types of security violations, the client and server use the security support provider interface (SSPI) message integrity functions MakeSignature and VerifySignature to protect messages.

A client calls the MakeSignature function to sign a message using its security context. The server uses the VerifySignature function to verify the message's origin. In addition to verifying the signature that accompanies the message, the VerifySignature function also checks that the nonce count (specified by the nc directive) is one greater than the last count sent for the nonce. If this is not the case, the VerifySignature function returns an SEC_OUT_OF_SEQUENCE error code.

SASL Only

The EncryptMessage and DecryptMessage functions supply confidentiality for post-authentication messages exchanged between client and server.

In order to use the message confidentiality functions, the server and client must have established a security context with the following attributes:

  • Quality of protection, specified by the qop directive, must be "auth-conf".
  • An encryption mechanism must have been specified by means of the cipher directive.


Querying Digest Security Context Attributes

[This is preliminary documentation and subject to change.]

The QueryContextAttributes function provides information about the current settings of a security context.

Microsoft Digest supports querying the following security context attributes.

Attribute | Description
SECPKG_ATTR_KEY_INFO | Information relating to the signing and encryption algorithms in use.
SECPKG_ATTR_PACKAGE_INFO | General information pertaining to Microsoft Digest, such as the maximum token size permitted by the security package.
SECPKG_ATTR_SIZES | The maximum sizes permitted for message-related data such as signatures.


Microsoft Digest Reference

[This is preliminary documentation and subject to change.]

The following documentation describes using Microsoft Security Support Provider Interface (SSPI) functions to access the Microsoft Digest Security Support Provider.

SSPI function as implemented by Microsoft Digest | Description
AcceptSecurityContext | Creates the server side of a security context shared by client and server.
AcquireCredentialsHandle | Provides credentials handles to clients and servers.
DecryptMessage | Removes encryption from messages sent by SASL clients.
EncryptMessage | Encrypts messages being sent to SASL servers.
InitializeSecurityContext | Creates the client side of a security context shared by client and server.
MakeSignature | Provides message integrity.
QueryContextAttributes | Gives information about an established security context.
VerifySignature | Checks message integrity.

For general information on using SSPI functions and structures, please refer to the SSPI documentation.


AcceptSecurityContext (Digest)

[This is preliminary documentation and subject to change.]

The AcceptSecurityContext function creates the server-side security context used to authenticate communications between a client and server.

SECURITY_STATUS AcceptSecurityContext(
  PCredHandle phCredential,
  PCtxtHandle phContext,
  PSecBufferDesc pInput,
  ULONG fContextReq,
  ULONG TargetDataRep,
  PCtxtHandle phNewContext,
  PSecBufferDesc pOutput,
  PULONG pfContextAttr,
  PTimeStamp ptsExpiry
);

Parameters

phCredential
[in] Handle to the server's credentials. This handle is returned by the AcquireCredentialsHandle function.
phContext
[in] Pointer to a CtxtHandle type handle to a security context. On the first call to AcceptSecurityContext, specify NULL.
pInput
[in] Pointer to a SecBufferDesc structure that describes the input buffers required by the security protocol. For Digest buffer requirements, see remarks.
fContextReq
[in] A ULONG containing zero or more flags representing attributes of the security context. The following context attributes flags are valid with Digest.
Flag | Description
ASC_REQ_INTEGRITY | Sign messages and verify signatures.
ASC_REQ_HTTP (0x10000000) | Use Digest for HTTP. Omit this flag to use Digest as a SASL mechanism.
ASC_REQ_CONFIDENTIALITY | Encrypt and decrypt messages. SASL only.
ASC_REQ_DELEGATE | Context is for delegated Microsoft Digest authentication.
ASC_REQ_ALLOCATE_MEMORY | Digest will allocate output buffers for you. You must free them using FreeContextBuffer.
ASC_REQ_REPLAY_DETECT | Detect replayed packets.

The requested attributes may not be supported by the client. For additional information, see the pfContextAttr parameter.

TargetDataRep
[in] Not used with Digest. Specify 0.
phNewContext
[in, out] Pointer to a CtxtHandle structure. On the first call to AcceptSecurityContext, receives a new context handle. On subsequent calls, specify this pointer in the phContext parameter.
pOutput
[out] Pointer to a SecBufferDesc structure containing one SecBuffer structure of type SECBUFFER_TOKEN. Receives the challenge which must be sent to the client.
pfContextAttr
[out] Pointer to a ULONG that receives flags indicating the attributes of the established context. For a list of valid values, see the fContextReq parameter. Do not check for security-related attributes until the final function call returns successfully. Other (non-security) attribute flags such as the ASC_RET_ALLOCATED_MEMORY flag, can be checked before the final return.
ptsExpiry
[out] Receives a constant maximum time. There is no expiration time for Digest security contexts or credentials.

Return Values

If the function succeeds, it returns one of the following values.

Value | Meaning
SEC_E_OK | No more calls to this function are required. If an output token was generated by the function, it must be sent to the client.
SEC_I_COMPLETE_NEEDED | Call the CompleteAuthToken function to finish re-establishing a previously authenticated connection.
SEC_I_CONTINUE_NEEDED | The server must send the output token to the client and wait for the client to return a token. Pass it into another call to AcceptSecurityContext, using the pInput parameter.

If the function fails, the return value is one of the following.

Value | Meaning
SEC_E_INVALID_TOKEN | An invalid token was passed in the input buffers or an invalid context handle was specified in the phContext parameter, or an incorrect number of input or output buffers was specified.
SEC_E_NO_CREDENTIALS | The credentials handle specified in the phCredential parameter is invalid.
SEC_E_SECURITY_QOS_FAILED | An invalid context attribute flag was specified in the fContextReq parameter.
STATUS_LOGON_FAILURE | You called AcceptSecurityContext and specified a context after the context was established. See Remarks.
SEC_E_INSUFFICIENT_MEMORY | One of the buffers is too small to hold output information. See Remarks.

Remarks

The following table shows the buffer configuration for Digest HTTP. All buffers are of type SECBUFFER_TOKEN.

Buffer # | Contents
0 | Empty for first call. The Challenge Response received from client for the second call.
1 | Method
2 | Reserved.
3 | HEntity
4 | Realm

SASL requires only buffer 0.

Clients use InitializeSecurityContext, the client-side counterpart to the AcceptSecurityContext function.

If the SEC_E_INSUFFICIENT_MEMORY error is received, consider specifying the ASC_REQ_ALLOCATE_MEMORY attribute flag.

The caller is responsible for determining whether the final context attributes are sufficient. If, for example, confidentiality was requested, but could not be established, some applications may choose to shut down the connection immediately.

If AcceptSecurityContext fails, the server must free the partially created context by calling the DeleteSecurityContext function.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.

See Also

AcquireCredentialsHandle, CtxtHandle, DeleteSecurityContext, InitializeSecurityContext, SecBuffer, SecBufferDesc


AcquireCredentialsHandle (Digest)

[This is preliminary documentation and subject to change.]

The AcquireCredentialsHandle function retrieves a handle to the credentials of a security principal. This handle is required by the InitializeSecurityContext and AcceptSecurityContext functions.

SECURITY_STATUS AcquireCredentialsHandle(
  SEC_CHAR *pszPrincipal,
  SEC_CHAR *pszPackage,
  ULONG fCredentialUse,
  PLUID pvLogonID,
  PVOID pAuthData,
  PVOID pGetKeyFn,
  PVOID pvGetKeyArgument,
  PCredHandle phCredential,
  PTimeStamp ptsExpiry
);

Parameters

pszPrincipal
[in] Optional. The user name of the security principal. If the caller has sufficient privileges, the principal's credentials are returned. See remarks.
pszPackage
[in] Specify MICROSOFT_DIGEST_NAME. This constant is defined as "Microsoft Digest Security Protocol Provider".
fCredentialUse
[in] Flag indicating how the credential will be used. Specify one of the following values.
Value | Meaning
SECPKG_CRED_INBOUND | The server will use the credential.
SECPKG_CRED_OUTBOUND | The client will use the credential.

pvLogonID
[in] Optional. A logon session identifier. If the caller has sufficient privileges the credential used to establish the logon session is returned. See remarks.
pAuthData
[in] Specify a SEC_WINNT_AUTH_IDENTITY structure containing authentication information to use to locate the credentials.
pGetKeyFn
[in] Not used with Digest. Specify NULL.
pvGetKeyArgument
[in] Not used with Digest. Specify NULL.
phCredential
[out] Pointer to a CredHandle. Receives the requested credential handle.
ptsExpiry
[out] Pointer to a TimeStamp. Receives a constant maximum time. There is no expiration time for Digest credentials.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value is an SECURITY_STATUS indicating the error. The following table describes common errors and their causes.

Value | Meaning
SEC_E_UNKNOWN_CREDENTIALS | The pAuthData parameter did not contain a credentials structure accepted by Digest.
SEC_E_NO_CREDENTIALS | The fCredentialUse parameter specified an invalid value.
SEC_E_INSUFFICIENT_MEMORY | There is not enough memory is available to complete the request.

Remarks

When you no longer need the returned credentials, free them by calling the FreeCredentialsHandle function.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.
Unicode: Implemented as Unicode and ANSI versions on Whistler.

See Also

AcceptSecurityContext, InitializeSecurityContext, FreeCredentialsHandle


CompleteAuthToken (Digest)

[This is preliminary documentation and subject to change.]

The CompleteAuthToken function completes the authentication of a client for which there is an existing security context. With Microsoft Digest, CompleteAuthToken is used on the server side only.

SECURITY_STATUS CompleteAuthToken(
  PCtxtHandle phContext,
  PSecBufferDesc pToken
);

Parameters

phContext
[in] Handle of the security context received from the AcceptSecurityContext function.
pToken
[in] Pointer to a SecBufferDesc structure received from the client.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value can be one of the following error codes.

Value | Meaning
SEC_E_INVALID_HANDLE | The context handle specified by phContext is invalid.
SEC_E_INVALID_TOKEN | pToken did not contain a valid SECBUFFER_TOKEN buffer, or contained too few buffers.
SEC_E_OUT_OF_SEQUENCE | The client's security context was located, but the message number is incorrect.
SEC_E_MESSAGE_ALTERED | The client's security context was located, but the client's message has been tampered with.

Remarks

After calling CompleteAuthToken you do not have to call VerifySignature; it is called automatically.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.

See Also

AcceptSecurityContext, SecBufferDesc, VerifySignature


DecryptMessage (Digest)

[This is preliminary documentation and subject to change.]

The DecryptMessage function provides integrity and/or confidentiality for messages exchanged between client and server when using Microsoft Digest as a SASL mechanism only.

SECURITY_STATUS DecryptMessage(
  PCtxtHandle phContext,
  PSecBufferDesc pMessage,
  ULONG MessageSeqNo,
  PULONG pfQOP
);

Parameters

phContext
[in] Handle of the security context shared with the sender of the message.
pMessage
[in, out] Pointer to a SecBufferDesc structure. On input, the structure references one or more SecBuffer structures. One of these must be of type SECBUFFER_DATA or SECBUFFER_STREAM, and it must contain the encrypted message.
MessageSeqNo
[in] Not used with Microsoft Digest. Specify zero.
pfQOP
[out] Will receive SIGN_ONLY (0x800001) when the security context is set to verify the signature only. For more information, see Quality of Protection.

Return Values

If the function verifies that the message was received in the correct sequence, the return value is SEC_E_OK.

If the function fails to decrypt the message, the return value can be one of the following error codes.

Value | Meaning
SEC_E_OUT_OF_SEQUENCE | The message was not received in the correct sequence.
SEC_E_MESSAGE_ALTERED | The message has been altered.
SEC_E_INVALID_HANDLE | An invalid context handle was specified in the phContext parameter.
SEC_E_QOP_NOT_SUPPORTED | Neither confidentiality nor integrity are supported by the security context.
SEC_E_CRYPTO_SYSTEM_INVALID | The cipher chosen for the security context is not supported.
SEC_E_BUFFER_TOO_SMALL | The message buffer is too small.

Remarks

DecryptMessage is called by the message recipient. The sender should use the EncryptMessage function.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.

See Also

EncryptMessage, SecBuffer, SecBufferDesc


EncryptMessage (Digest)

[This is preliminary documentation and subject to change.]

The EncryptMessage function provides integrity and/or confidentiality for messages exchanged between client and server when using Microsoft Digest as a SASL mechanism only.

SECURITY_STATUS EncryptMessage(
  PCtxtHandle phContext,
  ULONG fQOP,
  PSecBufferDesc pMessage,
  ULONG MessageSeqNo
);

Parameters

phContext
[in] Handle of the security context shared with the receiver of the message.
fQOP
[in] Not used with Microsoft Digest. Specify zero.
pMessage
[in, out] Pointer to a SecBufferDesc structure that contains a set of SecBuffer structures. There must be one buffer of type SECBUFFER_DATA, which contains the message to be encrypted in place or signed. There must be a second buffer of type SECBUFFER_PADDING or SEC_BUFFER_DATA to hold signature information. For instructions on calculating the size of this output buffer, see remarks.
MessageSeqNo
[in] Optional. Used when messages will be signed only; ignored when messages are to be encrypted. Specify the nonce count. If the count is not specified, Microsoft Digest manages sequence numbering internally.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value is one of the following error codes.

Value | Meaning
SEC_E_INVALID_HANDLE | An invalid context handle was specified in the phContext parameter.
SEC_E_QOP_NOT_SUPPORTED | Neither confidentiality nor integrity are supported by the security context.
SEC_E_CRYPTO_SYSTEM_INVALID | The cipher chosen for the security context is not supported.
SEC_E_BUFFER_TOO_SMALL | The output buffer is too small. See Remarks.

Remarks

EncryptMessage is called by the message sender. The message recipient must call the DecryptMessage function.

Obtain the size of the output buffer by calling the QueryContextAttributes function and specifying SECPKG_ATTR_SIZES. The function will return a SecPkgContext_Sizes structure. The size of the output buffer is the sum of the values in the cbMaxSignature and cbBlockSize members.

For optimal performance, the SecBuffer structures should be allocated from contiguous memory.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.

See Also

DecryptMessage, QueryContextAttributes, SecBuffer, SecBufferDesc


InitializeSecurityContext (Digest)

[This is preliminary documentation and subject to change.]

The InitializeSecurityContext function creates the client-side security context used to authenticate communications between a client and server.

The Digest implementation of InitializeSecurityContext generates a challenge response which the client must pass to the target server.

SECURITY_STATUS InitializeSecurityContext(
  PCredHandle phCredential,
  PCtxtHandle phContext,
  SEC_CHAR *pszTargetName,
  ULONG fContextReq,
  ULONG Reserved1,
  ULONG TargetDataRep,
  PSecBufferDesc pInput,
  ULONG Reserved2,
  PCtxtHandle phNewContext,
  PSecBufferDesc pOutput,
  PULONG pfContextAttr,
  PTimeStamp ptsExpiry
);

Parameters

phCredential
[in] Handle to client's credentials. This handle is returned by the AcquireCredentialsHandle function.
phContext
[in] Optional. Pointer to a CtxtHandle. You can specify NULL.
pszTargetName
[in] Specify a null terminated string that uniquely identifies the URI of the requested resource.
fContextReq
[in] Specify a combination of flags to request that the security context support certain features, or attributes. The following attributes flags are valid with Digest.
Flag | Description
ISC_REQ_ALLOCATE_MEMORY | Digest will allocate output buffers for you. You must still free them using FreeContextBuffer.
ISC_REQ_CONFIDENTIALITY | Encrypt and decrypt messages. SASL only.
ISC_REQ_DELEGATE | Context is for delegated Digest authentication.
ISC_REQ_HTTP (0x10000000) | Use Digest for HTTP. Omit this flag to use Digest as a SASL mechanism.
ISC_REQ_INTEGRITY | Sign messages and verify signatures.
ISC_REQ_REPLAY_DETECT | Detect replayed packets.

The requested attributes may not be supported by the server. For additional information, see the pfContextAttr parameter.

Reserved1
[reserved] Reserved value; specify zero.
TargetDataRep
[in] Not used with Digest; specify zero.
pInput
[in] Pointer to a SecBufferDesc structure that describes the input buffers required by the security protocol. For Digest buffer details, see remarks.
Reserved2
[reserved] Reserved value; specify zero.
phNewContext
[in, out] Pointer to a CtxtHandle. Receives a security context handle.
pOutput
[out] Pointer to a SecBufferDesc structure containing one SecBuffer structure of type SECBUFFER_TOKEN. Receives the challenge response which must be sent to the server.
pfContextAttr
[out] Pointer to a ULONG that receives bit flags indicating the attributes of the established context. For a list of valid values, see the fContextReq parameter. Do not check for security related attributes until the final function call returns successfully. Other (non-security) attribute flags such as the ASC_RET_ALLOCATED_MEMORY flag, can be checked before the final return.
ptsExpiry
[out] Returns a constant maximum time. There is no expiration time for Digest security contexts or credentials.

Return Values

If the function succeeds, the function returns one of the following values.

Value | Meaning
SEC_E_OK | The security context was successfully initialized. No more calls to this function are required. If an output token was generated by the function, it must be sent to the server.
SEC_I_CONTINUE_NEEDED | The client must send the output token to the server and wait for a return token to use in another call to InitializeSecurityContext.

If the function fails, the return value is one of the following error codes.

Value | Meaning
SEC_E_INVALID_HANDLE | An invalid context handle was specified in the phContext parameter.
SEC_E_TARGET_UNKNOWN | The target was not recognized.
SEC_E_NO_CREDENTIALS | The supplied credentials could not be authenticated.
SEC_E_INSUFFICIENT_MEMORY | One of the buffers is too small to hold output information; see Remarks.

Remarks

The following table shows the buffer configuration for Digest HTTP.

Buffer # | Contents
0 - SECBUFFER_TOKEN | The challenge received from the server. May be empty only for SASL applications.
1 - SECBUFFER_PKG_PARAMS | Method.
2 - SECBUFFER_PKG_PARAMS | HEntity. See Input Buffers for the Digest Challenge Response.

SASL requires only buffer 0.

Servers use AcceptSecurityContext, the server-side counterpart to the InitializeSecurityContext function.

The caller is responsible for determining whether the final context attributes are sufficient. If, for example, confidentiality was requested, but could not be established, some applications may choose to shut down the connection immediately.

If attributes of the security context are not sufficient, the client must free the partially created context by calling the DeleteSecurityContext function.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.
Unicode: Implemented as Unicode and ANSI versions on Whistler.

See Also

AcceptSecurityContext, AcquireCredentialsHandle, CtxtHandle, DeleteSecurityContext, FreeContextBuffer, SecBuffer, SecBufferDesc


MakeSignature (Digest)

[This is preliminary documentation and subject to change.]

The MakeSignature function generates message identifiers and sequence numbers used to detect message tampering.

SECURITY_STATUS MakeSignature(
  PCtxtHandle phContext,
  ULONG fQOP,
  PSecBufferDesc pMessage,
  ULONG MessageSeqNo
);

Parameters

phContext
[in] Handle of the security context shared with the receiver of the message.
fQOP
[in] Not used with Microsoft Digest. Specify zero.
pMessage
[in, out] Pointer to a SecBufferDesc structure that contains a set of SecBuffer structures. When Digest is used as an HTTP authentication protocol, the buffers should be configured as follows.
Buffer # | Contents
0 - SECBUFFER_TOKEN | Empty.
1 - SECBUFFER_DATA | Method.
2 - SECBUFFER_DATA | URI.
3 - SECBUFFER_DATA | Hentity. See Input Buffers for the Digest Challenge Response.
4 - SECBUFFER_PADDING | Empty. Receives the signature.

When Digest is used as an SASL mechanism, the buffers should be configured as follows.
Buffer # | Contents
0 - SECBUFFER_TOKEN | Empty - Receives the signature. See Remarks.
1 - SECBUFFER_DATA | Message
2 - SECBUFFER_PADDING | Empty.

MessageSeqNo
[in] Optional. Specify the nonce count. If the count is not specified, Microsoft Digest manages sequence numbering internally.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value may be one of the following error codes.

Value | Meaning
SEC_E_INVALID_HANDLE | The context handle specified by phContext is invalid.
SEC_E_INVALID_TOKEN | pMessage did not contain a valid SECBUFFER_TOKEN buffer, or contained too few buffers.
SEC_E_OUT_OF_SEQUENCE | The nonce count is out of sequence.
SEC_E_NO_AUTHENTICATING_AUTHORITY | The security context (phContext) must be revalidated.
STATUS_INVALID_PARAMETER | The nonce count is not numeric.
SEC_E_QOP_NOT_SUPPORTED | The quality of protection negotiated between the client and server did not include integrity checking.

Remarks

The VerifySignature function verifies the messages signed by the MakeSignature function.

The buffer that receives the signature must be large enough to hold the largest possible signature. Determine the size required by calling the QueryContextAttributes function and specifying SECPKG_ATTR_SIZES. Check the returned SecPkgContext_Sizes structure member cbMaxSignature.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.

See Also

SecBuffer, SecBufferDesc, VerifySignature


QueryContextAttributes (Digest)

[This is preliminary documentation and subject to change.]

The QueryContextAttributes function retrieves information about attributes or features supported by a specified security context.

SECURITY_STATUS QueryContextAttributes(
  PCtxtHandle phContext,
  ULONG ulAttribute,
  PVOID pBuffer
);

Parameters

phContext
[in] Handle to the security context to be queried.
ulAttribute
[in] Specifies the attribute of the context to be returned. Specify one of the following values.
Value | Information returned | Structure returned
SECPKG_ATTR_KEY_INFO | The signature and encryption algorithms in use. | SecPkgContext_KeyInfo
SECPKG_ATTR_PACKAGE_INFO | General information pertaining to Microsoft Digest, such as the maximum token size permitted by the security package. | SecPkgContext_PackageInfo
SECPKG_ATTR_SIZES | The maximum size permitted for message-related data such as tokens and signatures. | SecPkgContext_Sizes

pBuffer
[in, out] Pointer to a structure containing the attribute. The ulAttribute parameter description indicates the structure returned for each attribute. For additional information, see Remarks.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value is a nonzero error code.

Remarks

The caller allocates the structure specified by the pBuffer parameter. Microsoft Digest allocates any memory required to hold variable sized members of the pBuffer structure. Memory allocated by Digest must be freed by calling the FreeContextBuffer function.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.
Unicode: Implemented as Unicode and ANSI versions on Whistler.

See Also

FreeContextBuffer, SecPkgContext_KeyInfo, SecPkgContext_PackageInfo, SecPkgContext_Sizes


VerifySignature (Digest)

[This is preliminary documentation and subject to change.]

The VerifySignature function verifies the signature of a message signed by the sender using the MakeSignature function.

SECURITY_STATUS VerifySignature(
  PCtxtHandle phContext,
  PSecBufferDesc pMessage,
  ULONG MessageSeqNo,
  PULONG pfQOP
);

Parameters

phContext
[in] Handle to the security context established with the sender of the message.
pMessage
[in] Pointer to a SecBufferDesc structure that contains the message and signature in SecBuffer structures.
MessageSeqNo
[in] Optional. Specify the expected nonce count or zero.
pfQOP
[out] Not used with Microsoft Digest. Specify zero.

Return Values

If the message was received in the correct sequence and has not been modified, the return value is SEC_E_OK.

If the function detects that the message is not correct according to the information in the signature, the return value can be one of the following error codes.

Value | Meaning
SEC_E_OUT_OF_SEQUENCE | The message was not received in the correct sequence.
SEC_E_MESSAGE_ALTERED | The message has been altered.
SEC_E_INVALID_HANDLE | The context handle specified by phContext is invalid.
SEC_E_INVALID_TOKEN | pMessage did not contain a valid SECBUFFER_TOKEN buffer, or contained too few buffers.
SEC_E_QOP_NOT_SUPPORTED | The quality of protection negotiated between the client and server did not include integrity checking.

Remarks

The MakeSignature function signs the messages verified by the VerifySignature function.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.

See Also

MakeSignature, SecBuffer, SecBufferDesc


Microsoft NTLM

Windows NT Challenge/Response (NTLM) is the authentication protocol used on networks that include systems running versions of the Microsoft® Windows NT® operating system earlier than Windows 2000 and on stand-alone systems. NTLM stands for Windows NT LAN Manager, a name chosen to distinguish this more advanced challenge/response-based protocol from its weaker predecessor LAN Manager (LM).

Beginning with Windows 2000, the Microsoft Kerberos security package adds greater security to networked systems than NTLM. Although Microsoft Kerberos is the protocol of choice for Windows 2000 networks, NTLM is still supported and must be used for network authentication if the network includes systems running versions of Windows NT earlier than Windows 2000. NTLM must also be used for logon authentication on stand-alone systems.

NTLM credentials are based on data obtained during the interactive logon process and consist of a domain name, a user name, and a one-way hash of the user's password. NTLM uses an encrypted challenge/response protocol to authenticate a user without sending the user's password over the wire. Instead, the system requesting authentication must perform a calculation that proves it has access to the secured NTLM credentials.

Interactive NTLM authentication over a network typically involves two systems: a client system, where the user is requesting authentication, and a domain controller, where information related to the user's password is kept. Noninteractive authentication — which may be required to permit an already logged-on user to access a resource such as a server application — typically involves three systems: a client, a server, and a domain controller that does the authentication calculations on behalf of the server.

The following steps present an outline of NTLM noninteractive authentication.

Note The first item provides the user's NTLM credentials and occurs as part of the interactive authentication (logon) process.

  1. (Interactive authentication only) A user accesses a client machine and provides a domain name, user name, and password. The client computes a cryptographic hash of the password and discards the actual password.
  2. The client sends the user name to the server (in plaintext).
  3. The server generates a 16 byte random number, called a challenge or nonce, and sends it to the client.
  4. The client encrypts this challenge with the hash of the user's password and returns the result to the server. This is called the response.
  5. The server sends the following three items to the domain controller: the user name, the challenge sent to the client, and the response received from the client.
  6. The domain controller uses the user name to retrieve the hash of the user's password from the Security Account Manager database. It uses this password hash to encrypt the challenge.
  7. The domain controller compares the encrypted challenge it computed (in step 6) to the response computed by the client (in step 4). If they are identical, authentication is successful.

Your application should not access the NTLM security package directly; instead, it should use the Negotiate security package. Negotiate allows your application to take advantage of more advanced security protocols if they are supported by the systems involved in the authentication. Currently, the Negotiate security package selects between Kerberos and NTLM. Negotiate selects Kerberos unless it cannot be used by one of the systems involved in the authentication.


Microsoft Schannel

Microsoft Schannel Start Page

Microsoft Secure Channel (Schannel)

Purpose

Secure Channel, also known as Schannel, is a security support provider (SSP) containing a set of security protocols that provide identity authentication and secure, private communication through encryption.

Where Applicable

Schannel is primarily used for Internet applications that require secure Hypertext Transfer Protocol (HTTP) communications.

Developer Audience

Microsoft® Schannel is designed for use by C/C++ programmers and requires a familiarity with the Security Support Provider Interface.

Run-Time Requirements

Microsoft Schannel requires the Microsoft® Windows NT® 4.0 or Windows® 2000 operating system.

See Also

Security Support Provider Interface

About Secure Channel (Schannel)

General information about Microsoft Secure Channel

Creating a Secure Connection Using Schannel

Information about setting up a secure connection between a client and server

Schannel SSP Reference

Microsoft Secure Channel functions and structures

PSDK Samples Using Schannel

Description and location of Schannel samples shipped with the Platform SDK

Feedback

Make error reports and feature requests directly to Microsoft.


About Secure Channel (Schannel)

[This is preliminary documentation and subject to change.]

Secure Channel, also known as Schannel, is a set of security protocols that provide identity authentication and secure, private communication through encryption.

Schannel includes the following security protocols:

  • Transport Layer Security (TLS)
  • Secure Sockets Layer (SSL)
  • Private Communications Technology (PCT)

TLS is the first choice among these protocols. SSL 3.0 is in wide use and is closely related to TLS; TLS is sometimes referred to as "SSL 3.1". SSL 2.0 and PCT are included for backward compatibility and should not be used for new development. The Schannel protocols provide authentication through the use of X.509 certificates, and secure communications using sets of cryptographic algorithms called cipher suites.

Schannel is commonly used for Internet applications that require secure Hypertext Transfer Protocol (HTTP) communications. Schannel protocols used with HTTP usually use port 443; however, this is not required. Clients request secure HTTP using the HTTPS specifier. For example the URL for a secure connection to the fictitious example.microsoft.com Web site would be https://www.example.microsoft.com. Schannel may also be used in concert with communications protocols other than HTTP. The name of the secure channel security support provider is "Microsoft Unified Security Protocol Provider".

The following topics provide detailed information about Schannel.

Topic | Description
Message Authentication Codes in Schannel | The message authentication code (MAC) and how it is used to ensure message integrity
Cipher Suites in Schannel | Cipher suites and algorithms
Schannel Credentials | Credentials used in server and client authentication
Transport Layer Security (TLS) Protocol | Preferred protocol for protecting information communicated over the Internet. This protocol is sometimes referred to as SSL 3.1, and is typically the protocol intended when the term "SSL" is used.
Secure Sockets Layer (SSL) Protocol | SSL 3.0 and SSL 2.0 protocols. SSL 3.0 is widely supported. SSL 2.0 is superseded by SSL 3.0 and TLS.
Private Communications Technology (PCT) | Protocol supported for backwards compatibility
Schannel and CryptoAPI | Elements of CryptoAPI used by Schannel.


Message Authentication Codes in Schannel

[This is preliminary documentation and subject to change.]

A message authentication code (MAC) is used to detect message tampering and forgery. The sender of a message creates a MAC by encrypting a one-way hash of the message body using a session key shared by sender and recipient. The MAC is appended to the message that is sent to the recipient. The message recipient generates the MAC again, using the shared session key and message body, and compares the generated MAC to the MAC received from the sender. If the two are identical, then the sender must have the shared session key, and the message has not been altered in transit.

In Schannel protocols, the algorithm used to generate the MAC is determined by the cipher suite in use by the sender and recipient.


Cipher Suites in Schannel

[This is preliminary documentation and subject to change.]

A cipher suite is a set of cryptographic algorithms. Schannel protocols use algorithms from a cipher suite to create keys and encrypt information. A cipher suite specifies one algorithm for each of the following tasks:

  • Key exchange
  • Bulk encryption
  • Message authentication

Key exchange algorithms protect information required to create shared keys. These algorithms are asymmetric (public-key algorithms) and perform well for relatively small amounts of data.

Bulk encryption algorithms encrypt messages exchanged between clients and servers. These algorithms are symmetric and perform well for large amounts of data.

Message authentication algorithms generate message hashes and signatures that ensure the integrity of a message.

Developers specify these elements using ALG_IDs. For more information, see Specifying Schannel Ciphers and Cipher Strengths.

For protocol-specific information, see the following topics.

Topic | Description
TLS Cipher Suites | Information on the cipher suites available with the TLS protocol.
Secure Sockets Layer (SSL) Protocol | General information on SSL 2.0 and 3.0, including the available cipher suites.


Schannel Credentials

[This is preliminary documentation and subject to change.]

Schannel protocols require credentials to authenticate servers and optionally, clients. Server authentication, where the server provides proof of its identity to the client, is required by the Schannel security protocols. Client authentication may be requested by the server at any time.

Schannel credentials are X.509 certificates. Public and private key information from certificates is used to authenticate the server and optionally, the client. These keys are also used to provide message integrity while client and server exchange the information required to generate and exchange session keys.

For programming information, see Obtaining Schannel Credentials.


Transport Layer Security (TLS) Protocol

[This is preliminary documentation and subject to change.]

Schannel supports version 1.0 of the Transport Layer Security protocol. This protocol is an industry standard designed to protect the privacy of information communicated over the Internet. TLS assumes that a connection-oriented transport, typically TCP, is in use. The TLS protocol allows client/server applications to detect:

  • message tampering
  • message interception
  • message forgery

The full specification of the TLS Protocol is available from the IETF website http://www.ietf.org/rfc/rfc2246.txt.

Organization of TLS

Client/server communication using TLS involves following steps:

  1. Handshake and cipher suite negotiation
  2. Authentication of parties
  3. Key-related information exchange
  4. Application data exchange

The steps that make up TLS are divided into two protocols that, together, provide connection security:

  • TLS Handshake Protocol — (steps 1 – 3)
  • TLS Record Protocol — (step 4)


TLS Handshake Protocol

[This is preliminary documentation and subject to change.]

The Transport Layer Security (TLS) Handshake Protocol is responsible for the authentication and key exchange necessary to establish or resume secure sessions. When establishing a secure session, the Handshake Protocol manages the following:

  • Cipher suite negotiation
  • Authentication of the server and optionally, the client
  • Session key information exchange.

Cipher Suite Negotiation

The client and server make contact and choose the cipher suite that will be used throughout their message exchange.

Authentication

In TLS, a server proves its identity to the client. The client might also need to prove its identity to the server. PKI, the use of public/private key pairs, is the basis of this authentication. The exact method used for authentication is determined by the cipher suite negotiated.

Key Exchange

The client and server exchange random numbers and a special number called the Pre-Master Secret. These numbers are combined with additional data permitting client and server to create their shared secret, called the Master Secret. The Master Secret is used by client and server to generate the Write MAC Secret, which is the session key used for hashing, and the Write Key which is the session key used for encryption.

Establishing a Secure Session using TLS

The TLS Handshake Protocol involves the following steps:

  1. The client sends a "Client hello" message to the server, along with the client's random value and supported cipher suites.
  2. The server responds by sending a "Server hello" message to the client, along with the server's random value.
  3. The server sends its certificate to the client for authentication and may request a certificate from the client. The server sends the "Server hello done" message.
  4. If the server has requested a certificate from the client, the client sends it.
  5. The client creates a random Pre-Master Secret and encrypts it with the public key from the server's certificate, sending the encrypted Pre-Master Secret to the server.
  6. The server receives the Pre-Master Secret. The server and client each generate the Master Secret and session keys based on the Pre-Master Secret.
  7. The client sends "Change cipher spec" notification to server to indicate that the client will start using the new session keys for hashing and encrypting messages. Client also sends "Client finished" message.
  8. Server receives "Change cipher spec" and switches its record layer security state to symmetric encryption using the session keys. Server sends "Server finished" message to the client.
  9. Client and server can now exchange application data over the secured channel they have established. All message sent from client to server and from server to client are encrypted using session key.

Resuming a Secure Session using TLS

  1. The client sends a "Client hello" message using the Session ID of the session to be resumed.
  2. The server checks its session cache for a matching Session ID. If a match is found, and the server is able to resume the session, it sends a "Server hello" message with the Session ID.

    Note If a session ID match is not found, the server generates a new session ID and the TLS client and server perform a full handshake.

  3. Client and server must exchange "Change cipher spec" messages and send "Client finished" and "Server finished" messages.
  4. Client and server can now resume application data exchange over the secure channel.


TLS Record Protocol

[This is preliminary documentation and subject to change.]

The Transport Layer Security (TLS) Record protocol secures application data using the keys created during the Handshake. The Record Protocol is responsible securing application data and verifying its integrity and origin. It manages the following:

  • Dividing outgoing messages into manageable blocks, and reassembling incoming messages.
  • Compressing outgoing blocks and decompressing incoming blocks (optional).
  • Applying a message authentication code (MAC) to outgoing messages, and verifying incoming messages using the MAC.
  • Encrypting outgoing messages and decrypting incoming messages.

When the Record Protocol is complete, the outgoing encrypted data is passed down to the Transmission Control Protocol (TCP) layer for transport.


TLS Cipher Suites

[This is preliminary documentation and subject to change.]

Schannel supports the following cipher suites for TLS 1.0. The suites are listed in order from most secure to least secure.

Cipher suite
TLS_RSA_WITH_RC4_128_MD5
TLS_RSA_WITH_RC4_128_SHA
TLS_RSA_WITH_3DES_EDE_CBC_SHA
TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
TLS_RSA_WITH_DES_CBC_SHA
TLS_DHE_DSS_WITH_DES_CBC_SHA
TLS_RSA_EXPORT1024_WITH_RC4_56_SHA
TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA
TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA
TLS_RSA_EXPORT_WITH_RC4_40_MD5
TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5
TLS_RSA_WITH_NULL_MD5
TLS_RSA_WITH_NULL_SHA


TLS Versus SSL

[This is preliminary documentation and subject to change.]

TLS is a standard closely related to SSL 3.0, and is sometimes referred to as "SSL 3.1". TLS supersedes SSL 2.0 and should be used in new development. Applications that require a high level of interoperability should support SSL 3.0 and TLS. Because of the similarities between these two protocols, SSL details are not included in this documentation, except where they differ from TLS. The following is from RFC2246:

"The differences between this protocol and SSL 3.0 are not dramatic, but they are significant enough that TLS 1.0 and SSL 3.0 do not interoperate (although TLS 1.0 does incorporate a mechanism by which a TLS implementation can back down to SSL 3.0)."


Secure Sockets Layer (SSL) Protocol

[This is preliminary documentation and subject to change.]

Schannel supports versions 2.0 and 3.0 of the SSL protocol.

  • SSL 3.0
  • SSL 2.0

SSL 3.0

SSL 3.0 is the predecessor of the Transport Layer Security TLS Protocol.

Schannel supports the following cipher suites for SSL 3.0. The suites are listed in order from most secure to least secure. SSL 3.0 supports all of the cipher suites of listed under TLS Cipher Suites. In addition, SSL 3.0 also supports SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA.

SSL 2.0

SSL 2.0 has been superseded by TLS and should not be used for new development.

Schannel supports the following cipher suites for SSL 2.0. The suites are listed in order from most secure to least secure.

Cipher Suite
SSL_RC4_128_WITH_MD5
SSL_DES_192_EDE3_CBC_WITH_MD5
SSL_RC2_CBC_128_CBC_WITH_MD5
SSL_DES_64_CBC_WITH_MD5
SSL_RC4_128_EXPORT40_WITH_MD5


Private Communications Technology (PCT)

[This is preliminary documentation and subject to change.]

PCT has been superseded by Secure Sockets Layer 3.0 and the Transport Layer Security (TLS) Protocol.

Schannel supports PCT 1.0 for backward compatibility only; it should not be used for new development. PCT supports most of the cipher suites supported by SSL 2.0.


Schannel and CryptoAPI

[This is preliminary documentation and subject to change.]

Starting with Microsoft® Windows® 2000, Schannel uses CryptoAPI for cryptographic operations such as storing public/private keys. The following topics provide detailed information on how Schannel makes use of CrytptoAPI.

  • Certificate Stores
  • CryptoAPI 2.0 Private Keys


Certificate Stores

[This is preliminary documentation and subject to change.]

Both client and server certificates must be stored in a certificate store accessible by the application process. Typically, this is the MY store, also known as the personal store. Client applications such as Microsoft® Internet Explorer normally use the current user's MY store while servers such as Internet Information Services (IIS) use the local machine system MY store.

The ROOT store and the certification authority (CA) store are used when Schannel or an application builds a certificate chain to be sent to the remote computer. These stores are used to validate a received certificate chain. For more information, see Performing Authentication using Schannel.


CryptoAPI 2.0 Private Keys

[This is preliminary documentation and subject to change.]

Schannel credentials are represented internally as CERT_CONTEXT structures. Schannel locates the private key associated with a particular certificate context using the certificate's CERT_KEY_PROV_INFO_PROP_ID property. Using this property, Schannel accesses the private key by calling the CryptAcquireContext function. For additional details, see Public/Private Key Pairs.

Every Schannel credential contains a reference to one or more private keys, each associated with a particular certificate. The private keys are handled quite differently depending on whether the credential is for a client or a server.

Client Private Keys

Client private keys are managed by the cryptographic service provider (CSP) in use. Client private keys are typically stored by CSPs of type PROV_RSA_FULLor PROV_RSA_SIGNATURE.

If the client application makes the CryptAcquireContext call manually then before calling AcquireCredentialsHandle, the client must bind the CSP's handle to the certificate context using the CERT_KEY_PROV_HANDLE_PROP_ID property. If Schannel finds this property set, it does not use the CERT_KEY_PROV_INFO_PROP_ID property.

Server Private Keys

Server private keys are stored by one of the following CSPs:

  • PROV_RSA_SCHANNEL
  • PROV_DH_SCHANNEL
  • PROV_FORTEZZA CSP

The choice of CSP depends on the selected key exchange algorithm. Server private keys must be of type AT_KEYEXCHANGE.


Creating a Secure Connection Using Schannel

[This is preliminary documentation and subject to change.]

The Schannel security package provides access to four security protocols:

  • Transport Layer Security (TLS 1.0)
  • Secure Sockets Layer (SSL 3.0)
  • Private Communications Technology (PCT)
  • Secure Sockets Layer (SSL 2.0)

Note The PCT and SSL 2.0 protocols have been superseded by the TLS protocol and should not be used for new development.

SSPI support for Schannel is available starting with Microsoft® Windows NT® version 4.0 with SP 4. Completing the following tasks sets up a secure connection between a client and server.:

  1. Obtain Schannel Credentials
  2. Create an Schannel Security Context

After a connection is established you can retrieve information about its attributes. For details, see Getting information about Schannel Connections.

If, after you have established a connection, your application's security requirements change or the connection is lost, you can renegotiate the connection. For details, see Renegotiating an Schannel Connection.

When you are finished with an Schannel connection you should perform the necessary cleanup. For details, see Shutting Down an Schannel Connection.

For information on samples shipped with the Platform Software Development Kit (PSDK) that demonstrate the Schannel security package, see the PSDK samples using Schannel.


Obtaining Schannel Credentials

[This is preliminary documentation and subject to change.]

Credentials are required by the Schannel authentication process; both client and server must obtain valid credentials to establish a security context for message exchange. For an example that demonstrates this procedure, see Getting credentials.

Your application obtains credentials by calling the AcquireCredentialsHandle function, which returns a handle to the requested credentials. Because credentials handles are used to store configuration information, the same handle cannot be used for both client-side and server-side operations. This means that applications that support both client and server connections must obtain a minimum of two credentials handles.

In Windows 2000, an SCHANNEL_CRED structure specifies the following:

  • A security protocol
  • The allowable ciphers
  • Minimum and maximum cipher strengths
  • An X.509 certificate used for authentication — Required for server, optional for client unless server requests client authentication.

Pass the SCHANNEL_CRED structure (via the pAuthData parameter) to the AcquireCredentialsHandle function. This function returns the credentials handle required to establish a security context.

For detailed information on setting the ciphers used with Schannel, see Specifying Schannel Ciphers and Cipher Strengths.

For information on certificates, see Certificate and Certificate Store Functions.

For information on Schannel credentials prior to Windows 2000, see Schannel Credentials Prior to Windows 2000.

For an example that demonstrates opening a certificate store and locating a certificate to use for Schannel authentication, see Getting a Certificate.


Schannel Example - Getting Credentials

The following example demonstrates how a typical client would obtain Schannel credentials. The example follows the recommended practice of using the system defaults for ciphers and cipher strengths. This allows the Schannel package to use the strongest possible algorithms to secure the channel.

#include <windows.h>
#include <ntsecapi.h>
#include <stdio.h>
#include <sspi.h>
#include <schnlsp.h>

void getSchannelClientHandle(PCredHandle ppClientCred)
{
  SECURITY_STATUS SecStatus;
  TimeStamp Lifetime;
  CredHandle hCred;
  SCHANNEL_CRED credData;

  ZeroMemory(&credData, sizeof(credData));
  credData.dwVersion = SCHANNEL_CRED_VERSION;

  //Specify the TLS V1.0 (client-side) security protocol.
  credData.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT;

  SecStatus = AcquireCredentialsHandle (
       NULL,                  // Default principal.
       UNISP_NAME,            // The name of the SSP.
       SECPKG_CRED_OUTBOUND,  // Client will use the credentials.
       NULL,                  // Use the current LOGON id.
       &credData,             // Protocol-specific data.
       NULL,                  // Default.
       NULL,                  // Default.
       &hCred,                // Receives the credential handle.
       &Lifetime              // Receives the credential time limit.
  );
  printf("Client credentials status: 0x%x\n", SecStatus);
  // Return the handle to the caller.
  *ppClientCred = hCred;
  return;
  // When caller is done with this handle
  // call FreeCredentialsHandle function.
}

The primary difference between the client-side and server-side request for credentials is that the server must provide a certificate using a CERT_CONTEXT structure as follows:

  PCCERT_CONTEXT serverCert; // Server-side certificate.
  // Get the server certificate.
  //
  if (! (serverCert = getServerCertificate())) return;
  // getServerCertificate is a placeholder function.
  credData.paCred = &serverCert;

The example function getServerCertificate is a placeholder function for this application-specific activity. For an example implementation of the getServerCertificate function, see Getting a Certificate.

Note When requesting credentials to be used by the server, change the third (fCredentialUse) parameter of the AcquireCredentialsHandle function from SECPKG_CRED_OUTBOUND to SECPKG_CRED_INBOUND.


Schannel Example - Getting a Certificate

Platform SDK: Security

Schannel Example—Getting a Certificate

The following example demonstrates opening a certificate store and locating a certificate that will be passed to the AcquireCredentialsHandle function, by means of the SCHANNEL_CRED structure. This example is meant to illustrate the steps taken to obtain a CERT_CONTEXT structure containing a certificate; you should select a certificate and certificate store appropriate for your application.

#define MACHINE_NAME "example server"

PCCERT_CONTEXT getServerCertificate ()
{
  HCERTSTORE hMyCertStore = NULL;
  PCCERT_CONTEXT aCertContext;

  // Open the "MY" store, also called the personal store.
  // This call to CertOpenStore opens the Local_Machine MY
  // store as opposed to the Current_User's MY store.

    hMyCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM,
                                 X509_ASN_ENCODING,
                                 0,
                                 CERT_SYSTEM_STORE_LOCAL_MACHINE,
                                 L"MY");

  if (hMyCertStore == NULL)
  {
    printf("Error opening MY store for server.\n");
    goto cleanup;
  }
  //
  // Search for a certificate with some specified
  // string in it. This example would attempt to find
  // a certificate with the string "example server" in
  // its subject string. Substitute an appropriate sting
  // to find a certificate for a specific user.
  //
  aCertContext = CertFindCertificateInStore(hMyCertStore,
                  X509_ASN_ENCODING,
                  0,
                  CERT_FIND_SUBJECT_STR_A,
                  MACHINE_NAME, // Use appropriate subject name.
                  NULL
  );

  if (aCertContext == NULL)
  {
    printf("Error retrieving server certificate.");
    goto cleanup;
  }
cleanup:
  CertCloseStore(hMyCertStore,0);
  return aCertContext;
}


Specifying Schannel Ciphers and Cipher Strengths

Platform SDK: Security

Specifying Schannel Ciphers and Cipher Strenths

[This is preliminary documentation and subject to change.]

For client/server information exchanges, the default behavior of Schannel is to negotiate the best cipher available based on those enabled in the registry. Applications may limit the ciphers and cipher strengths allowed for a connection by using members of the SCHANNEL_CRED structure as follows:

  1. Set the palgSupportedAlgs member to an array of ALG_IDs containing the allowable ciphers. See Cipher IDs below.
  2. Set the dwMinimumCipherStrength and/or dwMaximumCipherStrength members to the allowable minimum and maximum strengths. See Cipher Strength Values below.
  3. Pass the SCHANNEL_CRED structure (by means of the pAuthData parameter) in a call to the AcquireCredentialsHandle function. This function returns a credentials handle.
  4. Specify the credentials handle in a call to the client-side InitializeSecurityContext function or the server-side AcceptSecurityContext function.

Cipher IDs

The default behavior of Schannel is to request the best cipher available based on Schannel entries in the system registry. Do not change the system registry; the settings it contains for Schannel are used globally and will affect other applications. For the list of valid constants, see ALG_IDs.

Cipher Strength Values

This Schannel feature is typically used to limit a connection to either domestic or export strength ciphers. Domestic strengths include 56, and 128 bits, while export strength is limited to 56 bits. If you set the minimum and maximum values to zero Schannel will use all available cipher strengths.

Using TLS or SSL 3.0, set the dwMinimumCipherStrength member to -1 (negative one) to enable the "Null Cipher" cipher suites, which provide signatures but no encryption. If dwMaximumCipherStrength is also set to -1 then only the "Null Cipher" suites will be enabled. This setting is intended for development only and should not be used in production systems.

Querying Cipher Information

To retrieve the cipher strength settings for a credential, call the QueryCredentialsAttribute function and specify SECPKG_ATTR_CIPHER_STRENGTHS as the uLAttribute parameter.

To retrieve the list of supported algorithms for a credential, call the QueryCredentialsAttributes with SECPKG_ATTR_SUPPORTED_ALGS as the uLAttribute parameter.


Schannel Credentials Prior to Windows 2000

Windows 2000 credentials offer more flexibility, and their use is recommended. However, a server-side application that serves clients running Windows NT 4.0 SP4 or Windows Me might need to use older formats. When credentials created on these systems are used, a pointer to an SCH_CRED structure is passed in the pAuthData parameter when the AcquireCredentialsHandle function is called.

Certificates are passed in the paPublic member of the SCH_CRED structure as a pointer to a SCH_CRED_PUBLIC_CERTCHAIN structure.

An RSA private key is exported from a CryptoAPI 2.0 private key BLOB into the pPrivateKey member of a SCH_CRED_SECRET_PRIVKEY structure using CryptExportKey. After the key has been exported, the private key BLOB can be destroyed.


Creating an Schannel Security Context

[This is preliminary documentation and subject to change.]

To establish a security context that will protect communications between a client and server, both must participate in the following information exchange process:

Client-Side

  1. The client calls the InitializeSecurityContext function.
  2. Schannel begins creating a security context according to the rules of the selected security protocol. The function's return code indicates whether or not the client must call the function again. InitializeSecurityContext may return a token representing the context.
  3. If a token was returned, the client sends it to the server.
  4. When InitializeSecurityContext returns SEC_E_ OK, the client is done. If the function returns SEC_I_CONTINUE_NEEDED, the client must wait for the server to send it a token. When the client has the token from the server, it must call the InitializeSecurityContext function again. (Return to step 2.)

Server-Side

  1. The server waits for a client to send a message containing a security token. The server passes the token received from the client into the AcceptSecurityContext function.
  2. Schannel builds on the partial security context represented by the token. Schannel returns a token to the server, and a return code indicating whether or not the server must call the function again.
  3. If a token was returned, the server sends it to the client.
  4. When AcceptSecurityContext returns SEC_E_ OK, the server is done. If the function returns SEC_I_CONTINUE_NEEDED, then the server must wait for the client to send it a token. When the server has the token from the client, it must call the AcceptSecurityContext function again. (Return to step 2.)

If either function returns a value other than SEC_E_OK, SEC_I_CONTINUE_NEEDED, or SEC_I_INCOMPLETE_MESSAGE (see the following paragraph) an error has occurred. The client and server should call the DeleteSecurityContext function to delete the partially established security context.

A special case that can alter client-side and server-side processing is when too little or too much information is sent to the client or server from the other party. In the case of too little information, both functions return SEC_I_INCOMPLETE_MESSAGE. For information on recognizing and handling insufficient or excess information, see Extra buffers Returned by Schannel.


Performing Authentication using Schannel

[This is preliminary documentation and subject to change.]

All Schannel protocols require the server to provide a certificate from a trusted certification authority (CA) as proof of its identity. This process is called server authentication. Client authentication, where the client provides proof of its identity, is optional and may be requested by the server at any time.

Authenticating the Server

In Windows 2000 the default behavior of Schannel is to use the WinVerifyTrust function to verify the integrity and ownership of the server certificate. To disable this feature, specify ISC_REQ_MANUAL_CRED_VALIDATION when calling the InitializeSecurityContext function. For more information, see Manually Validating Schannel Credentials. On the Windows NT 4.0 and Windows Me platforms, the server certificate is not automatically validated.

Authenticating the Client

Schannel does not validate client's certificates; the server must perform this authentication manually. Typically, the server will check the client's identity in a database containing user account information. For servers that need to obtain a client's Windows NT account using a certificate, see Mapping Certificates.

When the server requests client authentication, the client must send the server one of its certificates. By default, Schannel will, with no notification to the client, attempt to locate a client certificate and send it to the server. To disable this feature, clients specify ISC_REQ_USE_SUPPLIED_CREDS when calling the InitializeSecurityContext function. When this flag is specified, Schannel will return SEC_I_INCOMPLETE_CREDENTIALS to the client when the server requests authentication and the client has not previously supplied a certificate.


Mapping Certificates

[This is preliminary documentation and subject to change.]

Note The information in this topic is valid only for servers that require client authentication.

On Windows 2000, when a server application requires client authentication, Schannel automatically attempts to map the certificate supplied by the client to a Windows NT/Windows 2000 user account.

Once the security context has been established, the server application can use the QuerySecurityContextToken function to obtain an access token for the user account to which the client certificate was mapped. Also, the server can use the ImpersonateSecurityContext function to impersonate the client.

For more information on authentication, see Performing Authentication Using Schannel.


Manually Validating Schannel Credentials

[This is preliminary documentation and subject to change.]

By default, Schannel validates the server certificate by calling the WinVerifyTrust function; however, if you have disabled this feature using the ISC_REQ_MANUAL_CRED_VALIDATION flag, you must validate the certificate provided by the server that is attempting to establish its identity.

To manually validate the server certificate, you must first get it. Use the QueryContextAttributes function and specify the SECPKG_ATTR_REMOTE_CERT_CONTEXT attribute value. This attribute returns a CERT_CONTEXT structure containing the certificate supplied by the server. This certificate is called the leaf certificate because it is the last certificate in the certificate chain and is farthest away from the root certificate.

Using the leaf certificate you must verify the following:

  • The certificate chain is complete and the root is a certificate from a trusted certification authority (CA).
  • The current time is not beyond the begin and end dates for each of the certificates in the certificate chain.
  • None of the certificates in the certificate chain have been revoked.
  • The depth of the leaf certificate is not deeper than the maximum allowable depth specified in the certificate extension. This check is only necessary if there is a depth specified.
  • The usage of the certificate is correct, for example, a client certificate should not be used to authenticate a server.
  • For server authentication, the server identity contained in the server's leaf certificate matches the server that the client is attempting to contact. Typically, the client will match some item in the certificate's Subject Name field to the server's IP address or DNS name.


Getting Information About Schannel Connections

[This is preliminary documentation and subject to change.]

The following topics describe the functions that return information on specified Schannel credentials and the security context securing a client/server connection.

Topic | Description
Querying the Attributes of an Schannel Context | Describes how to get Schannel settings specified when creating the security context that secures an Schannel connection.
Querying the Attributes of an Schannel Credential | Describes how to get the Schannel settings specified when selecting the credential used to create a connection. The settings are valid for all connections (security contexts) created using the specified credential.


Querying the Attributes of an Schannel Context

[This is preliminary documentation and subject to change.]

The QueryContextAttributes function provides Schannel-specific information about a security context. Most of the information is originally specified when the context is created with the client-side InitializeSecurityContext or server-side AcceptSecurityContext functions. Some information is specified when obtaining a handle to the credential used to create the context (see Obtaining Schannel Credentials).

The following table lists Schannel-specific flags used with the QueryContextAttributes function.

Flag | Description
SECPKG_ATTR_AUTHORITY | Retrieves certification authority (CA) name in a SecPkgContext_Authority structure.
SECPKG_ATTR_CONNECTION_INFO | Returns protocol and cipher information in a SecPkgContext_ConnectionInfo structure.
SECPKG_ATTR_ISSUER_LIST | Obsolete. Use SECPKG_ATTR_ISSUER_LIST_EX.
SECPKG_ATTR_ISSUER_LIST_EX | Returns a list of trusted CA names in a SecPkgContext_IssuerListInfoEx structure.
SECPKG_ATTR_KEY_INFO | Superseded. Use SECPKG_ATTR_CONNECTION_INFO.
SECPKG_ATTR_LIFESPAN | Returns the context start and end times. Uses a SecPkgContext_Lifespan structure.
SECPKG_ATTR_LOCAL_CERT_CONTEXT | Returns the certificate used to establish the local side of the connection. Uses a CERT_CONTEXT structure.
SECPKG_ATTR_LOCAL_CRED | Obsolete. Use SECPKG_ATTR_LOCAL_CERT_CONTEXT.
SECPKG_ATTR_NAMES | Returns the user or subject name associated with the context. Uses a SecPkgContext_Names structure.
SECPKG_ATTR_PROTO_INFO | This value has been superseded by SECPKG_ATTR_CONNECTION_INFO. Returns information about the selected protocol. Uses a SecPkgContext_ProtoInfo structure.
SECPKG_ATTR_REMOTE_CERT_CONTEXT | Returns the certificate used to establish the remote side of the connection. Uses a CERT_CONTEXT structure.
SECPKG_ATTR_REMOTE_CRED | Obsolete. Use SECPKG_ATTR_REMOTE_CERT_CONTEXT.
SECPKG_ATTR_SIZES | Returns the sizes of several message related structures. Uses a SecPkgContext_Sizes structure.
SECPKG_ATTR_STREAM_SIZES | Returns the sizes of several stream-oriented structures. Uses a SecPkgContext_StreamSizes structure.


Querying the Attributes of an Schannel Credential

[This is preliminary documentation and subject to change.]

The QueryCredentialsAttributes function provides Schannel-specific information about a credential. This information is originally specified when the credential is created (see Obtaining Schannel Credentials). The information reported by this function is valid for any connections (security contexts) created using the specified credential.

The following table lists Schannel-specific information you can obtain using the QueryCredentialsAttributes function.

Attribute | Description
SECPKG_ATTR_SUPPORTED_ALGS | Returns a SecPkgCred_SupportedAlgs structure indicated the algorithms that can be included in the negotiated cipher suite. For a list of valid values see ALG_ID.
SECPKG_ATTR_CIPHER_STRENGTHS | Returns a SecPkgCred_CipherStrengths structure indicating the permissible strengths for ciphers included in the negotiated cipher suite.
SECPKG_ATTR_SUPPORTED_PROTOCOLS | Returns a SecPkgCred_SupportedProtocols structure indicating the permissible protocols.


Managing Schannel Connections

The following topics discuss the connection-related actions that may be taken by a client or server using Schannel.

  • Renegotiating an Schannel Connection
  • Recognizing a Request to Renegotiate a Connection
  • Shutting Down an Schannel Connection


Renegotiating an Schannel Connection

[This is preliminary documentation and subject to change.]

To change a connection's attributes, such as the cipher suite or client authentication, you can request a "redo" or renegotiation of the connection.

If the attributes you want to change are controlled by credentials, you must obtain new credentials before you renegotiate the connection. For more information, see Obtaining Schannel Credentials.

To request a redo from a client application, call the InitializeSecurityContext function. Server applications call the AcceptSecurityContext function. Set the parameters as follows:

  • Specify the existing security context in the phContext parameter.
  • (Clients only) Specify the same server name (in the pszTargetName parameter) as specified when establishing the context.
  • Specify new credentials, using the phCredential parameter, if applicable.
  • If you want to change context attributes unrelated to the credentials, specify these attributes using the fContextReq parameter.

After calling the appropriate function, your application should send the results to the client and continue processing incoming messages using the DecryptMessage function.

The DecryptMessage function will return SEC_I_RENEGOTIATE when Schannel is ready for your application to proceed. When you receive the SEC_I_RENEGOTIATE return code, your application must call AcceptSecurityContext (servers) or InitializeSecurityContext (clients), passing in empty input buffers. After this call returns a value, proceed as though your application were creating a new connection.


Recognizing a Request to Renegotiate a Connection

[This is preliminary documentation and subject to change.]

The DecryptMessage function traps requests for renegotiation coming from the message sender. It notifies your application by decrypting the message data and returning the SEC_I_RENEGOTIATE value.

Your application must handle such requests by calling AcceptSecurityContext (servers) or InitializeSecurityContext (clients) and passing in empty input buffers. After this initial call returns a value, proceed as though your application were creating a new connection.


Shutting Down an Schannel Connection

[This is preliminary documentation and subject to change.]

When a client or server is finished with a connection, it must shut it down. The other party, in turn, must recognize the shutdown and delete the connection.

To shut down an Schannel connection

  1. Call the ApplyControlToken function, specifying the SCHANNEL_SHUTDOWN control token.
  2. After receiving an SEC_E_OK return value from ApplyControlToken, call the InitializeSecurityContext (clients) or AcceptSecurityContext (servers) function, passing in empty buffers.
  3. Proceed as though your application is creating a new connection until the function returns SEC_I_CONTEXT_EXPIRED or SEC_E_OK to indicate that the connection is shut down.
  4. Send the final output information, if any, to the remote party.
  5. Call DeleteSecurityContext to free resources held by the connection.

Recognizing a Shutdown

The DecryptMessage function returns SEC_I_CONTEXT_EXPIRED when the message sender has shut down the connection. After receiving this return value, do the following:

To delete a connection that has been shutdown by the remote party

  1. Call EncryptMessage, passing in an empty input buffer.
  2. Send the output buffers from the EncryptMessage call to the remote party (the sender of the decrypted message).
  3. Delete the security context by calling the DeleteSecurityContext function.


Extra Buffers Returned by Schannel

Information must be sent between the client and server while a security context is being established, and afterwards as secure messages are exchanged using the encryption and decryption features provided by Schannel. The following functions are used to accomplish these tasks:

  • AcceptSecurityContext
  • InitializeSecurityContext
  • DecryptMessage

Schannel has a well defined set of behaviors for incomplete or excess information included in the input buffers to these functions. Information is exchanged between the client and server in the following manner:

  1. The local party interacts with Schannel by calling an SSPI function and passing in information. Typically, the information was received from the remote party.
  2. The function returns a status code and output buffers containing information.
  3. Depending on the status code, the output buffers are sent to the remote party by means of some communication mechanism.
  4. The remote party reads information sent by the local party.
  5. The loop repeats, with the local and remote parties interchanged. (The remote party calls an SSPI function and passes in the information read in the previous step…)

Everything works as expected when the input buffer to the SSPI function contains exactly the information needed. However, due to the stream-oriented nature of some communications protocols this may not be the case; a block of information received from a remote party may contain less data than is required or more data than can be processed by Schannel in a single function call.

If the input buffer contains too little information, the functions return SEC_E_INCOMPLETE_MESSAGE. The caller must obtain additional data from the remote party and call the function again.

When the input buffers contains too much information, Schannel does not treat this as an error. The function processes as much of the input as it can, and returns the status code for that processing activity. In addition, Schannel indicates the presence of unprocessed information in the input buffers by returning an output buffer of type SECBUFFER_EXTRA. Testing the output buffers for this type of buffer is the only way to detect this situation. The cbBuffer field of the extra buffer structure indicates how many bytes of input were not processed.

Note The pvBuffer field of the extra buffer does not contain a copy of the excess data.

If you receive an extra buffer from a SSPI function, you must remove the already processed information from the input buffer and call the function again. Schannel can, and often does, return only the extra buffer and nothing else in the output buffers.


PSDK Samples Using Schannel

[This is preliminary documentation and subject to change.]

The samples shipped with the Platform SDK contains a sample web client and web server that use the Schannel security package. If you have installed the Platform SDK samples, these samples can be found at:

<PSDKInstallation Dir>\Samples\WinBase\Security\SSL

Substitute your Platform SDK installation directory for <PSDKInstallation Dir>


Schannel Reference

[This is preliminary documentation and subject to change.]

The following documentation describes the Microsoft Security Support Provider Interface (SSPI) functions used to access the Schannel security package.

Section | Description
Schannel Functions | Reference pages containing Schannel-specific information for SSPI functions.
Schannel Structures | Structures used by Schannel functions.


Schannel Functions

[This is preliminary documentation and subject to change.]

Schannel is accessed by using Microsoft Security Support Provider Interface (SSPI). The information presented here is specific to the Schannel security package. Generalized reference pages for these functions can be found in SSPI Functions.

The following SSPI functions have Schannel-specific reference pages.

Function | Description
AcceptSecurityContext | Creates the server-side security context.
AcquireCredentialsHandle | Retrieves a handle to Schannel credentials.
ApplyControlToken | Initiates a shut down of a connection.
DecryptMessage | Decrypts and verifies the integrity of a message.
EncryptMessage | Signs and encrypts a message to protect the privacy of its contents.
InitializeSecurityContext | Creates the client-side security context.
QueryContextAttributes | Retrieves the specified attribute information from a security context.
QueryCredentialsAttributes | Retrieves the specified attribute information from a credential.


AcceptSecurityContext (Schannel)

[This is preliminary documentation and subject to change.]

The AcceptSecurityContext function creates the server-side security context used to secure communications between a client and server.

The Schannel implementation of AcceptSecurityContext returns the messages required by the selected protocol and a security token, which the server must pass to the client.

SECURITY_STATUS AcceptSecurityContext(
  PCredHandle phCredential,
  PCtxtHandle phContext,
  PSecBufferDesc pInput,
  ULONG fContextReq,
  ULONG TargetDataRep,
  PCtxtHandle phNewContext,
  PSecBufferDesc pOutput,
  PULONG pfContextAttr,
  PTimeStamp ptsExpiry
);

Parameters

phCredential
[in] Handle to the server's credentials. This handle is returned by the AcquireCredentialsHandle function.
phContext
[in, out] Pointer to a CtxtHandle. This pointer receives a token representing the security context. On the first call to AcceptSecurityContext, specify NULL. On future calls, specify the token received in the phNewContext parameter after the first call to this function.
pInput
[in] Pointer to a SecBufferDesc structure containing two SecBuffer structures. The first buffer must be of type SECBUFFER_TOKEN and contain the security token received from the client. The second buffer should be of type SECBUFFER_EMPTY.
fContextReq
[in] Indicates that the security context should support certain features, or attributes. The following table lists the valid flags for Schannel.
Flag | Description
ASC_REQ_REPLAY_DETECT | Detect replayed packets.
ASC_REQ_SEQUENCE_DETECT | Detect messages received out of sequence.
ASC_REQ_CONFIDENTIALITY | Encrypt messages.
ASC_REQ_STREAM | Support a stream-oriented connection. Schannel will set this flag automatically if you do not.
ASC_REQ_ALLOCATE_MEMORY | Schannel will allocate output buffers for you. You must free them using FreeContextBuffer.
ASC_REQ_EXTENDED_ERROR | When errors occur, the remote party will be notified.
ASC_REQ_CONNECTION | The security context will not handle formatting messages.
ASC_REQ_MUTUAL_AUTH | The client is required to supply a certificate to be used for client authentication.

The requested attributes may not be supported by the client. For additional information, see the pfContextAttr parameter.

TargetDataRep
[in] Not used with Schannel. Specify zero.
phNewContext
[in, out] Pointer to a CtxtHandle structure. On the first call to AcceptSecurityContext, this pointer receives a new context handle. In subsequent calls, pass this handle using the phContext parameter and specify NULL for phNewContext.
pOutput
[in, out] Pointer to a SecBufferDesc structure that contains a SecBuffer structure of type SECBUFFER_TOKEN. On output, this buffer will receive a token for the security context. The token must be sent to the client. The function may also return a buffer of type SECBUFFER_EXTRA.
pfContextAttr
[out] Pointer to a ULONG that receives bit flags indicating the attributes of the established context. For a list of valid values, refer to the table included in the fContextReq parameter description. pfContextAttr receives a set of flags corresponding to each of the values in the table; however, the ASC_REQ prefix is replaced by ASC_RET to differentiate between requested attributes and returned attributes.

Warning Do not check for security-related attributes until the final function call returns successfully. Other (non-security) attribute flags such as the ASC_RET_ALLOCATED_MEMORY flag, can be checked before the final return.

ptsExpiry
[out] Optional. Pointer to a TimeStamp structure. In Whistler, when the remote party has supplied a certificate to be used for authentication, this parameter receives the expiration time for that certificate. If no certificate was supplied, a maximum time value is returned. In Windows versions prior to Whistler, this parameter is not altered by the function.

Return Values

If the function succeeds, it returns one of the following values.

Value | Meaning
SEC_E_OK | The security context received from the client was accepted. No more calls to this function are required. If an output token was generated by the function, it must be sent to the client.
SEC_E_INCOMPLETE_MESSAGE | The data in the input buffer is incomplete. The application must read additional data from the client and call AcceptSecurityContext again.
SEC_I_CONTINUE_NEEDED | The server must send the output token to the client and wait for the client to return a token. Pass the returned token into another call to AcceptSecurityContext, using the pInput parameter.

If the function fails, it returns one of the following values.

Value | Meaning
SEC_E_INVALID_TOKEN | An invalid token was passed in the input buffers.
SEC_E_INVALID_HANDLE | An invalid context handle was specified in the phContext parameter.
SEC_E_UNSUPPORTED_FUNCTION | An invalid context attribute flag (ASC_REQ_DELEGATE or ASC_REQ_PROMPT_FOR_CREDS) was specified in the fContextReq parameter.
SEC_E_NO_CREDENTIALS | The supplied credentials could not be authenticated.
SEC_E_INSUFFICIENT_MEMORY | One of the buffers is too small to hold output information; see Remarks.

Remarks

Clients use InitializeSecurityContext, the client-side counterpart to the AcceptSecurityContext function, to create a security context.

If the SEC_E_INSUFFICIENT_MEMORY error is received, specify the ASC_REQ_ALLOCATE_MEMORY attribute flag in the fContextReq parameter.

The caller is responsible for determining whether the final context attributes are sufficient. If, for example, confidentiality (encryption) was requested, but could not be established, some applications may choose to shut down the connection immediately. If the security context cannot be established, the server must free the partially created context by calling the DeleteSecurityContext function.

Once the security context has been established, the server application can use the QuerySecurityContextToken function to obtain a handle to the user account to which the client certificate was mapped. Also, the server can use the ImpersonateSecurityContext function to impersonate the user. For additional information, see Performing Authentication using Schannel.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.

See Also

AcquireCredentialsHandle, CtxtHandle, DeleteSecurityContext, InitializeSecurityContext, SecBuffer, SecBufferDesc, TimeStamp


AcquireCredentialsHandle (Schannel)

[This is preliminary documentation and subject to change.]

The AcquireCredentialsHandle function retrieves a handle to the credentials of a security principal. This handle is required by the InitializeSecurityContext and AcceptSecurityContext functions.

SECURITY_STATUS AcquireCredentialsHandle(
  SEC_CHAR *pszPrincipal,
  SEC_CHAR *pszPackage,
  ULONG fCredentialUse,
  PLUID pvLogonID,
  PVOID pAuthData,
  PVOID pGetKeyFn,
  PVOID pvGetKeyArgument,
  PCredHandle phCredential,
  PTimeStamp ptsExpiry
);

Parameters

pszPrincipal
[in] Not used with Schannel. Specify NULL.
pszPackage
[in] Specify UNISP_NAME. This constant is defined as "Microsoft Unified Security Protocol Provider".
fCredentialUse
[in] Flag indicating how the credential will be used. Specify one of the following values.
Value | Meaning
SECPKG_CRED_INBOUND | The server will use the credential.
SECPKG_CRED_OUTBOUND | The client will use the credential.

pvLogonID
[in] Not used with Schannel. Specify NULL.
pAuthData
[in] In Windows 2000, specify an SCHANNEL_CRED structure indicating the protocol to use and settings for various customizable channel features. For earlier versions of Schannel, use an SCH_CRED structure.
pGetKeyFn
[in] Not used with Schannel. Specify NULL.
pvGetKeyArgument
[in] Not used with Schannel. Specify NULL.
phCredential
[out] Pointer to a CredHandle. Receives the requested credential handle.
ptsExpiry
[out] Optional. Pointer to a TimeStamp. In Windows Whistler, when the remote party has supplied a certificate to be used for authentication, this parameter receives the expiration time for that certificate. If no certificate was supplied then a maximum time value is returned. In Windows versions prior to Whistler, this parameter receives zero.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value is an SECURITY_STATUS indicating the error. The following table lists common error values and their causes.

Value | Cause
SEC_E_UNKNOWN_CREDENTIALS | The pAuthData parameter did not contain a credentials structure accepted by Schannel.
SEC_E_NO_CREDENTIALS | The fCredentialUse parameter specified an invalid value.
SEC_E_INSUFFICIENT_MEMORY | There is not enough memory is available to complete the request.

Remarks

When you no longer need the returned credentials, free them by calling the FreeCredentialsHandle function.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

AcceptSecurityContext, InitializeSecurityContext, FreeCredentialsHandle


ApplyControlToken (Schannel)

[This is preliminary documentation and subject to change.]

The ApplyControlToken function is used to shut down the security context underlying an existing Schannel connection.

SECURITY_STATUS ApplyControlToken(
  PCtxtHandle phContext,
  PSecBufferDesc pInput
);

Parameters

phContext
[in] Handle to a security context. Schannel will shut down the context and notify the remote party with whom this context was established. See Remarks.
pInput
[in] Pointer to a SecBufferDesc structure that describes a single SecBuffer structure. The SecBuffer specifies the control token to apply to the context; the buffer must be configured as follows:
Buffer | Contents
Type | SECBUFFER_TOKEN
Size | sizeof(DWORD)
Value | The address of a DWORD set to the constant SCHANNEL_SHUTDOWN

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value is a nonzero error code.

Remarks

For information on the way Schannel notifies the remote party of the shutdown, see the remarks accompanying the DecryptMessage function reference page.

For additional information, see Shutting Down an Schannel Connection.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

DecryptMessage, SecBuffer, SecBufferDesc


DecryptMessage (Schannel)

[This is preliminary documentation and subject to change.]

The DecryptMessage function decrypts secured messages. It also signals when the message sender is requesting a renegotiation (redo) of the connection attributes or has shutdown the connection.

SECURITY_STATUS DecryptMessage(
  PCtxtHandle phContext,
  PSecBufferDesc pMessage,
  ULONG MessageSeqNo,
  PULONG pfQOP
);

Parameters

phContext
[in] Handle to the security context previously established with the message sender.
pMessage
[in, out] Pointer to a SecBufferDesc structure. For contexts that are not connection-oriented, on input, the structure must contain four SecBuffer structures. Exactly one buffer must be of type SECBUFFER_DATA and contain an encrypted message, which is decrypted in place. The remaining buffers are used for output and must be of type SECBUFFER_EMPTY.

For connection-oriented contexts a SECBUFFER_DATA type buffer must be supplied, as noted for non-connection-oriented contexts. Additionally, a second SECBUFFER_TOKEN type buffer containing a security token must also be supplied.

MessageSeqNo
[in] Not used with Schannel. Specify zero.
pfQOP
Not used with Schannel. Specify NULL.

Return Values

If the function completes successfully and no connection state changes, such as renegotiation or shutdown, were initiated by the remote party, the return value is SEC_E_OK.

If the function fails or the connection state has changed, the function returns a nonzero value indicating the error or state. The following table contains common error and information codes returned by the Schannel DecryptMessage function.

Value | Meaning
SEC_E_INVALID_HANDLE | The phContext parameter is invalid.
SEC_E_INCOMPLETE_MESSAGE | The data in the input buffers is incomplete. The application must obtain more data and call DecryptMessage again.
SEC_I_RENEGOTIATE | The remote party requests a redo. See Remarks.
SEC_E_INVALID_TOKEN | Buffers are of the wrong type or no buffer of type SECBUFFER_DATA was found.
SEC_I_CONTEXT_EXPIRED | The remote party shut down the connection. See Remarks.

Remarks

The DecryptMessage function returns SEC_E_CONTEXT_EXPIRED when the message sender has shut down the connection. After receiving this return value, your application must do the following:

  1. Call EncryptMessage, passing in an empty input buffer.
  2. Send the output buffers from the EncryptMessage call to the remote party (the sender of the decrypted message).
  3. Delete the security context by calling the DeleteSecurityContext function.

The DecryptMessage function returns SEC_I_RENEGOTIATE when the message sender wants to renegotiate the connection (security context). Your application must handle a requested renegotiation by calling AcceptSecurityContext (server-side) or InitializeSecurityContext (client-side) and passing in empty input buffers. After this initial call returns a value, proceed as though your application was creating a new connection. For more information, see Creating an Schannel Security Context.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.

See Also

AcceptSecurityContext, DeleteSecurityContext, EncryptMessage, InitializeSecurityContext, SecBuffer, SecBufferDesc


EncryptMessage (Schannel)

[This is preliminary documentation and subject to change.]

The EncryptMessage function encrypts a message using the session key negotiated with the remote party who will receive the message. The encryption algorithm is determined by the cipher suite in use.

SECURITY_STATUS EncryptMessage(
  PCtxtHandle phContext,
  ULONG fQOP,
  PSecBufferDesc pMessage,
  ULONG MessageSeqNo
);

Parameters

phContext
[in] Handle to the security context previously established with the message recipient.
fQOP
[in] Not used with Schannel. Specify zero.
pMessage
[in, out] Pointer to a SecBufferDesc structure. On input, this structure contains one or more SecBuffer structures, exactly one of which must be of type SECBUFFER_DATA. This buffer contains the message which is encrypted in place. For more information, see Remarks.
MessageSeqNo
[in] Not used with Schannel. Specify zero.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value is a nonzero error code. The following table contains common error codes returned by the Schannel EncryptMessage function.

Value | Meaning
SEC_E_INVALID_HANDLE | The phContext parameter is invalid.
SEC_E_INVALID_TOKEN | No SECBUFFER_DATA type buffer was found.
SEC_E_INSUFFICIENT_MEMORY | There is not enough memory available to complete the requested action.
SEC_E_CONTEXT_EXPIRED | The remote party closed the connection. See Remarks.

Remarks

The pMessage parameter must contain a SecBufferDesc structure with the buffers described in the following table.

Note These buffers must be supplied in the order shown.

Buffer type | Description
SECBUFFER_STREAM_HEADER | Used internally. No initialization required.
SECBUFFER_DATA | Contains the plain-text message to be encrypted.
SECBUFFER_STREAM_TRAILER | Used internally. No initialization required.
SECBUFFER_EMPTY | Used internally. No initialization required. Size can be zero.

To determine the maximum size of each of the buffers you must call the QueryContextAttributes function and specify the SECPKG_ATTR_STREAM_SIZES attribute. This function returns a SecPkgContext_StreamSizes structure whose members contain the maximum sizes for the header (cbHeader member), message (cbMaximumMessage member) and trailer (cbTrailer member) buffers.

For optimal performance the pMessage buffers should be allocated from contiguous memory.

After calling EncryptMessage, the application sends the encrypted message packet to the remote computer. This must include the returned header, data, and trailer buffers.

The EncryptMessage function returns SEC_E_CONTEXT_EXPIRED when the remote party has shut down the security context specified by the phContext parameter. After receiving this return value, your application should do the following:

  1. Send the output buffers from the EncryptMessage call to the remote party.
  2. Delete the security context by calling the DeleteSecurityContext function.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.

See Also

QueryContextAttributes, SecBuffer, SecBufferDesc, SecPkgContext_StreamSizes


InitializeSecurityContext (Schannel)

[This is preliminary documentation and subject to change.]

The InitializeSecurityContext function creates the client-side security context used to secure communications between a client and server.

The Schannel implementation of InitializeSecurityContext returns the messages required by the selected protocol and a security token that the client must pass to the target server.

SECURITY_STATUS InitializeSecurityContext(
  PCredHandle phCredential,
  PCtxtHandle phContext,
  SEC_CHAR *pszTargetName,
  ULONG fContextReq,
  ULONG Reserved1,
  ULONG TargetDataRep,
  PSecBufferDesc pInput,
  ULONG Reserved2,
  PCtxtHandle phNewContext,
  PSecBufferDesc pOutput,
  PULONG pfContextAttr,
  PTimeStamp ptsExpiry
);

Parameters

phCredential
[in] Pointer to a handle to the client's credentials. This handle is returned by the AcquireCredentialsHandle function.
phContext
[in, out] Pointer to a CtxtHandle. This pointer receives a token representing the security context. On the first call to InitializeSecurityContext, specify NULL. On future calls, specify the token received in the phNewContext parameter after the first call to this function.
pszTargetName
[in] Specify a string that uniquely identifies the target server. Schannel uses this value to locate the session in the session cache when re-establishing a connection.
fContextReq
[in] Indicates that the security context should support certain features, or attributes. Specify any combination of the following attributes flags.
Flag | Description
ISC_REQ_REPLAY_DETECT | Detect replayed packets.
ISC_REQ_SEQUENCE_DETECT | Detect messages received out of sequence.
ISC_REQ_CONFIDENTIALITY | Encrypt messages.
ISC_REQ_STREAM | Support a stream-oriented connection.
ISC_REQ_ALLOCATE_MEMORY | Schannel will allocate output buffers for you. You must still free them using FreeContextBuffer.
ISC_REQ_EXTENDED_ERROR | When errors occur, the remote party will be notified.
ISC_REQ_CONNECTION | The security context will not handle formatting messages.
ISC_REQ_MUTUAL_AUTH | Client and server will be authenticated.
ISC_REQ_USE_SUPPLIED_CREDS | Schannel must not attempt to supply credentials for the client automatically.
ISC_REQ_MANUAL_CRED_VALIDATION | Schannel must not authenticate the server automatically.

The requested attributes may not be supported by the client. For additional information, see the pfContextAttr parameter.

Reserved1
[reserved] Reserved value; specify zero.
TargetDataRep
[in] Not used with Schannel. Specify zero.
pInput
[in, out] Pointer to a SecBufferDesc structure that contains pointers to the buffers supplied to Schannel. On the first call to the function, specify NULL. On additional calls, there should be two buffers. The first of type SECBUFFER_TOKEN containing the token received from the server. The second buffer will received data that is not processed by Schannel, if any.
Reserved2
[reserved] Reserved value; must be zero.
phNewContext
[in, out] Pointer to a CtxtHandle structure. On the first call to InitializeSecurityContext, this pointer receives a new context handle. In subsequent calls, pass this handle using the phContext parameter and specify NULL for phNewContext.
pOutput
[out] Pointer to a SecBufferDesc structure that describes one SecBuffer structure of type SECBUFFER_TOKEN, which receives a security token. If the ISC_REQ_ALLOCATE_MEMORY flag is specified Schannel will allocate this buffer and put the appropriate information in the SecBufferDesc.
pfContextAttr
[out] Pointer to a ULONG that receives bit flags indicating the attributes of the established context. For a list of valid values, refer to the table included in the fContextReq parameter description. pfContextAttr receives a set of flags corresponding to each of the values in the table; however, the ISC_REQ prefix is replaced by ISC_RET to differentiate between requested attributes and returned attributes.

Warning Do not check for security-related attributes until the final function call returns successfully. Other (non-security) attribute flags such as the ISC_RET_ALLOCATED_MEMORY flag, can be checked before the final return.

ptsExpiry
[out] Optional. Pointer to a TimeStamp structure. In Whistler, when the remote party has supplied a certificate to be used for authentication, this parameter receives the expiration time for that certificate. If no certificate was supplied then a maximum time value is returned. In Windows versions prior to Whistler, this parameter is not altered by the function.

Return Values

If the function succeeds, the function returns one of the following values.

Value | Meaning
SEC_E_OK | The security context was successfully initialized. No more calls to this function are required. If an output token was generated by the function, it must be sent to the server.
SEC_E_INCOMPLETE_MESSAGE | The data in the input buffer is incomplete. The application must read additional data from the server and call InitializeSecurityContext again.
SEC_I_INCOMPLETE_CREDENTIALS | The server has requested client authentication, and the supplied credentials either do not include a certificate or the certificate was not issued by a certification authority (CA) trusted by the server. See Remarks.
SEC_I_CONTINUE_NEEDED | The client must send the output token to the server and wait for a return token to use in another call to InitializeSecurityContext.

If the function fails, the return value is one of the following error codes.

Value | Meaning
SEC_E_INVALID_HANDLE | An invalid context handle was specified in the phContext parameter.
SEC_E_TARGET_UNKNOWN | The target was not recognized.
SEC_E_NO_CREDENTIALS | The supplied credentials could not be authenticated.
SEC_E_UNSUPPORTED_FUNCTION | An invalid context attribute flag (ISC_REQ_DELEGATE or ISC_REQ_PROMPT_FOR_CREDS) was specified in the fContextReq parameter.
SEC_E_INSUFFICIENT_MEMORY | One of the buffers is too small to hold output information; see Remarks.

Remarks

Servers use AcceptSecurityContext, the server-side counterpart to the InitializeSecurityContext function.

If the function returns SEC_I_INCOMPLETE_CREDENTIALS, check that you specified a valid and trusted certificate in your credentials. The certificate is specified when calling the AcquireCredentialsHandle function. The certificate must be a client authentication certificate issued by a certification authority (CA) trusted by the server. To obtain a list of the CAs trusted by the server, call the QueryContextAttributes function and specify the SECPKG_ATTR_ISSUER_LIST_EX attribute.

After you have a client authentication certificate from a CA trusted by the server, you should create a new credential by calling the AcquireCredentialsHandle function, and then call InitializeSecurityContext again, specifying the new credential in the phCredential parameter.

The caller is responsible for determining whether the final context attributes are sufficient. If, for example, confidentiality (encryption) was requested, but could not be established, some applications may choose to shut down the connection immediately. If the security context cannot be established, the client must free the partially created context by calling the DeleteSecurityContext function.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

AcceptSecurityContext, AcquireCredentialsHandle, CtxtHandle, DeleteSecurityContext, FreeContextBuffer, SecBuffer, SecBufferDesc, TimeStamp


QueryContextAttributes (Schannel)

[This is preliminary documentation and subject to change.]

The QueryContextAttributes function retrieves information about attributes or features supported by a specified security context.

SECURITY_STATUS QueryContextAttributes(
  PCtxtHandle phContext,
  ULONG ulAttribute,
  PVOID pBuffer
);

Parameters

phContext
[in] Handle to the security context to be queried.
ulAttribute
[in] Specifies which context attribute is returned. The following table lists the valid values.
Value | Information returned | Structure returned
SECPKG_ATTR_AUTHORITY | The certification authority (CA) that issued the remote party's certificate. | SecPkgContext_Authority
SECPKG_ATTR_CONNECTION_INFO | The protocol, ciphers, and cipher strengths in use. | SecPkgContext_ConnectionInfo
SECPKG_ATTR_ISSUER_LIST | Superseded by SECPKG_ATTR_ISSUER_LIST_EX. | SecPkgContext_IssuerListInfo (Obsolete)
SECPKG_ATTR_ISSUER_LIST_EX | List of trusted certification authorities. | SecPkgContext_IssuerListInfoEx
SECPKG_ATTR_KEY_INFO

(superseded by SECPKG_ATTR_CONNECTION_INFO)

 The signature and encryption algorithms in use. SecPkgContext_KeyInfo
SECPKG_ATTR_LIFESPAN | The time at which the server certificate expires. | SecPkgContext_Lifespan
SECPKG_ATTR_LOCAL_CERT_CONTEXT | The local party's certificate context. | CERT_CONTEXT. See Remarks.
SECPKG_ATTR_LOCAL_CRED | Superseded by SECPKG_ATTR_LOCAL_CERT_CONTEXT | SecPkgContext_LocalCredentialInfo (obsolete)
SECPKG_ATTR_NAMES | The remote party's subject name. | SecPkgContext_Names
SECPKG_ATTR_PACKAGE_INFO | See the SecPkgInfo structure for details. | SecPkgContext_PackageInfo
SECPKG_ATTR_PROTO_INFO | Superseded by SECPKG_ATTR_CONNECTION_INFO. | SecPkgContext_ProtoInfo (obsolete)
SECPKG_ATTR_REMOTE_CERT_CONTEXT | The remote party's certificate context. | CERT_CONTEXT. See Remarks.
SECPKG_ATTR_REMOTE_CRED | Superseded by SECPKG_ATTR_REMOTE_CERT_CONTEXT | SecPkgContext_RemoteCredentialInfo (obsolete)
SECPKG_ATTR_SIZES | Sizes for Schannel tokens and message blocks. | SecPkgContext_Sizes
SECPKG_ATTR_STREAM_SIZES | Sizes for Schannel stream-oriented elements, including headers, trailers and block sizes. | SecPkgContext_StreamSizes

pBuffer
[in, out] Pointer to a structure containing the requested attribute. The ulAttribute parameter description indicates the structure returned for each attribute. For additional information, see Remarks.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value is a nonzero error code.

Remarks

The caller allocates the structure specified by the pBuffer parameter and Schannel allocates any memory required to hold variable-sized members of the pBuffer structure. Memory allocated by Schannel must be freed by calling the FreeContextBuffer function.

Calling the QueryContextAttributes function with the SECPKG_ATTR_REMOTE_CERT_CONTEXT or SECPKG_ATTR_LOCAL_CERT_CONTEXT attribute flags, returns a CERT_CONTEXT structure. The hStore member of this structure will contain a handle to a certificate store containing the intermediate certificates, if any. The caller is responsible for calling CertFreeCertificateContext to free the certificate context.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.


QueryCredentialsAttributes (Schannel)

[This is preliminary documentation and subject to change.]

The QueryCredentialsAttributes function retrieves information for a credential. The information is valid for any security context created with the specified credential.

SECURITY_STATUS QueryCredentialsAttributes(
  PCredHandle phCredential,
  ULONG ulAttribute,
  PVOID pBuffer
);

Parameters

phCredential
[in] Handle of the credential to be queried.
ulAttribute
[in] Specifies the attribute to query. This parameter can be any of the following attributes.
Attribute | pBuffer Type
SECPKG_ATTR_SUPPORTED_ALGS | SecPkgCred_SupportedAlgs
SECPKG_ATTR_CIPHER_STRENGTHS | SecPkgCred_CipherStrengths
SECPKG_ATTR_SUPPORTED_PROTOCOLS | SecPkgCred_SupportedProtocols

pBuffer
[out] Pointer to a buffer that receives the requested attribute. See the table above.

Return Values

If the function succeeds, the return value is SEC_E_OK.

If the function fails, the return value may be one of the following error codes.

Value | Meaning
SEC_E_INVALID_HANDLE | The credentials handle specified by phCredential is invalid.
SEC_E_UNSUPPORTED_FUNCTION | The specified attribute is not supported by Schannel.

Remarks

Credentials attributes are originally specified using an SCHANNEL_CRED structure with the AcquireCredentialsHandle function. For additional information, see Obtaining Schannel Credentials.

Note An application can find the system default cipher strength by querying the SECPKG_ATTR_CIPHER_STRENGTHS attribute and specifying a default credential. A default credential is created by calling AcquireCredentialsHandle with a NULL pAuthData parameter.

The caller allocates the structure pointed to by the pBuffer parameter and Schannel allocates buffers for any pointers returned in the pBuffer structure. The caller must call the FreeContextBuffer function to free buffers allocated by Schannel.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Library: Use Secur32.lib.

See Also

AcquireCredentialsHandle, FreeContextBuffer, SCHANNEL_CRED, SecPkgCred_CipherStrengths, SecPkgCred_SupportedAlgs, SecPkgCred_SupportedProtocols


Schannel Structures

[This is preliminary documentation and subject to change.]

The following structures are defined for use with Schannel.

  • SCH_CRED
  • SCH_CRED_PUBLIC_CERTCHAIN
  • SCH_CRED_SECRET_PRIVKEY
  • SCHANNEL_CRED
  • SecPkgContext_Authority
  • SecPkgContext_ConnectionInfo
  • SecPkgContext_IssuerListInfoEx
  • SecPkgContext_KeyInfo
  • SecPkgContext_ProtoInfo
  • SecPkgCred_CipherStrengths
  • SecPkgCred_SupportedAlgs
  • SecPkgCred_SupportedProtocols


SCH_CRED

[This is preliminary documentation and subject to change.]

The SCH_CRED structure contains the data for credentials used in Schannel Version 1 and 2. This structure is used with credentials in earlier versions of Windows. For more information, see Schannel Credentials Prior to Windows 2000.

This structure is has been superseded by the SCHANNEL_CRED structure.

typedef struct _SCH_CRED
{
  DWORD      dwVersion;
  DWORD      cCreds;
  PVOID *    paSecret;
  PVOID *    paPublic;
  DWORD      cMappers;
  struct _HMAPPER ** aphMappers;
} SCH_CRED, * PSCH_CRED;

Members

dwVersion
The Schannel version that the credentials will be used with.
cCreds
Size of the array passed into paSecret and paPublic. This is typically either zero or one.
paSecret
Array of SCH_CRED_SECRET_PRIVKEY structure pointers.
paPublic
Array of SCH_CRED_PUBLIC_CERTCHAIN structure pointers.
cMappers
Reserved. Must be zero.
aphMappers
Reserved. Must be zero.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Schannel.h; include Schnlsp.h.


SCH_CRED_PUBLIC_CERTCHAIN

[This is preliminary documentation and subject to change.]

The SCH_CRED_PUBLIC_CERTCHAIN structure contains a single certificate. A certification chain can be built from this certificate. This structure is used with credentials in earlier versions of Windows. For more information, see Schannel Credentials Prior to Windows 2000.

typedef struct _SCH_CRED_PUBLIC_CERTCHAIN
{
  DWORD   dwType;
  DWORD   cbCertChain;
  PBYTE   pCertChain;
} SCH_CRED_PUBLIC_CERTCHAIN, *PSCH_CRED_PUBLIC_CERTCHAIN;

Members

dwType
Must always be set to SCH_CRED_X509_CERTCHAIN.
cbCertChain
Size of the X.509 certificate, in bytes.
pCertChain
Pointer to an X.509 leaf certificate.

Remarks

This structure does not directly support certificate chains. If a server needs to use certificate chains, the intermediate certificates can be placed in the certification authority's (CA) certificate store and Schannel will automatically pick them up from there.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Schannel.h; include Schnlsp.h.


SCH_CRED_SECRET_PRIVKEY

[This is preliminary documentation and subject to change.]

The SCH_CRED_SECRET_PRIVKEY structure contains private key information needed to authenticate a client or server. This structure is used with credentials in earlier versions of Windows. For more information, see Schannel Credentials Prior to Windows 2000.

typedef struct _SCH_CRED_SECRET_PRIVKEY
{
  DWORD   dwType;
  PBYTE   pPrivateKey;
  DWORD   cbPrivateKey;
  PSTR    pszPassword;
} SCH_CRED_SECRET_PRIVKEY, *PSCH_CRED_SECRET_PRIVKEY;

Members

dwType
Must always be set to SCHANNEL_SECRET_PRIVKEY.
pPrivateKey
Pointer to an encrypted private key.
cbPrivateKey
Number of bytes in the encrypted private key.
pszPassword
Pointer to a null-terminated string that Schannel uses to decrypt the private key.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Schannel.h; include Schnlsp.h.


SCHANNEL_CRED

[This is preliminary documentation and subject to change.]

The SCHANNEL_CRED structure contains the data for an Schannel credential.

typedef struct _SCHANNEL_CRED
{
  DWORD           dwVersion;
  DWORD           cCreds;
  PCCERT_CONTEXT * paCred;
  HCERTSTORE      hRootStore;
  DWORD           cMappers;
  struct _HMAPPER **  aphMappers;
  DWORD           cSupportedAlgs;
  ALG_ID *        palgSupportedAlgs;
  DWORD           grbitEnabledProtocols;
  DWORD           dwMinimumCipherStrength;
  DWORD           dwMaximumCipherStrength;
  DWORD           dwSessionLifespan;
  DWORD           dwFlags;
  DWORD           reserved;
} SCHANNEL_CRED, *PSCHANNEL_CRED;

Members

dwVersion
Set to SCHANNEL_CRED_VERSION.
cCreds
Number of structures in the paCred array.
paCred
Array of pointers to CERT_CONTEXT structures. Each pointer specifies a certificate containing a private key to be used in authenticating the application. Typically, this array contains one structure for each key exchange method supported by the application.

Client applications often pass in an empty list and either depend on Schannel to find an appropriate certificate or create a certificate later if needed.

hRootStore
Optional. Valid for server applications only. Handle to a certificate store containing self-signed root certificates for certification authorities (CAs) trusted by the application. This member is used only by server-side applications requiring client authentication.
cMappers
Reserved.
aphMappers
Reserved.
cSupportedAlgs
Number of algorithms in the palgSupportedAlgs array.
palgSupportedAlgs
Optional. Pointer to an array of ALG_IDs representing the algorithms supported by connections made with credentials acquired using this structure. If cSupportedAlgs is zero or palgSupportedAlgs is NULL, Schannel uses the system defaults.
grbitEnabledProtocols
Optional. DWORD containing a bit string representing the protocols supported by connections made with credentials acquired using this structure. If this member is zero, Schannel selects the protocol. Transport Layer Security 1.0 should be chosen for new development.

This member is used only by the Microsoft Unified Security Protocol Provider security package.

The global system registry settings take precedence over this value. For example, if SSL3 is disabled in the registry, it cannot be enabled using this member.

This member can contain any of the following flags.
Constant | Description
SP_PROT_TLS1_CLIENT | Transport Layer Security 1.0 client-side.
SP_PROT_TLS1_SERVER | Transport Layer Security 1.0 server-side.
SP_PROT_SSL3_CLIENT | Secure Sockets Layer 3.0 client-side.
SP_PROT_SSL3_SERVER | Secure Sockets Layer 3.0 server-side.
SS_PROT_PCT1_CLIENT | Private Communications Technology 1.0 client-side (Obsolete).
SP_PROT_PCT1_SERVER | Private Communications Technology 1.0 server-side.(Obsolete).
SP_PROT_SSL2_CLIENT | Secure Sockets Layer 2.0 client-side. Superseded by SP_PROT_TLS1_CLIENT
SP_PROT_SSL2_SERVER | Secure Sockets Layer 2.0 server-side. Superseded by SP_PROT_TLS1_SERVER.

dwMinimumCipherStrength
Minimum bulk encryption cipher strength allowed for connections, in bits.

If this member is zero, Schannel uses the system default. If this member is -1 the SSL3/TLS MAC-only cipher suites (also known as NULL cipher) are enabled.

dwMaximumCipherStrength
Maximum bulk encryption cipher strength allowed for connections, in bits.

If this member is zero, Schannel uses the system default.

dwSessionLifespan
The maximum life span of credentials acquired using this structure.
dwFlags
Contains bit flags that control the behavior of Schannel in Windows 2000. Can be zero or a combination of the following values.
Constant | Restrictions | Description
SCH_CRED_NO_SYSTEM_MAPPER | Windows 2000 server-side only. | Prevent Schannel from using the built-in system certificate mapping functions to map client certificates to a Windows NT/2000 user account .
SCH_CRED_NO_SERVERNAME_CHECK | Windows 2000 client-side only. | Prevent Schannel from comparing the supplied target name with the subject names in server certificates.
SCH_CRED_MANUAL_CRED_VALIDATION | Windows 2000 client-side only. | Prevent Schannel from validating the received server certificate chain.
SCH_CRED_NO_DEFAULT_CREDS | Windows 2000 client-side only. | Prevent Schannel from attempting to automatically supply a certificate chain for client authentication.
SCH_CRED_AUTO_CRED_VALIDATION | Windows 2000 client-side only. | This flag is the opposite of SCH_CRED_MANUAL_CRED_VALIDATION and is part of the default behavior of Schannel.
SCH_CRED_REVOCATION_CHECK_CHAIN | Windows 2000. For additional restrictions, see Remarks. | When validating a certificate chain, check all certificates for revocation.
SCH_CRED_REVOCATION_CHECK_END_CERT | Windows 2000. For additional restrictions, see Remarks. | When validating a certificate chain, check only the last certificate for revocation.
SCH_CRED_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT | Windows 2000. For additional restrictions, see remarks. | When validating a certificate chain, do not check the root for revocation.
SCH_CRED_IGNORE_NO_REVOCATION_CHECK | Windows 2000. For additional restrictions, see Remarks. | When checking for revoked certificates, ignore CRYPT_E_NO_REVOCATION_CHECK errors.
SCH_CRED_IGNORE_REVOCATION_OFFLINE | Windows 2000. For additional restrictions, see remarks. | When checking for revoked certificates, ignore CRYPT_E_REVOCATION_OFFLINE errors.
SCH_CRED_USE_DEFAULT_CREDS | Windows 2000 client-side only. | Schannel attempts to automatically supply a certificate chain for client authentication. Opposite of SCH_CRED_NO_DEFAULT_CREDS.

reserved
Reserved. Must be zero.

Remarks

The following certificate revocation flags are mutually exclusive:

  • SCH_CRED_REVOCATION_CHECK_CHAIN
  • SCH_CRED_REVOCATION_CHECK_END_CERT
  • SCH_CRED_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT

These flags are valid only for Windows 2000 applications. To customize Schannel's certificate revocation error reporting, use the following flags.

  • SCH_CRED_IGNORE_NO_REVOCATION_CHECK
  • SCH_CRED_IGNORE_REVOCATION_OFFLINE

When Schannel checks the revocation status of a certificate chain, these flags instruct it to ignore any CRYPT_E_NO_REVOCATION_CHECK and CRYPT_E_REVOCATION_OFFLINE errors respectively. These flags are ignored if no certificate revocation flag is set.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Schannel.h; include Schnlsp.h.

See Also

QuerySecurityContextToken


SecPkgContext_Authority

[This is preliminary documentation and subject to change.]

The SecPkgContext_Authority structure contains the name of the authenticating authority if one is available. It can be a certification authority (CA) or the name of a server or domain that authenticated the connection. The QueryContextAttributes function uses this structure.

typedef struct _SecPkgContext_Authority {
  SEC_CHAR *    sAuthorityName;
} SecPkgContext_Authority, * PSecPkgContext_Authority;

Members

sAuthorityName
Pointer to a NULL-terminated string containing the name of the authenticating authority, if available.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Unicode: Declared as Unicode and ANSI structures.


SecPkgContext_ConnectionInfo

[This is preliminary documentation and subject to change.]

The SecPkgContext_ConnectionInfo structure contains protocol and cipher information. This structure is used by the QueryContextAttributes function.

typedef struct _SecPkgContext_ConnectionInfo
{
  DWORD    dwProtocol;
  ALG_ID   aiCipher;
  DWORD    dwCipherStrength;
  ALG_ID   aiHash;
  DWORD    dwHashStrength;
  ALG_ID   aiExch;
  DWORD    dwExchStrength;
} SecPkgContext_ConnectionInfo, *PSecPkgContext_ConnectionInfo;

Members

dwProtocol
Protocol used to establish this connection. The following table describes the constants valid for this member.
Constant | Description
SP_PROT_TLS1_CLIENT | Transport Layer Security 1.0 client-side.
SP_PROT_TLS1_SERVER | Transport Layer Security 1.0 server-side.
SP_PROT_SSL3_CLIENT | Secure Sockets Layer 3.0 client-side.
SP_PROT_SSL3_SERVER | Secure Sockets Layer 3.0 server-side.
SS_PROT_PCT1_CLIENT | Private Communications Technology 1.0 client-side (Obsolete).
SP_PROT_PCT1_SERVER | Private Communications Technology 1.0 server-side.(Obsolete).
SP_PROT_SSL2_CLIENT | Secure Sockets Layer 2.0 client-side. Superseded by SP_PROT_TLS1_CLIENT.
SP_PROT_SSL2_SERVER | Secure Sockets Layer 2.0 server-side. Superseded by SP_PROT_TLS1_SERVER.

aiCipher
Algorithm identifier (ALG_ID) for the bulk encryption cipher used by this connection. The following table describes the constants valid for this member.
ALG_ID Constant | Description
CALG_RC2 | RC2 block encryption algorithm
CALG_RC4 | RC4 stream encryption algorithm
CALG_DES | DES encryption algorithm
CALG_SKIPJACK | Skipjack block encryption algorithm (FORTEZZA)
0 (Zero) | No encryption

dwCipherStrength
Strength of the bulk encryption cipher, in bits. Can be one of the following values: 0, 40, 56, 80, 128, or 168.
aiHash
ALG_ID indicating the hash used for generating message authentication codes (MACs). The following table describes the constants valid for this member.
ALG_ID constant | Description
CALG_MD5 | MD5 hashing algorithm.
CALG_SHA. | SHA hashing algorithm.

dwHashStrength
Strength of the hash, in bits: 128 or 160.
aiExch
ALG_ID indicating the key exchange algorithm used to generate the shared master secret. The following table describes the constants valid for this member.
ALG_ID Contant | Description
CALG_RSA_KEYX | RSA key exchange.
CALG_DH_EPHEM | Diffie-Hellman key exchange.
CALG_EXCH_KEA | Fortezza.

dwExchStrength
Strength of the key exchange, in bits. Typically, this member contains one of the following values: 512, 768, 1024, or 2048.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Schannel.h; include Schnlsp.h.


SecPkgContext_IssuerListInfoEx

[This is preliminary documentation and subject to change.]

The SecPkgContext_IssuerListInfoEx structure holds a list of trusted certification authorities (CAs). This structure is used by the Schannel security package QueryContextAttributes function.

typedef struct _SecPkgContext_IssuerListInfoEx
{
  PCERT_NAME_BLOB  aIssuers;
  DWORD            cIssuers;
} SecPkgContext_IssuerListInfoEx, *PSecPkgContext_IssuerListInfoEx;

Members

aIssuers
Pointer to CERT_NAME_BLOB containing a list of the names of CAs that the server trusts.
cIssuers
The number of names in aIssuers.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Schannel.h; include Schnlsp.h.


SecPkgContext_KeyInfo

[This is preliminary documentation and subject to change.]

This structure has been superseded by the SecPkgContext_ConnectionInfo structure.

The SecPkgContext_KeyInfo structure contains information about the session keys used in a security context. The QueryContextAttributes function uses this structure.

typedef struct _SecPkgContext_KeyInfo {
  SEC_CHAR   * sSignatureAlgorithmName;
  SEC_CHAR   * sEncryptAlgorithmName;
  ULONG        KeySize;
  ULONG        SignatureAlgorithm;
  ULONG        EncryptAlgorithm;
} SecPkgContext_KeyInfo, * PSecPkgContext_KeyInfo;

Members

sSignatureAlgorithmName
Pointer to a NULL-terminated string containing the name, if available, of the algorithm used for generating signatures, for example "MD5" or "SHA-2".
sEncryptAlgorithmName
Pointer to a NULL-terminated string containing the name, if available, of the algorithm used for encrypting messages. Reserved for future use.
KeySize
Specifies the size, in bits, of the key used for encrypting messages. Reserved for future use.
SignatureAlgorithm
Specifies the algorithm identifier (ALG_ID) used for generating signatures, if available.
EncryptAlgorithm
Specifies the algorithm identifier (ALG_ID) used for encrypting messages. Reserved for future use.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Sspi.h; include Security.h.
Unicode: Declared as Unicode and ANSI structures.

See Also

QueryContextAttributes


SecPkgContext_ProtoInfo

[This is preliminary documentation and subject to change.]

The SecPkgContext_ProtoInfo structure holds information about the protocol in use. This structure is used by the Schannel security package QueryContextAttributes function.

typedef struct _SecPkgContext_ProtoInfo
{
  SEC_WCHAR SEC_FAR * sProtocolName;
  unsigned long majorVersion;
  unsigned long minorVersion;
} SecPkgContext_ProtoInfo , SEC_FAR * PSecPkgContext_ProtoInfo;

Members

sProtocolName
Pointer to a string containing the name of the protocol.
majorVersion
Major version number.
minorVersion
Minor version number.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Requires Windows Me.
Header: Declared in Schannel.h; include Schnlsp.h.


SecPkgCred_CipherStrengths

[This is preliminary documentation and subject to change.]

The SecPkgCred_CipherStrengths structure holds the minimum and maximum strength permitted for the cipher used by the specified Schannel credential. This structure is used by the QueryCredentialsAttributes function.

typedef struct _SecPkgCred_CipherStrengths
{
  DWORD      dwMinimumCipherStrength;
  DWORD      dwMaximumCipherStrength;
} SecPkgCred_CipherStrengths, *PSecPkgCred_CipherStrengths;

Members

dwMinimumCipherStrength
Minimum cipher strength allowed.
dwMaximumCipherStrength
Maximum cipher strength allowed.

Remarks

For information on setting the cipher strength, see AcquireCredentialsHandle.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Schannel.h; include Schnlsp.h.


SecPkgCred_SupportedAlgs

[This is preliminary documentation and subject to change.]

The SecPkgCred_SupportedAlgs structure contains identifiers for algorithms permitted with a specified Schannel credential. This structure is used by the QueryCredentialsAttributes function.

typedef struct _SecPkgCred_SupportedAlgs
{
  DWORD     cSupportedAlgs;
  ALG_ID *  palgSupportedAlgs;
} SecPkgCred_SupportedAlgs, *PSecPkgCred_SupportedAlgs;

Members

cSupportedAlgs
Number of elements in the palgSupportedAlgs array.
palgSupportedAlgs
Array of algorithm identifiers (ALG_IDs) allowed with a credential.

Remarks

For information on setting the algorithms, see AcquireCredentialsHandle.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Schannel.h; include Schnlsp.h.


SecPkgCred_SupportedProtocols

[This is preliminary documentation and subject to change.]

The SecPkgCred_SupportedProtocols structure indicates the protocols permitted with a specified Schannel credential. This structure is used by the QueryCredentialsAttributes function.

typedef struct _SecPkgCred_SupportedProtocols
{
  DWORD  grbitProtocol;
} SecPkgCred_SupportedProtocols, *PSecPkgCred_SupportedProtocols;

Members

grbitProtocol
Flags representing the protocols supported with this credential. The following table lists the valid values.
Value | Description
SP_PROT_TLS1_CLIENT | Transport Layer Security 1.0 client-side.
SP_PROT_TLS1_SERVER | Transport Layer Security 1.0 server-side.
SP_PROT_SSL3_CLIENT | Secure Sockets Layer 3.0 client-side Superseded by SP_PROT_TLS1_CLIENT.
SP_PROT_SSL3_SERVER | Secure Sockets Layer 3.0 server-side Superseded by SP_PROT_TLS1_SERVER.
SS_PROT_PCT1_CLIENT | Private Communications Technology 1.0 client-side (Obsolete).
SP_PROT_PCT1_SERVER | Private Communications Technology 1.0 server-side.(Obsolete).
SP_PROT_SSL2_CLIENT | Secure Sockets Layer 2.0 client-side. Superseded by SP_PROT_TLS1_CLIENT.
SP_PROT_SSL2_SERVER | Secure Sockets Layer 2.0 server-side. Superseded by SP_PROT_TLS1_SERVER.

Remarks

For information on setting the protocols, see AcquireCredentialsHandle

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Schannel.h; include Schnlsp.h.


Custom Security Packages

Purpose

A security package is an implementation of a protocol for maintaining security on a computer system. A security protocol defines, and a security package implements, mechanisms that safeguard system integrity and privacy, such as:

  • Authenticating logon data provided by a user

  • Managing the credentials of security principals

  • Establishing the authenticity of a client or server

  • Protecting messages exchanged between a client and server

Beginning with the Microsoft® Windows® 2000 operating system, developers can combine these mechanisms in a single package that is fully integrated with the Local Security Authority (LSA).

Developer Audience

This documentation is intended for C/C++ developers and requires a familiarity with security concepts and the Local Security Authority. In particular, this documentation requires a familiarity with the following technologies:

  • Security Support Provider Interface

  • LSA Authentication

Run-time Requirements

Implementing security packages requires Windows 2000 or later.

See Also

LSA Authentication, Security Support Provider Interface

About Custom Security Packages

General information about custom security packages.

Creating Custom Security Packages

Information on implementing custom security packages including installation and registration.

Custom Security Package Reference

Documentation of the functions and structures related to custom security packages.

Feedback

Make error reports and feature requests directly to Microsoft.


About Custom Security Packages

Microsoft® Windows® 2000 provides the custom security package application programmer's interface (API) and a set of Local Security Authority (LSA) functions for implementing new security protocols that are integrated with the Windows 2000 operating system.

Microsoft® Windows NT® 4.0 supports developing custom security support providers (SSPs) that provide noninteractive authentication services and secure message exchange to client/server applications. Windows NT 4.0 also supports the development of custom authentication packages (APs) to provide services for applications that perform interactive authentication. Using the Windows 2000 custom security package API, developers can combine these services in a single package, called a security support provider/authentication package (SSP/AP).

As with Microsoft-provided security packages, custom security package users access interactive authentication services using the LSA Logon functions. Noninteractive authentication and message protection services can be accessed directly using Microsoft Security Support Provider Interface (SSPI).

The security packages deployed in SSP/APs are fully integrated with the LSA. Using the LSA support functions available to custom security packages, developers can implement advanced security features such as token creation, supplemental credentials support, and pass-through authentication. For a list of these support functions, see LSA Functions called by SSP/APs.

The following topics discuss aspects of custom security packages:

  • SSPs versus SSP/APs
  • LSA Mode Versus User Mode


SSPs versus SSP/APs

Security packages are deployed in one of the following types of dynamic-link libraries (DLLs):

  • Security Support Provider (SSP)
  • Security Support Provider/Authentication Package (SSP/AP)

Whether a security package is in an SSP or SSP/AP DLL is determined by the types of security services it provides, and the extent to which it requires integration with the Local Security Authority (LSA). These differences also determine the application programmer's interface (API) implemented in a custom security package.

SSPs

An SSP is a DLL that contains one or more security packages which provide authenticated connection, message integrity, and message encryption services to client/server applications. SSPs implement Microsoft Security Support Provider Interface (SSPI) functions. Applications can access the security packages in an SSP by calling the SSPI functions directly. SSPs are loaded into the client and server processes; they are not integrated with the LSA.

SSP/APs

An SSP/AP is a DLL that contains one or more security packages and can function as an SSP for client/server applications and as an authentication package for logon applications. To function in both of these roles, SSP/APs are loaded into the LSA process space at system startup and can be loaded into client/server application processes as well.

Custom SSP/AP security packages must implement both the functions implemented by authentication packages, and functions implemented by SSP/APs. These function implementations can make use of LSA support functions to offer advanced security features such as token creation, supplemental credentials support, and pass-through authentication.

If a custom SSP/AP security package provides the full range of message integrity and privacy functions, it will also implement the functions implemented by user-mode SSP/APs.


LSA Mode Versus User Mode

When an SSP/AP security package is functioning as an authentication package, it is loaded into the process space of the Local Security Authority (LSA) and is said to be in LSA mode. Logon applications access authentication package functionality using the LSA Logon Functions. Developers can use LSA support functions available only to LSA-mode security packages to implement more sophisticated authentication packages than previously supported.

When a security package provides security services to a client/server application, it is loaded into the client and server processes and is said to be in user mode. Client/server applications access the security package's security support services using Microsoft Security Support Provider Interface (SSPI).

LSA support for SSP/APs includes functions that the LSA-mode and user-mode instances of a security package can use to communicate. Additionally, the user-mode instance of a security package can delegate selected requests for information to the LSA-mode instance of the package.

For details about how security packages are initialized for each mode, see LSA-mode Initialization and User-mode Initialization.


Creating Custom Security Packages

SSP Security Packages

If a custom security support provider (SSP) security package will be used exclusively for client/server security support it can implement the Microsoft Security Support Provider Interface.

The SampSSP sample shipped with the Platform SDK contains a sample SSP security package implementation. If you have installed the Platform SDK samples, SampSSP can be found at:

<PSDKInstallation Dir>\Samples\WinBase\Security\WinNT\SampSSP

Substitute your Platform SDK installation directory for <PSDKInstallation Dir>

SSP/AP Security Packages

Custom security support provider/authentication packages (SSP/APs) contain security packages that function as authentication packages (APs) and security support providers (SSPs). These packages implement separate APIs to support each role.

Because it functions as an AP, a custom SSP/AP security package must provide implementations for all of the functions implemented by authentication packages. For information on implementing the AP functions see Creating Custom Authentication Packages in the Local Security Authority (LSA) Authentication documentation. For information on calling LSA support functions for custom APs, see Using LSA from an Authentication Package.

To provide integrated security support, a custom SSP/AP security package must provide implementations for the functions implemented by SSP/APs. LSA Functions Called by SSP/APs describes the support functions available to the SSP/AP developers that want to interact with the LSA.

SSP/AP security packages, in order to perform as both an AP and an SSP, may execute as part of the operating system and as part of a user application. These two modes of execution are known as LSA mode and user mode, respectively. For details about custom security packages in LSA-mode see LSA-mode Initialization. For details about user-mode, see User-mode Initialization.

If a custom SSP/AP security package offers services for client/server applications it should provide implementations for the functions described in Functions Implemented by User-mode SSP/APs. LSA Functions Called By User-mode SSP/APs describes the support functions available to an SSP/AP executing in a client or server process.

For information on registering an SSP/AP DLL, see Registering SSP/AP DLLs.


LSA Mode Initialization

When the computer system is started, the Local Security Authority (LSA) automatically loads all registered security support provider/authentication package (SSP/AP) DLLs into its process space. The following diagrams illustrate the initialization process.

Note "Kerberos" represents the Microsoft Kerberos SSP/AP, and "My SSP/AP" represents a custom SSP/AP containing two custom security packages.

At startup, the LSA calls the SpLsaModeInitialize function in each SSP/AP in order to obtain pointers to the functions implemented by each security package in the DLL. The function pointers are passed to the LSA in an array of SECPKG_FUNCTION_TABLE structures.

After receiving the set of SECPKG_FUNCTION_TABLE structures, the LSA calls each security package's SpInitialize function. The LSA uses this function call to pass each security package an LSA_SECPKG_FUNCTION_TABLE structure, which contains pointers to the LSA support functions available to security packages. In addition to storing the pointers to the LSA support functions, custom security packages should use their implementation of the SpInitialize function to perform any initialization-related processing.

For a list of the LSA support functions available to LSA-mode security packages, see LSA Functions Called by SSP/APs.

For information on registering an SSP/AP DLL, see Registering SSP/AP DLLs.


User Mode Initialization

Distributed (client/server) applications use security packages to obtain authenticated connections and to exchange messages. The application calls security support provider interface (SSPI) functions which are mapped to functions implemented by SSP/APs, and functions implemented by User-mode SSP/APs. This mapping is done by the security provider DLL (Secur32.dll, or Security.dll) which can be loaded into the client and server processes dynamically, or (as of windows 2000) statically linked using secur32.lib, shipped with the Platform SDK.

Loading the security package into the client or server's process is handled by the system, if the SSP/AP DLL that contains the security package is properly registered.

The server begins the process of obtaining a secure connection with a client by monitoring a port, waiting for a client to send a message. The client begins the process of obtaining a secure connection to the server by calling the SSPI function InitializeSecurityContext. This function is mapped to the custom security package's SpInitLsaModeContext function. SpInitLsaModeContext returns a token to the client, who forwards it to the server.

Upon receiving the token from the client, the server calls the SSPI function AcceptSecurityContext, which is dispatched to the security package's SpAcceptLsaModeContext function. If the SpAcceptLsaModeContext function succeeds and no more processing is required to establish the security context, the function should return STATUS_SUCCESS to the caller. If additional processing is required, the function should return SEC_I_CONTINUE_NEEDED, and return a token to the server. The server forwards the token to the client, who calls InitSecurityContext again.

This calling cycle may be repeated as often as necessary until an authenticated connection is established or fails. During this process, if the SpAcceptLsaModeContext or SpInitLsaModeContext function succeeds and no more processing is required to establish the security context, the function should return STATUS_SUCCESS to the caller. If additional processing is required, the function should return SEC_I_CONTINUE_NEEDED, and return a token to the caller, who is responsible for forwarding it.

The protocol implemented by the security package determines the number of times this cycle is repeated. For example, in security packages that supports three-leg mutual authentication, the calling sequence is as follows:

  1. Client obtains a token by calling InitializeSecurityContext, and sends it to the server. The server calls AcceptSecurityContext the first time, and gets back a reply token which it sends to the client.
  2. The client uses the token received from the server in a second call to InitializeSecurityContext, and gets back a final token. The client sends this token to the server.
  3. The server receives the token generated in leg 2 which it uses in the final call to AcceptSecurityContext.

When the SpAcceptLsaModeContext and SpInitLsaModeContext functions succeed and no more processing is required to establish the security context, the functions should return STATUS_SUCCESS to the caller. Additionally, if the custom security package supports the functions implemented by user-mode SSP/APs, SpAcceptLsaModeContext and SpInitLsaModeContext must return TRUE by way of the MappedContext parameter. The MappedContext value is not passed back to the application; it is intercepted by the LSA.

When MappedContext is true, the LSA calls the SSP/AP DLL's SpUsermodeInitialize function. This function provides tables of pointers to the user-mode functions implemented by each security package. Each package's SpInstanceInit function is called, using the function tables returned by SpUserModeInitialize. SpInstanceInit receives a table of pointers to LSA functions called by user-mode SSP/APs.


Registering SSP/AP DLLs

After developing a security support provider/authentication package dynamic-link library (SSP/AP DLL) containing one or more custom security packages, you must register it. To do so, add the name of your custom SSP/AP DLL to the data of the following registry value:

\HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Security Packages

The data for this registry value is a list of the names of SSP/AP DLLs, without the ".dll" extension. The data type for this list is REG_MULTI_SZ so there must be a null character ('\0') between each DLL name in the list.

Typically, SSP/AP DLLs are stored in the %systemroot%/system32 directory. If this is the path to your custom SSP/AP DLL then do not include the path as part of the DLL name. If, however, the DLL is in a different path, include the complete path to the DLL in the name.

Each time the system boots, the LSA loads the SSP/AP DLLs in this list and performs the initialization sequence described in LSA-Mode Initialization.

Note This registry information pertains to SSP/AP DLL's only. For information about registering security support providers (SSPs), see Writing and Installing a Security Support Provider. For information on the differences between SSP/AP and SSP DLLs, see SSPs Versus SSP/APs.


Custom Security Package Reference

The reference material for custom security packages deployed in Security Support Provider/Authentication Packages (SSP/APs) is divided into the following sections.

Section | Description
Custom Security Package Functions | Functions implemented or called by security packages.
Custom Security Package Structures | Structures used by custom security packages.
Custom Security Package Data Types | Enumerations used by custom security packages.


Custom Security Package Functions

The documentation for functions related to custom security packages deployed in Security Support Provider/Authentication Packages (SSP/APs) is divided into the following sections.

Section | Description
Functions Implemented by SSP/APs | Functions implemented by all SSP/AP security packages.
Functions Implemented by User-mode SSP/APs | Functions implemented by SSP/AP security packages that provide services to client/server applications.
LSA Functions Called by SSP/APs | Functions provided by the LSA to security packages executing in LSA-mode.
LSA Functions Called By User-mode SSP/APs | Functions available to SSP/AP security packages executing in a user-mode process.


Functions Implemented by SSP/APs

The following functions are implemented by security packages contained in Security Support Provider/Authentication Packages (SSP/APs).

In the table below, the first set of functions is implemented by Windows NT 4.0–style authentication packages (APs) as well as by Windows 2000 SSP/AP security packages. The second set of functions is implemented by SSP/AP security packages only.

The LSA accesses these functions using the SECPKG_FUNCTION_TABLE structure provided by the SSP/AP's SpLsaModeInitialize function.

The following functions are implemented by all APs.

Function | Description
LsaApInitializePackage | Initializes an authentication package.
LsaApLogonUser | Logs a user on to a system.
LsaApCallPackage | Processes package-specific service requests.
LsaApLogonTerminated | Processes notifications about terminated logon sessions.
LsaApCallPackageUntrusted | Processes requests for services from processes that are not part of the trusted computing base.
LsaApCallPackagePassthrough | Processes package-specific service requests.
LsaApLogonUserEx | Logs a user on to a system and generates an audit trail.
LsaApLogonUserEx2 | Logs a user on to a system, generates an audit trail, and retrieves credential information.

The following additional functions are implemented by SSP/AP security packages.

Function | Description
SPInitialize | Initializes a security package.
SpShutdown | Performs any cleanup required before the SSP/AP is unloaded.
SpGetInfo | Provides information about a security package.
SpAcceptCredentials | Stores existing credentials information.
SpAcquireCredentialsHandle | Provides a handle to user credentials.
SpQueryCredentialsAttributes | Provides information about the attributes of credentials.
SpFreeCredentialsHandle | Frees a handle to user credentials.
SpSaveCredentials | Saves user credentials.
SpGetCredentials | Retrieves user credentials.
SpDeleteCredentials | Deletes user credentials.
SpInitLsaModeContext | Initializes a security context for client-side processes in a client/server application.
SpAcceptLsaModeContext | Initializes a security context for server-side processes in a client/server application.
SpDeleteContext | Deletes a security context.
SpApplyControlToken | Applies a control token to a security context.
SpGetUserInfo | Retrieves user information.
SpGetExtendedInformation | Retrieves extended information about the security package.
SpQueryContextAttributes | Retrieves the attributes of a security context.
SpAddCredentials | Adds user credentials.
SpSetExtendedInformation | Sets extended information about the security package.


SpAcceptCredentials

The SpAcceptCredentials function is called by the LSA to pass the security package any credentials stored for the authenticated security principal. This function is called once for each set of credentials stored by the LSA.

NTSTATUS SpAcceptCredentials (
  SECURITY_LOGON_TYPE LogonType,
  PUNICODE_STRING AccountName,
  PSECPKG_PRIMARY_CRED PrimaryCredentials,
  PSECPKG_SUPPLEMENTAL_CRED SupplementalCredentials
);

Parameters

LogonType
[in] A SECURITY_LOGON_TYPE value indicating the type of logon.
AccountName
[in] Pointer to a UNICODE_STRING structure specifying the name of the logged-on account.
PrimaryCredentials
[in] Pointer to a SECPKG_PRIMARY_CRED structure containing the credentials used to logon. This structure can have NULL members.
SupplementalCredentials
[in] Pointer to a SECPKG_SUPPLEMENTAL_CRED structure containing package-specific supplemental credentials.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed.

Remarks

The security package should save the credentials so that it can service requests for credentials. For additional information, see the SpAcquireCredentialsHandle function.

SSP/APs must implement the SpAcceptCredentials function; unlike other SSP/AP functions the name of the function must be SpAcceptCredentials.

The LSA accesses the SpAcceptCredentials function through the SECPKG_FUNCTION_TABLE structure received from the SpLsaModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SECPKG_PRIMARY_CRED, SECPKG_SUPPLEMENTAL_CRED, SECURITY_LOGON_TYPE, SpAcquireCredentialsHandle, SpLsaModeInitialize


SpAcceptLsaModeContext

The SpAcceptLsaModeContext function is the server-side dispatch function used to create a security context shared by a server and client.

The SpAcceptLsaModeContext function is called when the server calls the AcceptSecurityContext function of the Security Support Provider Interface.

NTSTATUS <SpAcceptLsaModeContext> (
  LSA_SEC_HANDLE CredentialHandle,
  LSA_SEC_HANDLE ContextHandle,
  PSecBufferDesc InputBuffer,
  ULONG ContextRequirements,
  ULONG TargetDataRep,
  PLSA_SEC_HANDLE NewContextHandle,
  PSecBufferDesc OutputBuffer,
  PULONG ContextAttributes,
  PTimeStamp ExpirationTime,
  PBOOLEAN MappedContext,
  PSecBuffer ContextData
);

Parameters

CredentialHandle
[in] Optional. Handle to the credentials to use for the context.
ContextHandle
[in] Optional. Handle to the current context.
InputBuffer
[in] Pointer to a SecBufferDesc structure containing information from the client.
ContextRequirements
[in] Flags indicating the context requirements. The following table lists the valid values.
Flag | Description
ASC_REQ_DELEGATE | The server is allowed to impersonate the client.
ASC_REQ_MUTUAL_AUTH | Both the client and the server are required to prove their identity.
ASC_REQ_REPLAY_DETECT | The security context will support the detection of replayed packets.
ASC_REQ_SEQUENCE_DETECT | The security context will support the detection of out-of-order messages.
ASC_REQ_USE_SESSION_KEY | A new session key must be negotiated.
ASC_REQ_PROMPT_FOR_CREDS | If the client is an interactive user, the package must, if possible, prompt the user for the appropriate credentials.
ASC_REQ_USE_SUPPLIED_CREDS | The input buffer contains package-specific credential information which should be used to authenticate the connection.
ASC_REQ_ALLOCATE_MEMORY | The package must allocate memory. The caller must eventually call the FreeContextBuffer function to free memory allocated by the security package.
ASC_REQ_USE_DCE_STYLE | The caller expects a three-leg mutual authentication transaction.
ASC_REQ_DATAGRAM | A datagram-type communications channel should be used. For more information, see Datagram Contexts.
ASC_REQ_CONNECTION | A connection-type communications channel should be used. For more information see Connection-Oriented Contexts.
ASC_REQ_EXTENDED_ERROR | If the context fails, generate an error reply message to send back to the client.
ASC_REQ_STREAM | A stream-type communications channel should be used. For more information, see Stream Contexts.
ASC_REQ_INTEGRITY | Buffer integrity can be verified; however, replayed and out-of-sequence messages will not be detected.

TargetDataRep
[in] Flag indicating the data representation, such as byte ordering, to use. Contains SECURITY_NATIVE_DREP or SECURITY_NETWORK_DREP.
NewContextHandle
[out] Pointer to an LSA_SEC_HANDLE. On the first call to AcceptSecurityContext, this pointer receives the new context handle. On subsequent calls, NewContextHandle can be the same as the handle specified in the ContextHandle parameter.
OutputBuffer
[out] Pointer to a SecBufferDesc structure that receives information to be sent to the client.
ContextAttributes
[out] Pointer to flags specifying the context attributes that the server supports. For a list of valid values, see the ContextRequirements parameter.
ExpirationTime
[out] Pointer to a TimeStamp that receives the expiration time for the context.
MappedContext
[out] Pointer to a Boolean value. Set MappedContext to TRUE if the security package implements the user-mode SSP/AP functions.
ContextData
[out] Optional. Pointer to a SecBuffer structure that receives context-specific data to copy when creating the user-mode security context. Memory for ContextData must be allocated using the AllocateLsaHeap function. The LSA will free the memory.

Return Values

If the SpAcceptLsaModeContext function succeeds and no more processing is required to establish the security context, return STATUS_SUCCESS. If additional processing is required, the function should return SEC_I_CONTINUE_NEEDED.

If the function fails to create the security context for any other reason, return an NTSTATUS code indicating the reason.

Remarks

SpInitLsaModeContext is the client-side function for creating a security context.

SSP/APs must implement the SpAcceptLsaModeContext function. The actual name given to the implementation is up to the developer.

A pointer to the SpAcceptLsaModeContext function is available in the SECPKG_FUNCTION_TABLE structure received from the SpLsaModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

AllocateLsaHeap, SpInitLsaModeContext, SpLsaModeInitialize


SpAcquireCredentialsHandle

The SpAcquireCredentialsHandle function is called to obtain a handle to a principal's credentials. The security package can deny access to the caller if the caller does not have permission to access the credentials.

If the credentials handle is returned to the caller, the package should also specify an expiration time for the handle.

NTSTATUS <SpAcquireCredentialsHandle> (
  PUNICODE_STRING PrincipalName,
  ULONG CredentialUseFlags,
  PLUID LogonId,
  PVOID AuthorizationData,
  PVOID GetKeyFunction,
  PVOID GetKeyArgument,
  PLSA_SEC_HANDLE CredentialHandle,
  PTimeStamp ExpirationTime
);

Parameters

PrincipalName
[in] Optional. Pointer to a UNICODE_STRING structure containing the name of the security principal whose credentials are being requested. If this value is NULL, the caller requests a handle to the credentials of the user in whose security context the caller is executing.
CredentialUseFlags
[in] Flags indicating how the credentials will be used. The following values are valid.
Flag | Meaning
SECPKG_CRED_INBOUND | Credentials will be used with the AcceptSecurityContext function.
SECPKG_CRED_OUTBOUND | Credentials will be used with the InitializeSecurityContext function.

LogonId
[in] Optional. Pointer to an LUID containing the logon identifier of the security principal.
AuthorizationData
[in] Optional. Pointer to supplemental authentication data.
GetKeyFunction
[in] Pointer to a function in the caller's address space that generates session keys.
GetKeyArgument
[in] Pointer to the argument used with the GetKeyFunction function.
CredentialHandle
[out] Pointer to an LSA_SEC_HANDLE that receives the credentials.
ExpirationTime
[out] Pointer to a TimeStamp that receives the time the credentials handle expires.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed. The following table lists common reasons for failure and the error codes that should be returned.

Reason | Error code
The caller is denied access. | SEC_E_NOT_OWNER
There are no credentials available for the specified principal. | SEC_E_NO_CREDENTIALS

Remarks

The package can use the LSA support functions to determine whether the caller should be given access to the requested credentials.

Credentials obtained from SpAcquireCredentialsHandle are freed by calling the SpFreeCredentialsHandle function.

SSP/APs must implement the SpAcquireCredentialsHandle function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpAcquireCredentialsHandle function is available in the SECPKG_FUNCTION_TABLE structure received from the SpLsaModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SECPKG_FUNCTION_TABLE, SpFreeCredentialsHandle, SpLsaModeInitialize


SpAddCredentials

The SpAddCredentials function is used to add credentials for a security principal.

NTSTATUS <SpAddCredentials> (
  LSA_SEC_HANDLE CredentialHandle,
  PUNICODE_STRING PrincipalName,
  PUNICODE_STRING Package,
  ULONG CredentialUseFlags,
  PVOID AuthorizationData,
  PVOID GetKeyFunction,
  PVOID GetKeyArgument,
  PTimeStamp ExpirationTime
);

Parameters

CredentialHandle
[in] A handle to the credential to add.
PrincipalName
[in] Optional. Pointer to a UNICODE_STRING structure containing the name of the security principal whose credentials are being added.
Package
[in] Pointer to a UNICODE_STRING structure containing the name of the authenticating package.
CredentialUseFlags
[in] Flags indicating how the credentials will be used. The following values are valid.
Flag | Meaning
SECPKG_CRED_INBOUND | Credentials will be used with the AcceptSecurityContext function.
SECPKG_CRED_OUTBOUND | Credentials will be used with the InitializeSecurityContext function.

AuthorizationData
[in] Optional. Pointer to supplemental authentication data.
GetKeyFunction
[in] Pointer to a function in the caller's address space that generates session keys.
GetKeyArgument
[in] Pointer to the argument used with the GetKeyFunction function.
ExpirationTime
[out] Pointer to a TimeStamp that receives the time the credentials handle expires.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed.

Remarks

SSP/APs must implement the SpAddCredentials function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpAddCredentials function is available in the SECPKG_FUNCTION_TABLE structure received from the SpLsaModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SECPKG_FUNCTION_TABLE, SpLsaModeInitialize


SpApplyControlToken

The SpApplyControlToken function applies a control token to a security context. This function is not currently called by the LSA.

NTSTATUS <SpApplyControlToken> (
  LSA_SEC_HANDLE ContextHandle,
  PSecBufferDesc ControlToken
);

Parameters

ContextHandle
[in] Handle to the security context to be modified based on the ControlToken parameter.
ControlToken
[in] Pointer to a SecBufferDesc structure containing the token to apply to the context.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed. The following table lists common reasons for failure and the error codes that the function should return.

Reason | Error code
The token is invalid. | SEC_E_INVALID_TOKEN
The handle is invalid. | SEC_E_INVALID_HANDLE

Remarks

SSP/APs must implement the SpApplyControlToken function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpApplyControlToken function is available in the SECPKG_FUNCTION_TABLE structure received from the SpLsaModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SECPKG_FUNCTION_TABLE, SpLsaModeInitialize


SpDeleteContext

The SpDeleteContext function deletes a security context.

NTSTATUS  <SpDeleteContext> (
  LSA_SEC_HANDLE ContextHandle
);

Parameters

ContextHandle
[in] Handle to the security context to delete.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed. The following table lists a common reason for failure and the error code that the function should return.

Reason | Error code
The handle is invalid. | SEC_E_INVALID_HANDLE

Remarks

SSP/APs must implement the SpDeleteContext function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpDeleteContext function is available in the SECPKG_FUNCTION_TABLE structure received from the SpLsaModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SECPKG_FUNCTION_TABLE, SpLsaModeInitialize


SpDeleteCredentials

The SpDeleteCredentials function deletes credentials from a security package's list of primary or supplemental credentials.

NTSTATUS <SpDeleteCredentials> (
  LSA_SEC_HANDLE CredentialHandle,
  PSecBuffer Key
);

Parameters

CredentialHandle
[in] Handle to the credentials to delete.
Key
[in] Pointer to a SecBuffer structure whose contents indicate which credentials to delete. The information stored in the Key parameter is package specific.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed.

Remarks

SSP/APs must implement the SpDeleteCredentials function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpDeleteCredentials function is available in the SECPKG_FUNCTION_TABLE structure received from the SpLsaModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SECPKG_FUNCTION_TABLE, SecBuffer, SpLsaModeInitialize


SpFreeCredentialsHandle

The SpFreeCredentialsHandle function frees credentials acquired by calling the SpAcquireCredentialsHandle function.

NTSTATUS <SpFreeCredentialsHandle> (
  LSA_SEC_HANDLE CredentialHandle
);

Parameters

CredentialHandle
[in] Handle to the credentials to free.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed. The following table lists a common reason for failure and the error code that the function should return.

Reason | Error code
The handle is invalid. | SEC_E_INVALID_HANDLE

Remarks

SSP/APs must implement the SpFreeCredentialsHandle function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpFreeCredentialsHandle function is available in the SECPKG_FUNCTION_TABLE structure received from the SpLsaModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SECPKG_FUNCTION_TABLE, SpAcquireCredentialsHandle, SpLsaModeInitialize


SpGetCredentials

The SpGetCredentials function retrieves the primary and supplemental credentials from the user object.

NTSTATUS <SpGetCredentials> (
  LSA_SEC_HANDLE CredentialHandle,
  PSecBuffer Credentials
);

Parameters

CredentialHandle
[in] Handle to the credentials to be retrieved.
Credentials
[out] Pointer to a SecBuffer structure that receives the credentials.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed. The following table lists common reasons for failure and the error codes that the function should return.

Reason | Error code
There is not sufficient memory to retrieve the credentials. | SEC_E_INSUFFICIENT MEMORY
The handle is invalid. | SEC_E_INVALID_HANDLE

Remarks

SSP/APs must implement the SpGetCredentials function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpGetCredentials function is available in the SECPKG_FUNCTION_TABLE structure received from the SpLsaModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SECPKG_FUNCTION_TABLE, SpLsaModeInitialize


SpGetExtendedInformation

The SpGetExtendedInformation function provides extended information about a security package.

NTSTATUS  <SpGetExtendedInformation>(
  SECPKG_EXTENDED_INFORMATION_CLASS Class,
  PSECPKG_EXTENDED_INFORMATION *ppInformation
);

Parameters

Class
[in] A value from the SECPKG_EXTENDED_INFORMATION_CLASS enumeration indicating the type of extended information.
ppInformation
[out] Pointer to a pointer to a SECPKG_EXTENDED_INFORMATION structure allocated by the security package. If the function call succeeds, the returned structure contains the requested information.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed.

Remarks

Extended information is set using the SpSetExtendedInformation function.

An SSP/AP must implement the SpGetExtendedInformation function; however, the actual name given to the implementation is up to the package developer.

A pointer to the SpGetExtendedInformation function is available in the SECPKG_FUNCTION_TABLE structure received from the SpLsaModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SECPKG_EXTENDED_INFORMATION, SECPKG_EXTENDED_INFORMATION_CLASS, SECPKG_FUNCTION_TABLE, SecPkgInfo, SpLsaModeInitialize, SpSetExtendedInformation


SpGetInfo

The SpGetInfo function provides general information about the security package, such as its name and capabilities.

The SpGetInfo function is called when the client calls the QuerySecurityPackageInfo function of the Security Support Provider Interface.

NTSTATUS <SpGetInfo> (
  PSecPkgInfo PackageInfo
);

Parameters

PackageInfo
[out] Pointer to a SecPkgInfo structure that is allocated by the LSA and must be populated by the package.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed.

Remarks

It is safe to place pointers to constant or dynamic data into the SecPkgInfo structure—the LSA will make a copy of the data prior to forwarding it.

SSP/APs must implement the SpGetInfo function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpGetInfo function is available in the SECPKG_FUNCTION_TABLE structure received from the SpLsaModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SECPKG_FUNCTION_TABLE, SecPkgInfo, SpLsaModeInitialize


SpGetUserInfo

The SpGetUserInfo function retrieves information about a logon session.

NTSTATUS <SpGetUserInfo> (
  PLUID LogonId,
  ULONG Flags,
  PSecurityUserData *UserData
);

Parameters

LogonId
[in] Pointer to an LUID containing the logon session for which information is to be retrieved.
Flags
[in] Specifies the acceptable length of the domain name as one of the following values.
Flag value | Description
NO_LONG_NAMES | The returned domain name cannot be longer than 15 characters.
UNDERSTANDS_LONG_NAMES | The returned domain name can be longer than 15 characters.

UserData
[out] Pointer to a pointer to a SecurityUserData structure. If the function call succeeds, the user information is returned in this structure. The security package should allocate the memory for this structure in the caller's address space. The caller is responsible for freeing the buffer by calling the FreeContextBuffer function.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed.

Remarks

The Flags value NO_LONG_NAMES provides compatibility with Microsoft NTLM.

SSP/APs must implement the SpGetUserInfo function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpGetUserInfo function is available in the SECPKG_FUNCTION_TABLE structure received from the SpLsaModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

FreeContextBuffer, SECPKG_FUNCTION_TABLE, SpLsaModeInitialize


SpInitialize

The SpInitialize function is called once by the LSA to provide a security package with general security information and a dispatch table of support functions. The security package should save the information and do internal initialization processing, if any is needed.

NTSTATUS <SpInitialize> (
  ULONG_PTR PackageId,
  PSECPKG_PARAMETERS Parameters,
  PLSA_SECPKG_FUNCTION_TABLE FunctionTable
);

Parameters

PackageId
[in] A unique identifier the LSA assigns to each security package. The value is valid until the system is restarted.
Parameters
[in] A pointer to a SECPKG_PARAMETERS structure containing primary domain and machine state information.
FunctionTable
[in] Pointer to a table of LSA support functions that a security package can call.

Return Values

If the function succeeds, return STATUS_SUCCESS, or an informational status code.

If the function fails, return an NTSTATUS error code indicating the reason it failed. For more information, see Remarks.

Remarks

If SpInitialize returns an NTSTATUS error code to the LSA, the package will be unloaded, and the LSA will not include it in the list of available security packages.

SSP/APs must implement the SpInitialize function; however, the actual name given to the implementation is up to the developer.

A pointer to the SSP/AP's implementation of the SpInitialize function must be in the SECPKG_FUNCTION_TABLE structure passed to the LSA from the SpLsaModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SECPKG_FUNCTION_TABLE, SECPKG_PARAMETERS, SpLsaModeInitialize


SpInitLsaModeContext

The SpInitLsaModeContext function is the client-side dispatch function used to establish a security context between a server and client.

The SpInitLsaModeContext function is called when the client calls the InitializeSecurityContext function of the Security Support Provider Interface.

NTSTATUS  <SpInitLsaModeContext> (
  LSA_SEC_HANDLE CredentialHandle,
  LSA_SEC_HANDLE ContextHandle,
  PUNICODE_STRING TargetName,
  ULONG ContextRequirements,
  ULONG TargetDataRep,
  PSecBufferDesc InputBuffers,
  PLSA_SEC_HANDLE NewContextHandle,
  PSecBufferDesc OutputBuffers,
  PULONG ContextAttributes,
  PTimeStamp ExpirationTime,
  PBOOLEAN MappedContext,
  PSecBuffer ContextData
);

Parameters

CredentialHandle
[in] Optional. Handle to the credentials to use for the context. CredentialHandle can be NULL if the ContextHandle parameter is not NULL.
ContextHandle
[in] Optional. Handle to the context to use as the basis for this context. ContextHandle can be NULL if the CredentialHandle parameter is not NULL.
TargetName
[in] Optional. Pointer to a UNICODE_STRING containing the name of the target of the context. The content of TargetName is package-specific and is not interpreted by the LSA.
ContextRequirements
[in] Flags indicating the context attributes required by the client. The actual context attributes are returned in the ContextAttributes parameter.

The following table lists the valid values.
Flag | Description
ISC_REQ_DELEGATE | The server is allowed to impersonate the client.
ISC_REQ_MUTUAL_AUTH | Both the client and the server are required to prove their identity.
ISC_REQ_REPLAY_DETECT | The security context will support the detection of replayed packets.
ISC_REQ_SEQUENCE_DETECT | The security context will support the detection of out-of-order messages.
ISC_REQ_USE_SESSION_KEY | A new session key must be negotiated.
ISC_REQ_PROMPT_FOR_CREDS | If the client is an interactive user, the package must, if possible, prompt the user for the appropriate credentials.
ISC_REQ_USE_SUPPLIED_CREDS | The input buffer contains package-specific credential information which should be used to authenticate the connection.
ISC_REQ_ALLOCATE_MEMORY | The package must allocate memory. The caller must eventually call the FreeContextBuffer function to free memory allocated by the package.
ISC_REQ_USE_DCE_STYLE | The caller expects a three-leg mutual authentication transaction.
ISC_REQ_DATAGRAM | A datagram-type communications channel should be used. For more information, see Datagram Contexts.
ISC_REQ_CONNECTION | A connection-type communications channel should be used. For more information see Connection-oriented Contexts.
ISC_REQ_EXTENDED_ERROR | If the context fails, generate an error reply message to send back to the client.
ISC_REQ_STREAM | A stream-type communications channel should be used. For more information, see Stream Contexts.
ISC_REQ_INTEGRITY | Buffer integrity is verified; however, replayed and out-of-sequence messages will not be detected.

TargetDataRep
[in] Flag indicating the data representation, such as byte ordering, on the target. Contains SECURITY_NATIVE_DREP or SECURITY_NETWORK_DREP.
InputBuffers
[in] Pointer to a SecBufferDesc structure containing the previous reply message from the server. The first time this function is called the InputBuffers parameter is NULL.
NewContextHandle
[out] Pointer that receives a handle to the new security context.
OutputBuffers
[out] Pointer to a SecBufferDesc structure containing the security token to pass back to the server.
ContextAttributes
[out] Pointer to flags specifying the attributes of the new context. The client requests a set of attributes using the ContextRequirements parameter. If the ContextRequirements flags do not match the ContextAttributes flags, the client must decide whether to continue or terminate. For a complete list of the valid flags, see Context Requirements.
ExpirationTime
[out] Pointer to a TimeStamp that receives the expiration time for the new context.
MappedContext
[out] Pointer to a Boolean value. Set MappedContext to TRUE if the security package implements the user-mode SSP/AP functions.
ContextData
[out] Pointer to a SecBuffer structure that receives the data to copy when creating a user-mode security context. Allocate memory for ContextData using the AllocateLsaHeap function. The LSA will free the memory.

Return Values

If the function succeeds and no more processing is required, return STATUS_SUCCESS. If processing is not complete the function should return SEC_I_CONTINUE_NEEDED. When this value is returned, the caller must call the InitializeSecurityContext function again.

If the function fails to create the security context for any other reason, it should return an NTSTATUS code indicating the reason it failed.

Remarks

The SpAcceptLsaModeContext function is the server-side function for creating a context.

SSP/APs must implement the SpInitLsaModeContext function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpInitLsaModeContext function is available in the SECPKG_FUNCTION_TABLE structure received from the SpLsaModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

AllocateLsaHeap, InitializeSecurityContext, SECPKG_FUNCTION_TABLE , SpAcceptLsaModeContext, SpLsaModeInitialize, TimeStamp


SpLsaModeInitialize

The SpLsaModeInitialize function is called once by the LSA for each registered security support provider/authentication package (SSP/AP) DLL it loads. This function provides the LSA with pointers to the functions implemented by each security package in the SSP/AP DLL.

NTSTATUS NTAPI SpLsaModeInitialize (
  ULONG LsaVersion,
  PULONG PackageVersion,
  PSECPKG_FUNCTION_TABLE *ppTables,
  PULONG pcTables
);

Parameters

LsaVersion
[in] The version of the LSA.
PackageVersion
[out] Pointer to a ULONG that returns the SSP/AP DLL version number.
ppTables
[out] Pointer to an array of SECPKG_FUNCTION_TABLE structures. Each structure is a table of pointers to the functions implemented by a security package deployed in the SSP/AP DLL.
pcTables
[out] Pointer that returns the number of elements in the array pointed to by the ppTables parameter.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed.

Remarks

The SpLsaModeInitialize function must be implemented by SSP/AP DLLs.

The ppTables parameter should contain one SECPKG_FUNCTION_TABLE for each security package deployed in the DLL.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SECPKG_FUNCTION_TABLE


SpQueryContextAttributes

The SpQueryContextAttributes function retrieves the attributes of a security context.

The SpQueryContextAttributes function is the dispatch function for the QueryContextAttributes function of the Security Support Provider Interface.

NTSTATUS <SpQueryContextAttributes> (
  LSA_SEC_HANDLE ContextHandle,
  ULONG ContextAttribute,
  PVOID Buffer
);

Parameters

ContextHandle
[in] Handle to the security context.
ContextAttribute
[in] Context attribute to query. For a list of valid values, see the QueryContextAttributes function.
Buffer
[out] Pointer that receives the address of a buffer containing the requested attributes. Memory for the Buffer parameter should be allocated with the AllocateHeap function from the SECPKG_DLL_FUNCTIONS function table in user-mode. In LSA-mode use the AllocateLsaHeap function.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed. The following table lists a common reason for failure and the error code that the function should return.

Reason | Error code
The handle is invalid. | SEC_E_INVALID_HANDLE

Remarks

SSP/APs must implement the SpQueryContextAttributes function; however, the actual name given to the implementation is up to the developer.

A pointer to the LSA-mode implementation of the SpQueryContextAttributes function is available in the SECPKG_FUNCTION_TABLE structure received from the SpLsaModeInitialize function.

A pointer to the user-mode implementation of the SpQueryContextAttributes function is available in the SECPKG_USER_FUNCTION_TABLE structure received from the SpUserModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SECPKG_FUNCTION_TABLE, SpLsaModeInitialize


SpQueryCredentialsAttributes

The SpQueryCredentialsAttributes function retrieves the attributes for a credential.

The SpQueryCredentialsAttributes function is the dispatch function for the QueryCredentialsAttributes function of the Security Support Provider Interface.

NTSTATUS <SpQueryCredentialsAttributes> (
  LSA_SEC_HANDLE CredentialHandle,
  ULONG CredentialAttribute,
  PVOID Buffer
);

Parameters

CredentialHandle
[in] Handle to the credential to query.
CredentialAttribute
[in] Attribute to query. The following table lists the valid values.
Attribute | Description
SECPKG_CRED_ATTR_NAMES | The name of the principal associated with the credentials.
SECPKG_ATTR_SUPPORTED_ALGS | The algorithms supported with a particular credential.
SECPKG_ATTR_CIPHER_STRENGTHS | The minimum and maximum cipher strength used with a credential.
SECPKG_ATTR_SUPPORTED_PROTOCOLS | The protocols supported with a particular credential.

Buffer
[out] Pointer to a buffer that receives the requested attributes. Allocate memory for this buffer using the AllocateClientBuffer function, so that caller can free it by calling the FreeContextBuffer function.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed. The following table lists common reasons for failure and the error codes that the function should return.

Reason | Error code
Memory allocation failed. | SEC_E_INSUFFICIENT_MEMORY
The credential handle is invalid. | SEC_E_INVALID_HANDLE

Remarks

SSP/APs must implement the SpQueryCredentialsAttributes function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpQueryCredentialsAttributes function is available in the SECPKG_FUNCTION_TABLE structure received from the SpLsaModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SECPKG_FUNCTION_TABLE, SpLsaModeInitialize


SpSaveCredentials

The SpSaveCredentials function is used to save a supplemental credential to the user object.

NTSTATUS <SpSaveCredentials> (
  LSA_SEC_HANDLE CredentialHandle,
  PSecBuffer Credentials
);

Parameters

CredentialHandle
[in] Handle to the credential to save.
Credentials
[in] Pointer to a SecBuffer structure containing the credential information to be saved.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed.

Remarks

SSP/APs must implement the SpSaveCredentials function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpSaveCredentials function is available in the SECPKG_FUNCTION_TABLE structure received from the SpLsaModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SECPKG_FUNCTION_TABLE, SpLsaModeInitialize, SpMarshallSupplementalCreds


SpSetExtendedInformation

The SpSetExtendedInformation function is used to set extended information about the security package.

NTSTATUS <SpSetExtendedInformation> (
  SECPKG_EXTENDED_INFORMATION_CLASS Class,
  PSECPKG_EXTENDED_INFORMATION Info
);

Parameters

Class
[in] A SECPKG_EXTENDED_INFORMATION_CLASS enumeration value indicating the type of extended information.
Info
[in] Pointer to a SECPKG_EXTENDED_INFORMATION structure containing the extended information set.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed.

Remarks

To retrieve extended information, the SpGetExtendedInformation function is called.

An SSP/AP must implement the SpSetExtendedInformation function; however, the actual name given to the implementation is up to the package developer.

A pointer to the SpSetExtendedInformation function is available in the SECPKG_FUNCTION_TABLE structure received from the SpLsaModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SECPKG_EXTENDED_INFORMATION, SECPKG_EXTENDED_INFORMATION_CLASS, SECPKG_FUNCTION_TABLE, SecPkgInfo, SpGetExtendedInformation, SpLsaModeInitialize


SpShutDown

The SpShutDown function is called by the LSA before the security support provider/authentication package (SSP/AP) is unloaded. The implementation of this function should release any allocated resources, such as credentials.

NTSTATUS <SpShutdown> (
  VOID
);

Parameters

This function has no parameters.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed.

Remarks

SSP/APs must implement the SpShutDown function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpShutDown function is available in the SECPKG_FUNCTION_TABLE structure received from the SpLsaModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SECPKG_FUNCTION_TABLE, SpLsaModeInitialize


Functions Implemented by User-mode SSP/APs

The following functions are implemented by security support provider/authentication packages (SSP/APs) that can be loaded into client/server applications.

An SSP/AP indicates that it implements the user-mode functions by returning TRUE in the MappedContext parameter of the SpInitLsaModeContext and SpAcceptLsaModeContext functions. The SpInitLsaModeContext function is used by the client side of a transport level application, while SpAcceptLsaModeContext is used by the server side.

Loading an SSP/AP into the client process or server process is handled by the security provider DLL, either Security.dll or Secur32.dll. The security provider DLL loads the SSP/AP by locating the address of the SpUserModeInitialize function implemented by the SSP/AP and calling it. This function returns a set of tables containing pointers to the user-mode functions implemented in each security package.

After the SSP/AP is loaded into the client or server process, the LSA will copy the security context information (returned by SpInitLsaModeContext or SpAcceptLsaModeContext) and any additional context-related data to the process and call the security package's SpInitUserModeContext function.

Client/server applications access user-mode functionality by calling Security Support Provider Interface (SSPI) functions. The SSPI functions are mapped by the security provider DLL using the SECPKG_USER_FUNCTION_TABLE supplied by the package.

Function | Description
SpInstanceInit | Initializes user-mode security packages in an SSP/AP.
SpInitUserModeContext | Creates a user-mode security context.
SpMakeSignature | Creates a signature for a message. Implements the SSPI MakeSignature function.
SpVerifySignature | Validates the signature of a message. Implements the SSPI VerifySignature function.
SpSealMessage | Encrypts a message. Implements the SSPI EncryptMessage function.
SpUnsealMessage | Decrypts a message. Implements the SSPI DecryptMessage function.
SpGetContextToken | Retrieves a context token. Used by the SSPI ImpersonateSecurityContext function.
SpQueryContextAttributes | Retrieves the attributes of a security context. Implements the SSPI QueryContextAttributes function.
SpCompleteAuthToken | Completes an authentication token. Implements the SSPI CompleteAuthToken function.
SpDeleteContext | Deletes a security context. Implements the SSPI DeleteSecurityContext function.
SpFormatCredentials | Formats credentials.
SpMarshallSupplementalCreds | Serializes credentials.
SpExportSecurityContext | Exports a security context. Implements the SSPI ExportSecurityContext function.
SpImportSecurityContext | Imports a security context. Implements the SSPI ImportSecurityContext function.
SpUserModeInitialize | Called when an SSP/AP is loaded into an application's process space. This function provides the SECPKG_USER_FUNCTION_TABLE tables for each security package in the SSP/AP DLL.


SpCompleteAuthToken

The SpCompleteAuthToken function completes an authentication token.

The SpCompleteAuthToken function is the dispatch function for the CompleteAuthToken function of the Security Support Provider Interface.

NTSTATUS <SpCompleteAuthToken> (
  LSA_SEC_HANDLE ContextHandle,
  PSecBufferDesc InputBuffer
);

Parameters

ContextHandle
[in] Handle of the context to complete.
InputBuffer
[in] Pointer to a SecBufferDesc structure that contains package-specific information for the context.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed. The following table lists a common reason for failure and the error code that the function should return.

Reason | Error code
The handle is invalid. | SEC_E_INVALID_HANDLE

Remarks

SSP/APs must implement the SpCompleteAuthToken function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpCompleteAuthToken function is available in the SECPKG_USER_FUNCTION_TABLE structure received from the SpUserModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

CompleteAuthToken, SECPKG_USER_FUNCTION_TABLE, SpUserModeInitialize


SpExportSecurityContext

The SpExportSecurityContext function exports a security context to another process.

The SpExportSecurityContext function is the dispatch function for the ExportSecurityContext function of the Security Support Provider Interface.

NTSTATUS <SpExportSecurityContext>(
  LSA_SEC_HANDLE phContext,
  ULONG fFlags,
  PSecBuffer pPackedContext,
  PHANDLE pToken
);

Parameters

phContext
[in] Handle to the security context to export.
fFlags
[in] Optional. Specifies context duplication options. The following table lists the valid values which are defined in Sspi.h.
Value | Meaning
SECPKG_CONTEXT_EXPORT_RESET_NEW | New context is reset to initial state.
SECPKG_CONTEXT_EXPORT_DELETE_OLD | Old context is deleted during export.

pPackedContext
[out] Pointer to a SecBuffer structure containing the serialized context. Resources should be allocated using the AllocateClientBuffer function, and freed by the caller using the FreeContextBuffer function.
pToken
[out] Optional. Pointer to a handle that receives the context's token.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed.

Remarks

To import a previously exported security context use the SpImportSecurityContext function.

SSP/APs must implement the SpExportSecurityContext function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpExportSecurityContext function is available in the SECPKG_USER_FUNCTION_TABLE structure received from the SpUserModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SECPKG_USER_FUNCTION_TABLE, SpImportSecurityContext, SpUserModeInitialize


SpFormatCredentials

The SpFormatCredentials function formats credentials to be stored in a user object.

NTSTATUS <SpFormatCredentials> (
 PSecBuffer Credentials,
 PSecBuffer FormattedCredentials
);

Parameters

Credentials
[in] Pointer to a SecBuffer structure containing the credentials to be formatted.
FormattedCredentials
[out] Pointer to a SecBuffer structure containing the formatted credentials. Allocate memory for the structure using the AllocateHeap function.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed.

Remarks

SSP/APs must implement the SpFormatCredentials function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpFormatCredentials function is available in the SECPKG_USER_FUNCTION_TABLE structure received from the SpUserModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

AllocateHeap, SECPKG_USER_FUNCTION_TABLE, SpUserModeInitialize


SpGetContextToken

The SpGetContextToken function is used by the SSPI ImpersonateSecurityContext function to obtain the token to impersonate.

NTSTATUS <SpGetContextToken> (
  LSA_SEC_HANDLE ContextHandle,
  PHANDLE ImpersonationToken
);

Parameters

ContextHandle
[in] Handle to the context to impersonate.
ImpersonationToken
[out] Pointer that receives a handle to the token for the specified context. Return the handle to the token without first duplicating the handle or the token.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed. The following table lists a common reason for failure and the error code that the function should return.

Reason | Error code
The handle is invalid. | SEC_E_INVALID_HANDLE

Remarks

SSP/APs must implement the SpGetContextToken function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpGetContextToken function is available in the SECPKG_USER_FUNCTION_TABLE structure received from the SpUserModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

ImpersonateSecurityContext, SECPKG_USER_FUNCTION_TABLE, SpUserModeInitialize


SpImportSecurityContext

The SpImportSecurityContext function imports a security context from another process.

The SpImportSecurityContext function is the dispatch function for the ImportSecurityContext function of the Security Support Provider Interface.

NTSTATUS <SpImportSecurityContext> (
  PSecBuffer pPackedContext,
  HANDLE Token,
  PLSA_SEC_HANDLE phContext
);

Parameters

pPackedContext
[in] Pointer to a SecBuffer structure containing a serialized security context previously generated by the SpExportSecurityContext function.
Token
[in] Optional. Handle to the context token.
phContext
[out] Pointer to an LSA_SEC_HANDLE that receives the imported context handle.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed.

Remarks

SSP/APs must implement the SpImportSecurityContext function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpImportSecurityContext function is available in the SECPKG_USER_FUNCTION_TABLE structure received from the SpUserModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SECPKG_USER_FUNCTION_TABLE, SpExportSecurityContext, SpUserModeInitialize


SpInitUserModeContext

The SpInitUserModeContext function creates a user-mode security context from a packed LSA-mode context.

NTSTATUS <SpInitUserModeContext> (
  LSA_SEC_HANDLE ContextHandle,
  PSecBuffer PackedContext
);

Parameters

ContextHandle
[in] Handle to the LSA-mode context returned from the SpInitLsaModeContext or SpAcceptLsaModeContext function.
PackedContext
[in] Pointer to a SecBuffer structure that contains the serialized context data. Use the FreeContextBuffer function to free memory allocated for this structure.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed. The following table lists a common reason for failure and the error code that the function should return.

Reason | Error Code
Insufficient memory to create the context. | STATUS_INSUFFICIENT_RESOURCES

Remarks

The SpInitUserModeContext function is called after a security context has been created by the security package, if the MappedContext parameter of the SpInitLsaModeContext or SpAcceptLsaModeContext is set to TRUE. The package-specific context data should contain the information required to determine which function resulted in the call to SpInitUserModeContext.

SSP/APs must implement the SpInitUserModeContext function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpInitUserModeContext function is available in the SECPKG_USER_FUNCTION_TABLE structure received from the SpUserModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SECPKG_USER_FUNCTION_TABLE, SpAcceptLsaModeContext, SpInitLsaModeContext, SpUserModeInitialize


SpInstanceInit

The SpInstanceInit function is called once for each security package contained in an SSP/AP, when the SSP/AP is loaded into a client/server process. Security packages should use this function to perform any user mode-specific initialization.

NTSTATUS <SpInstanceInit> (
  ULONG Version,
  PSECPKG_DLL_FUNCTIONS FunctionTable,
  PVOID *UserFunctions
);

Parameters

Version
[in] The version of the LSA.
FunctionTable
[in] Pointer to a SECPKG_DLL_FUNCTIONS structure containing the support functions that the security package can use in user-mode.
UserFunctions
[out] Pointer that receives the address of a table of user-mode functions supported by the security package.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed.

Remarks

The SpInstanceInit function is called once when the SSP/AP is loaded into the user-mode process, after the SpUserModeInitialize function is called.

SSP/APs must implement the SpInstanceInit function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpInstanceInit function is available in the SECPKG_USER_FUNCTION_TABLE structure received from the SpUserModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SECPKG_USER_FUNCTION_TABLE, SpUserModeInitialize


SpMakeSignature

The SpMakeSignature function generates a signature based on the specified message and security context.

The SpMakeSignature function is the dispatch function for the MakeSignature function of the Security Support Provider Interface.

NTSTATUS <SpMakeSignature> (
  LSA_SEC_HANDLE ContextHandle,
  ULONG QualityOfProtection,
  PSecBufferDesc MessageBuffers,
  ULONG MessageSequenceNumber
);

Parameters

ContextHandle
[in] Handle to the security context to be used to generate the message signature.
QualityOfProtection
[in] Specifies package-specific flags that indicate the quality of protection. A security package can use this parameter to support the selection of cryptographic algorithms.
MessageBuffers
[in, out] Pointer to an array of SecBuffer structures. On input, the structures contain the message to be signed. On output, the SecBuffer structure of type SECBUFFER_TOKEN contains the signature.
MessageSequenceNumber
[in] Optional. Sequence number to assign to the message. Sequence numbers are optional and are used as protection against loss and insertion of messages.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed. The following table lists a common reason for failure and the error code that the function should return.

Reason | Error code
The handle is invalid. | SEC_E_INVALID_HANDLE

Remarks

The counter-part to the SpMakeSignature function is the SpVerifySignature function, used to verify signatures at the receiving end.

SSP/APs must implement the SpMakeSignature function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpMakeSignature function is available in the SECPKG_USER_FUNCTION_TABLE structure received from the SpUserModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

MakeSignature, SECPKG_USER_FUNCTION_TABLE, SpUserModeInitialize, SpVerifySignature


SpMarshallSupplementalCreds

The SpMarshallSupplementalCreds function converts supplemental credentials from a public format into a format suitable for local procedure calls.

NTSTATUS <SpMarshallSupplementalCreds> (
  ULONG CredentialSize,
  PUCHAR Credentials,
  PULONG MarshalledCredSize,
  PVOID *MarshalledCreds
);

Parameters

CredentialSize
[in] Specifies the size of the supplemental credentials.
Credentials
[in] Pointer to the supplemental credentials.
MarshalledCredSize
[out] Pointer to the size of the MarshalledCreds buffer.
MarshalledCreds
[out] Pointer that receives the address of the buffer containing the serialized credentials. Allocate the memory for this buffer by calling the AllocateHeap function.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed.

Remarks

SSP/APs must implement the SpMarshallSupplementalCreds function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpMarshallSupplementalCreds function is available in the SECPKG_USER_FUNCTION_TABLE structure received from the SpUserModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

AllocateHeap, SECPKG_USER_FUNCTION_TABLE, SpUserModeInitialize


SpSealMessage

The SpSealMessage function is used to encrypt a message exchanged between a client and server.

The SpSealMessage function is the dispatch function for the EncryptMessage function of the Security Support Provider Interface.

NTSTATUS <SpSealMessage> (
  LSA_SEC_HANDLE ContextHandle,
  ULONG QualityOfProtection,
  PSecBufferDesc MessageBuffers,
  ULONG MessageSequenceNumber
);

Parameters

ContextHandle
[in] Handle of the security context used to sign the message.
QualityOfProtection
[in] Specifies package-specific flags that indicate the quality of protection. An SSP/AP can use this parameter to enable the selection of cryptographic algorithms.
MessageBuffers
[in, out] Pointer to a SecBufferDesc structure containing message buffers. Only one of these message buffers can be of type SECBUFFER_DATA, and it contains the message to be encrypted. The buffer cannot have the SECBUFFER_READONLY attribute, as the encryption is done in-place.
MessageSequenceNumber
[in] Optional. Sequence number for the message.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed. The following table lists common reasons for failure and the error codes that the function should return.

Reason | Error code
The context could not be found or was not configured for message integrity. | STATUS_INVALID_HANDLE
The signature buffer could not be found or was too small. | STATUS_INVALID_PARAMETER

Remarks

Messages encrypted by the sender using the SpSealMessage function are decrypted using the SpUnSealMessage function.

SSP/APs must implement the SpSealMessage function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpSealMessage function is available in the SECPKG_USER_FUNCTION_TABLE structure received from the SpUserModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SECPKG_USER_FUNCTION_TABLE, SpUnSealMessage, SpUserModeInitialize


SpUnsealMessage

The SpUnsealMessage function is used to decrypt a message previously encrypted with the SpSealMessage function.

The SpUnSealMessage function is the dispatch function for the DecryptMessage function of the Security Support Provider Interface.

NTSTATUS <SpUnsealMessage>(
  LSA_SEC_HANDLE ContextHandle,
  PSecBufferDesc MessageBuffers,
  ULONG MessageSequenceNumber,
  PULONG QualityOfProtection
);

Parameters

ContextHandle
[in] Handle of the security context used to seal the message.
MessageBuffers
[in] Pointer to a SecBufferDesc structure containing the message buffers and a signature buffer.
MessageSequenceNumber
[in] Sequence number expected for the message. Sequence numbers are optional, and are used as protection against loss and insertion of messages. A value of SECURITY_NOSEQUENCE indicates that sequence numbers are not in use.
QualityOfProtection
[out] Not used.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed.

Remarks

SSP/APs must implement the SpUnSealMessage function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpUnSealMessage function is available in the SECPKG_USER_FUNCTION_TABLE structure received from the SpUserModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

DecryptMessage, SECPKG_USER_FUNCTION_TABLE, SpSealMessage, SpUserModeInitialize


SpUserModeInitialize

The SpUserModeInitialize function is called when a security support provider/authentication package (SSP/AP) DLL is loaded into the process space of a client/server application. This function provides the tables of pointers to the user-mode functions implemented by each security package in the SSP/AP DLL.

NTSTATUS SEC_ENTRY SpUserModeInitialize (
  ULONG LsaVersion,
  PULONG PackageVersion,
  PSECPKG_USER_FUNCTION_TABLE *ppTables,
  PULONG pcTables
);

Parameters

LsaVersion
[in] The version of the security provider DLL (either Secure32.dll on Win32® systems or Security.dll).
PackageVersion
[out] Pointer that returns the version of the SSP/AP DLL.
ppTables
[out] Pointer that returns an array of SECPKG_USER_FUNCTION_TABLE structures. Each structure is a table of pointers to the user-mode functions implemented by a security package deployed in the SSP/AP DLL.
pcTables
[out] Pointer that returns the number of elements in the array pointed to by the ppTables parameter.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed.

Remarks

The SpUserModeInitialize function must be implemented by SSP/AP DLLs that contain user-mode security packages.

The ppTables parameter should contain one SECPKG_USER_FUNCTION_TABLE for each user-mode security package deployed in the DLL. For more information on deploying security packages in DLLs, see User Mode Initialization.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SECPKG_USER_FUNCTION_TABLE


SpVerifySignature

The SpVerifySignature function verifies that the message received is correct according to the signature.

The SpVerifySignature function is the dispatch function for the VerifySignature function of the Security Support Provider Interface.

NTSTATUS <SpVerifySignature> (
  LSA_SEC_HANDLE ContextHandle,
  PSecBufferDesc MessageBuffers,
  ULONG MessageSequenceNumber,
  PULONG QualityOfProtection
);

Parameters

ContextHandle
[in] Handle to the security context used to sign the message.
MessageBuffers
[in] Pointer to a SecBufferDesc structure containing the message to verify.
MessageSequenceNumber
[in] Sequence number expected for the message. Sequence numbers are optional, and are used as protection against loss and insertion of messages. A value of SECURITY_NOSEQUENCE indicates that sequence numbers are not in use.
QualityOfProtection
[out] Pointer to package-specific flags that indicate the quality of protection.

Return Values

If the function succeeds, return STATUS_SUCCESS.

If the function fails, return an NTSTATUS code indicating the reason it failed. The following table lists a common reason for failure and the error code that the function should return.

Reason | Error code
The handle is invalid. | SEC_E_INVALID_HANDLE

Remarks

The signature verified by the SpVerifySignature function is created by the SpMakeSignature function, used by a message sender.

SSP/APs must implement the SpVerifySignature function; however, the actual name given to the implementation is up to the developer.

A pointer to the SpVerifySignature function is available in the SECPKG_USER_FUNCTION_TABLE structure received from the SpUserModeInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

MakeSignature, SECPKG_USER_FUNCTION_TABLE, SpMakeSignature, VerifySignature, SpUserModeInitialize


LSA Functions Called by SSP/APs

The LSA provides the following functions to security packages deployed in security support provider/authentication packages (SSP/APs). The functions are available in the LSA_SECPKG_FUNCTION_TABLE structure and can be called while the SSP/AP is loaded into the LSA's process space. The following functions are available to all APs.

Function | Description
CreateLogonSession | Creates an LSA logon session.
DeleteLogonSession | Deletes an LSA logon session.
AddCredential | Adds user credentials.
GetCredentials | Retrieves user credentials.
DeleteCredential | Deletes user credentials.
AllocateLsaHeap | Allocates memory from the heap.
FreeLsaHeap | Frees memory allocated by AllocateLsaHeap.
AllocateClientBuffer | Allocates memory in the address space of the package's client.
FreeClientBuffer | Frees memory in the address space of the package's client.
CopyToClientBuffer | Copies data to a buffer in the address space of the package's client.
CopyFromClientBuffer | Copies data from a buffer in the address space of the package's client.

The following functions are available to SSP/APs.

Function | Description
ImpersonateClient | Lets a security package impersonate its client.
UnloadPackage | Unloads an SSP/AP.
DuplicateHandle | Duplicates a handle.
SaveSupplementalCredentials | Saves supplemental credentials.
CreateThread | Creates a new thread.
GetClientInfo | Retrieves information about the security package's user process.
RegisterNotification | Sets up security package notification for special events.
CancelNotification | Cancels notification for special events.
MapBuffer | Maps a buffer into the SSP/AP's address space.
CreateToken | Creates a token.
AuditLogon | Creates an audit trail for a logon session.
CallPackage | Calls a package.
FreeReturnBuffer | Frees a buffer allocated by the LSA.
GetCallInfo | Retrieves information about the most recent function call.
CallPackageEx | Calls another package.
CreateSharedMemory | Creates a section of memory shared between clients and the SSP/AP.
AllocateSharedMemory | Allocates a section of shared memory.
FreeSharedMemory | Frees a section of shared memory.
DeleteSharedMemory | Deletes a section of shared memory.
OpenSamUser | Opens a handle to a Security Accounts Manager database entry.
GetUserCredentials | Not yet implemented.
GetUserAuthData | Returns the authorization data for a user.
CloseSamUser | Closes a handle to a Security Accounts Manager database entry.
ConvertAuthDataToToken | Converts authorization data to a user token.
ClientCallback | Allows a security package to invoke a function in the client process.
UpdateCredentials | Updates a user's credential information.
GetAuthDataForUser | Retrieve authorization data for a user account.
CrackSingleName | Converts a name from one format to another.
AuditAccountLogon | Creates audit records for attempted logons.
CallPackagePassthrough | Calls one security package from another.


AllocateSharedMemory

The AllocateSharedMemory function allocates a block of shared memory from a section of memory previously reserved by a call to the CreateSharedMemory function.

PVOID AllocateSharedMemory (
  PVOID SharedMem,
  ULONG Size
);

Parameters

SharedMem
[in] Pointer to a section of reserved shared memory.
Size
[in] Specifies the amount of shared memory to allocate, in bytes.

Return Values

If the function succeeds, the return value is a pointer to the allocated memory.

If the function fails, the return value is NULL.

Remarks

Reserve a section of shared memory using the CreateSharedMemory function. Free a block of memory allocated by AllocateSharedMemory using the FreeSharedMemory function.

A pointer to the AllocateSharedMemory function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

CreateSharedMemory, FreeSharedMemory, LSA_SECPKG_FUNCTION_TABLE, SpInitialize


AuditAccountLogon

The AuditAccountLogon function produces an audit record representing the mapping of a foreign principal name onto a Windows NT/Windows 2000 account.

NTSTATUS AuditAccountLogon (
  ULONG AuditId,
  BOOLEAN Success,
  PUNICODE_STRING Source,
  PUNICODE_STRING ClientName,
  PUNICODE_STRING MappedName,
  NTSTATUS Status
);

Parameters

AuditId
[in] Security package–defined message identifier. This value is included in the audit record.
Success
[in] Specifies whether the audit record is generated on success or failure of the logon.
Source
[in] Pointer to a UNICODE_STRING specifying the source of the logon attempt.
ClientName
[in] Pointer to a UNICODE_STRING specifying the client name.
MappedName
[in] Pointer to a UNICODE_STRING containing the Windows account name, to which the client name was mapped, if any.
Status
[in] An NTSTATUS value specifying any error that occurred.

Return Values

This function returns STATUS_SUCCESS.

Remarks

A pointer to the AuditAccountLogon function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

LSA_SECPKG_FUNCTION_TABLE, SpInitialize


AuditLogon

The AuditLogon function is used to audit a logon attempt.

VOID AuditLogon (
  NTSTATUS Status,
  NTSTATUS SubStatus,
  PUNICODE_STRING AccountName,
  PUNICODE_STRING AuthenticatingAuthority,
  PUNICODE_STRING WorkstationName,
  OPTIONAL PSID UserSid,
  SECURITY_LOGON_TYPE LogonType,
  PTOKEN_SOURCE TokenSource,
  PLUID LogonId
);

Parameters

Status
[in] Status of the logon attempt.
SubStatus
[in] Additional status information for the logon attempt.
AccountName
[in] Pointer to a UNICODE_STRING containing the account name used in the logon attempt.
AuthenticatingAuthority
[in] Pointer to a UNICODE_STRING containing the name of the authority that authenticated the logon, normally the Windows NT domain name.
WorkstationName
[in] Pointer to a UNICODE_STRING containing the name of the workstation used to attempt the logon.
UserSid
[in] Pointer to the SID of the security principal attempting to logon.
LogonType
[in] A SECURITY_LOGON_TYPE value indicating the type of logon.
TokenSource
[in] Pointer to a TOKEN_SOURCE structure specifying the source for the user token. Specify the package name.
LogonId
[in] Pointer to the logon session identifier. LogonId is valid only if the logon attempt was successful.

Return Values

This function does not return a value.

Remarks

A pointer to the AuditLogon function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

LSA_SECPKG_FUNCTION_TABLE, SpInitialize


CallPackage

The CallPackage function is used to call another security package to access its services.

NTSTATUS CallPackage (
  PUNICODE_STRING AuthenticationPackage,
  PVOID ProtocolSubmitBuffer,
  ULONG SubmitBufferLength,
  PVOID *ProtocolReturnBuffer,
  PULONG ReturnBufferLength,
  PNTSTATUS ProtocolStatus
);

Parameters

AuthenticationPackage
[in] Pointer to a UNICODE_STRING containing the name of the package to call.
ProtocolSubmitBuffer
[in] Pointer to the input buffer. The content of this buffer is package-specific.
SubmitBufferLength
[in] Size of the ProtocolSubmitBuffer parameter, in bytes.
ProtocolReturnBuffer
[out] Pointer that receives the address of the output buffer. The content of this buffer is package-specific.
ReturnBufferLength
[out] Pointer to a variable that receives the size of the ProtocolReturnBuffer parameter, in bytes.
ProtocolStatus
[out] Pointer to a variable that receives the status code returned by the called package.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code indicating the reason it failed. The following table lists a common reason for failure and the error code that the function returns.

Error code | Cause
STATUS_NO_SUCH_PACKAGE | The AuthenticationPackage parameter does not contain the name of a valid security package.

Remarks

A pointer to the CallPackage function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

CallPackageEx, LSA_SECPKG_FUNCTION_TABLE, SpInitialize


CallPackageEx

The CallPackageEx function is used to call another security package to access its services.

NTSTATUS CallPackageEx (
  PUNICODE_STRG AuthenticationPackage,
  PVOID ClientBufferBase,
  PVOID ProtocolSubmitBuffer,
  ULONG SubmitBufferLength,
  PVOID *ProtocolReturnBuffer,
  PULONG ReturnBufferLength,
  PNTSTATUS ProtocolStatus
);

Parameters

AuthenticationPackage
[in] Pointer to a UNICODE_STRING containing the name of the authentication package to call.
ClientBufferBase
[in] The base address of the input buffer, in the client's address space.
ProtocolSubmitBuffer
[in] Pointer to the input buffer.
SubmitBufferLength
[in] Size of ProtocolSubmitBuffer, in bytes.
ProtocolReturnBuffer
[out] Pointer that receives the address of the output buffer.
ReturnBufferLength
[out] Pointer to a variable that receives the size of ProtocolReturnBuffer, in bytes.
ProtocolStatus
[out] Pointer to a variable that receives the status code returned by the authentication package.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code indicating the reason it failed. The following table lists a common reason for failure and the error code that the function returns.

Error code | Cause
STATUS_NO_SUCH_PACKAGE | The AuthenticationPackage parameter does not contain the name of a valid security package.

Remarks

A pointer to the CallPackageEx function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

CallPackage, LSA_SECPKG_FUNCTION_TABLE, SpInitialize


CallPackagePassthrough

The CallPackagePassthrough function is used to call another security package to access its services.

NTSTATUS CallPackagePassthrough (
  PUNICODE_STRING AuthenticationPackage,
  PVOID ClientBufferBase,
  PVOID ProtocolSubmitBuffer,
  ULONG SubmitBufferLength,
  PVOID *ProtocolReturnBuffer,
  PULONG ReturnBufferLength,
  PNTSTATUS ProtocolStatus
);

Parameters

AuthenticationPackage
[in] Pointer to a UNICODE_STRING containing the name of the package to call.
ClientBufferBase
[in] The base address of the input buffer, in the client's address space.
ProtocolSubmitBuffer
[in] Pointer to the input buffer.
SubmitBufferLength
[in] Size of the ProtocolSubmitBuffer parameter, in bytes.
ProtocolReturnBuffer
[out] Pointer to the output buffer.
ReturnBufferLength
[out] Pointer to a variable that receives the size of the ProtocolReturnBuffer parameter, in bytes.
ProtocolStatus
[out] Pointer to a variable that receives the status code returned by the package.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code indicating the reason it failed. The following table lists a common reason for failure and the error code that the function returns.

Error code | Cause
STATUS_NO_SUCH_PACKAGE | The AuthenticationPackage parameter does not contain the name of a valid SSP/AP.

Remarks

The LSA does not examine or alter any of the function arguments.

A pointer to the CallPackagePassthrough function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

CallPackage, CallPackageEx, LSA_SECPKG_FUNCTION_TABLE, SpInitialize


CancelNotification

The CancelNotification function cancels a previously registered notification.

NTSTATUS CancelNotification (
  HANDLE NotifyHandle
);

Parameters

NotifyHandle
[in] Handle returned by a previous call to RegisterNotification.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code indicating the reason it failed. The following table lists a common reason for failure and the error code that the function returns.

Error code | Cause
STATUS_INVALID_PARAMETER | The handle specified by the NotifyHandle parameter is not valid.

Remarks

Use the RegisterNotification function to register a notification.

A pointer to the CancelNotification function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

RegisterNotification, LSA_SECPKG_FUNCTION_TABLE, SpInitialize


ClientCallback

The ClientCallback function allows an LSA-mode security package to call back to its user-mode package and invoke a function in its DLL there.

 NTSTATUS ClientCallback (
  PCHAR Callback,
  ULONG_PTR Argument1,
  ULONG_PTR Argument2,
  PSecBuffer Input,
  PSecBuffer Output
);

Parameters

Callback
[in] Pointer to the name of the function to invoke. The function must match the ClientCallback function prototype. See the Remarks section.
Argument1
[in] Pointer to the first argument to pass to the callback function.
Argument2
[in] Pointer to the second argument to pass to the callback function.
Input
[in] Pointer to a SecBuffer structure containing information to pass to the callback function.
Output
[out] Pointer to a SecBuffer structure that receives information passed from the callback function.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code indicating the reason it failed.

Remarks

A pointer to the ClientCallback function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

The user-mode security package must register the function to be called using the RegisterCallback function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

ClientCallback Function Prototype, LSA_SECPKG_FUNCTION_TABLE, RegisterCallback, SpInitialize


CloseSamUser

The CloseSamUser function closes a handle to a Security Accounts Manager (SAM) user account.

NTSTATUS CloseSamUser (
  PVOID UserHandle
);

Parameters

UserHandle
[in] Handle to the SAM user account previously opened using the OpenSamUser function.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code indicating the reason. The following table lists a common reason for failure and the error code that the function returns.

Error Code | Cause
STATUS_INVALID_HANDLE | The value specified for UserHandle is invalid or NULL.

Remarks

A pointer to the CloseSamUser function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

OpenSamUser, LSA_SECPKG_FUNCTION_TABLE, SpInitialize


ConvertAuthDataToToken

The ConvertAuthDataToToken function creates an access token from the authorization data returned from the GetAuthDataForUser or GetUserAuthData functions.

NTSTATUS ConvertAuthDataToToken (
  PVOID UserAuthData,
  ULONG UserAuthDataSize,
  SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
  PTOKEN_SOURCE TokenSource,
  SECURITY_LOGON_TYPE LogonType,
  PUNICODE_STRING AuthorityName,
  PHANDLE Token,
  PLUID LogonId,
  PUNICODE_STRING AccountName,
  PNTSTATUS SubStatus
);

Parameters

UserAuthData
[in] Pointer to the authorization data received from the GetAuthDataForUser or GetUserAuthData functions.
UserAuthDataSize
[in] Size, in bytes, of the authorization data specified by the UserAuthData parameter.
ImpersonationLevel
[in] A SECURITY_IMPERSONATION_LEVEL value specifying the impersonation level for the token to be created.
TokenSource
[in] Pointer to a TOKEN_SOURCE structure specifying the source to record in the token.
LogonType
[in] A SECURITY_LOGON_TYPE value indicating the type of logon to record in the token.
AuthorityName
[in] Pointer to a UNICODE_STRING structure that specifies the name of the authority that authorized this user, typically a domain name.
Token
[out] Pointer to a HANDLE that receives the user token handle.
LogonId
[out] Pointer to an LUID that receives the logon identifier for the token.
AccountName
[out] Pointer to a UNICODE_STRING structure that receives the account name encoded in the UserAuthData parameter.
SubStatus
[out] Pointer to a variable that receives additional information about the return value of the function call.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code indicating the reason it failed.

Remarks

A pointer to the ConvertAuthDataToToken function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

GetAuthDataForUser, GetUserAuthData, LSA_SECPKG_FUNCTION_TABLE, SECURITY_IMPERSONATION_LEVEL, SECURITY_LOGON_TYPE, SpInitialize, TOKEN_SOURCE, UNICODE_STRING


CrackSingleName

The CrackSingleName function converts a name from one format to another.

NTSTATUS CrackSingleName (
  ULONG FormatOffered,
  BOOLEAN PerformAtGC,
  PUNICODE_STRING NameInput,
  PUNICODE_STRING Prefix OPTIONAL,
  ULONG RequestedFormat,
  PUNICODE_STRING CrackedName,
  PUNICODE_STRING DnsDomainName,
  PULONG SubStatus
);

Parameters

FormatOffered
[in] Specifies the format of the input name. The following table contains the valid values for this parameter.
Value | Description
DS_CANONICAL_NAME | Complete canonical name (for example, example.microsoft.com/software/someone). The domain-only version includes a trailing forward slash (/).
DS_CANONICAL_NAME_EX | Same as DS_CANONICAL_NAME except that the rightmost forward slash (/) is replaced with a newline character (\n), even in a domain-only case (for example, example.microsoft.com/software\nsomeone).
DS_DISPLAY_NAME | A "friendly" display name (for example, John Smith). The display name is not necessarily the defining relative distinguished name (RDN).
DS_FQDN_1779_NAME | Fully qualified distinguished name (for example, CN=John Smith,OU=Users,DC=Example,DC=Microsoft,DC=Com).
DS_NT4_ACCOUNT_NAME | Windows NT® 4.0 account name (for example, Example\JSmith). The domain-only version includes trailing backslashes (\\).
DS_SERVICE_PRINCIPAL_NAME | Generalized service principal name (for example, www/www.microsoft.com@microsoft.com).
DS_SID_OR_SID_HISTORY_NAME | A security identifier (SID) for the object. This can be either the current SID or a SID from the object's SID history. The SID string can use either the standard string representation of a SID, or one of the string constants defined in Sddl.h. For information on converting a binary SID into a SID string, see SID Strings. This value is not valid for the formatDesired parameter.
DS_UNIQUE_ID_NAME | GUID string that the IIDFromString function returns (for example, {4fa050f0-f561-11cf-bdd9-00aa003a77b6}).
DS_UNKNOWN_NAME | Unknown name type.
DS_USER_PRINCIPAL_NAME | User principal name (for example, someone@example.microsoft.com).

PerformAtGC
[in] Specifies whether or not to perform the translation at a global catalog server.
NameInput
[in] Pointer to a UNICODE_STRING structure containing the name to convert.
Prefix
[in] Optional. Pointer to a UNICODE_STRING structure that specifies a prefix for the name.
RequestedFormat
[in] Specifies the format of the input name. See the FormatOffered parameter for a list of valid values.
CrackedName
[out] Pointer to a UNICODE_STRING structure that receives the reformatted name.
DnsDomainName
[out] Pointer to a UNICODE_STRING structure that receives the name of the domain that owns the name specified by the NameInput parameter.
SubStatus
[out] Pointer to a variable that receives additional information about the return value of the function call.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is STATUS_UNSUCCESSFUL. For additional information, see the value returned in the Substatus parameter.

Remarks

A pointer to the CrackSingleName function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

LSA_SECPKG_FUNCTION_TABLE, SpInitialize


CreateSharedMemory

The CreateSharedMemory function creates a section of memory that is shared by client processes and the security package.

PVOID NTAPI CreateSharedMemory (
  ULONG MaxSize,
  ULONG InitialSize
);

Parameters

[in] MaxSize
Specifies the maximum size of the shared memory.
[in] InitialSize
Specifies the initial size of the shared memory.

Return Values

The function returns a pointer to the block of shared memory, or NULL if the block was not reserved.

Remarks

Creating a shared section for each client is not advisable because it is a very expensive operation and may exhaust system resources.

The package's clients can write to shared memory which makes it susceptible to attack. Data in the shared segment should not be trusted.

The pointer returned by the CreateSharedMemory function is required by the AllocateSharedMemory, DeleteSharedMemory, and FreeSharedMemory functions.

Use the DeleteSharedMemory function to release memory reserved by the CreateSharedMemory function.

Pointers to these functions are available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

AllocateSharedMemory, DeleteSharedMemory, FreeSharedMemory, LSA_SECPKG_FUNCTION_TABLE, SpInitialize


CreateThread

The CreateThread function creates a thread that the LSA can track. The parameters are identical to the Win32 CreateThread function.

HANDLE CreateThread (
  SEC_ATTRS SecurityAttributes,
  ULONG StackSize,
  SEC_THREAD_START StartFunction,
  PVOID ThreadParameter,
  ULONG CreationFlags,
  PULONG ThreadId
);

Parameters

SecurityAttributes
[in] Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes.
StackSize
[in] Specifies the initial commit size of the stack, in bytes.
StartFunction
[in] Pointer to the application-defined function of type LPTHREAD_START_ROUTINE to be executed by the thread.
ThreadParameter
[in] Pointer to a single parameter value passed to the thread.
CreationFlags
[in] Specifies flags that control the creation of the thread.
ThreadId
[out] Pointer to a variable that receives the thread identifier.

Return Values

If the function succeeds, the return value is a handle to the new thread.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

A pointer to the CreateThread function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

For more information, see the Win32 CreateThread function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

CreateThread, GetLastError, LSA_SECPKG_FUNCTION_TABLE, SpInitialize


CreateToken

The CreateToken function is used by SSP/APs to create tokens while processing calls to SpAcceptLsaModeContext.

NTSTATUS CreateToken (
  PLUID LogonId,
  PTOKEN_SOURCE TokenSource,
  SECURITY_LOGON_TYPE LogonType,
  SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
  LSA_TOKEN_INFORMATION_TYPE TokenInformationType,
  PVOID TokenInformation,
  PTOKEN_GROUPS TokenGroups,
  PUNICODE_STRING AccountName,
  PUNICODE_STRING AuthorityName,
  PUNICODE_STRING Workstation,
  PUNICODE_STRING ProfilePath,
  PHANDLE Token,
  PNTSTATUS SubStatus
);

Parameters

LogonId
[in] Pointer to a logon session identifier for the new token. This identifier is obtained from a previous call to CreateLogonSession.
TokenSource
[in] Pointer to a TOKEN_SOURCE structure specifying the source for this token. Specify the package name.
LogonType
[in] A SECURITY_LOGON_TYPE value indicating the type of logon.
ImpersonationLevel
[in] A SECURITY_IMPERSONATION_LEVEL value indicating the extent to which a server process can impersonate a client process.
TokenInformationType
[in] Specifies the type of structure in the TokenInformation parameter.
Value | Structure
LsaTokenInformationNull | LSA_TOKEN_INFORMATION_NULL
LsaTokenInformationV1 | LSA_TOKEN_INFORMATION_V1

TokenInformation
[in] Pointer to the token information. The type of structure pointed to by TokenInformation is indicated by the TokenInformationType parameter.
TokenGroups
[in] Pointer to a TOKEN_GROUPS structure specifying groups not contained in TokenInformation.
AccountName
[in] Pointer to a UNICODE_STRING structure containing the name of the security principal. This information is used for auditing and name searches.
AuthorityName
[in] Pointer to a UNICODE_STRING structure containing the name of the authority that validated the logon credentials, normally the Windows NT domain name.
Workstation
[in] Pointer to a UNICODE_STRING structure containing the name of the client's workstation, normally a NETBIOS name.
ProfilePath
[in] Pointer to a UNICODE_STRING structure containing the path to the user's profile, if any.
Token
[out] Pointer that receives the address of a handle to the new token.
SubStatus
[out] Pointer to a variable that receives error information.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code indicating the reason it failed.

Remarks

A pointer to the CreateToken function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

SpAcceptLsaModeContext, LSA_SECPKG_FUNCTION_TABLE, SpInitialize


DeleteSharedMemory

The DeleteSharedMemory function releases a section of memory that is shared by clients and a security package.

BOOLEAN DeleteSharedMemory (
  PVOID SharedMem
);

Parameters

[in] SharedMem
Pointer to shared memory previously reserved by the CreateSharedMemory function.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE.

Remarks

The DeleteSharedMemory function releases the shared memory reserved by the CreateSharedMemory function.

To release shared memory allocated by the AllocateSharedMemory function, use the FreeSharedMemory function.

Pointers to these functions are available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

AllocateSharedMemory, CreateSharedMemory, FreeSharedMemory, LSA_SECPKG_FUNCTION_TABLE, SpInitialize


DuplicateHandle

The DuplicateHandle function creates a duplicate handle. The returned duplicate is in the caller's process space.

NTSTATUS DuplicateHandle (
  HANDLE SourceHandle,
  PHANDLE DestinationHandle
);

Parameters

SourceHandle
[in] The handle to duplicate.
DestinationHandle
[out] Pointer that receives the address of a duplicate of the SourceHandle handle. The duplicate handle is in the caller's process space.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code indicating the reason it failed.

Remarks

A pointer to the DuplicateHandle function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

LSA_SECPKG_FUNCTION_TABLE, SpInitialize


FreeReturnBuffer

The FreeReturnBuffer function is used to free buffers allocated by the LSA and returned to the security package. The package calls this function when the information in the returned buffer is no longer needed.

VOID FreeReturnBuffer (
  PVOID Base
);

Parameters

Base
[in] Pointer to the buffer to free.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code indicating the reason it failed.

Remarks

A pointer to the FreeReturnBuffer function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

LSA_SECPKG_FUNCTION_TABLE, SpInitialize


FreeSharedMemory

The FreeSharedMemory function frees a block of shared memory previously allocated by the AllocateSharedMemory function.

VOID FreeSharedMemory (
  PVOID SharedMem,
  PVOID Memory
);

Parameters

SharedMem
[in] Pointer to the shared memory section previously reserved using the CreateSharedMemory function.
Memory
[in] Pointer to the memory previously allocated from the shared memory section specified by the SharedMem parameter, using the AllocateSharedMemory function.

Return Values

This function does not return a value.

Remarks

A pointer to the FreeSharedMemory function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

AllocateSharedMemory, CreateSharedMemory, LSA_SECPKG_FUNCTION_TABLE, SpInitialize


GetAuthDataForUser

The GetAuthDataForUser function retrieves authentication information for a user from the Security Accounts Manager (SAM) database, and puts it into a format suitable for the ConvertAuthDataToToken function.

NTSTATUS GetAuthDataForUser (
  PSECURITY_STRING Name,
  SECPKG_NAME_TYPE NameType,
  PSECURITY_STRING Prefix,
  PUCHAR *UserAuthData,
  PULONG UserAuthDataSize,
  PUNICODE_STRING UserFlatName
);

Parameters

Name
[in] Pointer to a UNICODE_STRING structure specifying the name of the SAM account.
NameType
[in] A SECPKG_NAME_TYPE enumeration value specifying the type of account name in Name. The following table contains the list of valid values.
Value | Description
SecNameSamCompatible | Name is a Windows NT 4.0–style name.
SecNameAlternateId | Name is in the AltSecId property of the SAM account. You must specify a value for the Prefix parameter when using this value.
SecNameFlat | Name is a flat user principal name (UPN) style account name.
SecNameDN | Name is the distinguished name of the object. For more information, see the Remarks section.

Prefix
[in] Pointer to a UNICODE_STRING structure containing the prefix to use for names specified with the SecNameAlternateId NameType.
UserAuthData
[out] Pointer that receives the address of the retrieved data.
UserAuthDataSize
[out] Pointer to a ULONG that receives the size of the retrieved data.
UserFlatName
[out] Pointer to a UNICODE_STRING structure that receives the user principal name, if applicable.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code indicating the reason it failed.

Remarks

The GetAuthDataForUser function combines the OpenSamUser, GetUserAuthData and CloseSamUser functions into one call.

Pointers to these functions are available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

CloseSamUser, GetUserAuthData, OpenSamUser, LSA_SECPKG_FUNCTION_TABLE, SpInitialize


GetCallInfo

The GetCallInfo function retrieves information about the most recent function call.

BOOLEAN GetCallInfo (
  PSECPKG_CALL_INFO Info
);

Parameters

Info
[out] Pointer to a SECPKG_CALL_INFO structure that receives information about the call.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE.

Remarks

A pointer to the GetCallInfo function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

LSA_SECPKG_FUNCTION_TABLE, SpInitialize


GetClientInfo

The GetClientInfo function gets information about the client process, such as thread and process ID, and flags indicating the client's state and privileges.

NTSTATUS GetClientInfo (
  PSECPKG_CLIENT_INFO ClientInfo
);

Parameters

ClientInfo
[out] Pointer to a SECPKG_CLIENT_INFO structure that receives information about the client.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code indicating the reason it failed.

Remarks

A pointer to the GetClientInfo function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

LSA_SECPKG_FUNCTION_TABLE, SpInitialize


GetUserAuthData

The GetUserAuthData function returns the authorization data for the user in a single buffer.

NTSTATUS GetUserAuthData (
  PVOID UserHandle,
  PUCHAR *UserAuthData,
  PULONG UserAuthDataSize
);

Parameters

UserHandle
[in] Handle to the user account. This handle is returned by the OpenSamUser function.
UserAuthData
[out] Pointer that receives the consolidated authorization data.
UserAuthDataSize
[out] Pointer that receives the size of the authorization data.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code indicating the reason it failed.

Remarks

The authorization data returned by the GetUserAuthData function can be passed to the ConvertAuthDataToToken function.

A pointer to the GetUserAuthData function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

ConvertAuthDataToToken, LSA_SECPKG_FUNCTION_TABLE, OpenSamUser, SpInitialize


GetUserCredentials

The GetUserCredentials function is not yet implemented.


ImpersonateClient

The ImpersonateClient function is called by security packages to impersonate the package user.

NTSTATUS ImpersonateClient ( );

Parameters

This function has no parameters.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code indicating the reason it failed.

Remarks

To end the impersonation, call the RevertToSelf function.

A pointer to the ImpersonateClient function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

LSA_SECPKG_FUNCTION_TABLE, SpInitialize


MapBuffer

The MapBuffer function maps a SecBuffer structure into the address space of the security support provider/authentication package (SSP/AP).

NTSTATUS MapBuffer (
  PSecBuffer InputBuffer,
  PSecBuffer OutputBuffer
);

Parameters

InputBuffer
[in] Pointer to the SecBuffer structure to map.
OutputBuffer
[out] Pointer that receives the address of the mapped SecBuffer structure.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code indicating the reason it failed.

Remarks

If the SecBuffer has already been mapped, the MapBuffer function copies the contents of the input buffer over the output buffer.

A pointer to the MapBuffer function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

LSA_SECPKG_FUNCTION_TABLE, SpInitialize


OpenSamUser

The OpenSamUser function retrieves a handle to a user account in the Security Accounts Manager (SAM) database.

NTSTATUS OpenSamUser (
  PSECURITY_STRING Name,
  SECPKG_NAME_TYPE NameType,
  PSECURITY_STRING Prefix,
  BOOLEAN AllowGuest,
  ULONG Reserved,
  PVOID *UserHandle
);

Parameters

Name
[in] Pointer to a UNICODE_STRING structure specifying the name of the SAM account.
NameType
[in] A SECPKG_NAME_TYPE enumeration value specifying the type of account name in Name. The following table contains the list of valid values.
Value | Description
SecNameSamCompatible | Name is a Windows NT 4.0–style name.
SecNameAlternateId | Name is in the AltSecId property of the SAM account. This value is used with the Prefix parameter.
SecNameFlat | Name is a flat user principal name (UPN) style account name.
SecNameDN | Name is the distinguished name of the object. For more information, see the Remarks section.

Prefix
[in] Pointer to a UNICODE_STRING structure specifying the prefix to use with names using the SecNameAlternateId NameType.
AllowGuest
[in] Specifies whether to use the Guest account if the SAM account is not found.
Value | Description
FALSE | If the user is not found, the OpenSamUser function call fails.
TRUE | If the user is not found and the Guest account is enabled, the Guest account is used.

Reserved
[in] Reserved. Specify zero.
UserHandle
[out] Pointer to a pointer that receives a handle to the user account.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code indicating the reason it failed. The following table lists common reasons for failure, and the error codes that the function returns.

Error code | Cause
STATUS_INVALID_PARAMETER | NameType is SecNameAlternateId and Prefix is NULL.
STATUS_NO_SUCH_USER | The SAM account could not be found.

Remarks

Close the handle received by the UserHandle parameter by calling the CloseSamUser function.

The distinguished name of a user identifies the name, domain, and the complete path to the Active Directory™ object that represents the user.

A pointer to the OpenSamUser function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

CloseSamUser, LSA_SECPKG_FUNCTION_TABLE, SpInitialize


RegisterNotification

The RegisterNotification function provides a mechanism whereby the security package is notified. Notification can occur at fixed intervals, when an event object is signaled, or during certain system events.

HANDLE RegisterNotification (
  SEC_THREAD_START StartFunction,
  PVOID Parameter,
  ULONG NotificationType,
  ULONG NotificationClass,
  ULONG NotificationFlags,
  ULONG IntervalMinutes,
  HANDLE WaitEvent
);

Parameters

StartFunction
[in] The function that is called to accept notification.
Parameter
[in] The argument of the function specified in the StartFunction parameter.
NotificationType
[in] Specifies the type of notification. The following table lists the valid values.
Constant | Usage
NOTIFIER_TYPE_INTERVAL | Notify at fixed intervals. Use the IntervalMinutes parameter to indicate the interval length.
NOTIFIER_TYPE_HANDLE_WAIT | Notify when the event handle specified by the WaitEvent parameter is signaled.
NOTIFIER_TYPE_STATE_CHANGE | Notify when there is a change in the machine's domain or installation type.
NOTIFIER_TYPE_NOTIFY_EVENT | Notify when a security event takes place. Use the NotificationClass parameter to specify the event of interest.
NOTIFIER_TYPE_IMMEDIATE | Notify immediately. This value implies NOTIFIER_FLAG_ONE_SHOT.

NotificationClass
[in] Specifies the class of events that generate notifications. Specify zero unless the NotificationType parameter is set to NOTIFIER_TYPE_NOTIFY_EVENT.
Constant | Usage
NOTIFY_CLASS_PACKAGE_CHANGE | A package was loaded, or a new package was selected as the preferred package. For more information, see Remarks.
NOTIFY_CLASS_ROLE_CHANGE | Reserved for internal use.
NOTIFY_CLASS_DOMAIN_CHANGE | Reserved for internal use.

NotificationFlags
[in] Specifies flags that control notification behavior.
Flag | Usage
NOTIFIER_FLAG_NEW_THREAD | Wait for notification using a new thread.
NOTIFIER_FLAG_ONE_SHOT | Notify only once.
NOTIFIER_FLAG_SECONDS | The IntervalMinutes parameter specifies seconds.

IntervalMinutes
[in] Specifies the time delay between notifications.
WaitEvent
[in] Optional. Handle to an event object. When the object is signaled, the notification occurs. This value is used in conjunction with the NotificationType value NOTIFIER_TYPE_HANDLE_WAIT.

Return Values

If the function succeeds, the return value is a handle to the notification.

If the function fails, the return value is NULL.

Remarks

If you specify the NOTIFY_CLASS_PACKAGE_CHANGE value for the NotificationClass parameter, the following values represent valid changes.

Value | Description
SECPKG_PACKAGE_CHANGE_LOAD | A package was loaded.
SECPKG_PACKAGE_CHANGE_UNLOAD | A package was unloaded.
SECPKG_PACKAGE_CHANGE_SELECT | A new package became the preferred security package.

A pointer to the RegisterNotification function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

LSA_SECPKG_FUNCTION_TABLE, SpInitialize


SaveSupplementalCredentials

The SaveSupplementalCredentials function is used by security packages to save credentials for later use.

NTSTATUS SaveSupplementalCredentials (
  PLUID LogonId,
  ULONG SupplementalCredSize,
  PVOID SupplementalCreds,
  BOOLEAN Synchronous
);

Parameters

LogonId
[in] Pointer to the logon identifier of the security principal whose credentials are to be saved.
SupplementalCredSize
[in] Size of the supplemental credentials, in bytes. The value specified for SupplementalCredSize can be zero.
SupplementalCreds
[in] Pointer to buffer containing supplemental credentials. The value specified for SupplementalCreds can be NULL.
Synchronous
[in] Specifies whether the function call will behave synchronously or asynchronously. If FALSE is specified, the function call will return immediately and the save operation will be done in a separate thread. If TRUE is specified, the current thread will handle the save operation and the function call will not return until the save is complete.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code indicating the reason it failed.

Remarks

A pointer to the SaveSupplementalCredentials function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

LSA_SECPKG_FUNCTION_TABLE, SpInitialize


UnloadPackage

The UnloadPackage function is available for use by security support provider/authentication packages (SSP/APs) that detect some unrecoverable problem after being loaded. The calling package is unloaded and removed from the list of valid packages.

NTSTATUS UnloadPackage ( );

Parameters

This function has no parameters.

Return Values

The function returns STATUS_SUCCESS.

Remarks

A pointer to the UnloadPackage function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

LSA_SECPKG_FUNCTION_TABLE, SpInitialize


UpdateCredentials

The UpdateCredentials function provides a mechanism for one security package to notify other packages that the credentials for a logon session have changed.

NTSTATUS UpdateCredentials (
  PSECPKG_PRIMARY_CRED PrimaryCredentials,
  OPTIONAL PSECPKG_SUPPLEMENTAL_CRED_ARRAY Credentials
);

Parameters

PrimaryCredentials
[in] Pointer to a SECPKG_PRIMARY_CRED structure containing the primary credentials.
Credentials
[in] Optional. Pointer to a SECPKG_SUPPLEMENTAL_CRED_ARRAY structure containing the supplemental credentials.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code indicating the reason it failed.

Remarks

To notify packages about the changed credentials, the LSA calls the SpAcceptCredentials function implementation in each package.

A pointer to the UpdateCredentials function is available in the LSA_SECPKG_FUNCTION_TABLE structure received by the SpInitialize function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

LSA_SECPKG_FUNCTION_TABLE, SECPKG_PRIMARY_CRED, SECPKG_SUPPLEMENTAL_CRED_ARRAY, SpAcceptCredentials, SpInitialize


LSA Functions Called By User-mode SSP/APs

A security package in an SSP/AP executing in a user-mode process can use the pointers in the SECPKG_DLL_FUNCTIONS table to access the following functions.

Function | PSDK Status
AllocateHeap | Allocates memory for buffers that are returned to the LSA.
FreeHeap | Frees memory previous allocated using AllocateHeap.
RegisterCallback | Registers a callback function that can be called from LSA-mode.


AllocateHeap

The AllocateHeap function allocates memory on the heap. Memory allocated with this routine must be freed using the FreeHeap function.

PVOID AllocateHeap(
  ULONG Length
);

Parameters

Length
[in] Number of bytes to allocate.

Return Values

This function returns a pointer to the allocated memory. If memory could not be allocated, the function returns NULL.

Remarks

To free memory allocated by the AllocateHeap function use the Freeheap function.

A pointer to the AllocateHeap function is available in the SECPKG_DLL_FUNCTIONS structure received from the SpInstanceInit function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

Freeheap, SECPKG_DLL_FUNCTIONS, SpInstanceInit


FreeHeap

The FreeHeap function releases memory previously allocated by the AllocateHeap function.

VOID FreeHeap(
  PVOID Base
);

Parameters

Base
[in, out] Pointer to the buffer to be freed.

Return Values

This function does not return a value. However, if the function sets Base to NULL, the buffer was freed. If Base is not NULL after the function call ends, the buffer could not be freed.

Remarks

A pointer to the FreeHeap function is available in the SECPKG_DLL_FUNCTIONS structure received from the SpInstanceInit function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

AllocateHeap, SECPKG_DLL_FUNCTIONS, SpInstanceInit


RegisterCallback

The RegisterCallback function is called by a user-mode security package to register user-mode callback functions.

A security package loaded into the LSA's process can call a registered user-mode callback function using the ClientCallBack function available in the LSA_SECPKG_FUNCTION_TABLE structure.

NTSTATUS RegisterCallback (
  ULONG CallbackId,
  PLSA_CALLBACK_FUNCTION Callback
);

Parameters

CallbackId
[in] Specifies an identifier for the function.
Callback
[in] Specifies the callback function that will execute in the user's process space. For information about the prototype for this function, see ClientCallback Function Prototype.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code indicating the reason it failed.

Remarks

The registered function is accessed by means of the ClientCallback function.

A pointer to the RegisterCallback function is available in the SECPKG_DLL_FUNCTIONS structure received from the SpInstanceInit function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.

See Also

ClientCallback; ClientCallback Function Prototype


ClientCallback Function Prototype

The ClientCallback function prototype is the prototype for the function that is accessed using the ClientCallback function.

LSA_CALLBACK_FUNCTION is a placeholder for the actual name of the function.

NTSTATUS NTAPI <LSA_CALLBACK_FUNCTION>(
  ULONG_PTR Argument1,
  ULONG_PTR Argument2,
  PSecBuffer InputBuffer,
  PSecBuffer OutputBuffer
);

Parameters

Argument1
[in] First argument to the function.
Argument2
[in] Second argument to the function.
InputBuffer
[in] Pointer to a SecBuffer structure containing information to pass to the function.
OutputBuffer
[out] Pointer to a SecBuffer structure that receives information passed from the function.

Return Values

The value returned by this function is ignored.

Remarks

The implementation of this function is accessed by means of the ClientCallback function.

See Also

ClientCallback, SecBuffer


Custom Security Package Structures

Custom security packages use the following structures.

Structure | Description
LSA_SECPKG_FUNCTION_TABLE | A table of pointers to the LSA functions that custom security packages can call.
SECPKG_CALL_INFO | Contains information about an executing function call.
SECPKG_CLIENT_INFO | Contains information about the user of a security package.
SECPK_CONTEXT_THUNKS | Contains information about calls to the security package that will be executed in-process with the LSA.
SECPKG_DLL_FUNCTIONS | Contains the functions available to custom security packages executing in-process with a client/server application.
SECPKG_EVENT_DOMAIN_CHANGE | Contains session and machine information. This structure name is an alias for the SECPKG_PARAMETERS structure.
SECPKG_EVENT_NOTIFY | Contains information about a security-related event.
SECPKG_EVENT_PACKAGE_CHANGE | Contains information about security package availability and use.
SECPKG_EXTENDED_INFORMATION | Contains extended information about the security package.
SECPKG_FUNCTION_TABLE | Contains pointers to the functions implemented by security packages.
SECPKG_GSS_INFO | Contains information on the GSS OID used to identify a security package.
SECPKG_MUTUAL_AUTH_LEVEL | Contains information about the mutual authentication level used by a security package.
SECPKG_PARAMETERS | Contains session and machine information.
SECPKG_PRIMARY_CRED | Contains primary credentials information.
SECPKG_SUPPLEMENTAL_CRED | Contains supplemental credentials information.
SECPKG_SUPPLEMENTAL_CRED_ARRAY | Contains supplemental credentials information.
SECPKG_USER_FUNCTION_TABLE | Contains the functions implemented by a security package loaded in-process with client/server applications.
SecurityUserData | Contains information about the logged on user.


LSA_SECPKG_FUNCTION_TABLE

The LSA_SECPKG_FUNCTION_TABLE structure contains pointers to the LSA functions that a security package can call. The LSA passes this structure to a security package when it calls the package's SpInitialize function.

typedef struct _LSA_SECPKG_FUNCTION_TABLE {
  PLSA_CREATE_LOGON_SESSION       CreateLogonSession;
  PLSA_DELETE_LOGON_SESSION       DeleteLogonSession;
  PLSA_ADD_CREDENTIAL             AddCredential;
  PLSA_GET_CREDENTIALS            GetCredentials;
  PLSA_DELETE_CREDENTIAL          DeleteCredential;
  PLSA_ALLOCATE_LSA_HEAP          AllocateLsaHeap;
  PLSA_FREE_LSA_HEAP              FreeLsaHeap;
  PLSA_ALLOCATE_CLIENT_BUFFER     AllocateClientBuffer;
  PLSA_FREE_CLIENT_BUFFER         FreeClientBuffer;
  PLSA_COPY_TO_CLIENT_BUFFER      CopyToClientBuffer;
  PLSA_COPY_FROM_CLIENT_BUFFER    CopyFromClientBuffer;
  PLSA_IMPERSONATE_CLIENT         ImpersonateClient;
  PLSA_UNLOAD_PACKAGE             UnloadPackage;
  PLSA_DUPLICATE_HANDLE           DuplicateHandle;
  PLSA_SAVE_SUPPLEMENTAL_CREDENTIALS SaveSupplementalCredentials;
  PLSA_CREATE_THREAD              CreateThread;
  PLSA_GET_CLIENT_INFO            GetClientInfo;
  PLSA_REGISTER_NOTIFICATION      RegisterNotification;
  PLSA_CANCEL_NOTIFICATION        CancelNotification;
  PLSA_MAP_BUFFER                 MapBuffer;
  PLSA_CREATE_TOKEN               CreateToken;
  PLSA_AUDIT_LOGON                AuditLogon;
  PLSA_CALL_PACKAGE               CallPackage;
  PLSA_FREE_LSA_HEAP              FreeReturnBuffer;
  PLSA_GET_CALL_INFO              GetCallInfo;
  PLSA_CALL_PACKAGEEX             CallPackageEx;
  PLSA_CREATE_SHARED_MEMORY       CreateSharedMemory;
  PLSA_ALLOCATE_SHARED_MEMORY     AllocateSharedMemory;
  PLSA_FREE_SHARED_MEMORY         FreeSharedMemory;
  PLSA_DELETE_SHARED_MEMORY       DeleteSharedMemory;
  PLSA_OPEN_SAM_USER              OpenSamUser;
  PLSA_GET_USER_CREDENTIALS       GetUserCredentials;
  PLSA_GET_USER_AUTH_DATA         GetUserAuthData;
  PLSA_CLOSE_SAM_USER             CloseSamUser;
  PLSA_CONVERT_AUTH_DATA_TO_TOKEN ConvertAuthDataToToken;
  PLSA_CLIENT_CALLBACK            ClientCallback;
  PLSA_UPDATE_PRIMARY_CREDENTIALS UpdateCredentials;
  PLSA_GET_AUTH_DATA_FOR_USER     GetAuthDataForUser;
  PLSA_CRACK_SINGLE_NAME          CrackSingleName;
  PLSA_AUDIT_ACCOUNT_LOGON        AuditAccountLogon;
  PLSA_CALL_PACKAGE_PASSTHROUGH   CallPackagePassthrough;
} LSA_SECPKG_FUNCTION_TABLE, *PLSA_SECPKG_FUNCTION_TABLE;

Members

For descriptions of the dispatch functions pointed to by the members of this structure, see LSA Functions Called By SSP/APs.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


SECPKG_CALL_INFO

The SECPKG_CALL_INFO structure contains information about a currently executing call. This structure is used by the GetCallInfo function.

typedef struct _SECPKG_CALL_INFO {
  ULONG ProcessId;
  ULONG ThreadId;
  ULONG Attributes;
  ULONG CallCount;
} SECPKG_CALL_INFO, * PSECPKG_CALL_INFO;

Members

ProcessId
The process identifier of the call.
ThreadId
The thread identifier of the call.
Attributes
The set of attribute flags that describe the call. The following table lists the valid attribute flag values.
Flag | Meaning
SECPKG_CALL_KERNEL_MODE | Call originated in kernel mode.
SECPKG_CALL_ANSI | Call came from ANSI stub.
SECPKG_CALL_URGENT | Call designated urgent.
SECPKG_CALL_RECURSIVE | Call is recursing.
SECPKG_CALL_IN_PROC | Call originated in process.
SECPKG_CALL_CLEANUP | Call is cleanup from a client.

CallCount
The call count.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


SECPKG_CLIENT_INFO

The SECPKG_CLIENT_INFO structure holds information about a security package's client. This structure is used by the GetClientInfo function.

typedef struct _SECPKG_CLIENT_INFO {
  LUID LogonId;
  ULONG ProcessID;
  ULONG ThreadID;
  BOOLEAN HasTcbPrivilege;
  BOOLEAN Impersonating;
  BOOLEAN Restricted;
} SECPKG_CLIENT_INFO, * PSECPKG_CLIENT_INFO;

Members

LogonId
The client's effective logon identifier.
ProcessID
The client's process identifier.
ThreadID
The client's thread identifier.
HasTcbPrivilege
TRUE if the client has the SeTcbPrivilege privilege; otherwise FALSE.
Impersonating
TRUE if the client is impersonating another security principal.
Restricted
The client is restricted in its ability to access securable objects or perform privileged operations.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


SECPKG_CONTEXT_THUNKS

The SECPKG_CONTEXT_THUNKS structure contains information about QueryContextAttributes calls to be executed in LSA mode.

This structure is used by the SpGetExtendedInformation and SpSetExtendedInformation functions.

typedef struct _SECPKG_CONTEXT_THUNKS {
  ULONG   InfoLevelCount;
  ULONG   Levels[1];
} SECPKG_CONTEXT_THUNKS, *PSECPKG_CONTEXT_THUNKS;

Members

InfoLevelCount
The number of attributes specified by the Levels parameter.
Levels
An array of one or more context attributes. See QueryContextAttributes for a complete list of valid values.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


SECPKG_DLL_FUNCTIONS

The SECPKG_DLL_FUNCTIONS structure contains pointers to the LSA functions that a security package can call while executing in-process with a client/server application. The LSA provides this structure during user-mode initialization using each security package's SpInstanceInit function.

typedef struct _SECPKG_DLL_FUNCTIONS {
  PLSA_ALLOCATE_LSA_HEAP AllocateHeap;
  PLSA_FREE_LSA_HEAP     FreeHeap;
  PLSA_REGISTER_CALLBACK RegisterCallback ;
} SECPKG_DLL_FUNCTIONS, * PSECPKG_DLL_FUNCTIONS;

Members

For descriptions of the functions pointed to by the members of this structure, see LSA Functions Called by User-Mode SSP/APs.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


SECPKG_EVENT_NOTIFY

The SECPKG_EVENT_NOTIFY structure contains information about security events. This structure is passed to a function registered to receive event notifications. Event notification functions are registered by calling the RegisterNotification function.

typedef struct _SECPKG_EVENT_NOTIFY {
  ULONG EventClass;
  ULONG Reserved;
  ULONG EventDataSize;
  PVOID EventData;
  PVOID PackageParameter;
} SECPKG_EVENT_NOTIFY, *PSECPKG_EVENT_NOTIFY ;

Members

EventClass
The event class.
Reserved
Reserved.
EventDataSize
The size of the EventData member.
EventData
The event details.
PackageParameter
Information specified as the Parameter value when RegisterNotification is called to register for notification.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


SECPKG_EVENT_PACKAGE_CHANGE

The SECPKG_EVENT_PACKAGE_CHANGE structure contains information about changes in security package availability. This structure is indirectly used by the RegisterNotification function. It is returned to a registered notification function when the function is registered to receive notifications for the NotificationClass parameter value NOTIFY_CLASS_PACKAGE_CHANGE.

typedef struct _SECPKG_EVENT_PACKAGE_CHANGE {
  ULONG ChangeType;
  LSA_SEC_HANDLE PackageId;
  SECURITY_STRING PackageName;
} SECPKG_EVENT_PACKAGE_CHANGE, * PSECPKG_EVENT_PACKAGE_CHANGE ;

Members

ChangeType
The type of change. One of the following values will be specified.
Value | Description
SECPKG_PACKAGE_CHANGE_LOAD | A package was loaded.
SECPKG_PACKAGE_CHANGE_UNLOAD | A package was unloaded.
SECPKG_PACKAGE_CHANGE_SELECT | A new package became the preferred security package.

PackageId
The identifier of the security package.
PackageName
The name of the security package.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


SECPKG_EXTENDED_INFORMATION

The SECPKG_EXTENDED_INFORMATION structure is used to hold information about optional package capabilities.

This structure is used by the SpGetExtendedInformation and SpSetExtendedInformation functions.

typedef struct _SECPKG_EXTENDED_INFORMATION {
  SECPKG_EXTENDED_INFORMATION_CLASS   Class;
  union {
  SECPKG_GSS_INFO          GssInfo;
  SECPKG_CONTEXT_THUNKS    ContextThunks;
  SECPKG_MUTUAL_AUTH_LEVEL MutualAuthLevel;
  } Info;
} SECPKG_EXTENDED_INFORMATION, * PSECPKG_EXTENDED_INFORMATION;

Members

Class
A value from the SECPKG_EXTENDED_INFORMATION_CLASS enumeration which identifies the information in the structure.
GssInfo
A SECPKG_GSS_INFO structure containing information used for GSS-compatible negotiations.
ContextThunks
A SECPKG_CONTEXT_THUNKS structure containing information about QueryContextAttributes calls to be executed in LSA mode.
MutualAuthLevel
A SECPKG_MUTUAL_AUTH_LEVEL structure containing the authentication level used by a security package.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


SECPKG_FUNCTION_TABLE

The SECPKG_FUNCTION_TABLE structure contains pointers to the LSA functions that a security package must implement. The LSA obtains this structure from an SSP/AP DLL when it calls the SpLsaModeInitialize function.

typedef struct _SECPKG_FUNCTION_TABLE {
  PLSA_AP_INITIALIZE_PACKAGE       InitializePackage;
  PLSA_AP_LOGON_USER               LogonUser;
  PLSA_AP_CALL_PACKAGE             CallPackage;
  PLSA_AP_LOGON_TERMINATED         LogonTerminated;
  PLSA_AP_CALL_PACKAGE_UNTRUSTED   CallPackageUntrusted;
  PLSA_AP_CALL_PACKAGE_PASSTHROUGH CallPackagePassthrough;
  PLSA_AP_LOGON_USER_EX            LogonUserEx;
  PLSA_AP_LOGON_USER_EX2           LogonUserEx2;
  SpInitializeFn                 * Initialize;
  SpShutdownFn                   * Shutdown;
  SpGetInfoFn                    * GetInfo;
  SpAcceptCredentialsFn          * AcceptCredentials;
  SpAcquireCredentialsHandleFn   * AcquireCredentialsHandle;
  SpQueryCredentialsAttributesFn * QueryCredentialsAttributes;
  SpFreeCredentialsHandleFn      * FreeCredentialsHandle;
  SpSaveCredentialsFn            * SaveCredentials;
  SpGetCredentialsFn             * GetCredentials;
  SpDeleteCredentialsFn          * DeleteCredentials;
  SpInitLsaModeContextFn         * InitLsaModeContext;
  SpAcceptLsaModeContextFn       * AcceptLsaModeContext;
  SpDeleteContextFn              * DeleteContext;
  SpApplyControlTokenFn          * ApplyControlToken;
  SpGetUserInfoFn                * GetUserInfo;
  SpGetExtendedInformationFn     * GetExtendedInformation;
  SpQueryContextAttributesFn     * QueryContextAttributes;
  SpAddCredentialsFn             * AddCredentials;
  SpSetExtendedInformationFn     * SetExtendedInformation;
} SECPKG_FUNCTION_TABLE, *PSECPKG_FUNCTION_TABLE;

Members

For descriptions of the functions pointed to by the members of this structure, see Functions Implemented by SSP/APs.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


SECPKG_GSS_INFO

A SECPKG_GSS_INFO structure contains information used for GSS-compatible negotiations.

This structure is used by the SpGetExtendedInformation and SpSetExtendedInformation functions.

typedef struct _SECPKG_GSS_INFO {
  ULONG EncodedIdLength;
  UCHAR EncodedId[4];
} SECPKG_GSS_INFO, * PSECPKG_GSS_INFO;

Members

EncodedIdLength
The encoded GSS OID length.
EncodedId
The encoded GSS OID.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


SECPKG_MUTUAL_AUTH_LEVEL

The SECPKG_MUTUAL_AUTH_LEVEL structure contains the authentication level used by a security package.

This structure is used by the SpGetExtendedInformation, and SpSetExtendedInformation functions.

typedef struct _SECPKG_MUTUAL_AUTH_LEVEL {
  ULONG MutualAuthLevel;
} SECPKG_MUTUAL_AUTH_LEVEL, * PSECPKG_MUTUAL_AUTH_LEVEL ;

Members

MutualAuthLevel
The mutual authentication level.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


SECPKG_PARAMETERS

The SECPKG_PARAMETERS structure contains information about the computer system. This structure is used by the SpInitialize function.

typedef struct _SECPKG_PARAMETERS {
  ULONG Version;
  ULONG MachineState;
  ULONG SetupMode;
  PSID DomainSid;
  UNICODE_STRING DomainName;
  UNICODE_STRING DnsDomainName;
  GUID DomainGuid;
} SECPKG_PARAMETERS, *PSECPKG_PARAMETERS;

Members

Version
The version of the Security Support Provider Interface in use.
MachineState
The state of the machine. The following table lists the valid values.
Value | Decscription
SECPKG_STATE_ENCRYPTION_PERMITTED | The security package may use encryption.
SECPKG_STATE_STRONG_ENCRYPTION_PERMITTED | The security package may use strong encryption.
SECPKG_STATE_DOMAIN_CONTROLLER | The machine is a domain controller.
SECPKG_STATE_WORKSTATION | The machine is a workstation with access to a network.
SECPKG_STATE_STANDALONE | The machine is a stand-alone system.

SetupMode
Contains a nonzero value if setup is running.
DomainSid
The security identifier of the primary domain.
DomainName
The name of the primary domain.
DnsDomainName
The Domain Name System (DNS) name of the primary domain.
DomainGuid
The GUID of the primary domain.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


SECPKG_PRIMARY_CRED

The SECPKG_PRIMARY_CRED structure contains the primary credentials. This structure is used by the LsaApLogonUserEx2 and SpAcceptCredentials functions.

typedef struct _SECPKG_PRIMARY_CRED {
  LUID LogonId;
  UNICODE_STRING DownlevelName;
  UNICODE_STRING DomainName;
  UNICODE_STRING Password;
  UNICODE_STRING OldPassword;
  PSID UserSid;
  ULONG Flags;
  UNICODE_STRING DnsDomainName;
  UNICODE_STRING Upn;
  UNICODE_STRING LogonServer;
  UNICODE_STRING Spare1;
  UNICODE_STRING Spare2;
  UNICODE_STRING Spare3;
  UNICODE_STRING Spare4;
} SECPKG_PRIMARY_CRED, *PSECPKG_PRIMARY_CRED;

Members

LogonId
The logon identifier.
DownlevelName
A UNICODE_STRING structure containing the Security Accounts Manager account name.
DomainName
A UNICODE_STRING structure containing the NETBIOS domain name where the account is located.
Password
A UNICODE_STRING structure containing the logon password.
OldPassword
A UNICODE_STRING structure containing the old password.
UserSid
Pointer to the security identifier.
Flags
The set of primary credentials flags. The following table lists the valid values for the Flags member.
Flag value | Description
PRIMARY_CRED_CLEAR_PASSWORD | The passwords are in clear text.
PRIMARY_CRED_OWF_PASSWORD | The passwords are encrypted using a one-way function.
PRIMARY_CRED_UPDATE | This is a change of existing credentials.
PRIMARY_CRED_CACHED_LOGON | The credentials were obtained from a cached logon. For more information, see Remarks.

DnsDomainName
A UNICODE_STRING structure containing the DNS domain name where the user account is located, if known.
Upn
A UNICODE_STRING structure containing the user principal name (UPN), if known.
LogonServer
A UNICODE_STRING structure containing the name of the server that processed the logon.
Spare1
A UNICODE_STRING structure. Reserved.
Spare2
A UNICODE_STRING structure. Reserved.
Spare3
A UNICODE_STRING structure. Reserved.
Spare4
A UNICODE_STRING structure. Reserved.

Remarks

For cached logons the RPC identifier of the package performing the logon is identified by shifting the Flags member to the right by the PRIMARY_CRED_LOGON_PACKAGE_SHIFT constant defined below.

#define PRIMARY_CRED_LOGON_PACKAGE_SHIFT 24

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


SECPKG_SUPPLEMENTAL_CRED

The SECPKG_SUPPLEMENTAL_CRED structure contains supplemental credentials recognized by the security package.

The structure is used by the SpAcceptCredentials function and the SECPKG_SUPPLEMENTAL_CRED_ARRAY structure.

typedef struct _SECPKG_SUPPLEMENTAL_CRED {
  UNICODE_STRING PackageName;
  ULONG CredentialSize;
  PUCHAR Credentials;
} SECPKG_SUPPLEMENTAL_CRED, *PSECPKG_SUPPLEMENTAL_CRED;

Member

PackageName
The name of the authentication package that authenticated the credentials.
CredentialSize
The size of the Credentials member, in bytes.
Credentials
Pointer to a set of package-specific supplemental credentials.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


SECPKG_SUPPLEMENTAL_CRED_ARRAY

The SECPKG_SUPPLEMENTAL_CRED_ARRAY structure contains supplemental credentials information. This structure is used by the LsaApLogonUserEx2 and UpdateCredentials functions.

typedef struct _SECPKG_SUPPLEMENTAL_CRED_ARRAY {
  ULONG CredentialCount;
  SECPKG_SUPPLEMENTAL_CRED Credentials[1];
} SECPKG_SUPPLEMENTAL_CRED_ARRAY, *PSECPKG_SUPPLEMENTAL_CRED_ARRAY;

Members

CredentialCount
The number of supplemental credentials in the Credentials member.
Credentials
An array containing supplemental credentials.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


SECPKG_USER_FUNCTION_TABLE

The SECPKG_USER_FUNCTION_TABLE structure contains pointers to the functions that a security package implements to support executing in process with client/server applications. This structure is provided by the SpUserModeInitialize function.

typedef struct _SECPKG_USER_FUNCTION_TABLE {
  SpInstanceInitFn *                 InstanceInit;
  SpInitUserModeContextFn *          InitUserModeContext;
  SpMakeSignatureFn *                MakeSignature;
  SpVerifySignatureFn *              VerifySignature;
  SpSealMessageFn *                  SealMessage;
  SpUnsealMessageFn *                UnsealMessage;
  SpGetContextTokenFn *              GetContextToken;
  SpQueryContextAttributesFn *       QueryContextAttributes;
  SpCompleteAuthTokenFn *            CompleteAuthToken;
  SpDeleteContextFn *                DeleteUserModeContext;
  SpFormatCredentialsFn *            FormatCredentials;
  SpMarshallSupplementalCredsFn *    MarshallSupplementalCreds;
  SpExportSecurityContextFn *        ExportContext;
  SpImportSecurityContextFn *        ImportContext;
} SECPKG_USER_FUNCTION_TABLE, *PSECPKG_USER_FUNCTION_TABLE;

Members

For descriptions of the functions pointed to by the members of this structure, see Functions Implemented by User-Mode SSP/APs

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


SecurityUserData

The SecurityUserData structure contains information about the user of a security support provider/authentication package. This structure is used by the SpGetUserInfo function.

typedef struct _SECURITY_USER_DATA {
  SECURITY_STRING UserName;
  SECURITY_STRING LogonDomainName;
  SECURITY_STRING LogonServer;
  PSID pSid;
} SECURITY_USER_DATA, *PSECURITY_USER_DATA, SecurityUserData, * PSecurityUserData;

Members

UserName
The name of the user.
LogonDomainName
The domain the user is logged onto.
LogonServer
The name of the server that logged the user on.
pSid
The security identifier (SID) of the user.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Ntsecpkg.h.


Custom Security Package Data Types

Custom security package functions use the following data types.

Enumerated data type | Description
SECPKG_EXTENDED_INFORMATION_CLASS | Indicates the type of information to get or set for a security package.
SECPKG_NAME_TYPE | Indicates the type of name specified for an account.


SECPKG_EXTENDED_INFORMATION_CLASS

The SECPKG_EXTENDED_INFORMATION_CLASS enumeration describes the type of information to set or get for a security package.

This enumeration is used by the SpGetExtendedInformation and SpSetExtendedInformation functions.

typedef enum _SECPKG_EXTENDED_INFORMATION_CLASS {
  SecpkgGssInfo = 1,
  SecpkgContextThunks,
  SecpkgMutualAuthLevel,
  SecpkgMaxInfo
} SECPKG_EXTENDED_INFORMATION_CLASS ;

Enumerated Values

SecpkgGssInfo
GSS OID information used to identify the security package in GSS-compatible negotiations.
SecpkgContextThunks
Identifies the calls to the QueryContextAttributes function that are handled in the LSA process space (LSA mode) rather than being handled in the client process space (user mode).
SecpkgMutualAuthLevel
The mutual authentication level used in the system. This value is valid for the SpGetExtendedInformation function only.
SecpkgMaxInfo
The end value for the enumeration. This value is not a valid parameter value.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


SECPKG_NAME_TYPE

The SECPKG_NAME_TYPE enumeration is used to describe the type of name specified for an account.

The SECPKG_NAME_TYPE enumeration is used by the GetAuthDataForUser and OpenSamUser functions.

typedef enum _SECPKG_NAME_TYPE {
  SecNameSamCompatible,
  SecNameAlternateId,
  SecNameFlat,
  SecNameDN
} SECPKG_NAME_TYPE;

Enumerated Values

SecNameSamCompatible
The account name is a Windows NT 4.0–style name.
SecNameAlternateId
The account name is in the AltSecId property of the SAM account.
SecNameFlat
The account name is a flat user principal name (UPN) style account name.
SecNameDN
The account name is the distinguished name of the object.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecpkg.h.


Certificate Services and Components

Certificate Services forms the basis for public key infrastructure. The following sections provide detailed information about Certificate Services and other components related to the certificate request process.

Topic | Description
Certificate Services | Service which issues and manages public key certificates.
Certificate Enrollment Control | ActiveX® control for generating a certificate request.
Smart Card Enrollment Control | ActiveX control for issuing certificates to a smart card.


Certificate Services

Purpose

Certificate Services provides customizable services for issuing and managing certificates used in software security systems employing public-key cryptography. Certificate Services performs a central role in the management of software security systems to enable secure communications across the Internet, corporate intranets, and other nonsecure networks.

Where Applicable

Certificate Services accepts standard PKCS #10 certificate requests and generates certificates in standard X.509 format. Certificates in X.509 format are used in all commercial Public Key Infrastructure (PKI) products. PKI protocols, such as Secure Sockets Layer (SSL) and Secure/Multipurpose Internet Mail Extensions (S/MIME), use certificates in X.509 format.

See Also

Certificate Enrollment Control

Crypto API

Smart Card Enrollment Control

Smart Card

About Certificate Services

Certificate Services concepts.

Using Certificate Services

Using and customizing Certificate Services components.

Certificate Services Reference

Certificate Services interfaces, their methods, and properties.

Feedback

Make error reports and feature requests directly to Microsoft.


About Certificate Services

Certificate Services receives requests for new certificates over transports such as RPC or HTTP. It checks each request against custom or site-specific policies, sets optional properties for the certificate to be issued, and issues the certificate. Certificate Services allows administrators to add elements to a certificate revocation list (CRL), and publish a signed CRL on a regular basis. Programmable interfaces are included for you to create support for additional transports, policies, and certificate properties and formats.

Certificate Services 2.0 can be installed in Microsoft® Windows® 2000 Server by means of the Control Panel's Add/Remove Programs icon; once the Add/Remove Programs application is running, choose Add/Remove Windows Components to install or uninstall Certificate Services. It is strongly recommended that users of the Certificate Services SDK become familiar with the Certificate Services product, including reading the Windows 2000 Help content for Certificate Services.

Certificate Services concepts are detailed in the following sections. The content is intended to help you develop applications that will interact with Certificate Services. For additional information, read the Certificate Services user documentation included in Microsoft® Windows NT®/Windows® 2000 Help.

Content | Section
Description of the features of Certificate Services | Certificate Services Features
Overview of Certificate Services architecture | Certificate Services Architecture
Relationship between you, your certificate and your public key | You, Your Certificate, and Your Public Key
Information about the Certificate Request properties | Certificate Request Guidelines
Details of how a certificate is processed by Certificate Services | Certificates
Description of the certification authority renewal process | Certification Authority Renewal

You may also find the following topics useful.

Content | Section
Documentation on Certificate Enrollment Control, which provides services for creating certificate requests. | Certificate Enrollment Control
Documentation on the Microsoft® Cryptographic Application Programming Interface (CryptoAPI), which provides cryptography-based security services. | Crypto API
Documentation on Smart Card Enrollment Control, which provides services for enrolling smart card users. | Smart Card Enrollment Control
Documentation on Smart Card, which provides services for developing and using smart card systems. | Smart Card
Name properties of certificates and certificate requests. | Name Properties
List and descriptions of X.509 certificate properties. | Certificate Properties


Certificate Services Features

Certificate Services allows an organization to manage the issuing, renewal and revocation of certificates. It has a number of features which make it valuable to organizations that do not choose to rely upon external certification authorities and who need a flexible tool that can be adapted to the needs of the organization. The following sections provide specific details.

Content | Section
Active Directory™ integration | Active Directory
Adherence to Standards | Adherence to Standards
Application uses | Application uses
Extensible framework | Extensibility
Hardware cryptography support | Hardware cryptography
Hierarchy support | Hierarchies
Policy independence information | Policy Independence
Request support | Requests
Transport independence information | Transport Independence


Active Directory

Certificate Services supports the use of Microsoft® Active Directory™. In the case of the enterprise certification authority (CA), Certificate Services requires the use of the Active Directory. The enterprise CA publishes user certificates and certificate revocation lists (CRL) to the Active Directory. A stand-alone CA can be administered to perform the same actions provided the Active Directory is available to the stand-alone CA and a custom policy module is used.


Adherence to Standards

Certificate Services accepts standard PKCS #10 requests and issues X.509 3.0 certificates. Certificate Services works with non-Microsoft clients and browsers, and non-Microsoft Web servers.


Application Uses

Certificate Services issues certificates that can be used in public key infrastructure (PKI) applications. For example, the certificates work in SSL, S/MIME and IPSEC applications. Possible scenarios where these certificates can be used are digital signing and message encryption. Certificate Services provides certificates, certificate revocation lists (CRL), and CRL distribution points (CDP) that are usable by both Microsoft and non-Microsoft applications.


Extensibility

Certificate Services supports X.509 certificate extensions. Policy modules can add or modify extensions, and an exit module can retrieve these extensions.

See Extension Handlers for more information.


Hardware Cryptography

Certificate Services supports hardware-related cryptography, such as issuing certificates stored on smart cards. The enterprise certification authority (CA) supports the issuance of smart card certificates for Microsoft® Windows NT® domain logon. Additionally, both the enterprise CA and stand-alone CA support issuance of other types of smart card certificates.

Consult product documentation for specific details. For developer information about smart cards, see Smart Card. See Smart Card Enrollment Control for information regarding the control which allows an administrator to request smart card certificates on behalf of users.


Hierarchies

Certificate Services supports certification authority (CA) hierarchies. A CA hierarchy consists of a top-level CA (called the Root CA) with one or more subordinate CAs which have been issued certificates by the root CA. A possible CA hierarchy scenario would be in an organization with one root CA, which was used to issue certificates to several subordinate CAs. The subordinate CAs can then issue end-entity certificates, such as certificates issued to a user. The user's certificate will contain a trust path for the CA hierarchy, in this case, including the certificate for both the issuing subordinate CA as well as the root CA.


Policy Independence

Certificates are granted according to policies that define criteria that requesters must meet in order to receive a certificate. For example, one policy may be to grant commercial certificates only if applicants present their identification in person. Another policy may grant credentials based on e-mail requests. An agency that issues credit cards may choose to consult a database and make phone inquiries before issuing a card.

Policies are implemented in policy modules written in Microsoft® Visual Basic® or C/C++. Certificate Services functions are isolated from any changes in policy that an agency might implement. Changes in policy can be fully implemented in the server policy module code. An enterprise certification authority (CA) should use only the Microsoft-provided enterprise policy module.


Requests

Certificate Services supports certificate requests based on the PKCS #10 format and also on the Keygen (Netscape) format. Additionally, Certificate Services provides an ICertRequest interface, which contains methods for submitting a certificate request and (if the request is approved) for receiving the resulting issued certificate.

Additional security-related interfaces are available in the Certificate Enrollment Control (which can generate a PKCS #10 request ) and the Smart Card Enrollment Control (which can generate certificate requests on behalf of smart card users).


Transport Independence

Certificates can be requested and distributed through any transport mechanism. Certificate Services accepts certificate requests from an applicant through HTTP, DCOM, RPC, disk file, or by custom transport. Certificate Services posts certificates to the applicant through HTTP, DCOM, RPC, disk file, or custom transport.

Transports are supported by intermediary applications and exit module DLLs, usually written in C/C++. The intermediary applications and exit modules isolate Certificate Services functions from communicating with any specific transport.


Certificate Services Architecture

Certificate Services is a development platform for building Certification Authorities for enterprises or secure Internet applications. A configured and operational certification authority will allow a site to issue, track, manage, and revoke certificates with minimal administration overhead and maximal security.

The Certificate Services consists of the server engine, the server database, and a set of modules and tools that work together to function as a certification authority. External applications, modules, and administration tools use Component Object Model (COM) interfaces to interact with the server engine. The following diagram shows the interfaces used by the server engine:

An operational certification system will typically have four major subsystems.

Subsystem | Description
Client | The client is the software that is used by the end user to generate a certificate request, send the request, and receive the finished certificate. An example of a client is Microsoft® Internet Explorer version 5.0. The client will typically interact with a custom interface maintained by the intermediary application.
Intermediary | The intermediary is a subsystem that consists of the intermediary application and the Certificate Services client interface (Certificate Services Web Client in the setup program). The intermediary application interacts directly with the client, receiving certificate requests and returning finished certificates. It communicates with the server engine through the Certificate Services client interface, which contains the ICertConfig and ICertReqest COM interfaces. An example of an intermediary application is Microsoft® Internet Information Services. The intermediary application can be implemented entirely through Active Server Pages.
Server | The server is the system that builds the certificate. In addition to the server engine, two configurable components are included; the policy module and the exit module. The policy module interacts with the server engine through the ICertPolicy and ICertServerPolicy interfaces. Exit modules (there can be more than one) interact with the server engine through the ICertExit and ICertServerExit interfaces.
Administrative Client | The administrative client is the system that monitors and manages certificates and requests. The administrative client uses the ICertAdmin interface to communicate with the server engine.

For further information about Certificate Services architecture, see Certificate Services Interfaces and Building a Certificate, and the following topics.

Content | Section
Customizable programs that can be used during the evaluation of certificate requests; these programs enforce the rules by which Certificate Services issues or denies the request. | Policy Modules
Customizable programs that receive notifications from the server engine when operations occur, such as when a certificate is issued, | Exit Modules
COM objects that provide routines for encoding the more complex extensions and data types. | Extension Handlers
Programs that communicate with client applications to allow the submitting of certificate requests. | Intermediaries


Policy Modules

Policy modules are programs that receive requests from the Certificate Services, evaluate those requests, and specify optional properties of the certificates that are built to fill these requests. A policy module is implemented as a dynamic link library (DLL). A policy module can use the ICertServerPolicy interface to communicate with Certificate Services. Certificate Services communicates with a policy module by means of direct COM calls or if the module doesn't support direct COM calls, by means of OLE Automation.

A policy module may view existing certificate properties and extensions, and it may also view request attributes and properties. In addition, a policy module may set or modify certificate extensions and "NotBefore" and "NotAfter" properties, as well as the relative distinguished name (RDN) of a Certificate Subject, subject to certain restrictions. A policy module ultimately issues or denies the certificate request or holds it pending.

Before writing a custom policy module, consider using one of the default policy modules. Both the Certificate Services enterprise certification authority (CA) and stand-alone CA ship with an appropriate default policy module. Both the enterprise and stand-alone default policy modules issue certificate requests (although the stand-alone default policy is to hold the certificate pending until it is manually issued by an administrator). An enterprise certification authority should use only the Microsoft-provided enterprise policy module.

The enterprise CA requires the Active Directory™. Additional features of its default policy module include certificate templates, access control list (ACL) security on the certificate templates to ensure requests are issued to only those authorized, predefined extensions added to the issued certificate, and support for smart card Windows NT domain logon certificates.

The default stand-alone CA policy module doesn't support many of the features of the default enterprise module, but it does support the issuance of smart card certificates (but not for Windows NT domain logon). See the product documentation for specific details as well as the most current capabilities of the default policy module.

For installations where the default policy module is unacceptable, Certificate Services allows custom policy modules. For more information, see Writing Custom Policy Modules.


Exit Modules

Exit modules receive notifications from the server engine when operations such as the issuance of a certificate occur. An exit module is implemented as a dynamic link library (DLL). A typical operation for an exit module is to publish a completed certificate in a specified location (the default enterprise certification authority exit module, for instance, publishes user certificates and certificate revocation lists (CRLs) to the Active Directory™). An exit module can use the ICertServerExit interface to communicate with Certificate Services. Certificate Services communicates with an exit module by means of direct COM calls, or if the module doesn't support direct COM calls, by means of OLE Automation.

An exit module may view existing certificate properties and extensions, and it may also view request attributes and properties. An exit module cannot, however, modify any properties.

Certificate Services provides a default exit module, but you can also create custom exit modules to meet special needs. However, before writing a custom exit module, consider using the default exit module. Moreover, for an enterprise certifcation authority, the default exit moduleshould always be used, even though you can add additional, custom exit modules. For more information, see Writing Custom Exit Modules.


Extension Handlers

Beginning with X.509 Certificate format Version 3, a certificate may contain certificate extensions. (See Certificate Properties for the contents of an X.509 Certificate). These extensions indicate additional information. For example, an extension can indicate additional subject identification information, or it can indicate key usage information, which specifies the tasks (such as signature or encryption) for which a key can be used. A set of standard extensions is defined for application use, and extensions may also be customized.

Each extension has an associated object identifier string that identifies the type of additional information and a data structure that contains this information. For example, the key usage object identifier is "2.5.29.15", which indicates key usage information. Its associated data structure is a CRYPT_BIT_BLOB (bit field) specifying how the key can be used.

An extension can be added to a certificate before it is issued. When the certificate is issued, any enabled extensions are part of the certificate. If an extension is marked critical, its use must be known by the using application, and the application must adhere to the intent or value of the extension. Certificate Services allows extensions to be set on a non-issued certificate through methods provided by ICertAdmin and ICertServerPolicy. See CERT_EXTENSION in the Crypto API documentation for details about certificate extensions, and see X.509 Certificate Extension Structures for information about common certificate extension data structures.

The extension handler is a COM object that provides routines for encoding the more complex, but commonly used extensions and data types, such as IA5String or PrintableString.

Extensions that have the data types DATE, LONG, and BSTR do not require an extension handler. The policy module simply calls ICertServerPolicy::SetCertificateExtension with the Type parameter set to a value representing the extension data type: PROPTYPE_DATE, PROPTYPE_LONG, or PROPTYPE_STRING. It then passes the extension to the server engine. The server engine, in turn, performs the ASN.1 encoding before storing the extension in the certificate.

However, extensions that have data types other than these default types must be ASN.1 encoded by an extension handler before the policy module passes them to the server engine. When the policy module calls ICertServerPolicy::SetCertificateExtension to pass an ASN.1-encoded extension to the server engine, it must set the Type parameter to PROPTYPE_BINARY. The server engine then simply stores this encoded extension in the certificate.

The default extension handler, CertEnc.dll, exports a number of ICertEncodeXXX interfaces and can be called by the policy module. The necessary type information is also contained in CertEncL.dll which is supplied in the Platform SDK for Windows 2000. Each interface provides an Encode method that returns an ASN.1-encoded certificate extension to the policy module in a binary format. The policy module can then set the extension in a certificate by calling the ICertServerPolicy::SetCertificateExtension method.

For more information, see Writing Custom Extension Handlers.


Intermediaries

Intermediaries communicate with client applications to allow them to submit certificate requests, and (assuming that the request results in an issued certificate) to download the issued certificate to the client. Each transport layer protocol requires its own intermediary.

Microsoft Certificate Services ships with an intermediary (the web enrollment pages) for HTTP. Another example of an intermediary is the Microsoft Windows 2000 Certificates MMC snap-in (which allows the Certificate Request Wizard to be invoked). If other transport layer protocols are to be used with Certificate Services, a developer can create an intermediary for each desired transport layer protocol.

Intermediaries communicate with Certificate Services using the ICertRequest and ICertConfig interfaces provided by the server engine. The ICertRequest::Submit method is used to submit a certificate request, and ICertRequest::GetCertificate is used to get the resulting issued certificate. Similarly, ICertConfig::GetConfig is used to determine which certification authority can be used to issue the certificate.

An intermediary is not language-dependent. It may be a program written in C++, Microsoft® Visual Basic®, Java, script, or another language.

In addition to gathering data from the client to build a certificate request, an intermediary may specify request attributes. Requests submitted to a certification authority running the enterprise policy module must indicate the type of certificate requested by specifying either a "CertificateTemplate" attribute or a Certificate Template extension in the request itself.

Note that during the creation of a certificate request, developers (and intermediaries) are responsible for maintaining the secrecy of the private key. Once a private key has been compromised (lost its secrecy), it is useless.

The Certificate Services web enrollment pages use the Certificate Enrollment Control, which protects private keys by generating them on the workstation. In addition to maintaining the secrecy of the private key, the Certificate Enrollment Control allows an intermediary to specify the Cryptographic Service Provider, key specification, key strength, and hash algorithm.

The Certificates MMC snap-in also uses the Certificate Enrollment Control (xenroll.dll). However, where the Certificate Services web enrollment pages cause the Certificate Enrollment Control resource (xenroll.dll) to be downloaded to the client if needed, the Certificates MMC snap-in runs in an environment where xenroll.dll is already an available resource.

In addition to ICertRequest and ICertConfig, developers of intermediaries may find the Certificate Enrollment Control and the Smart Card Enrollment Control to be useful.


You, Your Certificate, and Your Public Key

Certificate Services is a foundation for the Public Key Infrastructure (PKI), which provides the means for safeguarding and authenticating information. The relationship between a certificate holder, the certificate holder's identity, and the certificate holder's public key is a critical portion of PKI.

The public/private key pair

Public key infrastructure requires that a public/private key pair be used with each certificate. The mathematics of the public/private key pair are beyond the scope of this documentation, but it is important to note the functional relationship between the public and private key. In the public key infrastructure, cryptographic algorithms allow a public key to be used to encrypt data, and the related private key (and only the related private key) to decrypt the data. Similarly, a digital signature of the content (described in greater detail below) can be created with a private key. The corresponding public key can then be used to verify this signature. It is highly important to maintain the secrecy of the private key. The framework falls apart once the private key is compromised.

It should be noted that given enough time and resources, a public/private key pair can be compromised (the private key can be determined). The greater the length of the key, the more difficult it is to use such brute force to determine the private key. In practice, sufficiently strong keys can be used to make it unfeasible to determine the private key in a timely manner, making the Public Key Infrastructure a viable security mechanism.

Your private key may be stored (in protected format) on your hard disk, in which case you can use it only with the specific computer unless you move the key to another computer. An alternative is to have a key on a smart card, which can be used on a different computer provided it has a smart card reader and supporting software (Windows 2000 supports both the moving of keys as well as the use of smart cards).

Your public key is included as part of the certificate request (hence, a public/private key pair must exist before making the certificate request). The public key becomes part of the issued certificate.

The Certificate Request

Before a certificate is issued, a certificate request must be generated. This request applies to one entity, for example, an end-user, a machine, or an application. For discussion, assume that the entity is yourself. Details of your identity are included in the certificate request. Once the request is generated, it is submitted to a certification authority (CA). The CA then uses your identity information to determine if the request meets the CA's criteria for issuing a certificate. If the CA approves the request, it issues a certificate to you, as the entity named in the request.

The Certification Authority

Before issuing your certificate, the CA verifies your identity. When the certificate is issued, your identity is bound to the certificate, which contains your public key. Your certificate also contains the CA's digital signature (which can be verified by anyone who receives your certificate).

Because your certificate contains the identity of the issuing CA, an interested party that trusts this CA can extend that trust to your certificate. The issuance of a certificate doesn't establish trust, but transfers trust. If the certificate consumer doesn't trust the issuing CA, it won't (or at least shouldn't) trust your certificate.

A chain of signed certificates allows trust to be transferred to other CAs as well. This allows parties who use different CAs to still be able to trust certificates (provided there is a common CA in the chain, that is, a CA that is trusted by both parties).

The Certificate

In addition to your public key and the identity of the issuing CA, the issued certificate contains information about the purposes of your key and certificate. Furthermore, it includes the path to the CA's list of revoked certificates, and it specifies the certificate validity period (beginning and ending dates).

Assuming the certificate consumer trusts the issuing CA for your certificate, the certificate consumer must determine if the certificate is still valid by comparing the certificate's beginning and ending dates with the current time and by checking that your certificate in not on the CA's list of revoked certificates.

The Certificate Revocation List

Assuming the certificate is being used in a valid time period and the certificate consumer trusts the issuing CA, there is one more item for the certificate consumer to check before using the certificate: the certificate revocation list (CRL). The certificate consumer checks the CA's CRL (the path to which is included as an extension in your certificate) to make sure your certificate isn't on the list of certificates that have been revoked. CRLs exist because there are times when a certificate hasn't expired, but it can no longer be trusted. Periodically, the CA will publish an updated CRL. Certificate consumers are responsible for comparing certificates to the current CRL before considering the certificate trustworthy.

Your Public Key Used for Encryption

If a sender wants to encrypt a message before sending it to you, the sender first retrieves your certificate. After the sender determines that the CA is trusted and your certificate is valid and not revoked, the sender uses your public key (recall it is part of the certificate) with cryptographic algorithms to encrypt the plaintext message into ciphertext. When you receive the ciphertext, you use your private key to decrypt the ciphertext.

If a third party intercepts the ciphertext email, the third party will not be able to decrypt it without access to your private key.

Note that the bulk of the activities listed here are handled by software, not directly by the user.

Your Public Key Used for Signature Verification

A digital signature is used as confirmation that a message has not been altered and as confirmation of the message sender's identity. This digital signature is dependent on your private key and the message contents. Using the message as input and your private key, cryptographic algorithms create the digital signature. The contents of the message are not changed by the signing process. A recipient can use your public key (after checking your certificate's validity, issuing CA, and revocation status) to determine if the signature corresponds to the message contents and to determine if the message was sent by you.

If a third party intercepts the intended message, alters it (even slightly) and forwards it and the original signature to the recipient, the recipient, upon examination of the message and signature, will be able to determine the message is suspect. Similarly, if a third party creates a message and sends it with a bogus digital signature under the guise it originated from you, the recipient will be able to use your public key to determine that the message and signature do not correspond to each other.

Non-repudiation is also supported by digital signatures. If the sender of a signed message denies sending the message, the recipient can use the signature to refute that claim.

Note that the bulk of the activities listed here are also handled by software, not directly by the user.

Microsoft Certificate Services Role

Microsoft Certificate Services has the role of issuing certificates or denying requests for certificates, as directed by policy modules, which are responsible for ensuring the identity of the certificate requester. Certificate Services also provides the ability to revoke a certificate, as well as publish the CRL. Certificate Services can also centrally distribute issued certificates, such as to a directory service. The ability to issue, distribute, revoke and manage certificates, along with the publication of CRLs, provides the necessary capabilities for public key infrastructure.


Certificate Request Guidelines

The following sections provide information about certificate property names and Distinguished Name (DN) fields.

Section | Information
Property Names | Table of property names and object identifiers.
Distinguished Name Fields | Description of identifier fields.


Property Names

A certificate request Property Name can either be the "friendly" name of one of the common properties that the Certificate Services understands or an object identifier (OID). See Name Properties for more information about request property names.


Distinguished Name Fields

A certificate request contains information that should uniquely identify the individual making the request.

PKCS #10 format certificate requests that are accepted by Certificate Services contain identification fields that are referred to as Distinguished Name (DN) fields. These fields will contain the information that is input by the user when a certificate request is being created by Key Manager, Certificate Enrollment Control, or some other means.

The following are some guidelines for completion of DN fields in a certificate request.

Field | Description
Common Name | User Certificates: You should enter the person's full name (for example, John H. Doe). Machine Certificates: You should enter the fully qualified hostname/path used in DNS lookups that the server will be running on (for example, hostname.Microsoft.com).
Organization | The name you specify for the Organization field should be the legal name for your organization that is registered with the appropriate state, country, or city authority. The legal name of the organization must be used in the Organization field.
Organizational Unit | The Organizational Unit field can be used to differentiate between different divisions within an organization, for example "Internet Security Unit" or "Human Resources." This field is also recommended to be used for specifying a DBA (Doing Business As...) value.
Locality | The Locality field denotes the city that the organization resides in. If the organization has local standing only, by virtue of having a business license registered with the City Clerk for the City of Cambridge in the State of Massachusetts, then the Locality field must contain Cambridge.
State or Province | The State or Province field specifies where the organization is physically located. If your organization is incorporated in Delaware but has a DBA (Doing Business As...) within California, use California. The State or Province field should not be an abbreviated field. For example, "CA" is not a valid state name. "California" is the proper state name.
Country | The X.500 Naming Scheme standard requires a 2-character country/region code. The country/region code for the United States is US; the country/region code for Canada is CA.

See Also

Name Properties


Certificates

The following sections provide information related to the creation and publication of a certificate.

Content | Section
Information about how Certificate Services processes a request | Processing Certificate Requests
Information about building a certificate | Building a Certificate
Certificate formats supported by Certificate Services | Supported Certificate Formats


Processing Certificate Requests

Certificate Services performs the following steps when processing a certificate request:

  1. Request reception. The certificate request is sent by the client to an intermediary application, which formats it into a PKCS #10 format request and submits it to the server engine.
  2. Request approval. The server engine calls the Policy Module, which queries request properties, decides whether the request is authorized or not, and sets optional certificate properties.
  3. Certificate formation. If the request is approved, the server engine takes the request, and any properties requested by the Policy Module, and builds a complete certificate.
  4. Certificate publication. The server engine stores the completed certificate in the Certificate Services database and notifies the intermediary application of the request status. If the exit module has so requested, the server engine will notify it of a certificate issuance event. This allows the exit module to perform further operations such as publishing the certificate to an external certificate repository (for example, a directory service). Meanwhile, the intermediary gets the published certificate from Certificate Services and passes it back to the client.

The following diagram illustrates how a certificate request is processed by Certificate Services:


Building a Certificate

The order of calls in building a certificate is as follows:

  1. Certification authority (CA) initializes modules through calls to ICertPolicy and ICertExit (happens once on server initialization). The CA will initialize the policy and exit modules by calling ICertPolicy::Initialize and ICertExit::Initialize.
  2. Intermediary calls the CA through ICertConfig (happens once per intermediary initialization). The intermediary finds the needed configuration string by calling ICertConfig::GetConfig.
  3. Client calls the intermediary through an interface specific to the intermediary (happens once per request). The client sends a certificate request to the intermediary. This can be, for example, Microsoft® Internet Explorer sending a request through Certificate Enrollment Control to Microsoft Internet Information Services.
  4. Intermediary to CA through ICertRequest (happens once per request). The intermediary sends the certificate request to the CA through ICertRequest::Submit. In the case of Internet Information Services, this could be done through Active Server Page scripts.
  5. The CA calls the Policy Module through the ICertPolicy interface (happens once per request). The CA notifies the policy module that a request has arrived by calling ICertPolicy::VerifyRequest. The policy module can examine the request and change the certificate by calling methods of the ICertServerPolicy interface. The policy module can then indicate that the request is OK (if so, the certificate is built at this point), the request is to be denied, or the request should be suspended.
  6. (Optional) Administrator calls the CA through the ICertAdmin interface. If the request is suspended, the administrator can resubmit or deny the request, or modify request attributes and extensions. Note that if the request is resubmitted, the Policy Module will have another opportunity to process the request (as a result of a call to ICertPolicy::VerifyRequest). The task of resubmitting or denying the request can be performed by means of the Certification Authority MMC snap-in, or another application that uses ICertAdmin.
  7. The CA calls the exit module through the ICertExit interface. If the exit module has indicated (when ICertExit::Initialize was called, in step 1) that it is interested in seeing certificates issued or requests held pending, the CA will call ICertExit::Notify.
  8. The exit module calls the CA through the ICertServerExit interface. The exit module can examine the request and the new certificate by calling methods of ICertServerExit.


Supported Certificate Formats

Certificate Services can issue the following types of certificates:

  • X.509 v3 SSL-compatible client authentication certificate. This client authentication certificate identifies a client and is used by servers to authenticate a client that requests server access.
  • X.509 v3 SSL-compatible server authentication certificate. This server authentication certificate identifies a server and is used by clients to authenticate a server that the client wants to access.
  • S/MIME certificate. This certificate is used by clients for secure e-mail under the S/MIME (Secure/Multipurpose Internet Mail Extensions) protocol.
  • In addition to these certificates, Certificate Services can also be used to issue other X.509 certificates by writing a custom policy module.

    Note "Server authentication certificate" and "server certificate" as well as "client authentication certificate" and "client certificate" are interchangeable terms.

Additionally, Certificate Services includes certificate templates in the Microsoft Windows 2000 enterprise certification authority configuration. Consult the Windows 2000 Help documentation for certificate templates to understand how they define certificate purposes.


Certification Authority Renewal

Certificate Services 2.0 (released with Windows 2000) supports the renewal of a certification authority (CA). Renewal is the issuing of a new certificate for the CA in order to extend the CA's life beyond the end date of its original certificate. You can renew a CA as a task within the Certificate Authority MMC snap-in or by using the certutil.exe command-line utility (with the -renewCert verb).

Each renewal results in a new CA certificate; however, the administrator can either generate a new public/private key pair or re-use the existing public/private key pair for the CA certificate. For consistency and integrity, CA certificates and certificate revocation lists (CRL) issued by the CA before its renewal will be available after the CA has been renewed. To make these available, Certificate Services maintains an index of CA certificates, CRLs, and keys.

The following table illustrates the indexes and suffix names of CA certificates and CRLs during various CA renewal operations.

Operation | CA Certificate Index | CA Certificate File Name Suffix | CRL and Key Index | CRL and Key Container Name Suffix
Original CA installation | 0 | "" | 0 | ""
Renewal with new key | 1 | "(1)" | 1 | "(1)"
Renewal re-using key | 2 | "(2)" | 1 | "(1)"
Renewal re-using key | 3 | "(3)" | 1 | "(1)"
Renewal with new key | 4 | "(4)" | 4 | "(4)"
Renewal re-using key | 5 | "(5)" | 4 | "(4)"
Renewal with new key | 6 | "(6)" | 6 | "(6)"
Renewal re-using key | 7 | "(7)" | 6 | "(6)"

When a CA is installed, the certificate index is 0 and the certificate suffix is "" (an empty string). Each time the certificate is renewed (whether or not keys are re-used), the certificate index is incremented by one, and the certificate filename suffix becomes a string of the form "(n)", where n represents the number of times the CA certificate has been renewed. As shown in the table above, after the first renewal, the certificate index is 1 and the certificate filename suffix is "(1)". After the second renewal, the certificate index is 2 and the certificate filename suffix is "(2)", and so on.

Although the CA certificate index and suffix are incremented by one each time the CA is renewed, the CRL and key indexes and the filename suffixes are set to the CA certificate index only if the renewal process includes a new public/private key pair. If it does not, the values of these indexes and suffixes remain the same as they were for the last index. During renewal, an administrator specifies whether a new key pair is generated or the existing key pair is used. (In the Certificate Authority MMC snap-in, an option in the user interface specifies a new or an existing key pair; in the certutil.exe command-line program, the command 'certutil -renewCert' renews the CA with a new key pair, while the command 'certutil -renewCert ReuseKeys' renews the CA with the existing key pair.)

The CRL index is directly tied to the key index, which is set to the CA certificate index only when a new key pair is used for the renewal. As shown in the table above, after the first renewal (which used a new key pair), the index of the CRL and key is set to 1, and the CRL and key container name suffix is "(1)". After the second renewal, however, the index of the CRL and key remains 1, and the CRL and key container name suffix also remains "(1)"; this is because the second renewal used the existing key pair and only one CRL is issued for each CA key pair.

You can retrieve the indexed CA certificates and CRLs by calling the GetCertificateProperty method (in both the ICertServerExit and ICertServerPolicy interfaces). When you retrieve certain properties related to the CA certificate or CRL, you can append the CA certificate's zero-based index to the property names. For example, to retrieve the CRL index corresponding to the CA's third certificate, pass the property "CRLIndex.2" to ICertServerPolicy::GetCertificateProperty; for the above table, the retrieved "CRLIndex.2" property value would be 1. A property called "CertCount" can be used to determine the number of times the CA has been issued a CA certificate.

Windows 2000 CA certificates and CRLs contain an extension which provides information about the certificate and key index. The extension is defined in wincrypt.h as szOID_CERTSRV_CA_VERSION with a value of "1.3.6.1.4.1.311.21.1". The extension data is a DWORD value (encoded as X509_INTEGER in the extension); the low 16 bits are the certificate index, and the high 16 bits are the key index.

As stated earlier, the initial installation of a CA produces a certificate index of 0 and a key index of 0. Renewal of a CA certificate will cause the certificate index to be incremented. If the key is reused in the renewal, the key index will be the same as the previous key index. If the key is not reused, the key index will match the new certificate index.

See Also

ICertServerPolicy::GetCertificateProperty, ICertServerExit::GetCertificateProperty


Using Certificate Services

The open architecture of Certificate Services allows you to customize the product. An example of customization is using the ICertRequest object in a Web page or application to request certificates.

For examples relevant to customizing Certificate Services, see the sample code accompanying the Platform SDK. Note that when using the sample code for Certificate Services, you must use the samples specific to each major operating system release. For example, Certificate Services 1.0, shipped as part of Microsoft® Windows NT® 4 Option Pack, supports samples specific to the Windows NT4 Option Pack release. Certificate Services 2.0, shipped as part of Microsoft Windows® 2000, supports samples specific to the Windows 2000 release.

Certificate Services 2.0 can be installed in Windows 2000 Server by means of the Control Panel's Add/Remove Programs icon; once the Add/Remove Programs application is running, choose Add/Remove Windows Components to install or uninstall Certificate Services. It is strongly recommended that users of the Certificate Services SDK become familiar with the Certificate Services product, including reading the Windows 2000 Help content for Certificate Services.

The following topics provide further information about customizing or more fully using Certificate Services.

Topic | Information
Programming Certificate Services | Information about error checking and setting the VARIANT data type field, as well as using the Certificate Services APIs in Java.
Retrieving An Issued Certificate From the Active Directory | Information and sample code to retrieve a certificate from the Active Directory™ after it has been placed there by Certificate Services.
Customizing the Certificate Services Web Enrollment Pages | Information for customization of the Certificate Services Web enrollment pages.
Writing Custom Policy Modules | Information about writing policy modules to be used by Certificate Services.
Writing Custom Exit Modules | Information about writing exit modules to be used by Certificate Services.
Writing Custom Extension Handlers | Information about writing extension handlers.
Viewing the Certificate Services Database | Information about programmatically viewing the Certificate Services database.
Using the Certificate Services Backup and Restore Functions | Using functions for backing up and restoring the Certificate Services database.


Programming Certificate Services

This section discusses the following programming considerations.

Topic | Content
Using Certificate Services in C++ | Information specific to using Certificate Services in C++
Using Certificate Services in Visual Basic | Information specific to using Certificate Services in Microsoft® Visual Basic®
Using Certificate Services in Java | Information specific to using Certificate Services in Java
Setting the Type Tag Field | Indicating the data type for a VARIANT variable
Retrieving Error Messages | Retrieving the error messages associated with error codes


Using Certificate Services in C++

The Certificate Services API elements can be used in C/C++, Visual Basic, Java, Microsoft® Visual J++®, or other COM-compliant languages. These sections are intended to help a programmer knowledgeable in C++ use Certificate Services.

Section | Content
Return Values in C++ | Working with C++ return values from Certificate Services methods
Error Checking in C++ | Retrieving error information in C++


Return Values in C++

In C++, the return value is typically of type HRESULT. It is from this return value that it can be determined whether the method succeeded or not, and if not, what the error was. Certificate Services typically returns S_OK for the HRESULT when the method has completed successfully. Programmatic values that need to be returned are returned through "out" parameters in the method. The following example shows a C++ method call to retrieve a request property:

BSTR      bstrPropName = NULL;
VARIANT   varProp;
HRESULT   hr;

VariantInit(&varProp);

bstrPropName = SysAllocString(L"RequestID");

// Retrieve the request property.
// pCertServerPolicy is a pointer to a previously
// instantiated ICertServerPolicy object.
hr = pCertServerPolicy->GetRequestProperty(bstrPropName,
                                           PROPTYPE_LONG,
                                           &varProp);
if (S_OK != hr)
{
    printf("Failed GetRequestProperty [%x]\n", hr);
    // Take application-specific error action.
    // ...
}
else
{
    // Successfully retrieved property; use varProp as needed.
    // ...
}

// Done processing.
VariantClear(&varProp);
if (NULL != bstrPropName)
    SysFreeString(bstrPropName);

In the preceding code fragment, success or failure is returned to the HRESULT variable, hr. It is imperative to check the HRESULT variable for success [handled in the code by the condition (S_OK != hr)]. If the method completed successfully, the request property value is returned in the VARIANT varProp parameter.


Error Checking in C++

In C++, every Certificate Services method directly returns an HRESULT that indicates whether the method call succeeded or failed. If the call failed, the return value indicates why it failed.

The following code demonstrates how the returned HRESULT values can be used for error checking. For example error codes, see Common HRESULT Values.

HRESULT hr;
BSTR strAttributeName = SysAllocString(L"TheAttribute");
BSTR strAttributeValue = NULL;

hr = pICertServerPolicy->GetRequestAttribute(
                                strAttributeName,
                                &strAttributeValue);
if(S_OK != hr)          // Check to see if method failed…
{
    if (E_INVALIDARG == hr)
    {
        ... // Do something to recover from error, etc.
    }
}
// Free BSTRs when done.
if (NULL != strAttributeName)
    SysFreeString(strAttributeName);
if (NULL != strAttributeValue)
    SysFreeString(strAttributeValue);


Using Certificate Services in Visual Basic

The Certificate Services API elements can be used in C/C++, Visual Basic, Java, Visual J++, or other COM-compliant languages. These sections are intended to help a programmer knowledgeable in Visual Basic use Certificate Services.

Section | Content
Return Values in Visual Basic | Working with Visual Basic return values from Certificate Services methods
Error Checking in Visual Basic | Retrieving error information when programming in Visual Basic


Return Values in Visual Basic

In Microsoft® Visual Basic®, the return value can be handled by a Variant data type that automatically handles whatever type is returned, or by a specific non-Variant data type if supported by the method. A method call is as follows:

Example Code

' Variable for certificate property commonname.
Dim varName As Variant
' Retrieve the value for the subject commonname.
' objSrvPol is an instantiated CCertServerPolicy object variable.
varName = objSrvPol.GetCertificateProperty( _
                    "Subject.CommonName", _
                     PROPTYPE_STRING)

The following method call, which uses a non-Variant data type, also works.

' Variable for certificate property commonname.
Dim strName As String
' Retrieve the value for the subject commonname.
strName = objSrvPol.GetCertificateProperty( _
                    "Subject.CommonName", _
                     PROPTYPE_STRING)


Error Checking in Visual Basic

In Visual Basic, if an error occurs during the execution of a method, the method will throw an exception. The script or program must check for these exceptions separately from the return value.

Both Visual Basic and VBScript uses the Err object's Number property to check for errors, as shown in the example code that follows.

The properties of the Err object are set by the generator of an error — Visual Basic, an OLE object, or the Visual Basic programmer. The default property of the Err object is Number. Err.Number contains an integer and can be used by an Automation object to return an SCode.

When a run-time error occurs, the properties of the Err object are filled with information that uniquely identifies the error and information that can be used to handle it. To generate a run-time error in your code, use the Raise method.

The Err object's properties are reset to zero or zero-length strings ("") after a On Error Resume Next statement and after an Exit Sub or Exit Function statement within an error-handling routine. The Clear method can be used to explicitly reset Err.

The Err object is an intrinsic object with global scope; there is no need to create an instance of it in your code.

Example Code

The following is an example using the ICertAdmin object.

Private Sub Command1_Click()

    ' Specify the error handler.
    On Error GoTo MyErrHandler

    ' Declare and create an instance of the CCertAdmin object.
    ' Ensure the Visual Basic project references CCertAdmin's type library.
    Dim objAdm As CCertAdmin
    Set objAdm = New CCertAdmin

    ' Specify the expiration date for the CRL.
    Dim ExpDate As Date
    ExpDate = #1/1/2001 12:00:00 PM#

    ' Use the CCertAdmin object to publish the CRL.
    objAdm.PublishCRL "server01\myCAName", _
                      ExpDate

    ' Free the object.
    Set objAdm = Nothing

    ' Exit the subroutine.
    Exit Sub

MyErrHandler:
    ' An error occurred.
    ' Display the error.
    MsgBox ("Error: " & Err.Number _
            & " " & Err.Description _
            & " " & Err.Source)
    ' Continue running the program.
    ' You may want to implement other techniques here.
    Resume Next

End Sub


Using Certificate Services in Java

The Certificate Services API elements can be used in C/C++, Visual Basic, Java, Visual J++, or other COM-compliant languages. These sections are intended to help a programmer knowledgeable in Java use Certificate Services in Java and Microsoft Visual J++.

Section | Content
Return Values in Java | Working with Java return values from Certificate Services methods
Error Checking in Java | Retrieving error information when programming in Java
Using a Variant in Java | Declaring a Variant and assigning it a value
Exception Handling in Java | Using a try/catch block to trap Java and COM failure exceptions
Using Certificate Services and Creating a Console Application in Visual J++ | Creating a Console application, with example code that illustrates how to use Certificate Services API elements in Visual J++


Return Values in Java

The return type will typically be one of the java.lang.XXX class types; such as java.lang.String, or com.ms.com.Variant.


Error Checking in Java

In Java, if an error occurs during the execution of a method, the method will throw an exception. The script or program must check for these exceptions separately from the return value.

ComFailException indicates a failure. The exception object wraps an HRESULT, the return type for most methods in the Component Object Model (COM). The default value of the HRESULT stored in a ComFailException is E_FAIL (0x80004005L). All failure HRESULTs have their most significant bit set.

The values of system-defined HRESULTs can be found in WINERROR.H, included with the Microsoft® Platform SDK. For object specific errors, see the documentation associated with the object.

For system-defined errors, the detail message stored in the ComException object is the string returned by the Microsoft® Win32® API function FormatMessage, which returns a brief message associated with the error. This detail message can be retrieved by calling getMessage (defined by the Throwable class).


Using a Variant in Java

Variant data types can be represented in Java by means of com.ms.com.Variant. The following example code shows you how to declare a Variant variable and assign it a value before you call the CCertView::SetRestriction method.

com.ms.com.Variant varRest;
// Assign the value 5 to the Variant variable.
varRest = new com.ms.com.Variant(5);
// varRest could now be used as the 4th parameter
// in a call to CCertView::SetRestriction.
objView.SetRestriction(nIndex,
                       CVR_SEEK_GT,
                       CVR_SORT_ASCEND,
                       varRest);

Variant data types can also be return values from a Certificate Services method. The following example shows how to use a Variant as a return value from the IEnumCERTVIEWCOLUMN::GetValue method.

com.ms.com.Variant var1;
// Retrieve the value.
var1 = objCol.GetValue(CV_OUT_HEX);

When done using a Variant, clear it by calling the VariantClear method:

// Clear the Variant.
var1.VariantClear();


Exception Handling in Java

Exceptions in Java can be handled by means of try/catch blocks. A benefit of handling exceptions is the ability to programmatically respond to run-time errors. In addition to handling Java exceptions, you can write your programs to handle COM failure exceptions. The following example code shows how a try/catch block can be used to capture a COM failure exception in a call to CCertAdmin::ImportCertificate.

try
{
    int ReqID;

    // Import the certificate.
    ReqID = objAdm.ImportCertificate(strConfig,
                                     strCert,
                                     CR_IN_BINARY);
    // Display the request ID.
    System.out.println("Imported certificate has request ID: "
                       + ReqID);
}
catch (com.ms.com.ComFailException e)
{
    // Error encountered during the ImportCertificate call.
    // Display the error text and stack trace, then exit.
    System.out.println(e.getMessage());
    e.printStackTrace();
    System.exit(-1);
}

See the try, catch, and throw topics in the Microsoft Visual J++ documentation for more details about exception handling. To keep the Certificate Services SDK sample snippets brief, the reference pages generally do not contain exception handling.


Using Certificate Services and Creating a Console Application in Visual J++

The following steps can be used to create a console application in Visual J++. To provide an example of using the Certificate Services API elements, the example code that illustrates these steps will use the CCertConfig interface.

To create a console application

  1. Start the Visual J++ application.
  2. If the Visual J++ application starts with an existing project or an empty environment, in the File menu, select New Project.
  3. Specify 'Console Application' as the application type, and specify a directory location to store the project. (This example will use the project name "Project1".)
  4. In the Project Explorer pane, expand Project1 by clicking it, and then open the Class1.java source file by double-clicking it.
  5. To add a COM wrapper to the project, in the Project menu, choose Add COM-Wrapper. (This example requires the CertCli type library. If the CertCli type library is registered on your machine, select it from the Com Wrapper's list of Installed COM components. If the CertCli type library is not registered, you may copy it from the Platform SDK and use the browse button in the COM Wrapper dialog box to have it referenced in your project.)
  6. Edit the Class1.java source file; specifically, modify the main function by removing the "TODO:" comment and add your own code. (See the example code following this procedure.)
  7. Use the Build menu to build the application. After the application has been successfully built, run it by pressing Ctrl+F5 (or F5 to run in debug mode). Alternatively, run the application at a command prompt, by running 'jview Class1'. The command prompt must be in the directory which contains the successfully built Class1.class file. The jview application processes the class name as case-sensitive, so if your class is named Class1, you must run 'jview Class1', not 'jview class1'. The trailing '.class' extension is optional and is not case-sensitive (for example, 'jview Class1.class' is acceptable).

This example expects the main function to be written as follows (comments show where the Certificate Services CCertConfig object is declared and instantiated).

public static void main (String[] args)
{
    // This example will display a user interface to
    // allow a certification authority to be selected.

    try
    {

        // Constant values.
        final int CC_DEFAULTCONFIG = 0;
        final int CC_UIPICKCONFIG = 1;
        final int CC_FIRSTCONFIG = 2;

        // Declare and create an instance of a CCertConfig object.
        // The CertCli library is a COM wrapper added to the project.
        certcli.CCertConfig objCertCfg;
        objCertCfg = new certcli.CCertConfig();

        // Display a user interface for the user to pick a
        // certification authority.
        // The user's choice is returned in the strConfig variable.
        java.lang.String strConfig;
        strConfig = objCertCfg.GetConfig(CC_UIPICKCONFIG);

        // Display the choice from the user interface.
        System.out.println(strConfig);

        // Free the object.
        com.ms.com.ComLib.release(objCertCfg);

    }
    catch (com.ms.com.ComFailException e)
    {
        System.out.println(e.getMessage());
    }

}


Setting the Type Tag Field

VARIANT type variables have a type tag field vt that indicates the data type of the data. VARIANT type return values are returned by methods with the type tag field set to the data type of the return value. VARIANT type input parameters in a method call must have the type tag field set by the application to one of the supported values. The correspondence of parameter types to data types is as follows.

Parameter Type | Data Type
PROPTYPE_LONG | VT_I2 or VT_I4
PROPTYPE_DATE | VT_DATE
PROPTYPE_BINARY | VT_BSTR or (VT_BSTR | VT_BYREF)
PROPTYPE_STRING | VT_BSTR or (VT_BSTR | VT_BYREF)

Example Code

The following example written in C++ shows how the type tag field could be initialized for a call to the ICertServerPolicy::SetCertificateExtension method:

HRESULT hr;
BSTR strExtensionName = SysAllocString(L"2.29.38.4");
VARIANT varExt;
varExt.vt = VT_BSTR;    // initialize type tag field
varExt.bstrVal = SysAllocString(L"http://UrlTest.htm");

hr = pICertServerPolicy->SetCertificateExtension(
    strExtensionName,      // extension name
    PROPTYPE_STRING,
    EXTENSION_CRITICAL_FLAG,
    &varExt);

// Use the strAttributeValue ...

// Free it when done.
if (NULL != strExtensionName)
{
    SysFreeString(strExtensionName);
}
VariantClear(&varExt);


Retrieving Error Messages

When a method call produces an error, many functions return an error code. For most Certificate Services interfaces and API elements that return an error code, the error message text can be retrieved by calling FormatMessage with a NULL module handle. If FormatMessage does not succeed, the error code most likely resulted from a backup API element or database related error; calling FormatMessage with a module handle corresponding to the ntdsbmsg.dll library should retrieve the error message text. The following example shows how to retrieve error message text in a Certificate Services application.

// Display error message text, given an error code.
// Typically, the parameter passed to this function is retrieved
// from GetLastError().
void PrintCSBackupAPIErrorMessage(DWORD dwErr)
{

    WCHAR   wszMsgBuff[512];  // Buffer for text.

    DWORD   dwChars;  // Number of chars returned.

    // Try to get the message from the system errors.
    dwChars = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM |
                             FORMAT_MESSAGE_IGNORE_INSERTS,
                             NULL,
                             dwErr,
                             0,
                             wszMsgBuff,
                             200,
                             NULL );

    if (0 == dwChars)
    {
        // The error code did not exist in the system errors.
        // Try ntdsbmsg.dll for the error code.

        HINSTANCE hInst;

        // Load the library.
        hInst = LoadLibrary(L"ntdsbmsg.dll");
        if ( NULL == hInst )
        {
            printf("Can't load ntdsbmsg.dll\n");
            exit(1);  // Could 'return' instead of 'exit'.
        }

        // Try getting message text from ntdsbmsg.
        dwChars = FormatMessage( FORMAT_MESSAGE_FROM_HMODULE |
                                 FORMAT_MESSAGE_IGNORE_INSERTS,
                                 hInst,
                                 dwErr,
                                 0,
                                 wszMsgBuff,
                                 512,
                                 NULL );

        // Free the library.
        FreeLibrary( hInst );

    }

    // Display the error message, or generic text if not found.
    printf("Error value: %d Message: %ws\n",
            dwErr,
            dwChars ? wszMsgBuff : L"Error message not found." );

}


Retrieving an Issued Certificate from the Active Directory

An enterprise certification authority publishes issued certificates to the Active Directory™; a stand-alone certification authority may also publish issued certificates to the Active Directory. The following code sample illustrates how to acquire a certificate context for a certificate stored in the Active Directory. After the certificate context is acquired, you can retrieve the certificate's contents or perform certificate operations using the CryptoAPI functions.

Example Code

// Retrieve a user certificate from the Active Directory.
//
// This sample C++ code utilizes CryptoAPI calls to retrieve
// a certificate previously published to the Active Directory
// by Microsoft Certificate Services.
// Ensure crypt32.lib and secur32.lib are part of link libraries.

#define SECURITY_WIN32 1

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#include <security.h>

#define MAXBUFF 512

void __cdecl main()
{
    HCERTSTORE     hStore=NULL;

    PCCERT_CONTEXT pCertCtx = NULL;

    WCHAR          wszDN[MAXBUFF];
    WCHAR          wszQuery[MAXBUFF];
    DWORD          dwDN = MAXBUFF;

    // Determine the name of the user whose certificate is being
    // retrieved. This value can be constructed by other means,
    // but here we'll use GetUserNameEx.
    if (!GetUserNameExW(NameFullyQualifiedDN,
                        wszDN,
                        &dwDN))
    {
        printf("Failed GetUserNameExW\n");
        exit(1);
    }

    // Build the LDAP query string.
    swprintf(wszQuery,
             L"ldap:///%s?%s",
             wszDN,
             L"userCertificate");

    // Open the Active Directory certificate store.
    hStore = CertOpenStore(CERT_STORE_PROV_LDAP,
                           0,
                           0,
                           CERT_STORE_READONLY_FLAG,
                           wszQuery);
    if ( NULL == hStore)
    {
        printf("Failed CertOpenStore - %x\n", GetLastError());
        exit(1);
    }

    // Retrieve a certificate context from this opened store.
    // Here, we'll retrieve any existing certificate stored for
    // the user in the Active Directory.
    // Consult CertFindCertificateInStore documentation for search
    // types and calling instructions if more than one certificate
    // exists.
    pCertCtx = CertFindCertificateInStore(hStore,
                   X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                   0,
                   CERT_FIND_ANY,
                   NULL,
                   NULL);
    if (NULL == pCertCtx)
    {
        DWORD dwErr;
        dwErr = GetLastError();
        if (dwErr == CRYPT_E_NOT_FOUND)
            printf("User does not have certificate"
               "in Active Directory\n");
        else
            printf("Failed CertFindCertificateInStore - %x\n",
                   dwErr);
    }
    else
    {
        // Use the certificate context as needed.
        // Here, we'll display the serial number.
        // Consult the CryptoAPI documentation for other uses
        // of the certificate context.
        DWORD dwLen, i;
        dwLen = pCertCtx->pCertInfo->SerialNumber.cbData;
        // The serial number bytes are stored
        // least significant byte first.
        printf("Serial number: ");
        for (i = dwLen-1; i != MAXDWORD; i--)
            printf("%02x",
                   *(pCertCtx->pCertInfo->SerialNumber.pbData + i));
        printf("\n");
        // Free certificate context.
        CertFreeCertificateContext(pCertCtx);
    }

    // Close certificate store.
    CertCloseStore(hStore, 0);
}


Customizing the Certificate Services Web Enrollment Pages

The web enrollment pages shipped with Windows 2000 are provided as a means to request certificates from Certificate Services. An administrator can also customize some of the items viewable in the web enrollment pages. However, you should be familiar with the web enrollment pages and web scripting before making any modifications. It is useful to examine the web source files as they are encountered in this documentation.

The default values for the Distinguished Name fields for Organization, Organizational Unit, Locality, State and Country/Region are the values specified for the Certification Authority (CA) when Certificate Services is installed. These default values appear in the web pages and can be changed by the user during the certificate enrollment process. However, if you want other default values to appear in the web pages, you can edit the certdat.inc file (in the path \winnt\system32\certsrv\); specifically, you can assign custom values to the following variables provided for customization.

Variable | Description
sDefaultCompany | Default company (appears in the certificate request as the X.509 Organization field).
sDefaultOrgUnit | Default department (appears in the certificate request as the X.509 Organizational Unit field).
sDefaultLocality | Default city (appears in the certificate request as the X.509 Location field).
sDefaultState | Default state/province (appears in the certificate request as the X.509 State field).
sDefaultCountry | Default country/region (appears in the certificate request as the X.509 Country/Region field).
nPendingTimeoutDays | Number of days in which the user can retrieve a pending certificate after it has been requested.

No other variables should be changed in the certdat.inc file.

The following example sets the default Organizational Unit to "Marketing".

    sDefaultOrgUnit="Marketing"

Additionally, you can edit the certrqtp.inc file to add, change, or remove certificate templates or types available to the user. These templates and types, as well as related information, are contained in a dimensioned array, rgAvailReqTypes(m,2).

This array, like all Microsoft Visual Basic and VBScript arrays, is zero based, and as a result, the array's first dimension, m, allocates memory for m+1 items. Therefore, if in customizing the web pages, you need to modify the number of items in the rgAvailReqTypes array, set the m dimension to one less than the total number of items you need. For example, if you will have seven certificate templates, change the declaration of rgAvailReqTypes to

    Dim rgAvailReqTypes(6,2)

The array's second dimension, which always has the value 2, allocates the three fields that compose each item. These three fields represent the certificate template or type, the friendly name associated with this template or type, and whether the template requires S/MIME.

To make it easier to understand which of these fields is being accessed, certrqtp.inc also provides the following constants you can use when setting field values.

Constant | Description
FIELD_OID | (Applies to stand-alone CAs) Index to the item's first field; represents an object identifier (OID) for a certificate type.
FIELD_TEMPLATE | (Applies to enterprise CAs) Index to the item's first field; represents a certificate template.
FIELD_FRIENDLYNAME | Index to the item's second field; represents the friendly name (which the user will see when enrolling) of the item in the first field.
FIELD_NEEDS_SMIME_CAPABILITIES | (Applies to enterprise CAs) Value specifying whether the certificate template requires S/MIME capabilities. You must specify True or False for this value.

As an example, the expressions

    rgAvailReqTypes(0, FIELD_OID) = "1.3.6.1.5.5.7.3.2"
    rgAvailReqTypes(0, FIELD_FRIENDLYNAME) = "Web Browser Certificate"

assign the OID of "1.3.6.1.5.5.7.3.2" to the first item's first field and assign "Web Browser Certificate" to the first item's second field (the array value of 0 indexes the first item). The result of these assignments is that the user will see the text "Web Browser Certificate" when enrolling, and if the user selects "Web Browser Certificate", the certificate request will contain the OID "1.3.6.1.5.5.7.3.2".

The certrqtp.inc file also contains constants that are used for the friendly names of the certificate templates or types. The following is an example of the format.

' Strings for localization
Const L_WebBrowserCert_Text="Web Browser Certificate"
Const L_EmailProtectionCert_Text="E-Mail Protection Certificate"
Const L_UserTemplateCert_Text="User Certificate"

These constants are defined in a block in the certrqtp.inc file, and this grouping makes it easier to assign each of them a custom value. This is particularly helpful when you localize the friendly names for international versions of the web pages.

Finally, the certrqtp.inc file contains a variable that represents the number of certificate templates or types in the rgAvailReqTypes array. In contrast to the m dimension of the array, set the value of the nAvailReqTypes variable to the actual number of certificate templates or types that your installation will use; this value must be no larger than m+1. Although declared near the top of the certrqtp.inc file, nAvailReqTypes is assigned a value after the rgAvailReqTypes array is populated, making it easier to see how many elements are actually used by the array. The nAvailReqTypes value is used in an iteration elsewhere in the web enrollment pages, so it is important that this variable accurately reflect the number of certificate templates or types that you wish to be viewable to the user.

Note that merely adding certificate templates and types to the certrqtp.inc file doesn't guarantee that the user will be able to get a certificate with those traits; the CA must be authorized to issue a certificate for the specified certificate template or type. Consult the Certificate Services user documentation for information about which certificate templates or types are allowed for a certification authority (CA).

Installations may create their own applications or web pages to request and receive a certificate. The ICEnroll and ICertRequest objects allow programmers or scripters to build their own certificate request applications. Consult the ICEnroll and ICertRequest topics for specific details and sample code snippets.

To request a certificate to be issued on a smart card, you can use Smart Card Enrollment Control. For specific details and sample code snippets for using Smart Card Enrollment Control, see the ISCrdEnr topic.


Writing Custom Policy Modules

You can write policy modules in C/C++, or Microsoft® Visual Basic®. The required Microsoft compiler releases are Microsoft® Visual C++® version 5.0 (or later) or Microsoft Visual Basic® version 5.0 (or later). An enterprise certification authority (CA) should use only the Microsoft-provided enterprise policy module.

You must implement ICertPolicy when writing a custom policy module. Additionally, beginning with Windows 2000, you must implement ICertManageModule when writing a custom policy module.

Policy modules can call methods from ICertServerPolicy to assist in the processing of a certificate request; ICertServerPolicy allows properties and certificate extensions to be set and retrieved.

To aid in the debugging of policy and exit modules, Certificate Services can be run in console mode. To run Certificate Services in console mode, you must first stop the Certificate Services application (by using the certification authority MMC snap-in, by using the Services snap-in, or by issuing "net stop certsvc" at a command prompt). Then, start Certificate Services at a command prompt (invoked by running "cmd") by issuing the command '"certsrv -z". The command prompt will display text output from policy or exit module console output calls, such as the 'printf' function. (The Certificate Services application may also output text to the console window.) To exit Certificate Services in console mode, press CTRL+C. Remember to restart the Certificate Services application when you're done debugging. Running Certificate Services in console mode is recommended only for debugging purposes.

For further information, see the following topics.

Topic | Content
Writing Policy Modules in Visual Basic | Writing custom Policy Modules in Microsoft® Visual Basic®
Setting Certificate Properties | Setting the properties of a certificate


Writing Policy Modules in Visual Basic

This section describes the steps required to build a Policy Module in Visual Basic.

Windows NT 4.0 To build a Windows NT 4 policy module in Microsoft® Visual Basic® version 5.0 (or later), build an ActiveX DLL with a class module called CertificateAuthority.Policy. This naming convention must be followed in order for RegSvr32 to store the GUID in the correct location in the system registry when it is run on the policy module DLL. The class called Policy will implement the functionality of ICertPolicy.

To be sure of this, complete the following steps:

To build a Visual Basic policy module for Windows NT 4.0 implementations

  1. Create a new project, with the outcome to be an ActiveX dll.
  2. Set the project name to CertificateAuthority.
  3. Change the name of the class module to Policy. Ensure the class Instancing value is set to 5 (MultiUse).
  4. If you intend to use an ICertServerPolicy object in the Policy Module, find Certif.dll in the Projects.References list box and make sure Certif.dll's CertIF 1.0 Type Library check box is checked.
  5. Implement the methods of ICertPolicy in the Policy class.
  6. Build the DLL file. The Visual Basic build process will register the DLL on the build machine. If the DLL is intended to be run on another machine, copy the DLL file to the target machine and register it on the target machine by using RegSvr32.exe.

Windows 2000

An enterprise certification authority (CA) should use only the Microsoft-provided enterprise policy module. To build a Microsoft® Windows® 2000 stand-alone CA policy module in Microsoft® Visual Basic® version 5.0 (or later), build an ActiveX DLL with a class module called MyApp.Policy, and another class module called MyApp.PolicyManage, where MyApp is whatever name you want to give the project. The class called Policy will implement the functionality of ICertPolicy, and the class called PolicyManage will implement the functionality of ICertManageModule.

To build a Visual Basic policy module for Windows 2000 implementations

  1. Create a new project, with the outcome to be an ActiveX dll.
  2. [Optional] Change the project name to your choice. Unlike Windows NT 4 implementations, the project should not be called CertificateAuthority.
  3. Change the name of the class module to Policy. Ensure the class instancing value is set to 5 (MultiUse).
  4. If you intend to use an ICertServerPolicy object in the Policy Module, find CertCli.dll in the Projects.References list box and make sure that CertCli.dll's CertCli 1.0 Type Library check box is checked.
  5. Implement the methods of ICertPolicy in the Policy class.
  6. Add another class module, called PolicyManage. Implement the methods of ICertManageModule in the PolicyManage class.
  7. Build the DLL file. The Visual Basic build process will register the DLL on the build machine. If the DLL is intended to be run on another machine, copy the DLL file to the target machine and register it on the target machine by using RegSvr32.exe.

Example Code

C++ and Visual Basic samples are included in the documentation for the methods of ICertPolicy.


Setting Certificate Properties

The policy module interface (ICertServerPolicy) includes two methods for setting certificate properties and extensions, SetCertificateProperty and SetCertificateExtension. With these method calls, some of the properties and any of the extensions of a certificate can be set via the policy module.

Example Code

The following example, written in Microsoft® Visual Basic®, demonstrates how these method calls might appear in the policy module:

' Set the Subject's EMail address
Dim varEMail As Variant
varEMail = "someone@microsoft.com"
objSrvPol.SetCertificateProperty "Subject.EMail", _
                                  PROPTYPE_STRING, _
                                  varEMail
' Set an extension.
objSrvPol.SetCertificateExtension "2.29.38.4", _
                                PROPTYPE_STRING, _
                                EXTENSION_CRITICAL_FLAG, _
                                "http://example.microsoft.com"

Before calling these methods, the policy module would have called ICertServerPolicy::SetContext to let Certificate Services know which certificate request is having a property or extension set.

See Also

ICertServerPolicy::SetCertificateExtension, ICertServerPolicy::SetCertificateProperty


Writing Custom Exit Modules

Custom exit modules must implement the ICertExit interface, which is called by the server engine. The ICertExit::Initialize method is called by the server engine when the exit module is loaded. It allows the exit module to perform initialization and returns a value that informs the server engine of the kinds of events for which it wants notification. The ICertExit::GetDescription method must return a description string when the server engine requests it. The ICertExit::Notify method is called by the server engine to notify the exit module that an event has occurred.

Exit modules can call the ICertServerExit interface, which supports many of the same methods as the ICertServerPolicy interface, with the exception of the SetCertificateExtension and SetCertificateProperty methods.

To aid in the debugging of policy and exit modules, Certificate Services can be run in console mode. To run Certificate Services in console mode, you must first stop the Certificate Services application (by using the certification authority MMC snap-in, by using the Services snap-in, or by issuing "net stop certsvc" at a command prompt). Then, start Certificate Services at a command prompt (invoked by running "cmd") by issuing the command '"certsrv -z". The command prompt will display text output from policy or exit module console output calls, such as the 'printf' function. (The Certificate Services application may also output text to the console window.) To exit Certificate Services in console mode, press CTRL+C. Remember to restart the Certificate Services application when you're done debugging. Running Certificate Services in console mode is recommended only for debugging purposes.

See the Exit Module Customization topic in the Microsoft® Windows NT® or Windows 2000 Help for information on removing the existing exit module and installing a new one.


Writing Custom Extension Handlers

To create custom extensions or to encode a complex extension, you can write your own extension handlers that export custom interfaces. Microsoft Certificate Services ships with the following interfaces which can be used to encode various types of extension data: ICertEncodeAltName, ICertEncodeBitString, ICertEncodeCRLDistInfo, ICertEncodeDateArray, ICertEncodeLongArray, and ICertEncodeStringArray. These interfaces are contained in certenc.dll. Additionally, the type information for these interfaces is contained in CertEncL.dll, which is contained in the Windows 2000 Platform SDK.

Example Code

This example, written in Microsoft® Visual Basic®, demonstrates how a policy module can encode a string array and use it to set a certificate extension:

Private Const szOID_TEST1 As String = "0.1.2.3.4.5.6.0"

Set StringArray = New CCertEncodeStringArray
Dim Extension As String

StringArray.Reset 3, CERT_RDN_IA5_STRING
StringArray.SetValue 0, "Visual Basic Test String 1"
StringArray.SetValue 1, "Visual Basic Test String 2"
StringArray.SetValue 2, "Visual Basic Test String 3"

Extension = StringArray.Encode

CertServer.SetCertificateExtension _
        szOID_TEST1, _
        PROPTYPE_BINARY, _
        EXTENSION_DISABLE_FLAG, _
        Extension

For more information about extension handlers, see the following topic: Extension Handlers


Viewing the Certificate Services Database

The ICertView interface (introduced with Windows 2000) is used by properly authorized clients to view the Certificate Services database. It should be noted that, as part of the shipped product, the Certification Authority MMC snap-in can be used to view the Certificate Services database. ICertView is provided for programmatically viewing the database.

A properly authorized client means a user who has been granted permission to view the Certificate Services database; the Certification Authority MMC snap-in can be used to grant or restrict access to view the database (in the Properties section for the Certification Authority, select the Security tab). Additionally, to use the ICertView object, the client workstation is required to have installed the Certificate Services client components.

Although there are various scenarios for using ICertView and its related interfaces, the following depicts one possible sequence for developing a client application based on ICertView:

To view the Certificate Services database

  1. After obtaining an instance of the ICertView object, call ICertView::OpenConnection to communicate with a Certification Authority on a specific computer.
  2. Call ICertView::SetResultColumnCount to specify the number of columns in the view; SetResultColumnCount can also be used to specify a default view. If a default view is not specified in the call to SetResultColumnCount, the caller must call ICertView::SetResultColumn for each of the columns to be contained in the view.
  3. Optional. Specify sorting criteria and/or qualifying critieria for the database query by calling the ICertView::SetRestriction function. Qualifying criteria consists of informing the view to retrieve data based on qualifiers such as Greater Than, Less Than, Equal To, and so on.
  4. Call ICertView::OpenView to retrieve the data in the view; the view's data will consist of the columns requested by means of SetResultColumnCount (and if a default view wasn't specified, SetResultColumn). If SetRestriction was called, data in the columns will be sorted and/or qualified. OpenView creates a IEnumCERTVIEWROW object, which can be used to enumerate the view's rows.
  5. Use the IEnumCERTVIEWROW methods IEnumCERTVIEWROW::EnumCertViewAttribute, IEnumCERTVIEWROW::EnumCertViewColumn, and IEnumCERTVIEWROW::EnumCertViewExtension to retrieve attribute, column, and extension data as desired.


Using the Certificate Services Backup and Restore Functions

Certificate Services provides a set of functions which can be used to back up and restore the certificate services database files. The following sections describe how these functions may be used.

Section | Information
Setting the Backup and Restore Privileges | Setting the necessary privileges to call the Certificate Services backup and restore functions
Backing Up Certificate Services | Backup scenario using the backup functions
Restoring Certificate Services from Backup | Restore scenario using the backup functions
Backing Up and Restoring the Certificate Services Private Key | Backing up and restoring private keys, which cannot be backed up or restored with the Certificate Services API.


Setting the Backup and Restore Privileges

In order to successfully call the Certificate Services backup and restore API, the caller's token must include the backup and restore privileges. These privileges can be programmatically set, and the following code sample can be used to set or remove these privileges. The backup and restore privileges are required of all backup and restore applications, not merely Certificate Services backup and restore.

Example Code

// The following code can be used to enable or disable the
// backup privilege. By making the indicated substitutions, you can
// also use this code to enable or disable the restore privilege
// Use the following to enable the privilege:
//   hr = ModifyPrivilege(SE_BACKUP_NAME, TRUE);
// Use the following to disable the privilege:
//   hr = ModifyPrivilege(SE_BACKUP_NAME, FALSE);
// Use SE_RESTORE_NAME for the restore privilege.

HRESULT ModifyPrivilege(
    IN LPCTSTR szPrivilege,
    IN BOOL fEnable)
{
    HRESULT hr = S_OK;
    TOKEN_PRIVILEGES NewState;
    LUID             luid;
    HANDLE hToken    = NULL;

    // Open the process token for this process.
    if (!OpenProcessToken(GetCurrentProcess(),
                          TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
                          &hToken ))
    {
        printf("Failed OpenProcessToken\n");
        return ERROR_FUNCTION_FAILED;
    }

    // Get the local unique id for the privilege.
    if ( !LookupPrivilegeValue( NULL,
                                szPrivilege,
                                &luid ))
    {
        CloseHandle( hToken );
        printf("Failed LookupPrivilegeValue\n");
        return ERROR_FUNCTION_FAILED;
    }

    // Assign values to the TOKEN_PRIVILEGE structure.
    NewState.PrivilegeCount = 1;
    NewState.Privileges[0].Luid = luid;
    NewState.Privileges[0].Attributes =
              (fEnable ? SE_PRIVILEGE_ENABLED : 0);

    // Adjust the token privilege.
    if (!AdjustTokenPrivileges(hToken,
                               FALSE,
                               &NewState,
                               sizeof(NewState),
                               NULL,
                               NULL))
    {
        printf("Failed AdjustTokenPrivileges\n");
        hr = ERROR_FUNCTION_FAILED;
    }

    // Close the handle.
    CloseHandle(hToken);

    return hr;
}


Backing Up Certificate Services

The following is a scenario showing how you can use the Certificate Services backup functions to backup a Certificate Services database and its associated files.

  1. Load the certadm.dll library into memory (by calling LoadLibrary).
  2. Retrieve the address of each of the necessary functions in certadm.dll (by means of GetProcAddress). Use these addresses when calling the functions in the remaining steps.
  3. Call CertSrvIsServerOnline to determine if Certificate Services is online. Certificate Services must be online for the backup operations to be successful.
  4. Call CertSrvBackupPrepare to start a backup session. The resulting Certificate Services backup context handle will be used by many of the other backup functions.
  5. Call CertSrvRestoreGetDatabaseLocations to determine the restore map. The restore map contains the path(s) to be used when restoring the backup. Save the information retrieved by CertSrvRestoreGetDatabaseLocations to an application-specific location.
  6. Call CertSrvBackupGetDatabaseNames to determine the names of the database files to backup. For each of these files, execute steps 7 through 9.
  7. Call CertSrvBackupOpenFile to open the file for backup.
  8. Call CertSrvBackupRead to read a portion of bytes from the file, then call an application-specific routine to store the bytes on a backup medium. Repeat this step until all of the bytes in the file are backed up.
  9. Call CertSrvBackupClose to close the file.
  10. Call CertSrvBackupGetBackupLogs to determine the names of the log files to backup. For each of these files, execute steps 7 through 9.
  11. Call CertSrvBackupTruncateLogs to truncate the log files which were backed up in steps 6 and 10. This step is optional; however, call CertSrvBackupTruncateLogs only if all files returned by CertSrvBackupGetDatabaseNames and CertSrvBackupGetBackupLogs have been backed up (otherwise, the restore operation will fail). Consult the CertSrvBackupTruncateLogs reference page for details.
  12. Call CertSrvBackupGetDynamicFileList to determine the names of the non-database files to backup. These files are only identified by the function, and must be backed up by some other means.
  13. Backup the dynamic files identified in step 12, using routines separate from certadm.dll.
  14. Call CertSrvBackupEnd to end the backup session.
  15. Call CertSrvBackupFree as needed to release buffers allocated by certain Certificate Services backup functions. Calls to CertSrvBackupGetBackupLogs, CertSrvBackupGetDatabaseNames, and CertSrvBackupGetDynamicFileList will allocate buffers that can be freed by a call to CertSrvBackupFree.
  16. Release the certadm.dll resources by calling FreeLibrary.


Restoring Certificate Services from Backup

The following is a scenario of how the Certificate Services backup functions can be used to restore and recover a Certificate Services database and its associated files. The restoration process involves writing the files contained in a backup set to disk. You may restore multiple backup sets (one full backup plus zero or more incremental backups), but all restores must be complete prior to beginning the recovery process. The recovery process involves Certificate Services replaying log files to ensure database and log file consistency, thereby ensuring database integrity. The scenario illustrates the function calls to restore the backup sets and inform Certificate Services of the recovery parameters.

An existing full backup of the Certificate Services database must exist before implementing this scenario.

  1. Load the certadm.dll library into memory (by calling LoadLibrary).
  2. Retrieve the address of each of the necessary functions in certadm.dll (by means of GetProcAddress). Use these addresses when calling the functions in the remaining steps.
  3. Call CertSrvIsServerOnline to determine if Certificate Services is online. If Certificate Services is running, shut it down before proceeding. Certificate Services must not be online for the restore operations to be successful.
  4. Call CertSrvRestorePrepare to begin a restore session. The resulting Certificate Services backup context handle will be used by several of the other functions.
  5. Determine the path for the database location. During a backup scenario, this value would have been available from a call to CertSrvRestoreGetDatabaseLocations; this value should have been stored as part of the backup.
  6. Create a restore map specifying the name of the restored database. A Certificate Services database restore map structure (CSEDB_RSTMAPW) is used to specify a restore map. Set the CSEDB_RSTMAPW's pwszDatabaseName field and the CSEDB_RSTMAPW's pwszNewDatabaseName field to the database location determined in step 5. Optionally, if the restored database is to have a different name than the backup database, set the CSEDB_RSTMAPW's pwszNewDatabaseName field to the new database name.
  7. If you wish to ensure that modifications made to the database after the backup was performed are not reapplied after database restore is complete (as part of database recovery performed during the next Certificate Services startup), delete files from the target server's active database and log directories.
  8. Copy the files contained in the full backup to the target server's active database and log directories.
  9. Call CertSrvRestoreRegister to register a restore operation for the full backup. CertSrvRestoreRegister uses the restore map specified in step 6. CertSrvRestoreRegister also specifies the location of the backup database and logs. Calling CertSrvRestoreRegister will force Certificate Services to attempt a restore operation the next time it is started. It also prevents Certificate Services from processing Certificate Requests until the restoration is complete.
  10. Call CertSrvRestoreRegisterComplete, thereby finishing the registration activity that started in step 8. Note that the registration of a restore operation is an instruction for Certificate Services to follow when it is started; the actual recovery will take place only after Certificate Services is started.
  11. For each incremental backup to be restored, copy the files contained in the incremental backup to the target server's active log directory, then call CertSrvRestoreRegister, followed by a call to CertSrvRestoreRegisterComplete. The registration of the incremental backups for restoration can occur in any order, but only the set of files for one incremental backup should be copied to the server before each call to CertSrvRestoreRegister.
  12. Copy the Certificate Services dynamic files to the target server. The dynamic files would have been identified during the backup when CertSrvBackupGetDynamicFileList was called. It may be necessary to stop the World Wide Web Publishing Service to allow overwriting the dynamic files.
  13. Call CertSrvRestoreEnd to end the restore session.
  14. Start the Certificate Services application manually (or wait until the next reboot for it to start automatically). When Certificate Services starts, it will determine if a restore operation has been registered; if a restore operation has been registered, Certificate Services will begin the recovery. Certificate Services will not process any certificate requests until the recovery operation is completed.

Note When a recovery is complete, it is important that you make a new full backup of the Certificate Services database. This is necessary to truncate the restored log files and to establish a base backup set for future restores. Backups performed after a restore cannot be mixed with backups (full or incremental) taken before the restore; that is, after a certificate services database is restored and has progressed to a subsequent state, you cannot use the pre-restoration backups to restore the database to that subsequent state.


Backing Up and Restoring the Certificate Services Private Key

You cannot use the certadm.dll's backup and restore functions to back up the Certificate Services private key(s). Private keys can not be backed up by these functions because these functions are intended to backup and restore the Certificate Services database (and related files), and this database does not contain any private keys (even for self-issued certificates).

To back up a Certificate Services private key, use the Certification Authority MMC snap-in, or the certutil command (with -backup or -backupkey specified). Backing up the private key with the Certification Authority MMC snap-in or certutil results in the private key being written to PKCS #12 file. Even though this PKCS #12 file is password-protected, it should be considered extremely sensitive and must be stored securely; the password to the PKCS #12 file should also be guarded from unauthorized persons.

Similarly, private keys cannot be restored by the Certificate Services backup and restore functions. A Certificate Services backup key contained in a PKCS #12 file can be restored by the Certification Authority MMC snap-in, or by the certutil command (specifying the -restore or -restorekey verbs); note that the person performing the restore operation will need to know the password for the PKCS #12 file.

There are only two cases in which a Certificate Services private key must be backed up. The first case is after the installation of Certificate Services. The second case is after any renewal operation of the Certificate Services certificate.


Certificate Services Reference

The open architecture of Certificate Services allows you to customize aspects of the product. For example, you can write a custom policy module that performs some desired action, such as confirming employment status in a database, before issuing a certificate to an employee. (See Writing Custom Policy Modules.

The following sections document the interfaces and other API elements available in Certificate Services and describe certificate properties and HRESULT values.

Section | Content
Certificate Services Interfaces | Interfaces available for writing applications related to Certificate Services.
Backup and Restore Functions | Functions for backing up the Certificate Services database and for restoring it from backup.
Name Properties | Name properties of certificates and certificate requests.
Certificate Properties | Properties of a X.509 certificate.
Common HRESULT Values | Values returned by Certificate Services methods in C++.


Certificate Services Interfaces

The following interfaces are exported by the server engine and are called by external objects.

Interface | Description
ICertAdmin | Used by administration programs to manage requests, certificates, and revocations.
ICertAdmin2 | Used by administration programs to manage requests, certificates, and revocations. Supersedes ICertAdmin. New in the Whistler release.
ICertConfig | Used by clients to get information about the available servers.
ICertConfig2 | Used by clients to get information about the available servers. Supersedes ICertConfig. New in the Whistler release.
ICertRequest | Used to send a request to the server and get the results of the request.
ICertRequest2 | Used to send a request to the server and get the results of the request. Supersedes ICertRequest. New in the Whistler release.
ICertServerExit | Used by exit modules to get certificate and request properties.
ICertServerPolicy | Used by the policy module to get and set certificate and request properties.
ICertView | Used by clients for viewing the Certificate Services database.
ICertView2 | Used by clients for viewing the Certificate Services database. Supersedes ICertView. New in the Whistler release.
IEnumCERTVIEWATTRIBUTE | Used by clients to access the certificate attributes for a row in the Certificate Services view.
IEnumCERTVIEWCOLUMN | Used by clients to access the data columns of a row in the Certificate Services view.
IEnumCERTVIEWEXTENSION | Used by clients to access the certificate extension data for a row in the Certificate Services view.
IEnumCERTVIEWROW | Used by clients to enumerate the rows of the Certificate Services view.

The following interfaces are imported by the server engine.

Interface | Description
ICertExit | Exported by exit modules. Used by the server engine to deliver finished certificates and revocation information.
ICertManageModule | Exported by policy or exit modules. Used to display module information or to display a user interface for configuration of the module.
ICertPolicy | Exported by the policy module. Used by the server engine to check requests and get properties for certificates.

The following interfaces can be exported by extension handlers and are imported by the policy module.

Interface | Description
ICertEncodeAltName | Used by the policy module to handle alternate name extensions.
ICertEncodeBitString | Used by the policy module to handle bit strings used in certificate extensions.
ICertEncodeCRLDistInfo | Used by the policy module to handle certificate revocation list (CRL) distribution information arrays used in certificate extensions.
ICertEncodeDateArray | Used by the policy module to handle Date arrays used in certificate extensions.
ICertEncodeLongArray | Used by the policy module to handle Long arrays used in certificate extensions.
ICertEncodeStringArray | Used by the policy module to handle STRING arrays used in certificate extensions.

Note

The Certificate Services interfaces support only the apartment-threading model.


ICertAdmin

Platform SDK: Security

ICertAdmin [C++]

CCertAdmin [Visual Basic,Java]

The ICertAdmin interface allows properly authorized clients to perform the following actions:

  • Authorize or deny a certificate request.
  • Revoke an issued certificate.
  • Trigger the generation of a certificate revocation list (CRL).
  • Get the current CRL for the server.
  • Determine if a certificate is valid.

When you use the ICertAdmin interface, you have write-only access to request attributes and certificate extensions, but no direct access to other request and certificate properties.

ICertAdmin is defined in certadm.h. When you create your program, however, use certsrv.h as the include file. CertAdm.dll, on the other hand, provides the implementation of the ICertAdmin interface. In Windows 2000, the type information for this interface is also in CertAdmL.dll, which is shipped with the Platform SDK.

This interface performs administrative tasks, and administration tasks on Windows 2000 servers use DCOM, while Windows NT 4.0 servers use RPC. Attempts to use these methods on a Windows 2000 server must be done from a computer running Windows 2000. Code calling this interface's methods as defined in an old version of certadm.h include file will run on both Windows NT 4.0 and Windows 2000 servers as long as the client and the server are both running Windows 2000 or both running Windows NT 4.0.

Like the other Certificate Services interfaces, ICertAdmin supports only the apartment-threading model.

The following methods are provided by the ICertAdmin interface.

Method | Description
DenyRequest | Denies a certificate request.
GetCRL | Gets a pointer to the current CRL.
GetRevocationReason | Returns a value specifying the reason a certificate was revoked.
ImportCertificate | Imports a previously issued certificate.
IsValidCertificate | Checks the validity of a certificate.
PublishCRL | Publishes a new CRL.
ResubmitRequest | Submits a pended certificate request to the policy module.
RevokeCertificate | Revokes a certificate on a specified date.
SetCertificateExtension | Adds a new extension to a certificate to be issued.
SetRequestAttributes | Sets the attributes of a certificate request.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certadm.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertAdmin::DenyRequest

Platform SDK: Security

ICertAdmin::DenyRequest [C++]

CCertAdmin.DenyRequest [Visual Basic,Java]

The DenyRequest method denies a specified request. For this method to succeed, the certificate request must be pending. An enterprise certification authority (CA) does not have the option of holding certificate requests pending, so only a stand-alone CA can successfully call DenyRequest.

[C++]
HRESULT DenyRequest(
  BSTR const strConfig,
  LONG RequestId
);
[Visual Basic]
objAdmin.DenyRequest( _
  strConfig As String, _
  RequestId As Long _
)
[Java]
void DenyRequest(
  java.lang.String strConfig,
  int RequestId
);

Parameters

[Visual Basic] objAdmin
Object expression that resolves to a CCertAdmin object.
[C++,Visual Basic,Java] strConfig
[in] Represents a valid configuration string for the certification authority (CA) in the form MACHINENAME\CANAME, where MACHINENAME is the Certificate Services server's network name, and CANAME is the common name of the certification authority, as entered during Certificate Services setup. See ICertConfig for information about the configuration string name.
[C++,Visual Basic,Java] RequestId
[in] Specifies the ID of the request to be denied.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic,Java] None.

Remarks

This is an administrative task and administration tasks on Windows 2000 servers use DCOM, while Windows NT 4.0 servers use RPC. Attempts to use this method on a Windows 2000 server must be done from a computer running Windows 2000. Code calling this interface method as defined in an old version of certadm.h include file will run on both Windows NT 4.0 and Windows 2000 servers as long as the client and the server are both running Windows 2000 or both running Windows NT 4.0.

Example Code [C++]

The following example declares the necessary variables, initializes COM, and creates an instance of the CertAdmin class. It then calls DenyRequest and prints success or failure to the screen. Finally, it frees resources.

    // pointer to interface object
    ICertAdmin * pCertAdmin = NULL;

    // variable for machine\CAName
    BSTR       bstrCA = NULL;

    // variable for Request ID
    long       nReqID;

    HRESULT    hr;

    // Initialize COM.
    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    // Check status.
    if (FAILED(hr))
    {
        printf("Failed CoInitializeEx [%x]\n", hr);
        goto error;
    }

    // Create the CertAdmin object
    // and get a pointer to its ICertAdmin interface.
    hr = CoCreateInstance( CLSID_CCertAdmin,
                           NULL,
                           CLSCTX_INPROC_SERVER,
                           IID_ICertAdmin,
                           (void **)&pCertAdmin);
    if (FAILED(hr))
    {
        printf("Failed CoCreateInstance pCertAdmin [%x]\n", hr);
        goto error;
    }

    // Note the use of two '\' in C++ to produce one '\'.
    bstrCA = SysAllocString(L"server01\\myCAName");
    // nReqID is RequestID to be denied (hard-coded in this example).
    nReqID = 1234;
    // Deny the request.
    hr = pCertAdmin->DenyRequest( bstrCA, nReqID );
    if (FAILED(hr))
    {
        printf("Failed DenyRequest %ws %d [%x]\n",
               bstrCA, nReqID, hr);
        goto error;
    }
    else
        printf("Denied request %ws %d\n",
                bstrCA, nReqID );

    // Done processing.

error:

    // Free BSTR values.
    if (NULL != bstrCA)
        SysFreeString(bstrCA);

    // Clean up object resources.
    if (NULL != pCertAdmin)
        pCertAdmin->Release();

    // Free COM resources.
    CoUninitialize();

Example Code [Visual Basic]

The following example creates an instance of the CertAdmin class. It then calls DenyRequest. Finally, it frees resources.

' Create the Cert Admin object.
' Ensure the project references CertAdm TypeLib.
Dim objAdmin As CCertAdmin
Set objAdmin = New CCertAdmin

' Variable for the request ID, hard-coded here.
Dim nReqID As Long
nReqID = 1234

' Deny the request.
objAdmin.DenyRequest "server01\myCAName", nReqID

' Free the object.
Set objAdmin = Nothing

Example Code [Java]

The following example creates an instance of the CertAdmin class and declares the necessary variables. It then calls DenyRequest. Finally, it frees resources.

// Declare and create the CCertAdmin object.
// The CertAdm library is a COM wrapper
// that has been added to the project.
certadm.CCertAdmin objAdm;
objAdm = new certadm.CCertAdmin();

// Declare a string for the certification authority.
java.lang.String strConfig;
// Note the use of two '\' in Java to produce one '\'.
strConfig = "server01\\myCAName";

// Declare a variable for the request ID; hard-coded here.
int ReqID;
ReqID = 1234;

// Deny the request.
objAdm.DenyRequest(strConfig, ReqID);

// Free the object.
com.ms.com.ComLib.release(objAdm);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certadm.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertAdmin, ICertConfig


ICertAdmin::GetCRL

Platform SDK: Security

ICertAdmin::GetCRL [C++]

CCertAdmin.GetCRL [Visual Basic,Java]

The GetCRL method retrieves the current certificate revocation list (CRL) for the Certificate Services certification authority (CA).

[C++]
HRESULT GetCRL(
  BSTR const strConfig,
  LONG Flags,
  BSTR *pbstrCRL
);
[Visual Basic]
objAdmin.GetCRL( _
  strConfig As String, _
  Flags As Long _
) As String
[Java]
java.lang.String GetCRL(
  java.lang.String strConfig,
  int Flags
);

Parameters

[Visual Basic] objAdmin
Object expression that resolves to a CCertAdmin object.
[C++,Visual Basic,Java] strConfig
[in] Represents a valid configuration string for the CA whose CRL you want to retrieve. This string is in the form MACHINENAME\CANAME, where MACHINENAME is the Certificate Services server's network name, and CANAME is the common name of the CA, as entered during Certificate Services setup. See ICertConfig for information about the configuration string name.
[C++,Visual Basic,Java] Flags
[in] Specifies the format of the returned CRL. The value can be one of the following.
CRL format flag | Description
CR_OUT_BASE64HEADER | BASE64 format with begin/end.
CR_OUT_BASE64 | BASE64 format without begin/end.
CR_OUT_BINARY | Binary format.

[C++] pbstrCRL
[out] Pointer to a BSTR that receives the CRL.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and the pbstrCRL parameter points to a BSTR containing the CRL.

[Visual Basic,Java] The return value is the CRL stored in a String variable.

Remarks

This is an administrative task and administration tasks on Windows 2000 servers use DCOM, while Windows NT 4.0 servers use RPC. Attempts to use this method on a Windows 2000 server must be done from a computer running Windows 2000. Code calling this interface method as defined in an old version of certadm.h include file will run on both Windows NT 4.0 and Windows 2000 servers as long as the client and the server are both running Windows 2000 or both running Windows NT 4.0.

Remarks [C++]

To use this method, create a variable of BSTR type, set the variable to NULL, and pass the address of this variable in the pbstrCRL parameter. When you finish with the BSTR variable, make sure to free it by calling SysFreeString.

Example Code [C++]

The following example declares the necessary variables, initializes COM, and creates an instance of the CertAdmin class. It then calls GetCRL and prints success or failure to the screen. Finally, it frees resources.
    // Pointer to interface object
    ICertAdmin * pCertAdmin = NULL;

    // variable for machine\CAName
    BSTR       bstrCA = NULL;

    // variable to contain the retrieved CRL
    BSTR       bstrCRL = NULL;

    HRESULT    hr;

    // Initialize COM.
    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    // Check status.
    if (FAILED(hr))
    {
        printf("Failed CoInitializeEx [%x]\n", hr);
        goto error;
    }

    // Create the CertAdmin object
    // and get a pointer to its ICertAdmin interface.
    hr = CoCreateInstance( CLSID_CCertAdmin,
                           NULL,
                           CLSCTX_INPROC_SERVER,
                           IID_ICertAdmin,
                           (void **)&pCertAdmin);
    if (FAILED(hr))
    {
        printf("Failed CoCreateInstance pCertAdmin [%x]\n", hr);
        goto error;
    }

    // Note the use of two '\' in C++ to produce one '\'.
    bstrCA = SysAllocString(L"server01\\myCAName");
    // Retrieve the CRL.
    hr = pCertAdmin->GetCRL( bstrCA, CR_OUT_BINARY, &bstrCRL );
    if (FAILED(hr))
    {
        printf("Failed GetCRL [%x]\n", hr);
        goto error;
    }
    else
        printf("CRL retrieved successfully\n");
        // Use the CRL as needed...

    // Done processing.

error:

    // Free BSTR values.
    if (NULL != bstrCA)
        SysFreeString(bstrCA);

    if (NULL != bstrCRL)
        SysFreeString(bstrCRL);

    // Clean up object resources.
    if (NULL != pCertAdmin)
        pCertAdmin->Release();

    // Free COM resources.
    CoUninitialize();

Example Code [Visual Basic]

Two Visual Basic examples are shown, the first retrieving a base-64 CRL and the second retrieving a binary CRL. The first example declares the necessary constants and variables, and creates an instance of the CertAdmin class. It then calls GetCRL and displays the CRL. Finally, it frees resources. The second example shows how a binary CRL could be retrieved.

' BASE64 example.
' Constants understood by GetCRL.
Const CR_OUT_BASE64HEADER = 0
Const CR_OUT_BASE64 = &H1
Const CR_OUT_BINARY = &H2

' Create the CertAdmin object.
' Ensure the project references CertAdm TypeLib.
Dim objAdmin As CCertAdmin
Set objAdmin = New CCertAdmin

' Variable to contain retrieved CRL.
Dim strCRL As String

' Retrieve the CRL.
strCRL = objAdmin.GetCRL("server01\myCAName", CR_OUT_BASE64)

' Do something with the CRL; this sample
' displays the CRL in a message box.
MsgBox (strCRL)

' Free the object.
Set objAdmin = Nothing
' Binary example.
' If you wish to retrieve a binary CRL in Visual Basic, it is
' necessary to convert the string into a byte array.
' If you do not retrieve the CRL in this manner, the
' resulting CRL will be missing the last byte if
' an odd-number of bytes should have been returned. The following
' sample shows a work-around for this situation.
' Retrieve the CRL.
Dim strNewCRL As String
strNewCRL = objAdm.GetCRL("server01\myCAName", CR_OUT_BINARY)

' Determine the size of the needed array.
Dim ct As Integer
ct = LenB(strNewCRL)

' Dimension the byte array.
ReDim rgByte(ct) As Byte
' Assign the string contents to the byte array.
rgByte = strNewCRL

' Use the rgByte byte array as needed.
' ...

Example Code [Java]

The following code includes two examples, the first retrieving a base-64 CRL and the second retrieving a binary CRL.

// BASE64 sample.
final int CR_OUT_BASE64HEADER = 0x00;
final int CR_OUT_BASE64 = 0x01;
final int CR_OUT_BINARY = 0x02;
try
{
    java.lang.String strCRL;
    // Retrieve the CRL.
    strCRL = objAdm.GetCRL(strConfig,
                           CR_OUT_BASE64);

    // Use the CRL. This example writes it to a file.
    File CRLfile = new File("d:\\myCRL.crl");
    FileOutputStream fos;
    fos = new FileOutputStream(CRLfile);
    byte rgByte[];

    // Convert the String to an array of bytes.
    rgByte = strCRL.getBytes();
    // Write the bytes to the file.
    fos.write(rgByte);
    // Close the file.
    fos.close();
}
catch (com.ms.com.ComFailException e)
{
    System.out.println("ComFailure: " + e.getMessage());
    System.exit(-1);
}
catch (IOException e)
{
    System.out.println("IO Failure: " + e.getMessage());
}
// Binary sample
// Note: If you want to retrieve a binary CRL in Java, it is
// necessary to first place the CRL into a Variant, then into a byte
// array. If you do not retrieve the binary CRL in this manner, the
// resulting CRL will be missing the last byte if an odd-number of
// bytes should have been returned. The following sample shows a
// work-around for this situation.
// This Visual J++ source file will call CCertAdmin::GetCRL to
// retrieve a binary CRL file. The com.ms.com.Dispatch.invoke method
// is used to ensure that no bytes are lost when retrieving a
// string containing an odd number of bytes.

import java.io.*;
import com.ms.com.*;

public class Class1
{
    public static void main (String[] args)
    {
       final int CR_OUT_BINARY = 0x02;

        try
        {
            // Declare and create the object.
            // The CertAdm library is a COM wrapper
            // that has been added to the project.
            certadm.CCertAdmin objAdm;
            objAdm = new certadm.CCertAdmin();

            // Declare an array for the GetCRL method's arguments.
            Object rgArg[];
            rgArg = new Object[2];

            // The first argument is for the strConfig.
            rgArg[0] = new String("server01\\myCAName");
            // The second argument is for the Flags.
            rgArg[1] = new Integer(CR_OUT_BINARY);

            // Declare a Variant. Upon success,
            // this Variant will contain the CRL.
            Variant var1;
            // Retrieve the CRL.
            // Upon return, the Variant will have the type VT_BSTR.
            var1 = com.ms.com.Dispatch.invoke(objAdm,
                                              "GetCRL",
                                              Dispatch.Method,
                                              rgArg,
                                              null);
            // Constants, as defined in WTypes.h.
            final int VT_ARRAY = 0x2000;
            final int VT_UI1   = 17;
            // Change the Variant type to a byte array. When the
            // Variant is handled in this way, no bytes will be lost.
            // If var1.toString() had instead been called and the
            // CRL contained an odd number of bytes, the last byte
            // would have been lost.
            var1.changeType(VT_UI1 | VT_ARRAY);
            // Place the Variant contents into a byte array.
            // Note that you must cast the return to a byte array.
            byte rgByte[];
            rgByte = (byte[])var1.toByteArray();

            // Write the bytes to a file.
            File CRLFile = new File("D:\\binary.crl");
            FileOutputStream fos = new FileOutputStream(CRLFile);
            fos.write(rgByte);
            fos.close();

            // Release the variant resource.
            var1.VariantClear();

            // Release the object.
            com.ms.com.ComLib.release(objAdm);
        }
        catch (com.ms.com.ComFailException e)
        {
            System.out.println("COM Failure: " + e.getMessage());
        }
        catch (IOException e)
        {
            System.out.println("IO Failure: " + e.getMessage());
        }

    }
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certadm.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertAdmin, ICertConfig


ICertAdmin::GetRevocationReason

Platform SDK: Security

ICertAdmin::GetRevocationReason [C++]

CCertAdmin.GetRevocationReason [Visual Basic,Java]

The GetRevocationReason method returns a value specifying the reason a certificate was revoked. Before you call this method, you must call the IsValidCertificate method (see Remarks).

[C++]
HRESULT GetRevocationReason(
  LONG *pReason
);
[Visual Basic]
objAdmin.GetRevocationReason() As Long
[Java]
int GetRevocationReason();

Parameters

[Visual Basic] objAdmin
Object expression that resolves to a CCertAdmin object.
[C++] pReason
[out] Pointer to variable that will receive the revocation reason.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pReason is set to one of the values listed in the following table.

[Visual Basic,Java] Returns a value specifying the reason the certificate was revoked. The value can be one of the following (defined in wincrypt.h) revocation reason codes.

Revocation reason code | Value
CRL_REASON_UNSPECIFIED | 0
CRL_REASON_KEY_COMPROMISE | 1
CRL_REASON_CA_COMPROMISE | 2
CRL_REASON_AFFILIATION_CHANGED | 3
CRL_REASON_SUPERSEDED | 4
CRL_REASON_CESSATION_OF_OPERATION | 5
CRL_REASON_CERTIFICATE_HOLD | 6

Remarks

Before you call GetRevocationReason, call the IsValidCertificate method to retrieve the disposition of the certificate. To call GetRevocationReason, you must receive a certificate disposition CA_DISP_REVOKED from this earlier call, indicating that the certificate has been revoked. The call to IsValidCertificate establishes the identity of the certificate whose revocation reason you want to retrieve by calling GetRevocationReason.

This is an administrative task and administration tasks on Windows 2000 servers use DCOM, while Windows NT 4.0 servers use RPC. Attempts to use this method on a Windows 2000 server must be done from a computer running Windows 2000. Code calling this interface method as defined in an old version of certadm.h include file will run on both Windows NT 4.0 and Windows 2000 servers as long as the client and the server are both running Windows 2000 or both running Windows NT 4.0.

Example Code [C++]

    // nDisp value set by means of call to ICertAdmin::IsValidCertificate.
    if (CA_DISP_REVOKED == nDisp)
    {
        // Variable to contain revocation reason.
        long       nReason;

        // Retrieve the revocation reason.
        hr = pCertAdmin->GetRevocationReason(&nReason);
        if (FAILED(hr))
        {
            printf("Failed GetRevocationReason [%x]\n", hr);
            goto error;
        }
        else
            printf("Revocation reason = %d\n", nReason );
    }

Example Code [Visual Basic]

' For this sample, interested in revoked certs only.
Const CA_DISP_REVOKED = &H2 ' Returned by IsValidCertificate

' Constant values for GetRevocationReason
Const CRL_REASON_UNSPECIFIED = 0
Const CRL_REASON_KEY_COMPROMISE = 1
Const CRL_REASON_CA_COMPROMISE = 2
Const CRL_REASON_AFFILIATION_CHANGED = 3
Const CRL_REASON_SUPERSEDED = 4
Const CRL_REASON_CESSATION_OF_OPERATION = 5
Const CRL_REASON_CERTIFICATE_HOLD = 6

' Create the Cert Admin object.
' Ensure the project references CertAdm TypeLib.
Dim objAdmin As CCertAdmin
Set objAdmin = New CCertAdmin

' Variable used to retrieve revocation reason.
Dim nReason As Long

' Variable containing cert. serial number
' This value is hard-coded for this example.
Dim serial_num As String
serial_num = "01507ECF00000003"

' Must first call IsValidCertificate.
Dim nValid As Long
nValid = objAdmin.IsValidCertificate("server01\myCAName", serial_num)

If (CA_DISP_REVOKED = nValid) Then

' Determine why the certificate was revoked.
nReason = objAdmin.GetRevocationReason()

' Display a readable string based on the revoke reason.
Select Case nReason
   Case CRL_REASON_UNSPECIFIED
       MsgBox ("Revoked due to unspecified reason")
   Case CRL_REASON_KEY_COMPROMISE
       MsgBox ("Revoked due to key compromise")
   Case CRL_REASON_CA_COMPROMISE
       MsgBox ("Revoked due to CA compromise")
   Case CRL_REASON_AFFILIATION_CHANGED
       MsgBox ("Revoked due to affiliation change")
   Case CRL_REASON_SUPERSEDED
       MsgBox ("Revoked due to being superseded")
   Case CRL_REASON_CESSATION_OF_OPERATION
       MsgBox ("Revoked due to cessation of operation")
   Case CRL_REASON_CERTIFICATE_HOLD
       MsgBox ("Revoked due to certificate hold")
End Select

End If

' Free the object.
Set objAdmin = Nothing

Example Code [Java]

// Reason codes.
final int CRL_REASON_UNSPECIFIED = 0;
final int CRL_REASON_KEY_COMPROMISE = 1;
final int CRL_REASON_CA_COMPROMISE = 2;
final int CRL_REASON_AFFILIATION_CHANGED = 3;
final int CRL_REASON_SUPERSEDED = 4;
final int CRL_REASON_CESSATION_OF_OPERATION = 5;
final int CRL_REASON_CERTIFICATE_HOLD = 6;

// CA_DISP_REVOKED is the only disposition from
// IsValidCertificate() that is of interest in this sample.
final int CA_DISP_REVOKED = 0x02;

// Declare a string for the CA.
java.lang.String strConfig;
// Note the use of two '\' in Java to produce one '\'.
strConfig = "server01\\myCAName";

// Declare a string for the serial number.
java.lang.String strSerial_Number;
strSerial_Number = "0136679F000000000004";

int nDisp;
nDisp = objAdm.IsValidCertificate(strConfig,
                                  strSerial_Number);
if (CA_DISP_REVOKED == nDisp)
{
    // The certficate is revoked.
    // Retrieve the reason.
    int nReason;
    nReason = objAdm.GetRevocationReason();

    // Display the reason description.
    switch (nReason)
    {
    case CRL_REASON_UNSPECIFIED:
        System.out.println("Reason unspecified");
        break;
    case CRL_REASON_KEY_COMPROMISE:
        System.out.println("Key compromise");
        break;
    case CRL_REASON_CA_COMPROMISE:
        System.out.println("CA compromise");
        break;
    case CRL_REASON_AFFILIATION_CHANGED:
        System.out.println("Affiliation changed");
        break;
    case CRL_REASON_SUPERSEDED:
        System.out.println("Superseded");
        break;
    case CRL_REASON_CESSATION_OF_OPERATION:
        System.out.println("Operation ceased");
        break;
    case CRL_REASON_CERTIFICATE_HOLD:
        System.out.println("Certificate hold");
        break;
    default:
        System.out.println("Unexpected reason code");
        break;
    }
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certadm.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertAdmin, ICertAdmin::IsValidCertificate


ICertAdmin::ImportCertificate

Platform SDK: Security

ICertAdmin::ImportCertificate [C++]

CCertAdmin.ImportCertificate [Visual Basic,Java]

The ImportCertificate method takes a previously issued certificate and imports it to the certification authority's (CA) database. For the requirements that the certificate must meet to be successfully imported, see the Remarks section.

[C++]
HRESULT ImportCertificate(
  BSTR const strConfig,
  BSTR const strCertificate,
  LONG Flags,
  LONG *pRequestID
);
[Visual Basic]
objAdmin.ImportCertificate( _
  strConfig As String, _
  strCertificate As String, _
  Flags As Long _
) As Long
[Java]
java.lang.int ImportCertificate(
  java.lang.String strConfig,
  java.lang.String strCertificate,
  int Flags
);

Parameters

[Visual Basic] objAdmin
Object expression that resolves to a CCertAdmin object.
[C++,Visual Basic,Java] strConfig
[in] Represents a valid configuration string for the certification authority (CA) in the form MACHINENAME\CANAME, where MACHINENAME is the Certificate Services server's network name, and CANAME is the common name of the certification authority, as entered during Certificate Services setup. See ICertConfig for information about the configuration string name.
[C++,Visual Basic,Java] strCertificate
[in] The binary representation of the certificate being imported.
[C++,Visual Basic,Java] Flags
[in] Specifies the format of the certificate. The value can be any one of the following.
Format flag | Description
CR_IN_BASE64HEADER | BASE64 format with begin/end.
CR_IN_BASE64 | BASE64 format without begin/end.
CR_IN_BINARY | Binary format.

[C++] pRequestID
[out] Pointer to a LONG value that receives the database-assigned request ID for the imported certificate.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pRequestID is set to the value of the database-assigned request ID for the imported certificate.

[Visual Basic,Java] The return value is the database-assigned request ID for the imported certificate.

Remarks

The ImportCertificate method is useful in the case of a CA that has been partially restored from backup: If a certificate is not on the backup tape(s) used to restore the CA but exists in a file, the certificate can be imported by means of this method.

For this method to succeed, the certificate being imported must have been previously issued by the certification authority (CA) specified in strConfig. The restored CA will validate the certificate's signature, and if the signature is not valid, the method call will fail.

Furthermore, you cannot import a certificate if it already exists in the database. Each certificate in the database must be unique. The database ensures uniqueness by checking the certificate's serial number.

Example Code [C++]

// This code imports a binary certificate file.
// Variable for certificate.
BSTR   bstrCert=NULL;
// Variables for file, buffer, etc.
HANDLE hFile;
DWORD  cchFile, cbRead;
// Variable for request ID.
LONG   nID;

// Open the file containing the certificate.
hFile = CreateFile(L"d:\\cert1.cer",
                  GENERIC_READ,
                  FILE_SHARE_READ,
                  NULL,
                  OPEN_EXISTING,
                  0,
                  NULL);
if (INVALID_HANDLE_VALUE == hFile)
{
    printf("Unable to open file\n");
    // Take error action as needed…
}
// Determine the file size.
cchFile = GetFileSize(hFile, NULL);
if ( (DWORD)-1 == cchFile )
{
    printf("Failed GetFileSize\n");
    // Take error action as needed…
}
// Allocate the memory for the certificate.
bstrCert = SysAllocStringByteLen(NULL,cchFile);
if (NULL == bstrCert)
{
    printf("Failed SysAllocStringByteLen\n");
    // Take error action as needed…
}
// Read in the certificate.
if (!ReadFile(hFile,
             (char *)bstrCert,
             cchFile,
             &cbRead,
             NULL) || (cbRead != cchFile))
{
    printf("Failed to successfully read file\n");
    // Take error action as needed…
}
// Close the file.
CloseHandle(hFile);
// Import the certificate.
// bstrCA was previously allocated.
hr = pCertAdmin->ImportCertificate(bstrCA,
                                   bstrCert,
                                   CR_IN_BINARY,
                                   &nID);
if (FAILED(hr))
    printf("Failed ImportCertificate [%x]\n", hr);
else
    printf("Imported certificated has Request ID: %d\n", nID);

// Free memory, etc. (not shown)

Example Code [Visual Basic]

    ' This code imports a binary certificate file.
    ' Constants of interest to ImportCertificate.
    Const CR_IN_BASE64HEADER = 0
    Const CR_IN_BASE64 = &H1
    Const CR_IN_BINARY = &H2

    'Ensure CertAdm typelib is included in project.
    Dim objAdm As CCertAdmin
    Dim strCert As String
    Dim ReqID As Long
    Dim FSize As Long
    Dim rgByte() As Byte

    ' Create the CCertAdmin object.
    Set objAdm = New CCertAdmin
    ' Size the byte array.
    FSize = FileLen("d:\cert1.cer")
    ReDim rgByte(1 To FSize)
    ' Open the certificate file.
    Open "d:\cert1.cer" For Binary Access Read As #1
    ' Read the certificate into the byte array.
    Get #1, , rgByte
    ' Close the file.
    Close #1
    ' Assign the byte array to the string variable.
    strCert = rgByte

    ' Import the certificate.
    On Error GoTo Err
    ReqID = objAdm.ImportCertificate("Server\CertAuth", _
                                     strCert, _
                                     CR_IN_BINARY)
    MsgBox ("Imported certificate has Request ID " & ReqID)
    On Error Resume Next

Done:
    ' Free object.
    Set objAdm = Nothing
    Exit Sub
Err:
    MsgBox ("Failed to import certificate: " & Err.Description)
    Resume Done

Example Code [Java]

// This code imports a binary certificate file.
final int CR_IN_BASE64HEADER = 0;
final int CR_IN_BASE64 = 0x01;
final int CR_IN_BINARY = 0x02;

// Declare a string for the CA.
java.lang.String strConfig;
// Note the use of two '\' in Java to produce one '\'.
strConfig = "server01\\myCAName";

// Open the file containing the certificate.
File certfile = new File("d:\\cert1.cer");
// Determine the file's byte length.
int cByte = (int)certfile.length();

// Allocate an array for the certificate bytes.
// The length of the file determines the array size.
byte rgByte[];
rgByte = new byte[cByte];
FileInputStream fisCert;
// Read the bytes, by using a FileInputStream object.
try
{
    fisCert = new FileInputStream(certfile);
    // Read the certificate into the byte array.
    fisCert.read(rgByte);
    // Close the file.
    fisCert.close();
}
catch (IOException e)
{
    System.out.println("File error: "+e.getMessage());
    System.exit(-1);
}

// Now that the byte array is ready, place the contents
// into a char array. A java char is always two bytes. As a result,
// the char array size is half the size of the byte array.
// cByte+1 is necessary in case there are an odd number of bytes.
char rgChar[];
rgChar = new char[(cByte+1)/2];
// Fill the char array, two bytes into each char.
// This example assumes little-endian ordering.
int    j;
for (j=0; j<cByte/2; j++)
{
    // Two bytes make up each character.
    rgChar[j] = (char)((rgByte[j*2+1]<<8) + (rgByte[j*2] & 0xff));
}
// You must include the last byte if there was an odd number of bytes.
if (1 == cByte%2)
    rgChar[j] = (char)(rgByte[j*2] & 0xff);

// Use the char array to assign a value to a String variable.
java.lang.String strCert;
strCert = new java.lang.String(rgChar);
// NOTE: If you are importing a BASE64 or BASE64HEADER certificate,
// assign strCert by 'strCert = new java.lang.String(rgByte);'.
// (You won't need rgChar or the code that assigns values to
// rgChar). Also, if you are using BASE64 or BASE64HEADER, the
// appropriate flag (CR_IN_BASE64 or CR_IN_BASE64HEADER) must be
// specified as the third parameter in ImportCertificate.

try
{
    int ReqID;

    // Import the certificate.
    ReqID = objAdm.ImportCertificate(strConfig,
                                     strCert,
                                     CR_IN_BINARY);
    // Display the request ID.
    System.out.println("Imported certificate has request ID: "
                       + ReqID);
}
catch (com.ms.com.ComFailException e)
{
    // Error encountered during the ImportCertificate call.
    // Display the error text and stack trace, then exit.
    System.out.println(e.getMessage());
    e.printStackTrace();
    System.exit(-1);
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certadm.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertAdmin, ICertConfig


ICertAdmin::IsValidCertificate

Platform SDK: Security

ICertAdmin::IsValidCertificate [C++]

CCertAdmin.IsValidCertificate [Visual Basic,Java]

The IsValidCertificate method checks the validity of a certificate. The validity is checked by verifying the certificate against the certification authority (CA) key and then checking that the certificate has not been revoked.

[C++]
HRESULT IsValidCertificate(
  BSTR const strConfig,
  BSTR const strSerialNumber,
  LONG *pDisposition
);
[Visual Basic]
objAdmin.IsValidCertificate( _
  strConfig As String, _
  strSerialNumber As String _
) As Long
[Java]
int IsValidCertificate(
  java.lang.String strConfig,
  java.lang.String strSerialNumber
);

Parameters

[Visual Basic] objAdmin
Object expression that resolves to a CCertAdmin object.
[C++,Visual Basic,Java] strConfig
[in] Represents a valid configuration string for the CA in the form MACHINENAME\CANAME, where MACHINENAME is the Certificate Services server's network name, and CANAME is the common name of the certification authority, as entered during Certificate Services setup. See ICertConfig for information about the configuration string name.
[C++,Visual Basic,Java] strSerialNumber
[in] Specifies the serial number identifying the certificate to be reviewed. The string must specify the serial number as an even number of hexadecimal digits. If necessary, a zero can be prefixed to the number to produce an even number of digits. No more than one leading zero may be used.
[C++] pDisposition
[out] Pointer to a LONG that receives the disposition value.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pDisposition is set to one of the following values.

[Visual Basic,Java] The return value specifies the disposition of the certificate. The following are possible values. (These values are defined in certadm.h).

Value | Meaning
CA_DISP_INCOMPLETE | The call was not completed.
CA_DISP_ERROR | The call failed.
CA_DISP_REVOKED | The certificate has been revoked
CA_DISP_VALID | The certificate is still valid.
CA_DISP_INVALID | The certificate was never issued.
CA_DISP_UNDER_SUBMISSION | The certificate is pending.

Remarks

This method determines only if a certificate has been issued and is not currently revoked; it does not check that the current time and date are within the period for which the certificate is valid (the NotBefore and NotAfter certificate properties). An application which uses this method is also responsible for checking the certificate expiration.

This is an administrative task and administration tasks on Windows 2000 servers use DCOM, while Windows NT 4.0 servers use RPC. Attempts to use this method on a Windows 2000 server must be done from a computer running Windows 2000. Code calling this interface method as defined in an old version of certadm.h include file will run on both Windows NT 4.0 and Windows 2000 servers as long as the client and the server are both running Windows 2000 or both running Windows NT 4.0.

Example Code [C++]

    // variable for machine\CAName
    BSTR       bstrCA = NULL;

    // variable to contain the certificate serial number
    BSTR       bstrSerial = NULL;

    // variable to contain certificate disposition
    long       nDisp;

    HRESULT    hr;
    // Note the use of two '\' in C++ to produce one '\'.
    bstrCA = SysAllocString(L"server01\\myCAName");
    // Specify a serial number; hard-coded in this example.
    bstrSerial = SysAllocString(L"1234567890");
    // Determine if the certificate is valid.
    // pCertAdmin is previously instantiated ICertAdmin object pointer.
    hr = pCertAdmin->IsValidCertificate(bstrCA, bstrSerial, &nDisp);
    if (FAILED(hr))
    {
        printf("Failed IsValidCertificate [%x]\n", hr);
        goto error;
    }
    // Use nDisp as needed...

    // Done processing.

error:

    // Free BSTR values.
    if (NULL != bstrCA)
        SysFreeString(bstrCA);

    if (NULL != bstrSerial)
        SysFreeString(bstrSerial);

Example Code [Visual Basic]

' Constants returned by IsValidCertificate
Const CA_DISP_INCOMPLETE = 0
Const CA_DISP_ERROR = &H1
Const CA_DISP_REVOKED = &H2
Const CA_DISP_VALID = &H3
Const CA_DISP_INVALID = &H4
Const CA_DISP_UNDER_SUBMISSION = &H5

' Create the Cert Admin object.
' Ensure the project references CertAdm TypeLib.
Dim objAdmin As CCertAdmin
Set objAdmin = New CCertAdmin

' Variable used to retrieve validity status.
Dim nValid As Long

' Variable containing cert. serial number
' This value is hard-coded for this example.
Dim serial_num As String
serial_num = "01507B4A00000001"

' Check the validity of a certificate.
nValid = objAdmin.IsValidCertificate("server01\myCAName", serial_num)

' Display a message based on the result.
Select case nValid
  Case CA_DISP_INCOMPLETE
      MsgBox( "Validity = Incomplete")
  Case CA_DISP_ERROR
      MsgBox( "Validity = Error!")
  Case CA_DISP_REVOKED
      MsgBox( "Validity = Revoked Certificate")
  Case CA_DISP_VALID
      MsgBox( "Validity = Valid Certificate")
  Case CA_DISP_INVALID
      MsgBox( "Validity = Invalid Certificate")
  Case CA_DISP_UNDER_SUBMISSION
      MsgBox( "Validity = Request pending")
End Select

' Free the object.
Set objAdmin = Nothing

Example Code [Java]

final int CA_DISP_INCOMPLETE = 0x00;
final int CA_DISP_ERROR = 0x01;
final int CA_DISP_REVOKED = 0x02;
final int CA_DISP_VALID = 0x03;
final int CA_DISP_INVALID = 0x04;
final int CA_DISP_UNDER_SUBMISSION = 0x05;
// Declare a string for the CA.
java.lang.String strConfig;
// Note the use of two '\' in Java to produce one '\'.
strConfig = "server01\\myCAName";

// Declare a hard-coded string for the serial number.
java.lang.String strSerial_Number;
strSerial_Number = "610CE15D000000000002";

// Declare a variable to retrieve the validity status.
int nValid;
// Check the validity of the certificate.
nValid = objAdm.IsValidCertificate(strConfig,
                                   strSerial_Number);
switch (nValid)
{
case CA_DISP_INCOMPLETE:
    System.out.println("Validity = Incomplete");
    break;
case CA_DISP_ERROR:
    System.out.println("Validity = Error!");
    break;
case CA_DISP_REVOKED:
    System.out.println("Validity = Revoked Certificate");
    break;
case CA_DISP_VALID:
    System.out.println("Validity = Valid Certificate");
    break;
case CA_DISP_INVALID:
    System.out.println("Validity = Invalid Certificate");
    break;
case CA_DISP_UNDER_SUBMISSION:
    System.out.println("Validity = Request pending");
    break;
default:
    System.out.println("Unexpected value for Validity");
    break;
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certadm.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertAdmin, ICertConfig


ICertAdmin::PublishCRL

Platform SDK: Security

ICertAdmin::PublishCRL [C++]

CCertAdmin.PublishCRL [Visual Basic,Java]

The PublishCRL method causes the Certificate Services certification authority (CA) to publish a new certificate revocation list (CRL).

[C++]
HRESULT PublishCRL(
  BSTR const strConfig,
  DATE Date
);
[Visual Basic]
objAdmin.PublishCRL( _
  strConfig As String, _
  Date As Date _
)
[Java]
void PublishCRL(
  java.lang.String strConfig,
  double Date
);

Parameters

[Visual Basic] objAdmin
Object expression that resolves to a CCertAdmin object.
[C++,Visual Basic,Java] strConfig
[in] Represents a valid configuration string for the CA in the form MACHINENAME\CANAME, where MACHINENAME is the Certificate Services server's network name, and CANAME is the common name of the certification authority, as entered during Certificate Services setup. See ICertConfig for information about the configuration string name.
[C++,Visual Basic,Java] Date
[in] Specifies the expiration date of the CRL, in GMT time.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic,Java] None.

Remarks

This is an administrative task and administration tasks on Windows 2000 servers use DCOM, while Windows NT 4.0 servers use RPC. Attempts to use this method on a Windows 2000 server must be done from a computer running Windows 2000. Code calling this interface method as defined in an old version of certadm.h include file will run on both Windows NT 4.0 and Windows 2000 servers as long as the client and the server are both running Windows 2000 or both running Windows NT 4.0.

Example Code [C++]

    // variable for CRL expiration date
    DATE       ExpDate;

    // Intermediate variable
    SYSTEMTIME st;

    // Set the CRL Expiration Date to Noon on Jan. 1, 2005 GMT.
    // Zero out values first (avoids setting minutes, seconds, etc.).
    memset(&st, 0, sizeof(SYSTEMTIME));
    // Set the values of interest.
    st.wYear = 2005;
    st.wMonth = 1;     // Jan
    st.wDay = 1;       // 1st day of month
    st.wHour = 12;     // Noon
    // Place the date in required format.
    if (!SystemTimeToVariantTime( &st, &ExpDate))
    {
        printf("Unable to convert time\n");
        goto error;
    }

    // Publish the CRL.
    // pCertAdmin is previously instantiated ICertAdmin object.
    // bstrCA is previously allocated BSTR for machine\CAName.
    hr = pCertAdmin->PublishCRL(bstrCA, ExpDate);
    if (FAILED(hr))
    {
        printf("Failed PublishCRL [%x]\n", hr);
        goto error;
    }
    else
        printf("PublishCRL succeeded\n");
    // Done processing.

error:

    // Free resources, etc.

Example Code [Visual Basic]

Dim ExpDate As Date

'  Set the CRL Expiration Date to Noon on Jan. 1, 2005 GMT.
ExpDate = #1/1/2005 12:00:00 PM#

' Create the Cert Admin object.
' Ensure the project references CertAdm TypeLib.
Dim objAdmin As CCertAdmin
Set objAdmin = New CCertAdmin

' Publish the CRL
objAdmin.PublishCRL "server01\myCAName", ExpDate

' Free the object.
Set objAdmin = Nothing

Example Code [Java]

// This Visual J++ sample calls CCertAdmin.PublishCRL to
// publish a CRL. In order to use a programmer-friendly CRL
// expiration date, this sample uses J/Direct for a SYSTEMTIME
// class and also to call the WIN32 SystemTimeToVariantTime function.
import java.io.*;
import com.ms.win32.Kernel32;

// The following comment is a J/Direct directive.
/** @dll.struct() */
class SYSTEMTIME
{
    public short wYear;
    public short wMonth;
    public short wDayOfWeek;
    public short wDay;
    public short wHour;
    public short wMinute;
    public short wSecond;
    public short wMilliseconds;
}

public class Class1
{
    public static void main (String[] args)
    {

        try
        {
            // Declare and and create instance of the CCertAdm object.
            certadm.CCertAdmin objAdm;
            objAdm = new certadm.CCertAdmin();

            // Declare and create instance of the SYSTEMTIME variable.
            SYSTEMTIME st;
            st = new SYSTEMTIME();

            // Specify the CRL's expiration date. For this
            // example, the date is 1/1/2005 Noon GMT.
            st.wYear = 2005;
            st.wMonth = 1;     // January
            st.wDay = 1;       // 1st day of month
            st.wHour = 12;     // Noon
            st.wMinute = 0;
            st.wSecond = 0;
            st.wMilliseconds = 0;
            st.wDayOfWeek = 0;  // Not used in date conversion.

            // Declare a double array to contain the converted date.
            double d1[];
            d1 = new double[1];
            d1[0] = 0;

            // Declare a return value.
            boolean ret;
            // Call the function.
            ret = SystemTimeToVariantTime(st,d1);
            // Check the return value. If return value doesn't
            // equal true, the function call failed.
            if (true != ret)
                throw new Exception("SystemTimeToVariantTime");

            // Publish the CRL.
            objAdm.PublishCRL("server01\\myCAName",
                              d1[0]);

            // Release the object.
            com.ms.com.ComLib.release(objAdm);

        }
        catch (com.ms.com.ComFailException e)
        {
            System.out.println("COM error: " + e.getMessage());
        }
        catch (Exception e)
        {
            System.out.println("Error: " + e.getMessage());
        }
    }
        // The following comment is a J/Direct directive.
        /** @dll.import("oleaut32",unicode)*/
        private static native boolean SystemTimeToVariantTime(
                                      SYSTEMTIME s1,
                                      double[] pvTime);
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certadm.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertAdmin, ICertConfig


ICertAdmin::ResubmitRequest

Platform SDK: Security

ICertAdmin::ResubmitRequest [C++]

CCertAdmin.ResubmitRequest [Visual Basic,Java]

The ResubmitRequest method submits the specified request to the policy module for the specified certification authority (CA). For this method to succeed, the certificate request must be pending. An enterprise CA does not have the option of holding certificate requests pending, so only a stand-alone CA can successfully call ResubmitRequest.

[C++]
HRESULT ResubmitRequest(
  BSTR const strConfig,
  LONG RequestId,
  LONG *pDisposition
);
[Visual Basic]
objAdmin.ResubmitRequest( _
  strConfig As String, _
  RequestId As Long _
) As Long
[Java]
int ResubmitRequest(
  java.lang.String strConfig,
  int RequestId
);

Parameters

[Visual Basic] objAdmin
Object expression that resolves to a CCertAdmin object.
[C++,Visual Basic,Java] strConfig
[in] Represents a valid configuration string for the CA in the form MACHINENAME\CANAME, where MACHINENAME is the Certificate Services server's network name, and CANAME is the common name of the certification authority, as entered during Certificate Services setup. See ICertConfig for information about the configuration string name.
[C++,Visual Basic,Java] RequestId
[in] Specifies the ID of the request to resubmit.
[C++] pDisposition
[out] Pointer to disposition of the request.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pDisposition is set to one of the following values specifying the disposition of the request. This value is one of the following.

[Visual Basic,Java] The return value specifies the disposition of the request. This value is one of the following.

Value | Meaning
CR_DISP_INCOMPLETE | The request was not completed.
CR_DISP_ERROR | The request failed.
CR_DISP_DENIED | The request was denied.
CR_DISP_ISSUED | The certificate was issued.
CR_DISP_ISSUED_OUT_OF_BAND | The certificate issued separately.
CR_DISP_UNDER_SUBMISSION | The request was taken under submission.

Remarks

This is an administrative task and administration tasks on Windows 2000 servers use DCOM, while Windows NT 4.0 servers use RPC. Attempts to use this method on a Windows 2000 server must be done from a computer running Windows 2000. Code calling this interface method as defined in an old version of certadm.h include file will run on both Windows NT 4.0 and Windows 2000 servers as long as the client and the server are both running Windows 2000 or both running Windows NT 4.0.

Example Code [C++]

// Variable for disposition value.
long    nDisp;

// Specify the request ID to resubmit (hard-coded here).
long    nReqID = 1234;

hr = pCertAdmin->ResubmitRequest(bstrCA, nReqID, &nDisp);
if (FAILED(hr))
{
    printf("Failed ResubmitRequest [%x]\n", hr);
    goto error;
}
else
    printf("ResubmitRequest disposition is %d\n", nDisp);

Example Code [Visual Basic]

' Create the Cert Admin object.
' Ensure the project references CertAdm TypeLib.
Dim objAdmin As CCertAdmin
Set objAdmin = New CCertAdmin

' Variable for the request ID, hard-coded here.
Dim nReqID As Long
nReqID = 1234

' Variable for the returned disposition of the request.
Dim nDisp As Long

' Resubmit the request.
nDisp = objAdmin.ResubmitRequest("server01\myCAName", nReqID)

' Do something with the returned disposition.
MsgBox( nDisp )

' Free the object.
Set objAdmin = Nothing

Example Code [Java]

// Declare a string for the CA.
java.lang.String strConfig;
// Note the use of two '\' in Java to produce one '\'.
strConfig = "server01\\myCAName";

// Declare an int for the request ID, hard-coded here.
int ReqID;
ReqID = 8;

// Declare an int for the request disposition.
int nDisp;

// Resubmit the request.
nDisp = objAdm.ResubmitRequest(strConfig,
                               ReqID);
// Use the disposition value as needed...

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certadm.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertAdmin, ICertConfig, ICertRequest::Submit


ICertAdmin::RevokeCertificate

Platform SDK: Security

ICertAdmin::RevokeCertificate [C++]

CCertAdmin.RevokeCertificate [Visual Basic,Java]

The RevokeCertificate method revokes a certificate on a specified date, or immediately if desired. A revoked certificate will appear in a subsequent certificate revocation lists (CRL), provided the revocation date is effective at the time the CRL was published.

[C++]
HRESULT RevokeCertificate(
  BSTR const strConfig,
  BSTR const strSerialNumber,
  LONG Reason,
  DATE Date
);
[Visual Basic]
objAdmin.RevokeCertificate( -
  strConfig As String, _
  strSerialNumber As String, _
  Reason As Long, _
  Date As Date _
)
[Java]
void RevokeCertificate(
  java.lang.String strConfig,
  java.lang.String strSerialNumber,
  int Reason,
  double Date
);

Parameters

[Visual Basic] objAdmin
Object expression that resolves to a CCertAdmin object.
[C++,Visual Basic,Java] strConfig
[in] Represents a valid configuration string for the certification authority (CA) server in the form MACHINENAME\CANAME, where MACHINENAME is the Certificate Services server's network name, and CANAME is the common name of the CA, as entered during Certificate Services setup. See ICertConfig for information about the configuration string name.
[C++,Visual Basic,Java] strSerialNumber
[in] Specifies the serial number identifying the certificate to be revoked. The string must specify the serial number as an even number of hexadecimal digits. If necessary, a zero may be prefixed to the number to produce an even number of digits. However, no more than one leading zero may be used.
[C++,Visual Basic,Java] Reason
[in] Specifies the reason for the revocation. The following values (defined in wincrypt.h) are supported reason codes.
Revocation reason code | Value
CRL_REASON_UNSPECIFIED | 0
CRL_REASON_KEY_COMPROMISE | 1
CRL_REASON_CA_COMPROMISE | 2
CRL_REASON_AFFILIATION_CHANGED | 3
CRL_REASON_SUPERSEDED | 4
CRL_REASON_CESSATION_OF_OPERATION | 5
CRL_REASON_CERTIFICATE_HOLD | 6

Beginning with Windows 2000, you can reinstate a certificate revoked with the CRL_REASON_CERTIFICATE_HOLD revocation reason code by calling RevokeCertificate with MAXDWORD as the Reason value. Note that if a certificate has been revoked with any reason code other than CRL_REASON_CERTIFICATE_HOLD, it cannot be reinstated.

[C++,Visual Basic,Java] Date
[in] Specifies the date on which the revocation will become effective, in GMT time. The value 0 indicates the current GMT time, causing a certificate to be revoked immediately. The value of Date appears in the revoked certificate's Effective Revocation Date column (in the Certification Authority MMC snap-in).

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic,Java] None.

Remarks

This method can be called more than once on the same certificate, allowing you to change the effective revocation date and revocation reason.

If a currently revoked certificate has CRL_REASON_CERTIFICATE_HOLD as its reason code, you can reinstate the certificate by calling RevokeCertificate with MAXDWORD (defined in winnt.h) as the value for its reason code (the Reason parameter). Once reinstated, the certificate will not appear in future CRLs. (Reinstating a certificate is supported in Windows 2000 only).

This is an administrative task and administration tasks on Windows 2000 servers use DCOM, while Windows NT 4.0 servers use RPC. Attempts to use this method on a Windows 2000 server must be done from a computer running Windows 2000.

Example Code [C++]

    // Variable for certificate serial number.
    BSTR       bstrSerial = NULL;

    // Variable for request ID.
    long       nReason;

    // Variable for revocation date.
    DATE       RevokeDate;

    // Intermediate date variable.
    SYSTEMTIME st;

    // Specify the serial number to revoke (hard-coded here).
    bstrSerial = SysAllocString(L"1234567890");
    // Specify the revocation reason.
    nReason = CRL_REASON_AFFILIATION_CHANGED; // def'd in wincrypt.h
    // Specify when the cert should be revoked.
    // Note: To revoke immediately, merely set RevokeDate to 0.
    // This example sets the revoke date to noon on 1/1/2001.
    // Zero out values first (avoids setting minutes, seconds, etc).
    memset(&st, 0, sizeof(SYSTEMTIME));
    // Set the values of interest.
    st.wYear = 2001;
    st.wMonth = 1;     // Jan
    st.wDay = 1;       // 1st day of month
    st.wHour = 12;     // Noon
    // Place the date in required format.
    if (!SystemTimeToVariantTime( &st, &RevokeDate))
    {
        printf("Unable to convert time.\n");
        goto error;
    }

    // Revoke the certificate.
    // pCertAdmin is previously instantiated ICertAdmin object.
    // bstrCA is BSTR for machine\CAName.
    hr = pCertAdmin->RevokeCertificate( bstrCA,
                                        bstrSerial,
                                        nReason,
                                        RevokeDate );
    if (FAILED(hr))
    {
        printf("Failed RevokeCertificate. [%x]\n", hr);
        goto error;
    }
    else
        printf("Certificate %ws revoked.\n", bstrSerial );

    // Done processing.

error:

    // Free resources, etc....
    if ( NULL != bstrSerial )
        SysFreeString( bstrSerial );

Example Code [Visual Basic]

' Constant values used by RevokeCertificate.
Const CRL_REASON_UNSPECIFIED = 0
Const CRL_REASON_KEY_COMPROMISE = 1
Const CRL_REASON_CA_COMPROMISE = 2
Const CRL_REASON_AFFILIATION_CHANGED = 3
Const CRL_REASON_SUPERSEDED = 4
Const CRL_REASON_CESSATION_OF_OPERATION = 5
Const CRL_REASON_CERTIFICATE_HOLD = 6

' Create the CertAdmin object.
' Ensure the project references CertAdm TypeLib.
Dim objAdmin As CCertAdmin
Set objAdmin = New CCertAdmin

' Variable containing certificate serial number.
' This value is hard-coded for this example.
Dim serial_num As String
serial_num = "0150881500000009"

' Revoke the certificate.
' The reason is affiliation change.
' The revocation date is 8/31/1999 11:30 PM.
' To revoke immediately, use 0 for the date.
objAdmin.RevokeCertificate "server01\myCAName", _
                            serial_num, _
                            CRL_REASON_AFFILIATION_CHANGED, _
                            #8/31/1999 11:30:00 PM#

' Free the object.
Set objAdmin = Nothing
End Sub

Example Code [Java]

// Reason codes.
final int CRL_REASON_UNSPECIFIED = 0;
final int CRL_REASON_KEY_COMPROMISE = 1;
final int CRL_REASON_CA_COMPROMISE = 2;
final int CRL_REASON_AFFILIATION_CHANGED = 3;
final int CRL_REASON_SUPERSEDED = 4;
final int CRL_REASON_CESSATION_OF_OPERATION = 5;
final int CRL_REASON_CERTIFICATE_HOLD = 6;

// Declare a string for the CA.
java.lang.String strConfig;
// Note the use of two '\' in Java to produce one '\'.
strConfig = "server01\\myCAName";

// Declare a string for the serial number.
java.lang.String strSerial_Number;
strSerial_Number = "0136679F000000000004";

// Revoke the certificate, effective immediately.
objAdm.RevokeCertificate(strConfig,
                         strSerial_Number,
                         CRL_REASON_KEY_COMPROMISE,
                         0);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certadm.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertAdmin, ICertConfig


ICertAdmin::SetCertificateExtension

Platform SDK: Security

ICertAdmin::SetCertificateExtension [C++]

CCertAdmin.SetCertificateExtension [Visual Basic,Java]

The SetCertificateExtension method adds a new extension to the certificate issued in response to a certificate request. For this method to succeed, the certificate request must be pending. An enterprise certification authority (CA) does not have the option of holding certificate requests pending, so only a stand-alone CA can successfully call SetCertificateExtension.

[C++]
HRESULT SetCertificateExtension(
  BSTR const strConfig,
  LONG RequestId,
  BSTR const strExtensionName,
  LONG Type,
  LONG Flags,
  VARIANT const *pvarValue
);
[Visual Basic]
objAdmin.SetCertificateExtension( _
  strConfig As String, _
  RequestId As Long, _
  strExtensionName As String, _
  Type As Long, _
  Flags As Long, _
  pvarValue As Variant _
)
[Java]
void SetCertificateExtension(
  java.lang.String strConfig,
  int RequestId,
  java.lang.String strExtensionName,
  int Type,
  int Flags,
  com.ms.com.Variant pvarValue
);

Parameters

[Visual Basic] objAdmin
Object expression that resolves to a CCertAdmin object.
[C++,Visual Basic,Java] strConfig
[in] Represents a valid configuration string for the CA server in the form MACHINENAME\CANAME, where MACHINENAME is the Certificate Services server's network name, and CANAME is the common name of the CA, as entered during Certificate Services setup. See ICertConfig for information about the configuration string name.
[C++,Visual Basic,Java] RequestId
[in] Specifies the ID of the certificate request.
[C++,Visual Basic,Java] strExtensionName
[in] Specifies the object identifier (OID) for the extension to set. The string must be 31 or fewer non-NULL characters in length.
[C++,Visual Basic,Java] Type
[in] Specifies the type of extension being set. The Type parameter must agree with the data type of the pvarValue parameter. This data type is set in the vt field of the VARIANT structure. The Type parameter can be set to one of the following values.
Type | Description
PROPTYPE_LONG | Signed Long data
PROPTYPE_DATE | Date / Time
PROPTYPE_BINARY | Binary data
PROPTYPE_STRING | Unicode String data

[C++,Visual Basic,Java] Flags
[in] Specifies the flags for the extension being set. Use a value of 0 if no flag is to be set, or use one of the following flag values. You can join these flags by means of the OR operator, and also with policy private extension flags (the high 8 bits of the EXTENSION_POLICY_MASK field).
Flag value | Explanation
EXTENSION_CRITICAL_FLAG | This is a critical extension.
EXTENSION_DISABLE_FLAG | The extension will not be used.

Note When ExtFlags is set to EXTENSION_DISABLE_FLAG, the extension will be disabled in the server log and will not be added to the certificate.

[C++,Visual Basic,Java] pvarValue
[in] Specifies the value associated with the extension.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic,Java] None.

Remarks

This is an administrative task and administration tasks on Windows 2000 servers use DCOM, while Windows NT 4.0 servers use RPC. Attempts to use this method on a Windows 2000 server must be done from a computer running Windows 2000. Code calling this interface method as defined in an old version of certadm.h include file will run on both Windows NT 4.0 and Windows 2000 servers as long as the client and the server are both running Windows 2000 or both running Windows NT 4.0.

Example Code [C++]

    // Variable for extension name.
    BSTR         bstrExtName;

    // Variable for extension value.
    VARIANT     varExt;

    // Variable for Request ID.
    long        nReqID;
    // Specify the extension name.
    bstrExtName = SysAllocString(L"2.29.38.4");

    // Specify the extension value.
    varExt.vt = VT_BSTR;
    varExt.bstrVal = SysAllocString(L"http://UrlTest.htm");

    // Hard-coded the request ID for the certificate to receive the extension.
    nReqID = 1234;

    // Add the extension to the certificate.
    // pCertAdmin is pointer to a previously instantiated ICertAdmin object.
    // bstrCA is previously allocated BSTR for machine\CAName.
    hr = pCertAdmin->SetCertificateExtension( bstrCA,
                                              nReqID,
                                              bstrExtName,
                                              PROPTYPE_STRING,
                                              EXTENSION_CRITICAL_FLAG,
                                              &varExt );
    if (FAILED(hr))
        printf("Failed SetCertificateExtension [%x]\n", hr);
    else
        printf("SetCertificateExtension succeeded\n");

error:
    // Done processing.
    VariantClear(&varExt);
    if (NULL != bstrExtName)
        SysFreeString(bstrExtName);
    // Free other resources, etc....

Example Code [Visual Basic]

' Constants of interest (from certsrv.h).
Const PROPTYPE_LONG = &H1
Const PROPTYPE_DATE = &H2
Const PROPTYPE_BINARY = &H3
Const PROPTYPE_STRING = &H4
Const EXTENSION_CRITICAL_FLAG = &H1
Const EXTENSION_DISABLE_FLAG = &H2

Dim strExtName As String
Dim varExtValue As Variant

' Specify the extension name.
strExtName = "2.29.38.4"

' Specify the extension value.
varExtValue = "http://UrlTest.htm"

' Add the extension to the certificate (hardcoded request ID as 19).
objAdm.SetCertificateExtension "server01\myCAName", _
                               19, _
                               strExtName, _
                               PROPTYPE_STRING, _
                               EXTENSION_CRITICAL_FLAG, _
                               varExtValue

Example Code [Java]

// Constants used SetCertificateExtension.
final int PROPTYPE_LONG = 0x01;
final int PROPTYPE_DATE = 0x02;
final int PROPTYPE_BINARY = 0x03;
final int PROPTYPE_STRING = 0x04;
final int EXTENSION_CRITICAL_FLAG = 0x01;
final int EXTENSION_DISABLE_FLAG = 0x02;

// Declare a string for the CA.
java.lang.String strConfig;
// Note the use of two '\' in Java to produce one '\'.
strConfig = "server01\\myCAName";

// Declare an int for the request ID.
int ReqID;
ReqID = 7;

// Declare and assign a string for a custom extension name.
java.lang.String strExtName;
strExtName = "MyExtensionName";

// Declare a Variant and assign it to a custom extension value.
com.ms.com.Variant varExt;
varExt = new com.ms.com.Variant("http://UrlTest.htm");

// Set the certificate extension.
objAdm.SetCertificateExtension(strConfig,
                               ReqID,
                               strExtName,
                               PROPTYPE_STRING,
                               EXTENSION_CRITICAL_FLAG,
                               varExt);
// Clear the Variant when done.
varExt.VariantClear();

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certadm.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertAdmin, ICertConfig


ICertAdmin::SetRequestAttributes

Platform SDK: Security

ICertAdmin::SetRequestAttributes [C++]

CCertAdmin.SetRequestAttributes [Visual Basic,Java]

The SetRequestAttributes method sets attributes in the specified request. For this method to succeed, the certificate request must be pending. An enterprise certification authority (CA) does not have the option of holding certificate requests pending, so only a stand-alone CA can successfully call SetRequestAttributes.

[C++]
HRESULT SetRequestAttributes(
  BSTR const strConfig,
  LONG RequestId,
  BSTR const strAttributes
);
[Visual Basic]
objAdmin.SetRequestAttributes( _
  strConfig As String, _
  RequestId As Long, _
  strAttributes As String _
)
[Java]
void SetRequestAttributes(
  java.lang.String strConfig,
  int RequestId,
  java.lang.String strAttributes
);

Parameters

[Visual Basic] objAdmin
Object expression that resolves to a CCertAdmin object.
[C++,Visual Basic,Java] strConfig
[in] Represents a valid configuration string for the CA server in the form MACHINENAME\CANAME, where MACHINENAME is the Certificate Services server's network name, and CANAME is the common name of theCA, as entered during Certificate Services setup. See ICertConfig for information about the configuration string name.
[C++,Visual Basic,Java] RequestId
[in] Specifies the ID of the request receiving the attributes.
[C++,Visual Basic,Java] strAttributes
[in] Specifies the attribute data. Each attribute is a name/value string pair. The colon character separates the name and value, and a newline character separates multiple name/value pairs, for example:

[C++,Java] "AttributeName1:AttributeValue1\nAttributeName2:AttributeValue2"

[Visual Basic] "AttributeName1:AttributeValue1" & vbNewLine & "AttributeName2:AttributeValue2"

There is no set limit to the number of request attributes that may be added to a request.

When Certificate Services parses attribute names, it ignores spaces, hyphens (minus signs), and case. For example, "AttributeName1", "Attribute Name1", and "Attribute-name1" are all equivalent. For attribute values, Certificate Services ignores leading and trailing white space.

Note Attribute names and values must each be no more than 49 non-NULL characters.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic,Java] None.

Remarks

Attributes added or updated by calling SetRequestAttributes do not alter the initial attributes associated with the certificate request. The certificate request's initial attributes are unalterable once the certificate is requested (the ICertRequest::Submit method allows attributes to be specified at the time the certificate is requested).

You can use the Certificate Services MMC snap-in to display these initial request attributes, but not the attributes added with SetRequestAttributes. To enumerate or view the attributes added by means of SetRequestAttributes, you must use the IEnumCERTVIEWATTRIBUTE interface.

This is an administrative task and administration tasks on Windows 2000 servers use DCOM, while Windows NT 4.0 servers use RPC. Attempts to use this method on a Windows 2000 server must be done from a computer running Windows 2000. Code calling this interface method as defined in an old version of certadm.h include file will run on both Windows NT 4.0 and Windows 2000 servers as long as the client and the server are both running Windows 2000 or both running Windows NT 4.0.

Example Code [C++]

    // Variable for attributes.
    BSTR         bstrAttribs = NULL;

    // Variable for Request ID.
    long        nReqID;
    // Specify the attributes (in this example, two Name/Value pairs).
    bstrAttribs = SysAllocString(L"AttName1:AttValue1\nAttName2:AttValue2");

    // Hard-coded Request ID to receive the attributes.
    nReqID = 1234;

    // Add these attributes to the certificate.
    // pCertAdmin is previously instantiated ICertAdmin object pointer.
    // bstrCA is previously allocated BSTR for machine\CAName.
    hr = pCertAdmin->SetRequestAttributes( bstrCA,
                                           nReqID,
                                           bstrAttribs );
    if (FAILED(hr))
        printf("Failed SetRequestAttributes [%x]\n", hr);
    else
        printf("SetRequestAttributes succeeded\n");

    // Done processing.

error:

    if (NULL != bstrAttribs)
        SysFreeString(bstrAttribs);
    // Free other resources, etc....

Example Code [Visual Basic]

Dim strAtts As String

strAtts = "AttName1:AttValue1" & vbNewLine
strAtts = strAtts & "AttName2:AttValue2"

' Add attributes to pending request (hardcoded request ID as 19).
objAdm.SetRequestAttributes "server01\myCAName", 19, strAtts

Example Code [Java]

// Declare a string for the CA.
java.lang.String strConfig;
// Note the use of two '\' in Java to produce one '\'.
strConfig = "server01\\myCAName";

// Declare an int for the request ID.
int ReqID;
ReqID = 6;

// Declare and assign a string for the attributes.
java.lang.String strAttribs;
strAttribs = "AttName1:AttValue1\nAttName2:AttValue2";

// Set the request attributes for the request.
objAdm.SetRequestAttributes(strConfig,
                            ReqID,
                            strAttribs);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certadm.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertAdmin,

ICertConfig, IEnumCERTVIEWATTRIBUTE


ICertAdmin2

[This is preliminary documentation and subject to change.]

The ICertAdmin2 interface inherits all of the methods of ICertAdmin and includes the following new methods.

Method | Description
GetArchivedKey | Retrieves an archived key recovery BLOB.
GetCAProperty | Retrieves a property value from the certification authority (CA).
GetCAPropertyDisplayName | Retrieves the display name for a property.
GetCAPropertyFlags | Retrieves the property flags (denoting data type and indexed status) for a property.
PublishCRLs | Publishes certificate revocation lists for the CA.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Certadm.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertAdmin2::GetArchivedKey

[This is preliminary documentation and subject to change.]

The GetArchivedKey method retrieves an archived key recovery BLOB.

HRESULT ICertAdmin2::GetArchivedKey(
  BSTR const strConfig,
  LONG RequestId,
  LONG Flags,
  BSTR *pstrArchivedKey
);

Parameters

strConfig
[in] Represents a valid configuration string for the certification authority (CA) in the form MACHINENAME\CANAME, where MACHINENAME is the Certificate Services server's network name, and CANAME is the common name of the CA, as entered during Certificate Services setup. See ICertConfig for information about the configuration string name.
RequestId
[in] Represents the certificate request ID in the Certificates Services database.
Flags
[in] The following flags can be used to specify the format of the returned BLOB.
Flag | Description
CR_OUT_BASE64 | BASE64 without BEGIN/END
CR_OUT_BASE64HEADER | BASE64 with BEGIN CERTIFICATE and END CERTIFICATE
CV_OUT_BINARY | binary

pstrArchivedKey
[out] Pointer to the BSTR representing the retrieved archived key BLOB. It is the responsibility of the caller to free the BSTR when done by calling SysFreeString.

Return Values

The return value is an HRESULT. A value of S_OK indicates the method was successful.

Remarks

An archived key is encrypted in a PKCS #7 to the key recovery agent certificate(s), and is stored in the Certificate Services database in that form. This method retrieves the encrypted PKCS #7 is from the Certificate Services database, wraps it in a signed PKCS #7 which contains the user certificate and chain, the key recovery agent certificate(s), and the certification authority's signing certificate and chain. An authenticated attribute contains a certificate has used to uniquely identify the user certificate.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Certadm.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertAdmin2::GetCAProperty

[This is preliminary documentation and subject to change.]

The GetCAProperty method retrieves a property value for the certification authority (CA).

HRESULT ICertAdmin2::GetCAProperty(
  BSTR const strConfig,
  LONG PropId,
  LONG PropIndex,
  LONG PropType,
  LONG Flags,
  VARIANT *pvarPropertyValue
);

Parameters

strConfig
[in] Represents a valid configuration string for the CA in the form MACHINENAME\CANAME, where MACHINENAME is the Certificate Services server's network name, and CANAME is the common name of the CA, as entered during Certificate Services setup. See ICertConfig for information about the configuration string name.
PropId
[in] Specifies the property identifier. The property identifier can be one of the following defined values.
Property ID | Description | Type | Indexed
CR_PROP_BASECRL | The CA's full, or base, CRL. | Binary | Yes
CR_PROP_CACERTSTATE State of the CA certificate. The values can be:

CA_DISP_REVOKED // The certificate has been revoked

CA_DISP_VALID // The certificate is still valid

CA_DISP_INVALID // The certificate has expired.

 Long Yes
CR_PROP_CANAME | Name of the CA. | String | No
CR_PROP_CASIGCERT | An indexed CA signing certificate. | Binary | Yes
CR_PROP_CASIGCERTCHAIN | An indexed CA signing certificate chain. | Binary | Yes
CR_PROP_CASIGCERTCOUNT | Number of signing certificates for the CA. | Long | No
CR_PROP_CATYPE Type of CA. Can be one of the following values (defined in certsrv.h):

ENUM_ENTERPRISE_ROOTCA

ENUM_ENTERPRISE_SUBCA

ENUM_STANDALONE_ROOTCA

ENUM_STANDALONE_SUBCA

 Long No
CR_PROP_CAXCHGCERT | An indexed CA exchange certificate. | Binary | Yes
CR_PROP_CAXCHGCERTCHAIN | An indexed CA exchange certificate chain. | Binary | Yes
CR_PROP_CAXCHGCERTCOUNT | Number of exchange certificates for the CA. | Long | No
CR_PROP_CRLSTATE State of the CA's CRL. The values can be:

CA_DISP_REVOKED // All unexpired certificates using the certificate's CRL have been revoked.

CA_DISP_VALID // The certificate is still publishing CRLs as needed.

CA_DISP_INVALID // All certificates using the certificate's CRL are expired.

CA_DISP_ERROR // The certificate's CRL is managed by another certificate.

 Long Yes
CR_PROP_DELTACRL | The CA's delta CRL. | Binary | Yes
CR_PROP_DNSNAME | The CA's DNS Name. | String | No
CR_PROP_EXITCOUNT | Number of exit modules in use by the CA. | Long | No
CR_PROP_EXITDESCRIPTION | Description for the exit module. | String | Yes
CR_PROP_FILEVERSION | Certificate Services file version. | String | No
CR_PROP_PARENTCA | Name of the CA's parent CA. | String | No
CR_PROP_POLICYDESCRIPTION | Description for the policy module. | String | No
CR_PROP_PRODUCTVERSION | Product version in which the file shipped. | String | No
CR_PROP_SANITIZEDCANAME | Sanitized name of the CA. See ICertConfig::GetConfig for a definition of a sanitized CA name. | String | No
CR_PROP_SHAREDFOLDER | Name of the shared folder directory. | String | No

PropIndex
[in] If PropId is indexed, the zero-based index to use when retrieving the property value; if PropId is not indexed, this value is ignored.
PropType
[in] Specifies the type of the property, which corresponds to the Type column in the PropId table. The type can be one of the following types.
Type | Description
PROPTYPE_LONG | Signed Long data
PROPTYPE_DATE | Date / Time (reserved for future use)
PROPTYPE_BINARY | Binary data
PROPTYPE_STRING | Unicode String data

Flags
[in] The following flags can be used to specify the format of the returned property value; these flags have meaning only for binary data (such as certificates, certificate chains or certificate revocation lists) and is ignored otherwise.
Flag | Description
CV_OUT_BASE64 | BASE64 without BEGIN/END
CV_OUT_BASE64HEADER | BASE64 with BEGIN CERTIFICATE and END CERTIFICATE
CV_OUT_BASE64REQUESTHEADER | BASE64 with BEGIN NEW CERTIFICATE REQUEST and END NEW CERTIFICATE REQUEST
CV_OUT_BASE64X509CRLHEADER | BASE64 with BEGIN X509 CRL and END X509 CRL
CV_OUT_BINARY | binary
CV_OUT_HEX | hex string
CV_OUT_HEXADDR | hex string with address/offset
CV_OUT_HEXASCII | hex string with ASCII
CV_OUT_HEXASCIIADDR | hex string with ASCII and address/offset

pvarPropertyValue
[out] Pointer to a Variant that receives the requested property value. It is a caller's responsibility to free this resource when done by calling VariantClear.

Return Values

The return value is an HRESULT. A value of S_OK indicates the method was successful.

Example Code [C++]

VARIANT var1;
HRESULT hr;

VariantInit(&var1);
// Retrieve the CA signature certificate at index 0.
hr = pCertAdmin2->GetCAProperty(bstrCA,
                                CR_PROP_CASIGCERT,
                                0,
                                PROPTYPE_BINARY,
                                CV_OUT_BASE64HEADER,
                                &var1);
if (FAILED(hr))
{
    printf("Failed GetCAProperty\n");
    exit(1);  // Or other error action.
}

// Use the property as needed.
// ...

// Clear the variant when done.
VariantClear(&var1);

Example Code [Visual Basic]

' Constants for property IDs
Const CR_PROP_FILEVERSION As Long = 1
Const CR_PROP_PRODUCTVERSION As Long = 2
Const CR_PROP_EXITCOUNT As Long = 3
Const CR_PROP_EXITDESCRIPTION As Long = 4
Const CR_PROP_POLICYDESCRIPTION As Long = 5
Const CR_PROP_CANAME As Long = 6
Const CR_PROP_SANITIZEDCANAME As Long = 7
Const CR_PROP_SHAREDFOLDER As Long = 8
Const CR_PROP_PARENTCA As Long = 9
Const CR_PROP_CATYPE As Long = 10
Const CR_PROP_CASIGCERTCOUNT As Long = 11
Const CR_PROP_CASIGCERT As Long = 12
Const CR_PROP_CASIGCERTCHAIN As Long = 13
Const CR_PROP_CAXCHGCERTCOUNT As Long = 14
Const CR_PROP_CAXCHGCERT As Long = 15
Const CR_PROP_CAXCHGCERTCHAIN As Long = 16
Const CR_PROP_BASECRL As Long = 17
Const CR_PROP_DELTACRL As Long = 18
Const CR_PROP_CACERTSTATE As Long = 19
Const CR_PROP_CRLSTATE As Long = 20
' Constants for data types and indexed status
Const PROPTYPE_LONG As Long = &H1
Const PROPTYPE_DATE As Long = &H2
Const PROPTYPE_BINARY As Long = &H3
Const PROPTYPE_STRING As Long = &H4
Const PROPTYPE_MASK As Long = &HFF
Const PROPFLAGS_INDEXED As Long = &H10000
' Constants for binary flags
Const CV_OUT_BASE64HEADER As Long = 0
Const CV_OUT_BASE64 As Long = &H1
Const CV_OUT_BINARY As Long = &H2
Const CV_OUT_BASE64REQUESTHEADER As Long = &H3
Const CV_OUT_HEX As Long = &H4
Const CV_OUT_HEXASCII As Long = &H5
Const CV_OUT_BASE64X509CRLHEADER As Long = &H9
Const CV_OUT_HEXADDR As Long = &HA
Const CV_OUT_HEXASCIIADDR As Long = &HB

' CertAdm's type library is referenced in the project.
Dim objAdm2 As CCertAdmin
Set objAdm2 = New CCertAdmin

' Retrieve the CA signature certificate at index 0.
Dim varCACert As Variant
varCACert = objAdm2.GetCAProperty("\\SERVER01\MyCA", _
                    CR_PROP_CASIGCERT, _
                    0, _
                    PROPTYPE_BINARY, _
                    CV_OUT_BASE64HEADER)
' Use the property value as needed; this sample will
' place it into a message box.
MsgBox (varCACert)

' Free the object.
Set objAdm2 = Nothing

Example Code [Java]

// Constants for CA property IDs.
final int CR_PROP_FILEVERSION = 1;
final int CR_PROP_PRODUCTVERSION = 2;
final int CR_PROP_EXITCOUNT = 3;
final int CR_PROP_EXITDESCRIPTION = 4;
final int CR_PROP_POLICYDESCRIPTION = 5;
final int CR_PROP_CANAME = 6;
final int CR_PROP_SANITIZEDCANAME = 7;
final int CR_PROP_SHAREDFOLDER = 8;
final int CR_PROP_PARENTCA = 9;
final int CR_PROP_CATYPE = 10;
final int CR_PROP_CASIGCERTCOUNT = 11;
final int CR_PROP_CASIGCERT = 12;
final int CR_PROP_CASIGCERTCHAIN = 13;
final int CR_PROP_CAXCHGCERTCOUNT = 14;
final int CR_PROP_CAXCHGCERT = 15;
final int CR_PROP_CAXCHGCERTCHAIN = 16;
final int CR_PROP_BASECRL = 17;
final int CR_PROP_DELTACRL = 18;
final int CR_PROP_CACERTSTATE = 19;
final int CR_PROP_CRLSTATE = 20;
// Constants for property types.
final int PROPTYPE_LONG = 0x00000001;
final int PROPTYPE_DATE = 0x00000002;
final int PROPTYPE_BINARY = 0x00000003;
final int PROPTYPE_STRING = 0x00000004;
// Constants for binary flags
final int CV_OUT_BASE64HEADER = 0;
final int CV_OUT_BASE64 = 0x01;
final int CV_OUT_BINARY = 0x02;
final int CV_OUT_BASE64REQUESTHEADER = 0x03;
final int CV_OUT_HEX = 0x04;
final int CV_OUT_HEXASCII = 0x05;
final int CV_OUT_BASE64X509CRLHEADER = 0x09;
final int CV_OUT_HEXADDR = 0x0A;
final int CV_OUT_HEXASCIIADDR = 0x0B;

try
{
    // Declare and create an instance of the object.
    certadm.CCertAdmin objAdm2;
    objAdm2 = new certadm.CCertAdmin();

    com.ms.com.Variant var1;
    // Retrieve the property value.
    var1 = objAdm2.GetCAProperty("\\\\SERVER01\\MyCA",
                   CR_PROP_EXITCOUNT,
                    0,
                    PROPTYPE_LONG,
                    0);
    // Use the property value as needed.
    int nExitCount;
    nExitCount = var1.getInt();
    System.out.println(nExitCount +
                  " active exit module(s) in use.");
    // When done, release the variant resouce.
    var1.VariantClear();

    // Free the object.
    com.ms.com.ComLib.release(objAdm2);
}
catch (com.ms.com.ComFailException e)
{
    System.out.println(e.getMessage());
}

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Certadm.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertAdmin2::GetCAPropertyDisplayName

[This is preliminary documentation and subject to change.]

The GetCAPropertyDisplayName method retrieves the property display name for a certification authority (CA) property.

HRESULT ICertAdmin2::GetCAPropertyDisplayName(
  BSTR const strConfig,
  LONG PropId,
  BSTR *pstrDisplayName
);

Parameters

strConfig
[in] Represents a valid configuration string for the CA in the form MACHINENAME\CANAME, where MACHINENAME is the Certificate Services server's network name, and CANAME is the common name of the CA, as entered during Certificate Services setup. See ICertConfig for information about the configuration string name.
PropId
[in] Specifies the property identifier. See the table in ICertAdmin2::GetCAProperty for information about this parameter.
pstrDisplayName
[out] Pointer to the BSTR representing the property's display name. It is the responsibility of the caller to free the BSTR when done by calling SysFreeString.

Return Values

The return value is an HRESULT. A value of S_OK indicates the method was successful.

Example Code [C++]

BSTR     bstrDispName = NULL;
HRESULT  hr;

// Retrieve a property's display name.
hr = pCertAdmin2->GetCAPropertyDisplayName(bstrCA,
                                           CR_PROP_EXITCOUNT,
                                           &bstrDispName);
if (FAILED(hr))
{
    printf("Failed GetCAPropertyDisplayName\n");
    exit(1);  // Or other error action.
}
// Display the property's name.
printf("Property display name is %ws\n",
       bstrDispName);

// Free string.
SysFreeString(bstrDispName);

Example Code [Visual Basic]

GetCAPropertyDisplayName
' Constants for property IDs
Const CR_PROP_FILEVERSION As Long = 1
Const CR_PROP_PRODUCTVERSION As Long = 2
Const CR_PROP_EXITCOUNT As Long = 3
Const CR_PROP_EXITDESCRIPTION As Long = 4
Const CR_PROP_POLICYDESCRIPTION As Long = 5
Const CR_PROP_CANAME As Long = 6
Const CR_PROP_SANITIZEDCANAME As Long = 7
Const CR_PROP_SHAREDFOLDER As Long = 8
Const CR_PROP_PARENTCA As Long = 9
Const CR_PROP_CATYPE As Long = 10
Const CR_PROP_CASIGCERTCOUNT As Long = 11
Const CR_PROP_CASIGCERT As Long = 12
Const CR_PROP_CASIGCERTCHAIN As Long = 13
Const CR_PROP_CAXCHGCERTCOUNT As Long = 14
Const CR_PROP_CAXCHGCERT As Long = 15
Const CR_PROP_CAXCHGCERTCHAIN As Long = 16
Const CR_PROP_BASECRL As Long = 17
Const CR_PROP_DELTACRL As Long = 18
Const CR_PROP_CACERTSTATE As Long = 19
Const CR_PROP_CRLSTATE As Long = 20

' CertAdm's type library is referenced in the project.
Dim objAdm2 As CCertAdmin
Set objAdm2 = New CCertAdmin

' Retrieve and show a property's display name.
Dim str As String
str = objAdm2.GetCAPropertyDisplayName("\\SERVER01\MyCA", _
                                       CR_PROP_FILEVERSION)
MsgBox (str)

' Free the object.
Set objAdm2 = Nothing

Example Code [Java]

// Constants for CA property IDs.
final int CR_PROP_FILEVERSION = 1;
final int CR_PROP_PRODUCTVERSION = 2;
final int CR_PROP_EXITCOUNT = 3;
final int CR_PROP_EXITDESCRIPTION = 4;
final int CR_PROP_POLICYDESCRIPTION = 5;
final int CR_PROP_CANAME = 6;
final int CR_PROP_SANITIZEDCANAME = 7;
final int CR_PROP_SHAREDFOLDER = 8;
final int CR_PROP_PARENTCA = 9;
final int CR_PROP_CATYPE = 10;
final int CR_PROP_CASIGCERTCOUNT = 11;
final int CR_PROP_CASIGCERT = 12;
final int CR_PROP_CASIGCERTCHAIN = 13;
final int CR_PROP_CAXCHGCERTCOUNT = 14;
final int CR_PROP_CAXCHGCERT = 15;
final int CR_PROP_CAXCHGCERTCHAIN = 16;
final int CR_PROP_BASECRL = 17;
final int CR_PROP_DELTACRL = 18;
final int CR_PROP_CACERTSTATE = 19;
final int CR_PROP_CRLSTATE = 20;

try
{
    // Declare and create an instance of the object.
    certadm.CCertAdmin objAdm2;
    objAdm2 = new certadm.CCertAdmin();

    // Retrieve the property display name.
    java.lang.String strDispName;
    strDispName = objAdm2.GetCAPropertyDisplayName(
                          "\\\\Server01\\MyCA",
                          CR_PROP_EXITCOUNT);
    // Display the name.
    System.out.println("Display name is " + strDispName);

    // Free the object.
    com.ms.com.ComLib.release(objAdm2);
}
catch (com.ms.com.ComFailException e)
{
    System.out.println(e.getMessage());
}

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Certadm.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertAdmin2::GetCAPropertyFlags

[This is preliminary documentation and subject to change.]

The GetCAPropertyFlags method retrieves the property flags for a certification authority (CA) property. The property flags can be examined to determine the data type and to determine if the property is indexed.

HRESULT ICertAdmin2::GetCAPropertyFlags(
  BSTR const strConfig,
  LONG PropId,
  LONG *pPropFlags
);

Parameters

strConfig
[in] Represents a valid configuration string for the CA in the form MACHINENAME\CANAME, where MACHINENAME is the Certificate Services server's network name, and CANAME is the common name of the CA, as entered during Certificate Services setup. See ICertConfig for information about the configuration string name.
PropId
[in] Specifies the property identifier. See the table in ICertAdmin2::GetCAProperty for information about this parameter.
pPropFlags
[out] Pointer to LONG value that represents the property flags.

Return Values

The return value is an HRESULT. A value of S_OK indicates the method was successful.

Remarks

The LONG value retrieved by calling this method can be examined to determine the data type and the indexed status. To determine the data type and indexed status, use the PROPTYPE_MASK and PROPFLAGS_INDEXED values, respectively.

Example Code [C++]

// Variable to contain the property flags.
LONG nFlags;

// Retrieve a property's flags.
hr = pCertAdmin2->GetCAPropertyFlags(bstrCA,
                                     CR_PROP_EXITCOUNT,
                                     &nFlags);
if (FAILED(hr))
{
    printf("Failed GetCAPropertyFlags\n");
    exit(1);  // Or other error action.
}
// Display the property data type.
switch (nFlags & PROPTYPE_MASK)
{
    case PROPTYPE_BINARY:
        printf("Type is BINARY\n");
        break;
    case PROPTYPE_DATE:
        printf("Type is DATE\n");
        break;
    case PROPTYPE_LONG:
        printf("Type is LONG\n");
        break;
    case PROPTYPE_STRING:
        printf("Type is STRING\n");
        break;
    default:
        printf("Unexpected data type.\n");
        break;
}
// Display the property's indexed status.
printf("Property %s indexed\n",
       nFlags & PROPFLAGS_INDEXED ? "is" : "is not");

Example Code [Visual Basic]

' Constants for property IDs
Const CR_PROP_FILEVERSION As Long = 1
Const CR_PROP_PRODUCTVERSION As Long = 2
Const CR_PROP_EXITCOUNT As Long = 3
Const CR_PROP_EXITDESCRIPTION As Long = 4
Const CR_PROP_POLICYDESCRIPTION As Long = 5
Const CR_PROP_CANAME As Long = 6
Const CR_PROP_SANITIZEDCANAME As Long = 7
Const CR_PROP_SHAREDFOLDER As Long = 8
Const CR_PROP_PARENTCA As Long = 9
Const CR_PROP_CATYPE As Long = 10
Const CR_PROP_CASIGCERTCOUNT As Long = 11
Const CR_PROP_CASIGCERT As Long = 12
Const CR_PROP_CASIGCERTCHAIN As Long = 13
Const CR_PROP_CAXCHGCERTCOUNT As Long = 14
Const CR_PROP_CAXCHGCERT As Long = 15
Const CR_PROP_CAXCHGCERTCHAIN As Long = 16
Const CR_PROP_BASECRL As Long = 17
Const CR_PROP_DELTACRL As Long = 18
Const CR_PROP_CACERTSTATE As Long = 19
Const CR_PROP_CRLSTATE As Long = 20
' Constants for data types and indexed status
Const PROPTYPE_LONG As Long = &H1
Const PROPTYPE_DATE As Long = &H2
Const PROPTYPE_BINARY As Long = &H3
Const PROPTYPE_STRING As Long = &H4
Const PROPTYPE_MASK As Long = &HFF
Const PROPFLAGS_INDEXED As Long = &H10000

' CertAdm's type library is referenced in the project.
Dim objAdm2 As CCertAdmin
Set objAdm2 = New CCertAdmin

' Retrieve a property's flags.
Dim nFlags As Long
nFlags = objAdm2.GetCAPropertyFlags("\\SERVER01\MyCA", _
                                    CR_PROP_CASIGCERT)
' Output the property's data type.
Dim nType As Long
nType = PROPTYPE_MASK And nFlags
Select Case nType
    Case PROPTYPE_LONG
        MsgBox ("Data Type is LONG")
    Case PROPTYPE_DATE
        MsgBox ("Data Type is DATE")
    Case PROPTYPE_BINARY
        MsgBox ("Data Type is BINARY")
    Case PROPTYPE_STRING
        MsgBox ("Data Type is STRING")
    Case Else
        MsgBox ("Unexpected data type")
End Select
' Output the property's indexed status.
If (PROPFLAGS_INDEXED = (PROPFLAGS_INDEXED And nFlags)) Then
    MsgBox ("Property is indexed")
Else
    MsgBox ("Property is not indexed")
End If

' Free the object.
Set objAdm2 = Nothing

Example Code [Java]

// Constants for CA property IDs.
final int CR_PROP_FILEVERSION = 1;
final int CR_PROP_PRODUCTVERSION = 2;
final int CR_PROP_EXITCOUNT = 3;
final int CR_PROP_EXITDESCRIPTION = 4;
final int CR_PROP_POLICYDESCRIPTION = 5;
final int CR_PROP_CANAME = 6;
final int CR_PROP_SANITIZEDCANAME = 7;
final int CR_PROP_SHAREDFOLDER = 8;
final int CR_PROP_PARENTCA = 9;
final int CR_PROP_CATYPE = 10;
final int CR_PROP_CASIGCERTCOUNT = 11;
final int CR_PROP_CASIGCERT = 12;
final int CR_PROP_CASIGCERTCHAIN = 13;
final int CR_PROP_CAXCHGCERTCOUNT = 14;
final int CR_PROP_CAXCHGCERT = 15;
final int CR_PROP_CAXCHGCERTCHAIN = 16;
final int CR_PROP_BASECRL = 17;
final int CR_PROP_DELTACRL = 18;
final int CR_PROP_CACERTSTATE = 19;
final int CR_PROP_CRLSTATE = 20;
// Constants for property types.
final int PROPTYPE_LONG = 0x00000001;
final int PROPTYPE_DATE = 0x00000002;
final int PROPTYPE_BINARY = 0x00000003;
final int PROPTYPE_STRING = 0x00000004;
final int PROPTYPE_MASK = 0x000000FF;
final int PROPFLAGS_INDEXED = 0x00010000;

try
{
    // Declare and create an instance of the object.
    certadm.CCertAdmin objAdm2;
    objAdm2 = new certadm.CCertAdmin();

    // Retrieve the property flags.
    int nFlags;
    nFlags = objAdm2.GetCAPropertyFlags(
                          "\\\\SERVER01\\MyCA",
                          CR_PROP_EXITCOUNT);
    // Display the property type.
    int nType;
    nType = PROPTYPE_MASK & nFlags;
    switch (nType)
    {
        case PROPTYPE_LONG:
            System.out.println("Type is LONG");
            break;
        case PROPTYPE_DATE:
            System.out.println("Type is DATE");
            break;
        case PROPTYPE_BINARY:
            System.out.println("Type is BINARY");
            break;
        case PROPTYPE_STRING:
            System.out.println("Type is STRING");
            break;
        default:
            System.out.println("Unexpected data type");
            break;
    }
    // Display the indexed status.
    int nIndexed;
    nIndexed = PROPFLAGS_INDEXED & nFlags;
    if ( PROPFLAGS_INDEXED == nIndexed)
        System.out.println("Property is indexed.");
    else
        System.out.println("Property is not indexed.");

    // Free the object.
    com.ms.com.ComLib.release(objAdm2);
}
catch (com.ms.com.ComFailException e)
{
    System.out.println(e.getMessage());
}

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Certadm.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertAdmin2::PublishCRLs

[This is preliminary documentation and subject to change.]

The PublishCRLs method is used to publish certificate revocation lists (CRL) for a certification authority (CA). The method publishes a CRL based on the CA's current certificate, as well as CRLs based on any CA certificates which have been renewed and are not yet expired.

HRESULT ICertAdmin2::PublishCRLs(
  BSTR const strConfig,
  DATE Date,
  LONG CRLFlags
);

Parameters

strConfig
[in] Represents a valid configuration string for the certification authority (CA) in the form MACHINENAME\CANAME, where MACHINENAME is the Certificate Services server's network name, and CANAME is the common name of the certification authority, as entered during Certificate Services setup. See ICertConfig for information about the configuration string name.
Date
[in] Specifies the expiration date of the CRL, in GMT time.
CRLFlags
[in] LONG value which determines if a base CRL, a delta CRL, or both are published.
CRLFlag | Description
CA_CRL_BASE | A base CRL is published.
CA_CRL_DELTA | A delta CRL is published. Note that if the CA has not enabled delta CRL publishing, use of this flag will result in an error.

To publish both a base and delta CRL, bitwise-OR the flag values:

[C++,Java] CA_CRL_BASE | CA_CRL_DELTA

[Visual Basic] CA_CRL_BASE Or CA_CRL_DELTA

Return Values

The return value is an HRESULT. A value of S_OK indicates the method was successful.

Example Code [C++]

// Variable for CRL expiration date.
DATE    ExpDate;

// Intermediate variable
SYSTEMTIME st;

// Set the CRL Expiration Date to Noon on July 1, 2001.
// Zero out values first (avoids setting minutes, seconds, etc.).
memset(&st, 0, sizeof(SYSTEMTIME));
// Set the values of interest.
st.wYear = 2001;
st.wMonth = 7;     // July
st.wDay = 1;       // 1st day of month
st.wHour = 12;     // Noon
// Place the date in required format.
if (!SystemTimeToVariantTime( &st, &ExpDate))
{
    printf("Unable to convert time\n");
    exit(1);
}

// Publish a new base CRL.
hr = pCertAdmin2->PublishCRLs(bstrCA,
                              ExpDate,
                              CA_CRL_BASE);
if (FAILED(hr))
{
    printf("Failed PublishCRLs\n");
    exit(1);  // Or other error action.
}

Example Code [Visual Basic]

' Constants for PublishCRLs method
Const CA_CRL_BASE As Long = &H1
Const CA_CRL_DELTA As Long = &H2

' CertAdm's type library is referenced in the project.
Dim objAdm2 As CCertAdmin
Set objAdm2 = New CCertAdmin

' Publish the CRLs.
objAdm2.PublishCRLs "\\SERVER01\MyCA", #7/1/2001 12:00:00 PM#, _
             CA_CRL_BASE Or CA_CRL_DELTA

' Free the object.
Set objAdm2 = Nothing

Example Code [Java]

// This Visual J++ sample calls CCertAdmin.PublishCRLs to
// publish CRLs. In order to use a programmer-friendly CRL
// expiration date, this sample uses J/Direct for a SYSTEMTIME
// class and also to call the WIN32 SystemTimeToVariantTime function.
import java.io.*;
import com.ms.win32.Kernel32;

// The following comment is a J/Direct directive.
/** @dll.struct() */
class SYSTEMTIME
{
    public short wYear;
    public short wMonth;
    public short wDayOfWeek;
    public short wDay;
    public short wHour;
    public short wMinute;
    public short wSecond;
    public short wMilliseconds;
}

public class Class1
{
    public static void main (String[] args)
    {
        final int CA_CRL_BASE = 0x00000001;
        final int CA_CRL_DELTA = 0x00000002;

        try
        {
            // Declare and and create instance of the CCertAdm object.
            certadm.CCertAdmin objAdm2;
            objAdm2 = new certadm.CCertAdmin();

            // Declare and create instance of the SYSTEMTIME variable.
            SYSTEMTIME st;
            st = new SYSTEMTIME();

            // Specify the CRL's expiration date. For this
            // example, the date is 7/1/2001 Noon GMT.
            st.wYear = 2001;
            st.wMonth = 7;     // July
            st.wDay = 1;       // 1st day of month
            st.wHour = 12;     // Noon
            st.wMinute = 0;
            st.wSecond = 0;
            st.wMilliseconds = 0;
            st.wDayOfWeek = 0;  // Not used in date conversion.

            // Declare a double array to contain the converted date.
            double d1[];
            d1 = new double[1];
            d1[0] = 0;

            // Declare a return value.
            boolean ret;
            // Call the function.
            ret = SystemTimeToVariantTime(st,d1);
            // Check the return value. If return value doesn't
            // equal true, the function call failed.
            if (true != ret)
                throw new Exception("SystemTimeToVariantTime");

            // Publish the CRLs.
            objAdm2.PublishCRLs("SERVER01\\MyCA",
                                d1[0],
                                CA_CRL_BASE | CA_CRL_DELTA);

            // Release the object.
            com.ms.com.ComLib.release(objAdm2);

        }
        catch (com.ms.com.ComFailException e)
        {
            System.out.println("COM error: " + e.getMessage());
        }
        catch (Exception e)
        {
            System.out.println("Error: " + e.getMessage());
        }
    }
        // The following comment is a J/Direct directive.
        /** @dll.import("oleaut32",unicode)*/
        private static native boolean SystemTimeToVariantTime(
                                      SYSTEMTIME s1,
                                      double[] pvTime);
}

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Certadm.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertConfig

Platform SDK: Security

ICertConfig [C++]

CCertConfig [Visual Basic,Java]

The ICertConfig interface provides methods to examine the public configuration data specified during client setup. For each installation of Certificate Services, this public configuration data resides in the certsrv.txt file, which exists in the shared folder, the Active Directory, or both. Any server set up to post its configuration information in certsrv.txt is visible to ICertConfig.

Client programs can use ICertConfig to get the following information:

  • The set of Certificate Services servers in the enterprise.
  • The details of a specific Certificate Services server configuration.
  • The default Certificate Services server in the enterprise.

ICertConfig is defined in certcli.h. When you create your program, however, use certsrv.h as the include file. CertCli.dll provides the ICertConfig interface. In Windows 2000, the type information for this interface is also in CertCliL.dll, which is shipped with the Platform SDK.

The Certificate Services interfaces support only the apartment-threading model.

The following methods are provided by the ICertConfig interface.

Method | Description
GetConfig | Gets the default configuration string (the server name and certification authority (CA) name) for a Certificate Services server.
GetField | Gets a specific field from the current record of the configuration database.
Next | Points to the next available Certificate Services server configuration in the configuration point.
Reset | Resets the configuration query state.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certcli.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertConfig::GetConfig

Platform SDK: Security

ICertConfig::GetConfig [C++]

CCertConfig.GetConfig [Visual Basic,Java]

The GetConfig method retrieves the configuration string for a Certificate Services server. The configuration string is the server name and certification authority (CA) name separated by a slash. This configuration string can be used to refer unambiguously to a specific Certificate Services server. See Remarks for details.

[C++]
HRESULT GetConfig(
  LONG Flags,
  BSTR *pbstrOut
);
[Visual Basic]
objConfig.GetConfig( _
  Flags As Long _
) As String
[Java]
java.lang.String GetConfig(
  int Flags
);

Parameters

[Visual Basic] objConfig
Object expression that resolves to a CCertConfig object.
[C++,Visual Basic,Java] Flags
[in] Can be one of the following values.
Value | Description
CC_DEFAULTCONFIG | Retrieves the default CA.
CC_FIRSTCONFIG | Returns the first CA.
CC_UIPICKCONFIG | Displays a user Interface, allowing the user to select a CA.

[C++] pbstrOut
[out] Pointer to BSTR containing the configuration.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pbstrOut is set to the BSTR containing the configuration. To use this method, create a variable of the BSTR type, set the variable equal to NULL, and pass the address of this variable as the pbstrOut parameter. When you finish with the BSTR variable, make sure to free it by calling SysFreeString.

[Visual Basic,Java] The return value is a string specifying the configuration.

Remarks

The certification authority (CA) name portion of the configuration string that this function returns is the exact text entered during the Certificate Services setup process. Note that this text may be different from the form of the CA name found in files names (such as for the certificate revocation list) or in registry keys. This is because file names and registry keys use a sanitized version of the CA name.

The process of sanitizing the CA name is necessary to remove characters that are illegal for file names, registry key names, or distinguished name values, or that are illegal for reasons specific to Certificate Services. In the sanitizing process, any illegal character in the common name is converted to a five-character representation in the format '!xxxx', where '!' is used as an escape character and 'xxxx' represents four hexidecimal integers that uniquely identify the character being converted.

For example, the character '#' is not allowed in distinguished names in Active Directory™. If the CA name entered during setup is '#YourName', the sanitized CA name will be '!0023YourName'.

The following characters, if entered for the common name of the CA during setup, are converted to the '!xxxx' format during the sanitizing process. (This list is subject to change.)

Character | Value in !xxxx Format
< | !003c
> | !003e
" | !0022
/ | !002f
\ | !005c
: | !003a
| | !007c
? | !003f
* | !002a
# | !0023
, | !002c
+ | !002b
; | !003b
! | !0021

Any unprintable character and all non seven-bit Unicode characters are also converted to the '!xxxx' format.

A sanitized short name also exists if the sanitized name is too long for a 64 character Directory Services relative distinguished name (RDN). The sanitized short name consists of the sanitized name truncated and appended with a hash of the full sanitized name. The sanitized short name will reserve some of the 64 characters in order to contain certificate revocation list (CRL) suffixes, such as "(123)".

As stated earlier, the CA name portion of the configuration string returned by this method is the original text entered during setup. Note that Certificate Services methods that require a CA Name as a parameter accept the originally entered CA name. For example, for the CA Name '#YourName', ICertView::OpenConnection accepts '#YourName' as the parameter's CA portion.

Example Code [C++]

    // Pointer to interface object.
    ICertConfig * pConfig = NULL;

    // BSTR variable to contain CA configuration name.
    BSTR  bstrConfig = NULL;

    HRESULT    hr;

    // Initialize COM.
    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    // Check status.
    if (FAILED(hr))
    {
        printf("Failed CoInitializeEx - [%x]\n", hr);
        goto error;
    }

    // Create an instance of the CertConfig object.
    hr = CoCreateInstance( CLSID_CCertConfig,
                           NULL,
                           CLSCTX_INPROC_SERVER,
                           IID_ICertConfig,
                           (void **)&pConfig);
    if (FAILED(hr))
    {
        printf("Failed CoCreateInstance - pConfig [%x]\n", hr);
        goto error;
    }

    // Retrieve the default CA configuration string.
    hr = pConfig->GetConfig(CC_DEFAULTCONFIG, &bstrConfig);
    if (FAILED(hr))
    {
        printf("Failed GetConfig - [%x]\n", hr);
        goto error;
    }
    else
        printf("GetConfig returned: %ws\n", bstrConfig );

error:

    // Done processing.
    // Clean up object resource.
    if (NULL != pConfig)
        pConfig->Release();

    // Clean up BSTR value.
    if (NULL != bstrConfig)
        SysFreeString(bstrConfig);

    // Free COM resources.
    CoUninitialize();

Example Code [Visual Basic]

' Constants for CCertConfig.GetConfig.
Const CC_DEFAULTCONFIG = 0
Const CC_UIPICKCONFIG = &H1
Const CC_FIRSTCONFIG = &H2

' Create the object.
' Ensure the project references CertCli TypeLib.
Dim objCertConfig As CCertConfig
Set objCertConfig = New CCertConfig

' Retrieve the config information.
MsgBox (objCertConfig.GetConfig(CC_DEFAULTCONFIG))

' Free the object.
Set objCertConfig = Nothing

Example Code [Java]

// Constants used by GetConfig.
final int CC_DEFAULTCONFIG = 0;
final int CC_UIPICKCONFIG = 1;
final int CC_FIRSTCONFIG = 2;

// Declare and create an instance of a CCertConfig object.
// The CertCli library is a COM wrapper added to the project.
certcli.CCertConfig objCertCfg;
objCertCfg = new certcli.CCertConfig();

// Display a user interface to pick the certification authority.
java.lang.String strConfig;
strConfig = objCertCfg.GetConfig(CC_UIPICKCONFIG);

// Display the choice from the user interface.
System.out.println(strConfig);

// Free the object.
com.ms.com.ComLib.release(objCertCfg);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certcli.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertConfig, ICertView::OpenConnection


ICertConfig::GetField

Platform SDK: Security

ICertConfig::GetField [C++]

CCertConfig.GetField [Visual Basic,Java]

The GetField method gets a specific field from the current record of the configuration database.

[C++] HRESULT
GetField(
  BSTR const strFieldName,
  BSTR *pbstrOut
);
[Visual Basic]
objConfig.GetField( _
  strFieldName As String _
) As String
[Java]
java.lang.String GetField(
  BSTR strFieldName
);

Parameters

[Visual Basic] objConfig
Object expression that resolves to a CCertConfig object.
[C++,Visual Basic,Java] strFieldName
[in] Specifies the name of the field to return. The following are currently valid strings for field names (note that some certification authorities may not provide data for each field).
Field name | Description
Authority | Reference certification authority (CA) name
CommonName | Common name of the server
Config | Reference machine\CA name
Country | Country/region
Description | Descriptive comment about the server (replaces obsolete "Comment")
ExchangeCertificate | Name of the file containing the exchange certificate (applies to Certificate Services 1.0 only)
Flags | String representing location where the CA information was found (see Remarks section)
Locality | City or town
Organization | Organization
OrgUnit | Organizational unit
SanitizedName | CA name sanitized per rules described in ICertConfig::GetConfig
SanitizedShortName | CA name sanitized and shortened according to the rules described in ICertConfig::GetConfig
Server | Reference machine name
ShortName | SanitizedShortName, but with the '!xxx' sequences, as described in ICertConfig::GetConfig, translated back into the original text.
SignatureCertificate | Name of the file containing the CA certificate (also known as the CA signature certificate); this may or may not be a root certificate.
State | State or province

[C++] pbstrOut
[out] Pointer to a BSTR the receives the data from the field.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pbstrOut is set to the BSTR containing the field data. To use this method, create a variable of the BSTR type, set the variable equal to NULL, and pass the address of this variable as the pbstrOut parameter. When you finish with the BSTR variable, make sure to free it by calling SysFreeString..

[Visual Basic,Java] The return value is a string representing the data for the field.

Remarks

This method returns the field data for the specified field.

When you specify "Flags" in the strFieldName parameter, the retrieved data for the flags field is a string that can be converted to an integer by means of the C-library function _wtoi. The resulting integer represents a bitfield that can be examined to determine if the flags CAIF_DSENTRY and CAIF_SHAREDFOLDERENTRY are set. If CAIF_DSENTRY (0x00000001) is set, the information for the CA was contained in Directory Services. If CAIF_SHAREDFOLDERENTRY (0x00000002) is set, the information for the CA was contained in the shared folder. Note that one or both of these flags may be set.

Example Code [C++]

    BSTR  bstrFieldName = NULL;
    BSTR  bstrFieldValue = NULL;

    HRESULT    hr;

    // Retrieve a field value.
    bstrFieldName = SysAllocString(L"CommonName");
    // pConfig is previously instantiated ICertConfig object.
    hr = pConfig->GetField(bstrFieldName, &bstrFieldValue);
    if (FAILED(hr))
    {
        printf("Failed GetField - [%x]\n", hr);
        goto error;
    }
    else
        printf("GetField value for %ws is: %ws\n", bstrFieldName, bstrFieldValue );

error:

    // Free BSTR values.
    if (NULL != bstrFieldName)
        SysFreeString(bstrFieldName);

    if (NULL != bstrFieldValue)
        SysFreeString(bstrFieldValue);

Example Code [Visual Basic]

' Create the object.
' Ensure the project references CertCli TypeLib.
Dim objCertConfig As CCertConfig
Set objCertConfig = New CCertConfig

' Retrieve the field information.
MsgBox (objCertConfig.GetField("CommonName"))

' Free the object.
Set objCertConfig = Nothing

Example Code [Java]

// Variable to contain field information.
java.lang.String strFieldValue;

// Retrieve the field value for "CommonName".
strFieldValue = objCertCfg.GetField("CommonName");
System.out.println(strFieldValue);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certcli.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertConfig


ICertConfig::Next

Platform SDK: Security

ICertConfig::Next [C++]

CCertConfig.Next [Visual Basic,Java]

The Next method retrieves the index of the next available Certificate Services server configuration in the configuration point.

[C++]
HRESULT Next(
  LONG *pIndex
);
[Visual Basic]
objConfig.Next() As Long
[Java]
int Next();

Parameters

[C++] pIndex
[out] Pointer to a Long variable that will contain the index of the enumerated configuration, or -1 if there are no more configurations to enumerate.
[Visual Basic] objConfig
Object expression that resolves to a CCertConfig object.

Return Values

[C++] The return value is an HRESULT. If the method call is successful, the return value is S_OK, and the pIndex parameter contains the index of the enumerated configuration. If there are no more configurations to enumerate, the return value is S_FALSE, and the pIndex parameter points to a value of -1.

[Visual Basic,Java] Returns a value specifying the index of the next available Certificate Services server configuration in the configuration point. If no more configurations are available, the method returns a value of –1.

Example Code [C++]

    long       nIndex, nCount;
    HRESULT    hr;

    // Reset the configuration enumerator.
    nIndex = 0;
    // pConfig is previously instantiated ICertConfig object.
        hr = pConfig->Reset(nIndex, &nCount);
    if (FAILED(hr))
    {
        printf("Failed ICertConfig::Reset - [%x]\n", hr);
        goto error;
    }

    while (-1 != nIndex)
    {
        // Do something with each configuration.
        // ...

        // Get the next configuration.
        // If there are no more, nIndex becomes -1.
        hr = pConfig->Next(&nIndex);
        // Check return value and also nIndex
        if ((S_OK != hr) && (-1 != nIndex))
        {
            // Error reached.
            printf("Failed ICertConfig::Next - %x\n", hr);
            goto error;
        }
        // If there were no more configurations, then
        // nIndex equals -1, and the while loop ends.
    }

error:

    // Free up resources, etc.

Example Code [Visual Basic]

Private Sub Command1_Click()

    On Error GoTo Err1

    ' Declare and create the object.
    ' The CertCli type library is referenced in the project.
    Dim objCertConfig As CCertConfig
    Set objCertConfig = New CCertConfig

    ' Variable for enumeration index.
    Dim nIndex As Long

    ' Begin the enumeration.
    nIndex = objCertConfig.Next()
    Do While (nIndex <> -1)
        ' Display the CA configuration information.
        MsgBox (objCertConfig.GetField("Config"))
        ' Advance the iteration.
        nIndex = objCertConfig.Next()
    Loop

    ' Free the object resource.
    Set objCertConfig = Nothing

    Exit Sub

Err1:

    MsgBox (Err.Description)

End Sub

Example Code [Java]

// Variable for enumeration index.
int nIndex;

nIndex = objCertCfg.Next();
while (-1 != nIndex)
{
    // Display the index and "Authority" field.
    System.out.println(nIndex + ": " + objCertCfg.GetField("Authority"));
    nIndex = objCertCfg.Next();
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certcli.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertConfig, ICertConfig::Reset


ICertConfig::Reset

Platform SDK: Security

ICertConfig::Reset [C++]

CCertConfig.Reset [Visual Basic,Java]

The Reset method resets the configuration query state to point at the Certificate Services server configuration indexed on the specified configuration point. Each individual configuration indicates a specific Certificate Services server. Some Certificate Services servers may have multiple valid configurations in the configuration database.

[C++]
HRESULT Reset(
  LONG Index,
  LONG *pCount
);
[Visual Basic]
objConfig.Reset( _
  Index As Long _
) As Long
[Java]
int Reset(
  int Index
);

Parameters

[Visual Basic] objConfig
Object expression that resolves to a CCertConfig object.
[C++,Visual Basic,Java] Index
[in] Specifies the configuration point used by the configuration query to index a Certificate Services server configuration. The first configuration is index 0.
[C++] pCount
[out] Pointer to the the number of configurations in the enterprise.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and the pCount parameter is points to a Long containing the number of configurations in the enterprise.

[Visual Basic,Java] The return value is the number of configurations in the enterprise.

Example Code [C++]

long       nIndex, nCount;
HRESULT    hr;

// Reset the configuration enumerator.
nIndex = 0;
// pConfig is previously instantiated ICertConfig object.
hr = pConfig->Reset(nIndex, &nCount);
if (FAILED(hr))
{
    printf("Failed ICertConfig::Reset - [%x]\n", hr);
    // Call your error handler here.
}
// Reset was successful; use the configuration series as needed
// ...

Example Code [Visual Basic]

Dim nItems As Long
' Reset to the first configuration.
nItems = objCertConfig.Reset(0)

Example Code [Java]

// Reset the configuration enumerator.
int nItems;
nItems = objCertCfg.Reset(0);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certcli.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertConfig, ICertConfig::Next


ICertConfig2

[This is preliminary documentation and subject to change.]

The ICertConfig2 interface inherits all of the methods of ICertConfig and includes the following new method.

Method | Description
SetSharedFolder | Specifies a new path for the shared folder directory.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Certcli.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertConfig2::SetSharedFolder

[This is preliminary documentation and subject to change.]

The SetSharedFolder method specifies the path to be used as the CertificateAuthority's shared folder.

HRESULT ICertConfig2::SetSharedFolder(
  BSTR const strSharedFolder
);

Parameters

strSharedFolder
[in] String value specifying the path of the new shared folder directory.

Return Values

The return value is an HRESULT. A value of S_OK indicates the method was successful.

Example Code [C++]

HRESULT hr;

// Specify the shared folder.
hr = pCertConfig2->SetSharedFolder(bstrSharedFolder);
if (FAILED(hr))
{
    printf("Failed SetSharedFolder\n");
    exit(1);  // Or other error action.
}

Example Code [Visual Basic]

' CertCli's type library is referenced in the project.
Dim objCertConfig2 As CCertConfig
Set objCertConfig2 = New CCertConfig

' Specify the shared folder.
objCertConfig2.SetSharedFolder ("\\Server01\MySharedFolder")

' Free the object.
Set objCertConfig2 = Nothing

Example Code [Java]

try
{
    // Declare and create an instance of the object.
    certcli.CCertConfig objConfig2;
    objConfig2 = new certcli.CCertConfig();

    // Specify the shared folder.
    objConfig2.SetSharedFolder("\\\\Server01\\MySharedFolder");

    // Free the object.
    com.ms.com.ComLib.release(objConfig2);
}
catch (com.ms.com.ComFailException e)
{
    System.out.println(e.getMessage());
}

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Certcli.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertEncodeAltName

Platform SDK: Security

ICertEncodeAltName [C++]

CCertEncodeAltName [Visual Basic]

The ICertEncodeAltName interface provides methods for handling alternate names used in certificate extensions. A certificate extension can be created using an alternate name array stored in an extension handler COM object. Each element in the array is a structure containing a name string and a name choice.

This interface is useful for encoding and decoding szOID_SUBJECT_ALT_NAME2 "2.5.29.17" extensions; the SDK sample policy module uses this interface.

ICertEncodeAltName is defined in certenc.h. When you create your program, however, use certsrv.h as the include file. CertEnc.dll provides the ICertEncodeAltName interface. In Windows 2000, the type information for this interface is also in CertEncL.dll, which is shipped with the Platform SDK.

The Certificate Services interfaces support only the apartment-threading model.

The following methods are provided by the ICertEncodeAltName interface.

Method | Description
Decode | Decodes an ASN.1-encoded alternate name extension and stores the resulting array of strings in the extension handler.
Encode | Performs ASN.1 encoding on an alternate name array stored in the extension handler and returns the name array as an array of ASN.1-encoded strings.
GetName | Returns the alternate name at a specified index of an alternate name array.
GetNameChoice | Returns a name choice at a specified index of an alternate name array.
GetNameCount | Returns the count of names in an alternate name array.
Reset | Resets an alternate name array to a specified number of elements and clears the values.
SetNameEntry | Sets a name and name choice at a specified index of an alternate name array.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertEncodeAltName::Decode

Platform SDK: Security

ICertEncodeAltName::Decode [C++]

CCertEncodeAltName.Decode [Visual Basic]

The Decode method decodes an ASN.1-encoded alternate name extension and stores the resulting array of strings in the extension handler.

[C++]
HRESULT Decode(
  BSTR const strBinary
);
[Visual Basic]
objEncodeAltName.Decode( _
  strBinary As String _
)

Parameters

[Visual Basic] objEncodeAltName
Object expression that resolves to a CCertEncodeAltName object.
[C++,Visual Basic] strBinary
[in] Represents an ASN.1-encoded alternate name extension.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Remarks

Use this method to decode an alternate name extension.

Example Code [C++]

// Decode the encoded array; the decoded contents
// will be part of the object.
// bstrEncode is a previously encoded BSTR.
hr = pEncodeAltName->Decode(bstrEncode);
if (FAILED(hr))
{
    printf("Failed pEncodeAltName->Decode [%x]\n", hr);
    goto error;
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeAltName


ICertEncodeAltName::Encode

Platform SDK: Security

ICertEncodeAltName::Encode [C++]

CCertEncodeAltName.Encode [Visual Basic]

The Encode method performs ASN.1 encoding on an alternate name array stored in the COM object and returns an ASN.1-encoded alternate name extension. Before using this method, you must call both the Reset method to size the array and the SetNameEntry method to set each array element.

[C++]
HRESULT Encode(
  BSTR *pbstrBinary
);
[Visual Basic]
objEncodeAltName.Encode() As String

Parameters

[Visual Basic] objEncodeAltName
Object expression that resolves to a CCertEncodeAltName object.
[C++] pbstrBinary
[out] Pointer to BSTR that receives the ASN.1-encoded alternate name extension.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and the pbstrBinary parameter is points to the BSTR representing the ASN.1-encoded alternate name extension. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable in the pbstrBinary parameter. When you finish with the BSTR variable, make sure to free it by calling SysFreeString.

[Visual Basic] The return value is the ASN.1-encoded alternate name array.

Example Code [C++]

// Encode the array.
BSTR    bstrEncode = NULL;
hr = pEncodeAltName->Encode(&bstrEncode);
if (FAILED(hr))
{
    printf("Failed pEncodeAltName->Encode [%x]\n", hr);
    goto error;
}
// Use the encoded value as needed.
// ...
// Done processing.
// Free BSTR values.
if (NULL != bstrEncode)
    SysFreeString(bstrEncode);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeAltName, ICertEncodeAltName::Reset, ICertEncodeAltName::SetNameEntry


ICertEncodeAltName::GetName

Platform SDK: Security

ICertEncodeAltName::GetName [C++]

CCertEncodeAltName.GetName [Visual Basic]

The GetName method returns the alternate name at a specified index of an alternate name array.

[C++]
HRESULT GetName(
  LONG NameIndex,
  BSTR *pbstrName
);
[Visual Basic]
objEncodeAltName.GetName( _
  NameIndex As Long _
) As String

Parameters

[Visual Basic] objEncodeAltName
Object expression that resolves to a CCertEncodeAltName object.
[C++,Visual Basic] NameIndex
[in] Specifies the index of the alternate name entry. The first entry is at index zero. If the alternate name at the index being retrieved is CERT_ALT_NAME_OTHER_NAME, joining the index value with EAN_NAMEOBJECTID (defined as 0x80000000) by means of the OR operator will cause this method to retrieve the oject identifier (OID). If, on the other hand, the name choice at the index being retrieved is CERT_ALT_NAME_OTHER_NAME and the index is not joined with EAN_NAMEOBJECTID by the OR operator, this method will retrieve the binary value instead of the OID.
[C++] pbstrName
[out] Pointer to a BSTR that receives the alternate name.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and the pbstrName parameter points to a BSTR representing the alternate name. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable in the pbstrName parameter. When you finish with the BSTR variable, make sure to free it by calling SysFreeString).

[Visual Basic] The return value is the alternate name at the specified index. The return value is a Unicode string.

Example Code [C++]

// Retrieve the name at index 0.
BSTR    bstrAltNameReturn = NULL;
long    i = 0;

hr = pEncodeAltName->GetName(i, &bstrAltNameReturn);
if (FAILED(hr))
{
    printf("Failed pEncodeAltName->GetName [%x]\n", hr);
    goto error;
}
else
    printf("Index %d has value %ws\n", i, bstrAltNameReturn );
// Use the value as needed.
// ...

// Done processing; free BSTR.
If (NULL != bstrAltNameReturn)
    SysFreeString(bstrAltNameReturn);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeAltName, ICertEncodeAltName::GetNameChoice, ICertEncodeAltName::SetNameEntry


ICertEncodeAltName::GetNameChoice

Platform SDK: Security

ICertEncodeAltName::GetNameChoice [C++]

CCertEncodeAltName.GetNameChoice [Visual Basic]

The GetNameChoice method returns the name choice at a specified index of an alternate name array.

[C++]
HRESULT GetNameChoice(
  LONG NameIndex,
  LONG *pNameChoice
);
[Visual Basic]
objEncodeAltName.GetNameChoice( _
  NameIndex As Long _
) As Long

Parameters

[Visual Basic] objEncodeAltName
Object expression that resolves to a CCertEncodeAltName object.
[C++,Visual Basic] NameIndex
[in] Specifies the index of the alternate name entry. The first entry is at index zero.
[C++] pNameChoice
[out] Pointer to a LONG that receives the name choice specifier.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and the pNameChoice parameter points to a value that indicates the type of the alternate name. This is one of the following values.

[Visual Basic] The return value is the name choice at the specified index. The name choice indicates the type of the alternate name so that it can be used correctly. It must be one of the following values.

Name choice specifier | Description
CERT_ALT_NAME_DIRECTORY_NAME | The name is a directory name.
CERT_ALT_NAME_DNS_NAME | The name is an IA5 string specifying a DNS (Domain Name System) name in the format host.entity.domain.
CERT_ALT_NAME_IP_ADDRESS | The name is an octet string representing an Internet protocol address.
CERT_ALT_NAME_REGISTERED_ID | The name is a registered object identifier (OID).
CERT_ALT_NAME_RFC822_NAME | The name is an e-mail address.
CERT_ALT_NAME_URL | The name is an IA5 string specifying a uniform resource locator (URL) in the format service://hostname/pathname.
CERT_ALT_NAME_OTHER_NAME | The name consists of an object identifier (OID) and a binary BLOB.

Example Code [C++]

// Retrieve this name choice.
long    nChoice;
hr = pEncodeAltName->GetNameChoice(0, &nChoice);
if (FAILED(hr))
{
    printf("Failed pEncodeAltName->GetNameChoice [%x]\n", hr);
    goto error;
}
else
switch (nChoice)
{
    case CERT_ALT_NAME_DIRECTORY_NAME:
        printf("Directory choice type\n");
        break;
    case CERT_ALT_NAME_DNS_NAME:
        printf("DNS choice type\n");
        break;
    case CERT_ALT_NAME_IP_ADDRESS:
        printf("IP address choice type\n");
        break;
    case CERT_ALT_NAME_REGISTERED_ID:
        printf("OID choice type\n");
        break;
    case CERT_ALT_NAME_RFC822_NAME:
        printf("Email address choice type\n");
        break;
    case CERT_ALT_NAME_URL:
        printf("URL choice type\n");
        break;
    case CERT_ALT_NAME_OTHER_NAME:
        printf("OtherName choice type\n");
        break;
    default :
        printf("Unexpected choice type\n");
        break;
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeAltName, ICertEncodeAltName::GetName, ICertEncodeAltName::SetNameEntry


ICertEncodeAltName::GetNameCount

Platform SDK: Security

ICertEncodeAltName::GetNameCount [C++]

CCertEncodeAltName.GetNameCount [Visual Basic]

The GetNameCount method returns the number of names in an alternate name array.

[C++]
HRESULT GetNameCount(
  LONG *pNameCount
);
[Visual Basic]
objEncodeAltName.GetNameCount() As Long

Parameters

[C++] pNameCount
[out] Pointer to a Long which will represent the number of alternate names in the array.
[Visual Basic] objEncodeAltName
Object expression that resolves to a CCertEncodeAltName object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pNameCount is set to a value representing the number of alternate names in the array.

[Visual Basic] The return value is the number of alternate names in the array.

Example Code [C++]

long    nCount;

hr = pEncodeAltName->GetNameCount(&nCount);
if (FAILED(hr))
{
    printf("Failed pEncodeAltName->GetNameCount [%x]\n", hr);
    goto error;
}
printf("There are %d items in the AltName array\n", nCount );

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeAltName


ICertEncodeAltName::Reset

Platform SDK: Security

ICertEncodeAltName::Reset [C++]

CCertEncodeAltName.Reset [Visual Basic]

The Reset method resets an alternate name array to a specified number of elements. The values of all the elements are set to 0.

[C++]
HRESULT Reset(
  LONG NameCount
);
[Visual Basic]
objEncodeAltName.Reset( _
  NameCount As Long _
)

Parameters

[Visual Basic] objEncodeAltName
Object expression that resolves to a CCertEncodeAltName object.
[C++,Visual Basic] NameCount
[in] Specifies the count of elements to be initialized.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Example Code [C++]

    ICertEncodeAltName * pEncodeAltName = NULL;

    HRESULT    hr;

    // Initialize COM.
    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    // Check status.
    if (FAILED(hr))
    {
        printf("Failed CoInitializeEx - [%x]\n", hr);
        goto error;
    }

    // Instantiate the CertEncodeAltName object.
    hr = CoCreateInstance( CLSID_CCertEncodeAltName,
                           NULL,
                           CLSCTX_INPROC_SERVER,
                           IID_ICertEncodeAltName,
                           (void **)&pEncodeAltName);
    if (FAILED(hr))
    {
        printf("Failed CoCreateInstance - pEncodeAltName [%x]\n", hr);
        goto error;
    }

    // Inform the object there are 3 alt name elements.
    hr = pEncodeAltName->Reset(3);
    if (FAILED(hr))
    {
        printf("Failed pEncodeAltName->Reset [%x]\n", hr);
        goto error;
    }

    // Use the object as needed.
    // ...

    // Done processing.

error:

   // Clean up object resources.
    if (NULL != pEncodeAltName)
        pEncodeAltName->Release();

    // Free COM resources.
    CoUninitialize();

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeAltName


ICertEncodeAltName::SetNameEntry

Platform SDK: Security

ICertEncodeAltName::SetNameEntry [C++]

CCertEncodeAltName.SetNameEntry [Visual Basic]

The SetNameEntry method sets a name at a specified index of an alternate name array. Before using this method, you must call ICertEncodeAltName::Reset so that the object knows how many elements are in the array.

[C++]
HRESULT SetNameEntry(
  LONG NameIndex,
  LONG NameChoice,
  BSTR const strName
);
[Visual Basic]
objEncodeAltName.SetNameEntry( _
NameIndex As Long, _
  NameChoice As Long, _
  strName As String _
)

Parameters

[Visual Basic] objEncodeAltName
Object expression that resolves to a CCertEncodeAltName object.
[C++,Visual Basic] NameIndex
[in] Specifies the index of the alternate name entry. The first entry is at index zero. If NameChoice is CERT_ALT_NAME_OTHER_NAME, joining the index value with EAN_NAMEOBJECTID (defined as 0x80000000) by means of the OR operator will cause this method to set the OID; if, on the other hand, NameChoice is CERT_ALT_NAME_OTHER_NAME and the index is not joined with EAN_NAMEOBJECTID by the OR operator, this method will set the binary value instead of the OID.
[C++,Visual Basic] NameChoice
[in] Specifies the name choice. The name choice indicates the type of the alternate name so that it can be used correctly. It must be one of the following values.
Name choice specifier | Description
CERT_ALT_NAME_DIRECTORY_NAME | The name is a directory name.
CERT_ALT_NAME_DNS_NAME | The name is an IA5 string specifying a DNS (Domain Name System) name in the format host.entity.domain.
CERT_ALT_NAME_IP_ADDRESS | The name is an octet string representing an Internet Protocol address.
CERT_ALT_NAME_REGISTERED_ID | The name is a registered object identifier (OID).
CERT_ALT_NAME_RFC822_NAME | The name is an e-mail address.
CERT_ALT_NAME_URL | The name is an IA5 string specifying a URL (Uniform Resource Locator) in the format service://hostname/pathname.
CERT_ALT_NAME_OTHER_NAME | The name consists of an object identifier (OID) and a binary BLOB.

[C++,Visual Basic] strName
[in] Specifies the alternate name.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Example Code [C++]

// Place an Alt Name in the array's first element.
// bstrAltName is previously allocated BSTR for the Alt Name.
hr = pEncodeAltName->SetNameEntry(0,
                                  CERT_ALT_NAME_RFC822_NAME,
                                  bstrAltName);
if (FAILED(hr))
{
    printf("Failed pEncodeAltName->SetNameEntry [%x]\n", hr);
    goto error;
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeAltName


ICertEncodeBitString

Platform SDK: Security

ICertEncodeBitString [C++]

CCertEncodeBitString [Visual Basic]

The ICertEncodeBitString interface provides methods for handling bit strings used in certificate extensions. A certificate extension can be created using a bit string stored in an extension handler COM object instantiated by the policy module. The bit string can contain an arbitrary string of binary values. This interface is useful for encoding and decoding szOID_KEY_USAGE "2.5.29.15" extensions; the SDK sample policy module uses this interface.

ICertEncodeBitString is defined in certenc.h. When you create your program, however, use certsrv.h as the include file. CertEnc.dll provides the ICertEncodeBitString interface. In Windows 2000, the type information for this interface is also in CertEncL.dll, which is shipped with the Platform SDK.

The Certificate Services interfaces support only the apartment-threading model.

The following methods are provided by the ICertEncodeBitString interface.

Method | Description
Decode | Decodes an ASN.1-encoded bit string and stores the resulting bit string in the COM object.
Encode | Performs ASN.1 encoding on a bit string and returns the ASN.1-encoded bit string.
GetBitCount | Returns the number of bits in a bit string.
GetBitString | Returns the bit string.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertEncodeBitString::Decode

Platform SDK: Security

ICertEncodeBitString::Decode [C++]

CCertEncodeBitString.Decode [Visual Basic]

The Decode method decodes an ASN.1-encoded bit string and stores the resulting bit string in the COM object. Once the resulting bit string is stored in the COM object, the methods ICertEncodeBitString::GetBitCount and ICertEncodeBitString::GetBitString can be executed.

[C++]
HRESULT Decode(
  BSTR const strBinary
);
[Visual Basic]
objEncodeBitString.Decode( _
  strBinary As String _
)

Parameters

[Visual Basic] objEncodeBitString
Object expression that resolves to a CCertEncodeBitString object.
[C++,Visual Basic] strBinary
[in] An ASN.1-encoded bit string.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Remarks

Use this method to decode an encoded bit string.

Example Code [C++]

// Decode the bitstring; the decoded contents
// will be part of the object.
// bstrEncode is a previously encoded BSTR.
hr = pEncodeBitString->Decode(bstrEncode);
if (FAILED(hr))
{
    printf("Failed Decode [%x]\n", hr);
    goto error;
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeBitString


ICertEncodeBitString::Encode

Platform SDK: Security

ICertEncodeBitString::Encode [C++]

CCertEncodeBitString.Encode [Visual Basic]

The Encode method performs ASN.1 encoding on a bit string stored in the COM object and returns the ASN.1-encoded bit string. The bit string is first initialized and then set before being encoded.

[C++]
HRESULT Encode(
  LONG BitCount,
  BSTR strBitString,
  BSTR *pbstrBinary
);
[Visual Basic]
objEncodeBitString.Encode( _
  BitCount As Long, _
  strBitString As String _
) As String

Parameters

[Visual Basic] objEncodeBitString
Object expression that resolves to a CCertEncodeBitString object.
[C++,Visual Basic] BitCount
[in] Specifies the size of the bit string.
[C++,Visual Basic] strBitString
[in] Specifies the bit string whose contents will be encoded.
[C++] pbstrBinary
[out] Pointer to BSTR which will contain the encoded bit string.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pbstrBinary is set to the BSTR representing the ASN.1-encoded bit string. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable as pbstrBinary. You must free *pbstrBinary when done (by means of SysFreeString).

[Visual Basic] The return value is the ASN.1-encoded bit string.

Example Code [C++]

    BSTR    bstrKU = NULL;     // bstr for Key Usage, to be encoded
    BSTR    bstrEncode = NULL; // will accept the encoded bits

    // Pointer to interface object.
    ICertEncodeBitString * pEncodeBitString = NULL;

    HRESULT    hr;

    // Initialize COM.
    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    // Check status.
    if (FAILED(hr))
    {
        printf("Failed CoInitializeEx - [%x]\n", hr);
        goto error;
    }

    // Instantiate the CertEncodeBitString object.
    hr = CoCreateInstance(CLSID_CCertEncodeBitString,
                          NULL,
                          CLSCTX_INPROC_SERVER,
                          IID_ICertEncodeBitString,
                          (void **)&pEncodeBitString);
    if (FAILED(hr))
    {
        printf("Failed CoCreateInstance - pEncodeBitString [%x]\n", hr);
        goto error;
    }

    // Build the string to encode.
    BYTE byKeyUsage[2];
    // The constants are defined in WinCrypt.h.
    byKeyUsage[0] = CERT_DIGITAL_SIGNATURE_KEY_USAGE |
                    CERT_NON_REPUDIATION_KEY_USAGE |
                    CERT_DATA_ENCIPHERMENT_KEY_USAGE;
    byKeyUsage[1] = 0;
    bstrKU = SysAllocStringByteLen((const char *)byKeyUsage,
                                   sizeof(byKeyUsage));
    // Calculate the number of bits in the string.
    long nLen;
    nLen = SysStringByteLen(bstrKU) * 8;

    // Encode the string.
    hr = pEncodeBitString->Encode(nLen, bstrKU, &bstrEncode);
    if (FAILED(hr))
    {
        printf("Failed Encode [%x]\n", hr);
        goto error;
    }
    // Do something with the encoded BSTR.
    // ...

    // Done processing.
error:

    // Free BSTR values.
    if (NULL != bstrKU)
        SysFreeString(bstrKU);
    if (NULL != bstrEncode)
        SysFreeString(bstrEncode);
    // Free COM resources.
    CoUninitialize();

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeBitString


ICertEncodeBitString::GetBitCount

Platform SDK: Security

ICertEncodeBitString::GetBitCount [C++]

CCertEncodeBitString.GetBitCount [Visual Basic]

The GetBitCount method returns the number of bits in a bit string that belongs to the ICertEncodeBitString object and has been initialized by an earlier call to ICertEncodeBitString::Decode.

[C++]
HRESULT GetBitCount(
  LONG *pBitCount
);
[Visual Basic]
objEncodeBitString.GetBitCount() As Long

Parameters

[C++] pBitCount
[out] Pointer to a Long which will represent the number of bits in the bit string.
[Visual Basic] objEncodeBitString
Object expression that resolves to a CCertEncodeBitString object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pCount is set to a value representing the number of bits in the bit string.

[Visual Basic] The return value is the number of bits in the bit string.

Example Code [C++]

// Retrieve the bit count.
long    nLen;

hr = pEncodeBitString->GetBitCount(&nLen);
if (FAILED(hr))
{
    printf("Failed GetBitCount [%x]\n", hr);
    goto error;
}
printf("There are %d bits in the string\n", nLen);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeBitString


ICertEncodeBitString::GetBitString

Platform SDK: Security

ICertEncodeBitString::GetBitString [C++]

CCertEncodeBitString.GetBitString [Visual Basic]

The GetBitString method returns the string of bits in the object's bit string.

[C++]
HRESULT GetBitString(
  BSTR *pbstrBitString
);
[Visual Basic]
objEncodeBitString.GetBitString() As String

Parameters

[C++] pbstrBitString
[out] Pointer to BSTR which will contain the bit string.
[Visual Basic] objEncodeBitString
Object expression that resolves to a CCertEncodeBitString object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pbstrBitString is set to the BSTR representing the bit string. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable as pbstrBitString. You must free *pbstrBitString when done (by means of SysFreeString).

[Visual Basic] The return value is the bit string.

Example Code [C++]

BSTR     bstrValue = NULL;
HRESULT  hr;

// Retrieve the bit string.
hr = pEncodeBitString->GetBitString(&bstrValue);
if (FAILED(hr))
{
    printf("Failed GetBitString [%x]\n", hr);
    goto error;  // Or other action.
}

// Determine the bit string length.
LONG cbit;
cbit = pEncodeBitString->GetBitCount(&cbit);
if (FAILED(hr))
{
    printf("Failed GetBitCount [%x]\n", hr);
    goto error;  // Or other action.
}

// Display the BSTR contents.
BYTE  by, bit;
for (LONG i=0; i<cbit; i++)
{
    // Determine which byte is being accessed.
    by = ((BYTE*)bstrValue)[i/8];
    // Determine which bit is being accessed.
    bit = (by>>(7-(i%8))) & 1;
    // Display the bit counter and value.
    printf("Bit #%u: %u\n", i, bit);
}

// Done processing.
// Free BSTR.
if (NULL != bstrValue)
    SysFreeString(bstrValue);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeBitString


ICertEncodeCRLDistInfo

Platform SDK: Security

ICertEncodeCRLDistInfo [C++]

CCertEncodeCRLDistInfo [Visual Basic]

The ICertEncodeCRLDistInfo interface provides methods for handling certificate revocation list (CRL) distribution information arrays used in certificate extensions. A certificate extension can be created using a CRL distribution information array stored in an extension handler COM object instantiated by the policy module. Each element in the array is a CRL distribution point structure that contains an array of names and name choices. This interface is useful for encoding and decoding szOID_CRL_DIST_POINTS "2.5.29.31" extensions; the SDK sample policy module uses this interface.

ICertEncodeCRLDistInfo is defined in certenc.h. When you create your program, however, use certsrv.h as the include file. CertEnc.dll provides the ICertEncodeCRLDistInfo interface. In Windows 2000, the type information for this interface is also in CertEncL.dll, which is shipped with the Platform SDK.

The Certificate Services interfaces support only the apartment-threading model.

The following methods are provided by the ICertEncodeCRLDistInfo interface.

Method | Description
Decode | Decodes an ASN.1-encoded CRL distribution information extension and stores the resulting array in the COM object.
Encode | Performs ASN.1 encoding on a CRL distribution information array stored in the COM object and returns the ASN.1-encoded extension.
GetDistPointCount | Returns the number of CRL distribution point elements in a CRL distribution information array.
GetName | Returns the name at a specified index of a CRL distribution point structure.
GetNameChoice | Returns the name choice at a specified index of a CRL distribution point structure.
GetNameCount | Returns the number of names in a CRL distribution point structure.
Reset | Resets an array of CRL distribution information structures to a specified number of structures and clears the structure elements.
SetNameCount | Sets the name count for the specified distribution point in a CRL distribution information array.
SetNameEntry | Sets the name and name choice at a specified index of a distribution point in a CRL distribution information array.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertEncodeCRLDistInfo::Decode

Platform SDK: Security

ICertEncodeCRLDistInfo::Decode [C++]

CCertEncodeCRLDistInfo.Decode [Visual Basic]

The Decode method decodes an ASN.1-encoded CRL distribution information extension and stores the resulting array in the COM object.

[C++]
HRESULT Decode(
  BSTR const strBinary
);
[Visual Basic]
objEncodeCRLDistInfo.Decode( _
  strBinary As String _
)

Parameters

[Visual Basic] objEncodeCRLDistInfo
Object expression that resolves to a CCertEncodeCRLDistInfo object.
[C++,Visual Basic] strBinary
[in] An ASN.1-encoded CRL distribution information extension.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Remarks

This method places the decoded contents of strBinary into the object's array of CRL distribution information points. If the object's array already contains data, this existing content will be freed, and the array will be loaded with the decoded values.

Example Code [C++]

// bstrEncode is a previously encoded BSTR.
hr = pEncodeCRLDistInfo->Decode(bstrEncode);
if (FAILED(hr))
{
    printf("Failed pEncodeCRLDistInfo->Decode [%x]\n", hr);
    goto error;
}
// Successfully decoded; take other action as needed.
// ...

// Done processing.
if (NULL != bstrEncode)
    SysFreeString(bstrEncode);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeCRLDistInfo


ICertEncodeCRLDistInfo::Encode

Platform SDK: Security

ICertEncodeCRLDistInfo::Encode [C++]

CCertEncodeCRLDistInfo.Encode [Visual Basic]

The Encode method performs ASN.1 encoding on a certificate revocation list (CRL) distribution information array stored in the COM object and returns the ASN.1-encoded extension. Before using this method, you must call the Reset method to size the array and the SetNameCount and SetNameEntry methods to set each element in each distribution point structure.

[C++]
HRESULT Encode(
  BSTR *pbstrBinary
);
[Visual Basic]
objEncodeCRLDistInfo.Encode() As String

Parameters

[C++] pbstrBinary
[out] Pointer to BSTR which will contain the encoded CRL distribution information extension.
[Visual Basic] objEncodeCRLDistInfo
Object expression that resolves to a CCertEncodeCRLDistInfo object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pbstrBinary is set to the BSTR representing the ASN.1-encoded CRL distribution information extension. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable as pbstrBinary. You must free *pbstrBinary when done (by means of SysFreeString).

[Visual Basic] The return value is the ASN.1-encoded CRL distribution information array.

Example Code [C++]

BSTR    bstrEncode = NULL;

hr = pEncodeCRLDistInfo->Encode(&bstrEncode);
if (FAILED(hr))
{
    printf("Failed pEncodeCRLDistInfo->Encode [%x]\n", hr);
    goto error;
}

// Do something with the encoded BSTR.
// ...

// Done Processing; clear resources.
if (NULL != bstrEncode)
    SysFreeString(bstrEncode);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeCRLDistInfo, ICertEncodeCRLDistInfo::Reset, ICertEncodeCRLDistInfo::SetNameCount, ICertEncodeCRLDistInfo::SetNameEntry


ICertEncodeCRLDistInfo::GetDistPointCount

Platform SDK: Security

ICertEncodeCRLDistInfo::GetDistPointCount [C++]

CCertEncodeCRLDistInfo.GetDistPointCount [Visual Basic]

The GetDistPointCount method returns the number of CRL distribution points in a CRL distribution information array.

[C++]
HRESULT GetDistPointCount(
  LONG *pDistPointCount
);
[Visual]
Basic] objEncodeCRLDistInfo.GetDistPointCount() As Long

Parameters

[C++] pDistPointCount
[out] Pointer to a Long which will represent the number of CRL distribution points in the array.
[Visual Basic] objEncodeCRLDistInfo
Object expression that resolves to a CCertEncodeCRLDistInfo object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pDistPointCount is set to a value representing the number of CRL distribution points in the array.

[Visual Basic] The return value is the number of CRL distribution points in the array.

Example Code [C++]

// Retrieve the count of elements in the array.
long    nCount;
hr = pEncodeCRLDistInfo->GetDistPointCount(&nCount);
if (FAILED(hr))
{
    printf("Failed pEncodeCRLDistInfo->GetDistPointCount [%x]\n", hr);
    goto error;
}
else
    printf("There are %d elements in the array\n", nCount);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeCRLDistInfo


ICertEncodeCRLDistInfo::GetName

Platform SDK: Security

ICertEncodeCRLDistInfo::GetName [C++]

CCertEncodeCRLDistInfo.GetName [Visual Basic]

The GetName method returns the name at a specified index of a CRL distribution information point.

[C++]
HRESULT GetName(
  LONG DistPointIndex,
  LONG NameIndex,
  BSTR *pbstrName
);
[Visual Basic]
objEncodeCRLDistInfo.GetName( _
  DistPointIndex As Long, _
  NameIndex As Long _
) As String

Parameters

[Visual Basic] objEncodeCRLDistInfo
Object expression that resolves to a CCertEncodeCRLDistInfo object.
[C++,Visual Basic] DistPointIndex
[in] Specifies the index of the distribution point for which to get a name. The first value is at index zero.
[C++,Visual Basic] NameIndex
[in] Specifies the index of the name entry to get. The first value is at index zero.
[C++] pbstrName
[out] Pointer to BSTR representing the name value.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pbstrName is set to the BSTR representing the name at the specified index of the specified distribution point. The name value is a Unicode string. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable as pbstrName. You must free *pbstrName when done (by means of SysFreeString).

[Visual Basic] The return value is the name at the specified index of the specified distribution point. The return value is a Unicode string.

Example Code [C++]

BSTR    bstrNameReturn = NULL;

// Retrieve the name value of the first name in the first CRLDistInfo.
hr = pEncodeCRLDistInfo->GetName(0,
                                 0,
                                 &bstrNameReturn);
if (FAILED(hr))
{
    printf("Failed pEncodeCRLDistInfo->GetName [%x]\n", hr);
    goto error;
}
else
    printf("The retrieved choice value is: %ws\n", bstrNameReturn);

// Done processing; clean up BSTR.
if (NULL != bstrNameReturn)
    SysFreeString(bstrNameReturn);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeCRLDistInfo


ICertEncodeCRLDistInfo::GetNameChoice

Platform SDK: Security

ICertEncodeCRLDistInfo::GetNameChoice [C++]

CCertEncodeCRLDistInfo.GetNameChoice [Visual Basic]

The GetNameChoice method returns the name choice at a specified index of a CRL distribution information point.

[C++]
HRESULT GetNameChoice(
  LONG DistPointIndex,
  LONG NameIndex,
  LONG *pNameChoice
);
[Visual Basic]
objEncodeCRLDistInfo.GetNameChoice( _
  DistPointIndex As Long, _
  NameIndex As Long _
) As Long

Parameters

[Visual Basic] objEncodeCRLDistInfo
Object expression that resolves to a CCertEncodeCRLDistInfo object.
[C++,Visual Basic] DistPointIndex
[in] Specifies the index of the distribution point for which to get a name choice. The first value is at index zero.
[C++,Visual Basic] NameIndex
[in] Specifies the index of the name choice entry to get. The first value is at index zero.
[C++] pNameChoice
[out] Pointer to a Long representing the name choice.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pNameChoice is set to one of the values in the following table.

[Visual Basic] The return value is the name choice at the specified index. The name choice indicates the type of the name so that it can be used correctly. The name choice must be one of the following values.

Name choice specifier | Description
CERT_ALT_NAME_RFC822_NAME | The name is an e-mail address.
CERT_ALT_NAME_DNS_NAME | The name is an IA5 string specifying a DNS (Domain Name System) name in the format host.entity.domain.
CERT_ALT_NAME_URL | The name is an IA5 string specifying a URL (Uniform Resource Locator) in the format service://hostname/pathname.
CERT_ALT_NAME_REGISTERED_ID | The name is a registered object identifier (OID).

Example Code [C++]

long    nChoice;

// Retrieve the choice value of the first name in the first CRLDistInfo.
hr = pEncodeCRLDistInfo->GetNameChoice(0,
                                       0,
                                       &nChoice);
if (FAILED(hr))
{
    printf("Failed pEncodeCRLDistInfo->GetNameChoice [%x]\n", hr);
    goto error;
}
// Display text based on name choice.
switch (nChoice)
{
    case CERT_ALT_NAME_RFC822_NAME:
        printf("E-mail address\n");
        break;
    case CERT_ALT_NAME_DNS_NAME:
        printf("DNS value\n");
        break;
    case CERT_ALT_NAME_URL:
        printf("URL value\n");
        break;
    case CERT_ALT_NAME_REGISTERED_ID:
        printf("Registered OID\n");
        break;
    default :
        printf("Unexpected choice value\n");
        break;
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeCRLDistInfo


ICertEncodeCRLDistInfo::GetNameCount

Platform SDK: Security

ICertEncodeCRLDistInfo::GetNameCount [C++]

CCertEncodeCRLDistInfo.GetNameCount [Visual Basic]

The GetNameCount method returns the number of names in a CRL distribution point.

[C++]
HRESULT GetNameCount(
  LONG DistPointIndex,
  LONG *pNameCount
);
[Visual Basic]
objEncodeCRLDistInfo.GetNameCount( _
  DistPointIndex As Long _
) As Long

Parameters

[Visual Basic] objEncodeCRLDistInfo
Object expression that resolves to a CCertEncodeCRLDistInfo object.
[C++,Visual Basic] DistPointIndex
[in] Specifies the index of the distribution point for which to get the name count.
[C++] pNameCount
[out] Pointer to a Long which will represent the number of name values contained in the CRL distribution point.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pNameCount is set to a value representing the number of names in the CRL distribution point.

[Visual Basic] The return value is the number of names in the CRL distribution point.

Example Code [C++]

long    nCount;

// Retrieve the count of names in the CRLDistInfo at index 0.
hr = pEncodeCRLDistInfo->GetNameCount(0, &nCount);
if (FAILED(hr))
{
    printf("Failed pEncodeCRLDistInfo->GetNameCount [%x]\n", hr);
    goto error;
}
else
    printf("There are %d names in the CRLDistInfo\n", nCount);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeCRLDistInfo


ICertEncodeCRLDistInfo::Reset

Platform SDK: Security

ICertEncodeCRLDistInfo::Reset [C++]

CCertEncodeCRLDistInfo.Reset [Visual Basic]

The Reset method resets a CRL distribution information array to a specified number of distribution point structures. The values of all the elements in the array of structures are set to 0.

[C++]
HRESULT Reset(
  LONG DistPointCount
);
[Visual Basic]
objEncodeCRLDistInfo.Reset( _
  DistPointCount As Long _
)

Parameters

[Visual Basic] objEncodeCRLDistInfo
Object expression that resolves to a CCertEncodeCRLDistInfo object.
[C++,Visual Basic] DistPointCount
[in] Specifies the number of CRL distribution points in the CRL distribution information array.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Example Code [C++]

    ICertEncodeCRLDistInfo * pEncodeCRLDistInfo = NULL;

    HRESULT    hr;

    // Initialize COM.
    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    // Check status.
    if (FAILED(hr))
    {
        printf("Failed CoInitializeEx - [%x]\n", hr);
        goto error;
    }

    // Instantiate the CertEncodeCRLDistInfo object.
    hr = CoCreateInstance(CLSID_CCertEncodeCRLDistInfo,
                          NULL,
                          CLSCTX_INPROC_SERVER,
                          IID_ICertEncodeCRLDistInfo,
                          (void **)&pEncodeCRLDistInfo);
    if (FAILED(hr))
    {
        printf("Failed CoCreateInstance - pEncodeCRLDistInfo [%x]\n", hr);
        goto error;
    }

    // Inform the object there are 3 CRLDistInfo elements.
    hr = pEncodeCRLDistInfo->Reset(3);
    if (FAILED(hr))
    {
        printf("Failed pEncodeCRLDistInfo->Reset [%x]\n", hr);
        goto error;
    }
    // Do something else with the object.
    // ...

    // Done processing.

error:

    // Clean up object resources.
    if (NULL != pEncodeCRLDistInfo)
        pEncodeCRLDistInfo->Release();

    // Free COM resources.
    CoUninitialize();

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeCRLDistInfo


ICertEncodeCRLDistInfo::SetNameCount

Platform SDK: Security

ICertEncodeCRLDistInfo::SetNameCount [C++]

CCertEncodeCRLDistInfo.SetNameCount [Visual Basic]

The SetNameCount method sets a name count for the specified distribution point in a CRL distribution information array.

[C++]
HRESULT SetNameCount(
  LONG DistPointIndex,
  LONG NameCount
);
[Visual Basic]
objEncodeCRLDistInfo.SetNameCount( _
  DistPointIndex As Long, _
  NameCount As Long _
)

Parameters

[Visual Basic] objEncodeCRLDistInfo
Object expression that resolves to a CCertEncodeCRLDistInfo object.
[C++,Visual Basic] DistPointIndex
[in] Specifies the index of the distribution point for which to set the name count.
[C++,Visual Basic] NameCount
[in] Specifies the name count.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Example Code [C++]

// The CRLDistInfo at index 0 will have 1 name.
hr = pEncodeCRLDistInfo->SetNameCount(0, 1);
if (FAILED(hr))
{
    printf("Failed pEncodeCRLDistInfo->SetNameCount [%x]\n", hr);
    goto error;
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeCRLDistInfo


ICertEncodeCRLDistInfo::SetNameEntry

Platform SDK: Security

ICertEncodeCRLDistInfo::SetNameEntry [C++]

CCertEncodeCRLDistInfo.SetNameEntry [Visual Basic]

The SetNameEntry method sets a name at a specified index of a distribution point in a CRL distribution information array.

[C++]
HRESULT SetNameEntry(
  LONG DistPointIndex,
  LONG NameIndex,
  LONG NameChoice,
  BSTR const strName
);
[Visual Basic]
objEncodeCRLDistInfo.SetNameEntry( _
  DistPointIndex As Long, _
  NameIndex As Long, _
  NameChoice As Long, _
  strName As String _
)

Parameters

[Visual Basic] objEncodeCRLDistInfo
Object expression that resolves to a CCertEncodeCRLDistInfo object.
[C++,Visual Basic] DistPointIndex
[in] Specifies the index of the CRL distribution point for which to set the name. The first value is at index zero.
[C++,Visual Basic] NameIndex
[in] Specifies the index of the name entry to set. The first value is at index zero.
[C++,Visual Basic] NameChoice
[in] Specifies the name choice of the name being set. The name choice indicates the type of the name so that it can be used correctly. The name choice must be one of the following values.
Name choice specifier | Description
CERT_ALT_NAME_RFC822_NAME | The name is an e-mail address.
CERT_ALT_NAME_DNS_NAME | The name is an IA5 string specifying a DNS (Domain Name System) name in the format host.entity.domain.
CERT_ALT_NAME_URL | The name is an IA5 string specifying a URL (Uniform Resource Locator) in the format service://hostname/pathname.
CERT_ALT_NAME_REGISTERED_ID | The name is a registered object identifier (OID).

[C++,Visual Basic] strName
[in] Specifies the name.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Example Code [C++]

BSTR    bstrName= NULL;

// Initialize the BSTR.
bstrName = SysAllocString(L"someone@microsoft.com");
// Set the name, in this case for an email address.
hr = pEncodeCRLDistInfo->SetNameEntry(0,
                                      0,
                                      CERT_ALT_NAME_RFC822_NAME,
                                      bstrName);
if (FAILED(hr))
{
    printf("Failed pEncodeCRLDistInfo->SetNameEntry [%x]\n", hr);
    goto error;
}

// Done processing; clean up resources.
    if (NULL != bstrName)
        SysFreeString(bstrName);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeCRLDistInfo


ICertEncodeDateArray

Platform SDK: Security

ICertEncodeDateArray [C++]

CCertEncodeDateArray [Visual Basic]

The ICertEncodeDateArray interface provides methods for handling Date arrays used in certificate extensions. A certificate extension can be created using a Date array stored in an extension handler COM object instantiated by the policy module. Each element in the array is a Date value.

This interface is provided mainly as a demonstration for encoding custom extensions. The Certificate Services sample programs in the Platform SDK contain source code for this interface.

ICertEncodeDateArray is defined in certenc.h. When you create your program, however, use certsrv.h as the include file. CertEnc.dll provides the ICertEncodeDateArray interface. In Windows 2000, the type information for this interface is also in CertEncL.dll, which is shipped with the Platform SDK.

The Certificate Services interfaces support only the apartment-threading model.

The following methods are provided by the ICertEncodeDateArray interface.

Method | Description
Decode | Decodes an ASN.1-encoded Date array and stores the resulting array of Dates in the COM object.
Encode | Performs ASN.1 encoding on a Date array stored in the COM object and returns the ASN.1-encoded Date array.
GetCount | Returns the number of Date values in a Date array.
GetValue | Returns the Date value at a specified index of a Date array.
Reset | Resets a Date array to a specified number of elements and clears the values.
SetValue | Sets a Date value at a specified index of a Date array.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertEncodeDateArray::Decode

Platform SDK: Security

ICertEncodeDateArray::Decode [C++]

CCertEncodeDateArray.Decode [Visual Basic]

The Decode method decodes an ASN.1-encoded Date array and stores the resulting array of Date values in the COM object.

[C++]
HRESULT Decode(
  BSTR const strBinary
);
[Visual Basic]
objEncodeDateArray.Decode( _
  strBinary As String _
)

Parameters

[Visual Basic] objEncodeDateArray
Object expression that resolves to a CCertEncodeDateArray object.
[C++,Visual Basic] strBinary
[in] An ASN.1-encoded Date array.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Remarks

This method places the decoded contents of strBinary into the object's array of Date values. If the object's array already contains Date values, this existing content will be freed, and the array will be loaded with the decoded values.

Example Code [C++]

// bstrEncode is a previously encoded BSTR.
hr = pEncodeDateArray->Decode(bstrEncode);
if (FAILED(hr))
{
    printf("Failed pEncodeDateArray->Decode [%x]\n", hr);
    goto error;
}
// Successfully decoded.
// ...

// Done processing.
if (NULL != bstrEncode)
    SysFreeString(bstrEncode);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeDateArray


ICertEncodeDateArray::Encode

Platform SDK: Security

ICertEncodeDateArray::Encode [C++]

CCertEncodeDateArray.Encode [Visual Basic]

The Encode method performs ASN.1 encoding on a Date array stored in the COM object and returns the ASN.1-encoded Date array. Before calling this method, you must use the ICertEncodeDateArray::Reset method to size the array, and call the ICertEncodeDateArray::SetValue method to set each Date value in the array.

[C++]
HRESULT Encode(
  BSTR *pbstrBinary
);
[Visual Basic]
objEncodeDateArray.Encode() As String

Parameters

[C++] pbstrBinary
[out] Pointer to BSTR which will contain the encoded Date array
[Visual Basic] objEncodeDateArray
Object expression that resolves to a CCertEncodeDateArray object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pbstrBinary is set to the BSTR representing the encoded Date array. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable as pbstrBinary. You must free *pbstrBinary when done (by means of SysFreeString).

[Visual Basic] The return value is the ASN.1-encoded Date array.

Example Code [C++]

// Encode the values in the array.
BSTR bstrEncode = NULL;
hr = pEncodeDateArray->Encode(&bstrEncode);
if (FAILED(hr))
{
    printf("Failed pEncodeDateArray->Encode [%x]\n", hr);
    goto error;
}
// Do something with the encoded value.
// ...

// Done processing; clean up BSTR.
if (NULL != bstrEncode)
    SysFreeString (bstrEncode);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeDateArray, ICertEncodeDateArray::Reset, ICertEncodeDateArray::SetValue


ICertEncodeDateArray::GetCount

Platform SDK: Security

ICertEncodeDateArray::GetCount [C++]

CCertEncodeDateArray.GetCount [Visual Basic]

The GetCount method returns the number of Date values in the object's Date array.

[C++]
HRESULT GetCount(
  LONG *pCount
);
[Visual Basic]
objEncodeDateArray.GetCount() As Long

Parameters

[C++] pCount
[out] Pointer to a Long which will represent the number of Date values contained in the Date array.
[Visual Basic] objEncodeDateArray
Object expression that resolves to a CCertEncodeDateArray object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pCount is set to a value representing the number of Date values contained in the Date array

[Visual Basic] The return value is the number of Date values contained in the Date array.

Example Code [C++]

// Retrieve count and display the values in the array.
long   nCount;
hr = pEncodeDateArray->GetCount(&nCount);
if (FAILED(hr))
{
    printf("Failed pEncodeDateArray->GetCount [%x]\n", hr);
    goto error;
}
printf("There are %d values in the array\n", nCount);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeDateArray


ICertEncodeDateArray::GetValue

Platform SDK: Security

ICertEncodeDateArray::GetValue [C++]

CCertEncodeDateArray.GetValue [Visual Basic]

The GetValue method returns the Date value at a specified index of a Date array.

[C++]
HRESULT GetValue(
  LONG Index,
  DATE *pValue
);
[Visual Basic]
objEncodeDateArray.GetValue( _
  Index As Long _
) As Date

Parameters

[Visual Basic] objEncodeDateArray
Object expression that resolves to a CCertEncodeDateArray object.
[C++,Visual Basic] Index
[in] Specifies the index into the Date array from which to get the Date value. The first item is at index zero.
[C++] pValue
[out] Pointer to a Date value representing the value at the index specified.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pValue is set to a Date representing the value at the specified index.

[Visual Basic] The return value is the Date value at the specified index.

Example Code [C++]

// Retrieve count and display the values in the array.
long    nCount;
DATE    date;
hr = pEncodeDateArray->GetCount(&nCount);
if (FAILED(hr))
{
    printf("Failed pEncodeDateArray->GetCount [%x]\n", hr);
    goto error;
}

for (j = 0; j < nCount; j++)
{
    hr = pEncodeDateArray->GetValue(j, &date);
    if (FAILED(hr))
    {
        printf("Failed pEncodeDateArray->GetValue [%x]\n", hr);
        goto error;
    }
    // Do something with the date value.
    // ...
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeDateArray


ICertEncodeDateArray::Reset

Platform SDK: Security

ICertEncodeDateArray::Reset [C++]

CCertEncodeDateArray.Reset [Visual Basic]

The Reset method resets a Date array to a specified number of elements. The values of all the elements in the array are set to 0.

[C++]
HRESULT Reset(
  LONG Count
);
[Visual Basic]
objEncodeDateArray.Reset( _
  Count As Long _
)

Parameters

[Visual Basic] objEncodeDateArray
Object expression that resolves to a CCertEncodeDateArray object.
[C++,Visual Basic] Count
[in] Specifies the number of elements in the Date array.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Example Code [C++]

    // Pointer to interface object.
    ICertEncodeDateArray * pEncodeDateArray = NULL;

    HRESULT    hr;

    // Initialize COM.
    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    // Check status.
    if (FAILED(hr))
    {
        printf("Failed CoInitializeEx - [%x]\n", hr);
        goto error;
    }

    // Instantiate the CertEncodeDateArray object.
    hr = CoCreateInstance(CLSID_CCertEncodeDateArray,
                          NULL,
                          CLSCTX_INPROC_SERVER,
                          IID_ICertEncodeDateArray,
                          (void **)&pEncodeDateArray);
    if (FAILED(hr))
    {
        printf("Failed CoCreateInstance - pEncodeDateArray [%x]\n", hr);
        goto error;
    }

    // Inform the object there will be three items in the array.
    hr = pEncodeDateArray->Reset(3);
    if (FAILED(hr))
    {
        printf("Failed pEncodeDateArray->Reset [%x]\n", hr);
        goto error;
    }
    // Use the object as needed.
    // ...

    // Done processing.
error:
    // Clean up object resources.
    if (NULL != pEncodeDateArray)
        pEncodeDateArray->Release();

    // Free COM resources.
    CoUninitialize();

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeDateArray


ICertEncodeDateArray::SetValue

Platform SDK: Security

ICertEncodeDateArray::SetValue [C++]

CCertEncodeDateArray.SetValue [Visual Basic]

The SetValue method sets a Date value at the specified index of a Date array. It is necessary to call ICertEncodeDateArray::Reset before calling SetValue.

[C++]
HRESULT SetValue(
  LONG Index,
  DATE Value
);
[Visual Basic]
objEncodeDateArray.SetValue( _
  Index As Long, _
  Value As Date _
)

Parameters

[Visual Basic] objEncodeDateArray
Object expression that resolves to a CCertEncodeDateArray object.
[C++,Visual Basic] Index
[in] Specifies the index into the Date array at which to set a Date value. The first item in the array is at index zero.
[C++,Visual Basic] Value
[in] Specifies the Date value to set.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Example Code [C++]

int     j; // for looping

// Values which will be in the array
DATE    rgDate[3] =  { 36892.5,     // Noon 1/1/2001
                       37256.25,    // 6:00 AM 12/31/2001
                       37257.0 };   // 12:00 AM 1/1/2002
// Call Reset prior to this section (not shown here).
// Place the values in the array.
for (j = 0; j < 3; j++)
{
    hr = pEncodeDateArray->SetValue(j, rgDate[j]);
    if (FAILED(hr))
    {
        printf("Failed pEncodeDateArray->SetValue [%x]\n", hr);
        goto error;
    }
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeDateArray, ICertEncodeDateArray::Reset


ICertEncodeLongArray

Platform SDK: Security

ICertEncodeLongArray [C++]

CCertEncodeLongArray [Visual Basic]

The ICertEncodeLongArray interface provides methods for handling Long arrays used in certificate extensions. A certificate extension can be created using a Long array stored in an extension handler COM object instantiated by the policy module. Each element in the array is a Long value.

This interface is provided mainly as a demonstration for encoding custom extensions. The Certificate Services sample programs in the Platform SDK contain source code for this interface.

ICertEncodeLongArray is defined in certenc.h. When you create your program, however, use certsrv.h as the include file. CertEnc.dll provides the ICertEncodeLongArray interface. In Windows 2000, the type information for this interface is also in CertEncL.dll, which is shipped with the Platform SDK.

The Certificate Services interfaces support only the apartment-threading model.

The following methods are provided by the ICertEncodeLongArray interface.

Method | Description
Decode | Decodes an ASN.1-encoded Long array and stores the resulting array of Longs in the COM object.
Encode | Performs ASN.1 encoding on a Long array stored in the COM object and returns the ASN.1-encoded Long array.
GetCount | Returns the number of Long values in a Long array.
GetValue | Returns the Long value at a specified index of a Long array.
Reset | Resets a Long array to a specified number of elements.
SetValue | Sets a Long value at a specified index of a Long array.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertEncodeLongArray::Decode

Platform SDK: Security

ICertEncodeLongArray::Decode [C++]

CCertEncodeLongArray.Decode [Visual Basic]

The Decode method decodes an ASN.1-encoded Long array and stores the resulting array of Long values in the COM object.

[C++]
HRESULT Decode(
  BSTR const strBinary
);
[Visual Basic]
objEncodeLongArray.Decode( _
  strBinary As String _
)

Parameters

[Visual Basic] objEncodeLongArray
Object expression that resolves to a CCertEncodeLongArray object.
[C++,Visual Basic] strBinary
[in] An ASN.1-encoded Long array.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Remarks

This method will place the decoded contents of strBinary into the object's array of Long values. If the object's array already contains Long values, this existing content will be freed, and the array will be loaded with the decoded values.

Example Code [C++]

// bstrEncode is a previously encoded BSTR.
hr = pEncodeLongArray->Decode(bstrEncode);
if (FAILED(hr))
{
    printf("Failed pEncodeLongArray->Decode [%x]\n", hr);
    goto error;
}
// Successfully decoded.
// ...

// Done processing.
if (NULL != bstrEncode)
    SysFreeString(bstrEncode);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeLongArray


ICertEncodeLongArray::Encode

Platform SDK: Security

ICertEncodeLongArray::Encode [C++]

CCertEncodeLongArray.Encode [Visual Basic]

The Encode method performs ASN.1 encoding on a Long array stored in the COM object and returns the ASN.1-encoded Long array. The ICertEncodeLongArray::Reset method must first be used to size the array, and the ICertEncodeLongArray::SetValue method must be called to set each Long value in the array.

[C++]
HRESULT Encode(
  BSTR *pbstrBinary
);
[Visual Basic]
objEncodeLongArray.Encode() As String

Parameters

[C++] pbstrBinary
[out] Pointer to BSTR which will contain the encoded Long array.
[Visual Basic] objEncodeLongArray
Object expression that resolves to a CCertEncodeLongArray object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pbstrBinary is set to the BSTR representing the encoded Long array. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable as pbstrBinary. You must free *pbstrBinary when done (by means of SysFreeString).

[Visual Basic] The return value is the ASN.1-encoded Long array.

Example Code [C++]

// Encode the values in the array.
BSTR bstrEncode = NULL;
hr = pEncodeLongArray->Encode(&bstrEncode);
if (FAILED(hr))
{
    printf("Failed pEncodeLongArray->Encode [%x]\n", hr);
    goto error;
}
// Do something with the encoded value.
// ...

// Done processing; clean up BSTR.
if (NULL != bstrEncode)
    SysFreeString (bstrEncode);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeLongArray, ICertEncodeLongArray::Reset, ICertEncodeLongArray::SetValue


ICertEncodeLongArray::GetCount

Platform SDK: Security

ICertEncodeLongArray::GetCount [C++]

CCertEncodeLongArray.GetCount [Visual Basic]

The GetCount method returns the number of Long values in the object's Long array.

[C++]
HRESULT GetCount(
  LONG *pCount
);
[Visual Basic]
objEncodeLongArray.GetCount() As Long

Parameters

[C++] pCount
[out] Pointer to a Long which will represent the number of Long values contained in the Long array.
[Visual Basic] objEncodeLongArray
Object expression that resolves to a CCertEncodeLongArray object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pCount is set to a value representing the number of Long values contained in the Long array.

[Visual Basic] The return value is the number of Long values contained in the Long array.

Example Code [C++]

// Retrieve count and display the values in the array.
long   nCount;
hr = pEncodeLongArray->GetCount(&nCount);
if (FAILED(hr))
{
    printf("Failed pEncodeLongArray->GetCount [%x]\n", hr);
    goto error;
}
printf("There are %d values in the array\n", nCount);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeLongArray


ICertEncodeLongArray::GetValue

Platform SDK: Security

ICertEncodeLongArray::GetValue [C++]

CCertEncodeLongArray.GetValue [Visual Basic]

The GetValue method returns the Long value at a specified index of a Long array.

[C++]
HRESULT GetValue(
  LONG Index,
  LONG *pValue
);
[Visual Basic]
objEncodeLongArray.GetValue( _
  Index As Long _
) As Long

Parameters

[Visual Basic] objEncodeLongArray
Object expression that resolves to a CCertEncodeLongArray object.
[C++,Visual Basic] Index
[in] Specifies the index into the Long array from which to get the Long value. The first item is at index zero.
[C++] pValue
[out] Pointer to a Long representing the value at the index specified.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pValue is set to a Long representing the value at the specified index.

[Visual Basic] The return value is the Long value at the specified index.

Example Code [C++]

// Retrieve count and display the values in the array.
long   nCount, nValue;
hr = pEncodeLongArray->GetCount(&nCount);
if (FAILED(hr))
{
    printf("Failed pEncodeLongArray->GetCount [%x]\n", hr);
    goto error;
}
for (j = 0; j < nCount; j++)
{
    hr = pEncodeLongArray->GetValue(j, &nValue);
    if (FAILED(hr))
    {
        printf("Failed pEncodeLongArray->GetValue [%x]\n", hr);
        goto error;
    }
    // Do something with the value.
    // ...
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeLongArray


ICertEncodeLongArray::Reset

Platform SDK: Security

ICertEncodeLongArray::Reset [C++]

CCertEncodeLongArray.Reset [Visual Basic]

The Reset method resets a Long array to a specified number of elements. The values of all the elements in the array are set to 0.

[C++]
HRESULT Reset(
  LONG Count
);
[Visual Basic]
objEncodeLongArray.Reset( _
  Count As Long _
)

Parameters

[Visual Basic] objEncodeLongArray
Object expression that resolves to a CCertEncodeLongArray object.
[C++,Visual Basic] Count
[in] Specifies the number of elements in the Long array.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Example Code [C++]

    // Pointer to interface object
    ICertEncodeLongArray * pEncodeLongArray = NULL;

    HRESULT    hr;

    // Initialize COM.
    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    // Check status.
    if (FAILED(hr))
    {
        printf("Failed CoInitializeEx - [%x]\n", hr);
        goto error;
    }

    // Instantiate the CertEncodeLongArray object.
    hr = CoCreateInstance(CLSID_CCertEncodeLongArray,
                          NULL,
                          CLSCTX_INPROC_SERVER,
                          IID_ICertEncodeLongArray,
                          (void **)&pEncodeLongArray);
    if (FAILED(hr))
    {
        printf("Failed CoCreateInstance - pEncodeLongArray [%x]\n", hr);
        goto error;
    }

// Inform the object there will be ten items in the array.
    hr = pEncodeLongArray->Reset(10);
    if (FAILED(hr))
    {
        printf("Failed pEncodeLongArray->Reset [%x]\n", hr);
        goto error;
    }
    // Use the array as needed (not shown here).
    // ...

    // Done processing.

error:

    // Clean up object resources.
    if (NULL != pEncodeLongArray)
        pEncodeLongArray->Release();
    // Free COM resources.
    CoUninitialize();

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeLongArray


ICertEncodeLongArray::SetValue

Platform SDK: Security

ICertEncodeLongArray::SetValue [C++]

CCertEncodeLongArray.SetValue [Visual Basic]

The SetValue method sets a Long value at the specified index of a Long array. It is necessary to call ICertEncodeLongArray::Reset before calling SetValue.

[C++]
HRESULT SetValue(
  LONG Index,
  LONG Value
);
[Visual Basic]
objEncodeLongArray.SetValue( _
  Index As Long, _
  Value As Long _
)

Parameters

[Visual Basic] objEncodeLongArray
Object expression that resolves to a CCertEncodeLongArray object.
[C++,Visual Basic] Index
[in] Specifies the index into the Long array at which to set a Long value. The first item in the array is at index zero.
[C++,Visual Basic] Value
[in] Specifies the Long value to set.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Example Code [C++]

int     j; // for looping

// Values which will be in the array
long    rgLong[10] = { 1, 1234, 45, 45000, 2001,
                      -44, 515, 10000, 32000, -500 };

// Call Reset prior to this section (not shown here).
// Place the values in the array.
for (j = 0; j < 10; j++)
{
    hr = pEncodeLongArray->SetValue( j, rgLong[j] );
    if (FAILED(hr))
    {
        printf("Failed pEncodeLongArray->SetValue [%x]\n", hr);
        goto error;
    }
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeLongArray, ICertEncodeLongArray::Reset


ICertEncodeStringArray

Platform SDK: Security

ICertEncodeStringArray [C++]

CCertEncodeStringArray [Visual Basic]

The ICertEncodeStringArray interface provides methods for handling string arrays used in certificate extensions. A certificate extension can be created using a string array stored in an extension handler COM object instantiated by the policy module. Each element in the array is a string value.

This interface is provided mainly as a demonstration for encoding custom extensions. The Certificate Services sample programs in the Platform SDK contain source code for this interface.

ICertEncodeStringArray is defined in certenc.h. When you create your program, however, use certsrv.h as the include file. CertEnc.dll provides the ICertEncodeStringArray interface. In Windows 2000, the type information for this interface is also in CertEncL.dll, which is shipped with the Platform SDK.

The Certificate Services interfaces support only the apartment-threading model.

The following methods are provided by the ICertEncodeStringArray interface.

Method | Description
Decode | Decodes an ASN.1-encoded string array and stores the resulting array of strings in the COM object.
Encode | Performs ASN.1 encoding on a string array stored in the COM object and returns the ASN.1-encoded string array.
GetCount | Returns the number of values in a string array.
GetStringType | Returns the type of values contained in a string array.
GetValue | Returns the value at a specified index of a string array.
Reset | Resets a string array to a specified type and number of elements, and clears the values.
SetValue | Sets a value at a specified index of a string array.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertEncodeStringArray::Decode

Platform SDK: Security

ICertEncodeStringArray::Decode [C++]

CCertEncodeStringArray.Decode [Visual Basic]

The Decode method decodes an ASN.1-encoded string array and stores the resulting array of strings in the COM object.

[C++]
HRESULT Decode(
  BSTR const strBinary
);
[Visual Basic]
objEncodeStringArray.Decode( _
  strBinary As String _
)

Parameters

[Visual Basic] objEncodeStringArray
Object expression that resolves to a CCertEncodeStringArray object.
[C++,Visual Basic] strBinary
[in] An ASN.1-encoded string array.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Remarks

This method will place the decoded contents of strBinary into the object's array of strings. If the object's array already contains strings, this existing content will be freed and the array will be loaded with the decoded values.

Example Code [C++]

// bstrEncode is a previously encoded BSTR.
hr = pEncodeStringArray->Decode(bstrEncode);
if (FAILED(hr))
{
    printf("Failed pEncodeStringArray->Decode [%x]\n", hr);
    goto error;
}
// Successfully decoded; take other action as needed.
// ...

// Done processing.
if (NULL != bstrEncode)
    SysFreeString(bstrEncode);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeStringArray


ICertEncodeStringArray::Encode

Platform SDK: Security

ICertEncodeStringArray::Encode [C++]

CCertEncodeStringArray.Encode [Visual Basic]

The Encode method performs ASN.1 encoding on a string array stored in the COM object and returns the ASN.1-encoded string array. The ICertEncodeStringArray::Reset method must first be used to size the array, and the ICertEncodeStringArray::SetValue method must be called to set each string in the array.

[C++]
HRESULT Encode(
  BSTR *pbstrBinary
);
[Visual Basic]
objEncodeStringArray.Encode() As String

Parameters

[C++] pbstrBinary
[out] Pointer to BSTR which will contain the encoded string array.
[Visual Basic] objEncodeStringArray
Object expression that resolves to a CCertEncodeStringArray object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pbstrBinary is set to the BSTR representing the ASN.1-encoded string array. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable as pbstrBinary. You must free *pbstrBinary when done (by means of SysFreeString).

[Visual Basic] The return value is the ASN.1-encoded string array.

Example Code [C++]

BSTR    bstrEncode = NULL;

hr = pEncodeStringArray->Encode(&bstrEncode);
if (FAILED(hr))
{
    printf("Failed pEncodeStringArray->Encode [%x]\n", hr);
    goto error;
}
// Successfully encoded.
// ...

// Done processing.
if (NULL != bstrEncode)
    SysFreeString(bstrEncode);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeStringArray, ICertEncodeStringArray::Reset, ICertEncodeStringArray::SetValue


ICertEncodeStringArray::GetCount

Platform SDK: Security

ICertEncodeStringArray::GetCount [C++]

CCertEncodeStringArray.GetCount [Visual Basic]

The GetCount method returns the number of string values in a string array.

[C++]
HRESULT GetCount(
  LONG *pCount
);
[Visual Basic]
objEncodeStringArray.GetCount() As Long

Parameters

[C++] pCount
[out] Pointer to a Long which will represent the number of string values contained in the string array.
[Visual Basic] objEncodeStringArray
Object expression that resolves to a CCertEncodeStringArray object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pCount is set to a value representing the number of string values contained in the string array.

[Visual Basic] The return value is the number of string values contained in the string array.

Example Code [C++]

// Retrieve the number of strings in the array.
long nCount;
hr = pEncodeStringArray->GetCount(&nCount);
if (FAILED(hr))
{
    printf("Failed pEncodeStringArray->GetCount [%x]\n", hr);
    goto error;
}
printf("Count: %d\n", nCount);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeStringArray


ICertEncodeStringArray::GetStringType

Platform SDK: Security

ICertEncodeStringArray::GetStringType [C++]

CCertEncodeStringArray.GetStringType [Visual Basic]

The GetStringType method returns the type of string values contained in a string array.

[C++]
HRESULT GetStringType(
  LONG *pStringType
);
[Visual Basic]
objEncodeStringArray.GetStringType() As Long

Parameters

[C++] pStringType
[out] Pointer to a Long representing the string type.
[Visual Basic] objEncodeStringArray
Object expression that resolves to a CCertEncodeStringArray object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pStringType is set to one of the values in the following table.

[Visual Basic] The return value indicates the type of string values in the string array. The string type must be one of the following types.

String Type Specifier | Description
CERT_RDN_ANY_TYPE | For encoding an X509_UNICODE_NAME name.
CERT_RDN_NUMERIC_STRING | The characters 0 through 9 and the space character (8 bit).
CERT_RDN_PRINTABLE_STRING | Printable characters (8 bit).
CERT_RDN_T61_STRING | T.61 encoded characters (8 bit).
CERT_RDN_VIDEOTEX_STRING | VIDEOTEX characters.
CERT_RDN_IA5_STRING | IA5 (ASCII) characters.
CERT_RDN_GRAPHIC_STRING | A string of ISO defined GRAPHIC characters.
CERT_RDN_ISO646_STRING | 128 character set (8 bit).
CERT_RDN_GENERAL_STRING | A string of ISO defined GENERAL characters.
CERT_RDN_INT4_STRING | An array of INT4 values (32 bit).
CERT_RDN_UNICODE_STRING | Unicode characters (16 bit).

For more information about RDN types, please refer to the CryptoAPI 2.0 documents.

Example Code [C++]

// Retrieve the type of strings in the array.
long    nType;

hr = pEncodeStringArray->GetStringType(&nType);
if (FAILED(hr))
{
    printf("Failed pEncodeStringArray->GetStringType [%x]\n", hr);
    goto error;
}

// Display text based on string type in the array.
switch (nType)
{
    case CERT_RDN_ANY_TYPE:
        printf("String is of ANY type\n");
        break;
    case CERT_RDN_NUMERIC_STRING:
        printf("String is of NUMERIC type\n");
        break;
    case CERT_RDN_PRINTABLE_STRING:
        printf("String is of PRINTABLE type\n");
        break;
    case CERT_RDN_T61_STRING:
        printf("String is of T61 type\n");
        break;
    case CERT_RDN_VIDEOTEX_STRING:
        printf("String is of VIDEOTEX type\n");
        break;
    case CERT_RDN_IA5_STRING:
        printf("String is of IA5 type\n");
        break;
    case CERT_RDN_GRAPHIC_STRING:
        printf("String is of GRAPHIC type\n");
        break;
    case CERT_RDN_ISO646_STRING:
        printf("String is of ISO646 type\n");
        break;
    case CERT_RDN_GENERAL_STRING:
        printf("String is of GENERAL type\n");
        break;
    case CERT_RDN_INT4_STRING:
        printf("String is of INT4 type\n");
        break;
    case CERT_RDN_UNICODE_STRING:
        printf("String is of UNICODE type\n");
        break;
    default:
        printf("Unexpected type!\n");
        break;
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeStringArray


ICertEncodeStringArray::GetValue

Platform SDK: Security

ICertEncodeStringArray::GetValue [C++]

CCertEncodeStringArray.GetValue [Visual Basic]

The GetValue method returns the string value at a specified index of a string array.

[C++]
HRESULT GetValue(
  LONG Index,
  BSTR *pstr
);
[Visual Basic]
objEncodeStringArray.GetValue( _
  Index As Long _
) As String

Parameters

[Visual Basic] objEncodeStringArray
Object expression that resolves to a CCertEncodeStringArray object.
[C++,Visual Basic] Index
[in] Specifies the index into the string array from which to get the string value. The first item is at index zero.
[C++] pstr
[out] Pointer to BSTR representing the string value.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pstr is set to the BSTR representing the string value at the specified index. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable as pstr. You must free *pstr when done (by means of SysFreeString).

[Visual Basic] The return value is the string value at the specified index.

Example Code [C++]

// Retrieve the number of strings in the array.
long    nCount;
hr = pEncodeStringArray->GetCount(&nCount);
if (FAILED(hr))
{
    printf("Failed pEncodeStringArray->GetCount [%x]\n", hr);
    goto error;
}

// BSTR to contain value of string.
BSTR    bstrValue = NULL;
// Retrieve the values from the array.
for (int i = 0; i < nCount; i++)
{
    hr = pEncodeStringArray->GetValue(i, &bstrValue);
    if (FAILED(hr))
    {
        printf("Failed pEncodeStringArray->GetValue [%x]\n", hr);
        goto error;
    }

    // Display the value.
    printf("Index: %d Value: %ws\n", i, bstrValue );
    // Reuse the same BSTR for this loop.
    if (NULL != bstrValue)
    {
        SysFreeString(bstrValue);
        bstrValue = NULL;
    }
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeStringArray


ICertEncodeStringArray::Reset

Platform SDK: Security

ICertEncodeStringArray::Reset [C++]

CCertEncodeStringArray.Reset [Visual Basic]

The Reset method resets a string array to a specified number and type of elements. The values of all the elements in the string array are set to 0.

[C++]
HRESULT Reset(
  LONG Count,
  LONG StringType
);
[Visual Basic]
objEncodeStringArray.Reset( _
  Count As Long, _
  StringType As Long _
)

Parameters

[Visual Basic] objEncodeStringArray
Object expression that resolves to a CCertEncodeStringArray object.
[C++,Visual Basic] Count
[in] Specifies the number of elements in the string array.
[C++,Visual Basic] StringType
[in] Specifies the type of the elements in the string array. The type must be one of the following types.
String type specifier | Description
CERT_RDN_ANY_TYPE | For encoding an X509_UNICODE_NAME name.
CERT_RDN_NUMERIC_STRING | The characters 0 through 9 and the space character (8 bit).
CERT_RDN_PRINTABLE_STRING | Printable characters (8 bit).
CERT_RDN_T61_STRING | T.61 encoded characters (8 bit).
CERT_RDN_VIDEOTEX_STRING | VIDEOTEX characters.
CERT_RDN_IA5_STRING | IA5 (ASCII) characters.
CERT_RDN_GRAPHIC_STRING | A string of ISO defined GRAPHIC characters.
CERT_RDN_ISO646_STRING | 128 character set (8 bit).
CERT_RDN_GENERAL_STRING | A string of ISO defined GENERAL characters.
CERT_RDN_INT4_STRING | An array of INT4 values (32 bit).
CERT_RDN_UNICODE_STRING | Unicode characters (16 bit).

For more information about RDN types, please refer to the CryptoAPI 2.0 documents.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Example Code [C++]

    // Pointer to interface object
    ICertEncodeStringArray * pEncodeStringArray = NULL;

    HRESULT    hr;

    // Initialize COM.
    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    // Check status.
    if (FAILED(hr))
    {
        printf("Failed CoInitializeEx - [%x]\n", hr);
        goto error;
    }

    // Instantiate the CertEncodeStringArray object.
    hr = CoCreateInstance(CLSID_CCertEncodeStringArray,
                          NULL,
                          CLSCTX_INPROC_SERVER,
                          IID_ICertEncodeStringArray,
                          (void **)&pEncodeStringArray);
    if (FAILED(hr))
    {
        printf("Failed CoCreateInstance - pEncodeStringArray [%x]\n", hr);
        goto error;
    }

    // Inform the object there will be 3 strings to encode.
    hr = pEncodeStringArray->Reset(3, CERT_RDN_PRINTABLE_STRING);
    if (FAILED(hr))
    {
        printf("Failed pEncodeStringArray->Reset [%x]\n", hr);
        goto error;
    }
    // Use the array as needed (not shown here).
    // ...

    // Done processing.

error:

    // Clean up object resources.
    if (NULL != pEncodeStringArray)
        pEncodeStringArray->Release();

    // Free COM resources.
    CoUninitialize();

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeStringArray


ICertEncodeStringArray::SetValue

Platform SDK: Security

ICertEncodeStringArray::SetValue [C++]

CCertEncodeStringArray.SetValue [Visual Basic]

The SetValue method sets a string value at the specified index of a string array. It is necessary to call ICertEncodeStringArray::Reset before calling ICertEncodeStringArray::SetValue.

[C++]
HRESULT SetValue(
  LONG Index,
  BSTR const str
);
[Visual Basic]
objEncodeStringArray.SetValue( _
  Index As Long, _
  str As String _
)

Parameters

[Visual Basic] objEncodeStringArray
Object expression that resolves to a CCertEncodeStringArray object.
[C++,Visual Basic] Index
[in] Specifies the index into the string array at which to set a string value. The first item in the array is at index zero.
[C++,Visual Basic] str
[in] Specifies the string value to set.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Example Code [C++]

WCHAR * rgString[3] = { L"String 1",
                        L"String 2",
                        L"String 3" };

BSTR    bstrValue = NULL;

int     i;   // for looping

HRESULT hr;

// Call Reset prior to this section (not shown here).

// Populate the array.
for (i = 0; i < 3; i++)
{
    // Build the value to place in the array.
    // Error checking skipped in the following line.
    bstrValue = SysAllocString(rgString[i]);
     // Place this value into the array.
    hr = pEncodeStringArray->SetValue(i, bstrValue);
    if (FAILED(hr))
    {
        printf("Failed pEncodeStringArray->SetValue [%x]\n", hr);
        goto error;
    }

    // Reuse the same BSTR for this loop.
    if (NULL != bstrValue)
    {
        SysFreeString(bstrValue);
        bstrValue = NULL;
    }
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certenc.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertEncodeStringArray, ICertEncodeStringArray::Reset


ICertExit

Platform SDK: Security

ICertExit [C++]

CCertExit [Visual Basic]

The ICertExit interface is called by the Certificate Services server to notify an exit module that an event of interest to the exit module has occurred. Examples of such events are certificate issuance, CRL issuance, or server shutdown. The exit module can then query the server through the ICertServerExit interface to determine the properties of any object associated with the event, such as a certificate or CRL.

ICertExit is defined in certexit.h. When you create your program, however, use certsrv.h as the include file.

The Certificate Services interfaces support only the apartment-threading model.

The following methods, listed in v-table order, are provided by the ICertExit interface.

Method | Description
Initialize | Called by the server engine when it initializes itself.
Notify | Called by the server engine to notify an exit module that an event has occurred.
GetDescription | Returns a human readable description of the exit module and its function.

Remarks

No more than one Visual Basic exit module may be registered on the Certificate Services server at one time. If more than one Visual Basic exit module is registered, the Certification Authority MMC snap-in, Certificate Services application, or certutil command line program may produce errors. Note that the Microsoft Visual Basic development environment automatically registers a DLL when it is successfully built. As a result, you may encounter this situation when one Visual Basic exit module is already registered and another Visual Basic exit module is created. In order to avoid this situation, you must unregister one of the Visual Basic exit modules, by means of the command-line instruction 'regsvr32 /u filename.dll', where filename.dll is the name of the Visual Basic exit module which is not intended to be made active.

Note for WindowsNT 4.0 In WindowsNT 4.0, you must use the value c9e6e410-7364-11d0-8816-00a0c903b83c for the CLSID when implementing ICertExit. Also, the ProgID for a class implementing ICertExit must conform to a naming convention. Specifically, the ProgID must be of the form:

"CertificateAuthority.Exit"

For example, in C++, the following can be used in the DECLARE_REGISTRY macro of a class (CMyCertExitModule) that implements ICertExit:

DECLARE_REGISTRY(
    CMyCertExitModule,
    L"CertificateAuthority.Exit.1",
    L"CertificateAuthority.Exit",
    IDS_CERTEXITMODULE_DESC,
    THREADFLAGS_BOTH)

For the above sample, the IDS_CERTEXITMODULE_DESC value is an application-specific identifier in the resource file (.rc) for a string which describes the class.

Exit modules written in Visual Basic are not supported in versions of Windows NT 4.0 prior to SP6. This limitation has been removed for Windows NT 4.0 SP6 and Windows 2000.

Note for Windows 2000 Only a stand-alone certification authority should replace the Microsoft-provided policy or exit modules; when running an enterprise certification authority, the use of Microsoft-provided policy and exit modules is strongly recommended. The provided policy module may be replaced when running a stand-alone certification authority. Custom exit modules can always be used in addition to the Microsoft-provided exit module.

In Windows 2000, implementers of ICertExit should also implement ICertManageModule. Additionally, the ProgID for a class implementing ICertExit must conform to a naming convention. Specifically, the ProgID must be of the form:

"MyApp.Exit"

where MyApp is a specifier identifying the application. For example, in C++, the following could be used in the DECLARE_REGISTRY macro of a class (CMyCertExitModule) which implements ICertExit:

DECLARE_REGISTRY(
    CMyCertExitModule,
    L"MyCode.Exit.1",
    L"MyCode.Exit",
    IDS_CERTEXITMODULE_DESC,
    THREADFLAGS_BOTH)

For the above sample, the IDS_CERTEXITMODULE_DESC value is an application-specific identifier in the resource file (.rc) for a string which describes the class.

Implementers of ICertExit in Visual Basic must name their project in the form of

"MyApp"

where MyApp is a specifier identifying the application; further, the class implementing ICertExit must be named "Exit".

String constants defined in certmod.h may be used to simplify following the naming convention:

Constant | Value
wszCERTEXITMODULE_POSTFIX | TEXT(".Exit")

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certexit.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerExit


ICertExit::GetDescription

Platform SDK: Security

ICertExit::GetDescription [C++]

CCertExit.GetDescription [Visual Basic]

The GetDescription method returns a human readable description of the exit module and its function.

[C++]
HRESULT GetDescription(
  BSTR *pstrDescription
);
[Visual Basic]
objExit.GetDescription() As String

Parameters

[C++] pstrDescription
[out] Pointer to the BSTR representing the retrieved description.
[Visual Basic] objExit
Object expression that resolves to a CCertExit object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pstrDescription is set to the BSTR describing the exit module and its function.

[Visual Basic] Returns a string describing the exit module and its function.

Remarks

When you write custom exit modules, you should implement this functionality in your modules. The following examples are possible implementations.

Example Code [C++]

STDMETHODIMP
CCertExit::GetDescription(
    /* [out, retval] */ BSTR __RPC_FAR *pstrDescription)
{
    if (NULL == pstrDescription)
    {
        // Bad pointer address.
        return (E_POINTER);
    }
    if (NULL != *pstrDescription)
    {
        SysFreeString(*pstrDescription);
        *pstrDescription=NULL;
    }
    // wszMyExitModuleDesc defined elsewhere,
    // for example, #define wszMyExitModuleDesc  L"My Exit Module".
    *pstrDescription = SysAllocString(wszMyExitModuleDesc);
    if (NULL == *pstrDescription)
    {
        // Not enough memory
        return ( E_OUTOFMEMORY );
    }
    // Success
    return( S_OK );
}

Example Code [Visual Basic]

Public Function GetDescription() As String
    GetDescription = "My Visual Basic Exit Module"
End Function

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certexit.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertExit


ICertExit::Initialize

Platform SDK: Security

ICertExit::Initialize [C++]

CCertExit.Initialize [Visual Basic]

The Initialize method is called by the server engine when it initializes itself. The call to the exit module's Initialize method allows the exit module to perform initialization and inform the server engine which kinds of events it would like to be notified of.

[C++]
HRESULT Initialize(
  BSTR const strConfig,
  LONG *pEventMask
);
[Visual Basic]
objExit.Initialize( _
  strConfig As String _
) As Long

Parameters

[Visual Basic] objExit
Object expression that resolves to a CCertExit object.
[C++,Visual Basic] strConfig
[in] Represents the name of the certification authority, as entered during Certificate Services setup. See ICertConfig for information about the configuration string name.
[C++] pEventMask
[out] Pointer to the value representing the events for which the exit module requests notification.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pEventMask is set to a combination of the flags in the table below (or EXITEVENT_INVALID if the exit module does not want to be notified of any events).

[Visual Basic] The return value is a mask containing flags that indicate the events for which the exit module requests notification. After the call, all events of those types will be signaled by the server engine to the exit module through a call to ICertExit::Notify. Any or all of the following flags may be set.

Name | Event description
EXITEVENT_CERTDENIED | Certificate denied.
EXITEVENT_CERTISSUED | Certificate issued.
EXITEVENT_CERTPENDING | Certificate pending.
EXITEVENT_CERTRETRIEVEPENDING | Successful call to ICertRequest::RetrievePending.
EXITEVENT_CERTREVOKED | Certificate revoked.
EXITEVENT_CRLISSUED | Certificate revocation list issued.
EXITEVENT_SHUTDOWN | Certificate Services shutdown.

If the exit module does not want to be notified of any events, then the flag EXITEVENT_INVALID should be set.

Remarks

Writers of custom exit modules should implement this functionality in their modules. The following example code shows one such implementation.

Example Code [C++]

STDMETHODIMP
CCertExit::Initialize(
    /* [in] */ BSTR const strConfig,
    /* [retval][out] */ LONG __RPC_FAR *pEventMask)
{
    // Verify valid pointer passed in.
    if (NULL == pEventMask)
        return ( E_POINTER );  // Bad pointer

    // strConfig can be used by the Exit module.
    // Here, we are storing it in a BSTR member variable.
    m_strConfig = SysAllocString( strConfig );
    // Check to see if there was enough memory.
    if (NULL == m_strConfig)
        return ( E_OUTOFMEMORY );  // Not enough memory

    // Inform server engine (CA) that we're interested in
    // the following events.
    *pEventMask = EXITEVENT_CERTISSUED |
                  EXITEVENT_CERTPENDING |
                  EXITEVENT_CERTDENIED |
                  EXITEVENT_CERTREVOKED |
                  EXITEVENT_CERTRETRIEVEPENDING |
                  EXITEVENT_CRLISSUED |
                  EXITEVENT_SHUTDOWN;

    if ( fDebug )
    {
        printf("Exit's Initialize member called\n");
        printf("\tstrConfig = %ws\n", strConfig );
    }

    return( S_OK );
}

Example Code [Visual Basic]

Public Function Initialize( _
                strConfig As String) _
                As Long

' Values of interest for Initialize
Const EXITEVENT_INVALID = 0
Const EXITEVENT_CERTISSUED = &H1
Const EXITEVENT_CERTPENDING = &H2
Const EXITEVENT_CERTDENIED = &H4
Const EXITEVENT_CERTREVOKED = &H8
Const EXITEVENT_CERTRETRIEVEPENDING = &H10
Const EXITEVENT_CRLISSUED = &H20
Const EXITEVENT_SHUTDOWN = &H40

Initialize = EXITEVENT_CERTISSUED Or _
             EXITEVENT_CERTPENDING Or _
             EXITEVENT_CERTDENIED Or _
             EXITEVENT_CERTREVOKED Or _
             EXITEVENT_CERTRETRIEVEPENDING Or _
             EXITEVENT_CRLISSUED Or _
             EXITEVENT_SHUTDOWN

' Record Initialize being called.
Dim s As String
s = "Initialize: " & strConfig & " " & Now()

Open "d:\exitevnt.txt" For Append As #1
Print #1, s
Close #1

End Function

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certexit.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

CertConfig, ICertExit, ICertExit::Notify.


ICertExit::Notify

Platform SDK: Security

ICertExit::Notify [C++]

CCertExit.Notify [Visual Basic]

The Notify method is called by the server engine to notify an exit module that an event has occurred.

[C++]
HRESULT Notify(
  LONG ExitEvent,
  LONG Context
);
[Visual Basic]
objExit.Notify( _
  ExitEvent As Long, _
  Context As Long _
)

Parameters

[Visual Basic] objExit
Object expression that resolves to a CCertExit object.
[C++,Visual Basic] ExitEvent
[in] A mask indicating the kind of exit event that has occurred. The mask can have one of the following flag-bits set.
Name | Event description
EXITEVENT_CERTISSUED | Certificate issued.
EXITEVENT_CERTPENDING | Certificate pending.
EXITEVENT_CERTDENIED | Certificate denied.
EXITEVENT_CERTREVOKED | Certificate revoked.
EXITEVENT_CERTRETRIEVEPENDING | Successful call to ICertRequest::RetrievePending.
EXITEVENT_CRLISSUED | CRL issued.
EXITEVENT_SHUTDOWN | Certificate Services shutdown.

[C++,Visual Basic] Context
[in] Specifies a context handle that can be used to get properties associated with the event from the ICertServerExit interface.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Remarks

When you write custom exit modules, be sure to implement this functionality in your modules. The example code shows one such implementation.

Note In the version of Certificate Services released with the Windows NT Option Pack, the parameter ExitEvent was call Event; in Visual Basic, Event is a reserved word, and as a result, Windows NT 4.0 Exit modules fail in Visual Basic. There is no known workaround. This problem does not occur in Windows NT 4.0 SP6 or later, or in Windows 2000 because the parameter has been renamed ExitEvent.

If a certification authority is using multiple exit modules, Certificate Services will notify each exit module of the event (provided the exit module requested notification by means of ICertExit::Initialize). The order in which the exit modules are notified should not be assumed, nor should one exit module depend on the processing of another exit module. Each notified exit module must return from ICertExit::Notify before the next exit module will be notified. Multiple exit modules may be used in Windows 2000 only.

Example Code [C++]

STDMETHODIMP
CCertExit::Notify(
    /* [in] */ LONG ExitEvent,
    /* [in] */ LONG Context)
{
    char *pszEvent;
    HRESULT hr = S_OK;

    switch (ExitEvent)
    {
    case EXITEVENT_CERTISSUED:
        // Call app-specific function for issued certs.
        hr = MyEventCertIssued(Context);
        pszEvent = "certissued";
        break;

    case EXITEVENT_CERTPENDING:
        pszEvent = "certpending";
        break;

    case EXITEVENT_CERTDENIED:
        pszEvent = "certdenied";
        break;

    case EXITEVENT_CERTREVOKED:
        pszEvent = "certrevoked";
        break;

    case EXITEVENT_CERTRETRIEVEPENDING:
        pszEvent = "retrievepending";
        break;

    case EXITEVENT_CRLISSUED:
        pszEvent = "crlissued";
        break;

    case EXITEVENT_SHUTDOWN:
        // Call app-specific function for shutdown.
        hr = MyEventShutdown();
        pszEvent = "shutdown";
        break;

    default:
        pszEvent = "Unexpected event";
        break;
    }

    if ( fDebug )
    {
        // Display what took place.
        printf("Exit::Notify(%s=%x, context=%u) return=%x\n",
                      pszEvent,
                      ExitEvent,
                      Context,
                      hr);
    }

    return(hr);
}

Example Code [Visual Basic]

Public Sub Notify(ExitEvent As Long, _
                  Context As Long)
' Values of interest for Notify.
Const EXITEVENT_CERTISSUED = &H1
Const EXITEVENT_CERTPENDING = &H2
Const EXITEVENT_CERTDENIED = &H4
Const EXITEVENT_CERTREVOKED = &H8
Const EXITEVENT_CERTRETRIEVEPENDING = &H10
Const EXITEVENT_CRLISSUED = &H20
Const EXITEVENT_SHUTDOWN = &H40

Dim s As String
s = "Notify: "

Select Case ExitEvent

    Case EXITEVENT_CERTISSUED
        s = s & "A certificate was issued."
    Case EXITEVENT_CERTPENDING
        s = s & "A certificate was made pending."
    Case EXITEVENT_CERTDENIED
        s = s & "A certificate was denied issuance."
    Case EXITEVENT_CERTREVOKED
        s = s & "A certificate was revoked."
    Case EXITEVENT_CERTRETRIEVEPENDING
        s = s & "RetrievePending was called."
    Case EXITEVENT_CRLISSUED
        s = s & "A CRL was issued."
    Case EXITEVENT_SHUTDOWN
        s = s & "Certificate Services has shut down."
    Case Else

End Select

s = s & " " & Now()

' Output the event to a file.
Open "d:\exitevnt.txt" For Append As #1
Print #1, s
Close #1

End Sub

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certexit.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertExit


ICertManageModule

Platform SDK: Security

ICertManageModule [C++]

CCertManageModule [Visual Basic]

The ICertManageModule interface is provided to retrieve information about a Certificate Services Policy or Exit module. Additionally, the ICertManageModule interface provides a method to invoke the module user interface for setting and viewing configuration settings. Beginning with Windows 2000, writers of Policy and Exit modules should implement the ICertManageModule interface (in addition to the ICertPolicy and ICertExit interfaces, respectively). An enterprise certification authority (CA) should always use the Microsoft-provided enterprise policy and exit modules; additional exit modules are permitted for enterprise CAs.

The ProgID for a class implementing ICertManageModule must conform to a naming convention. Specifically, the ProgID must be of the form:

"MyApp.PolicyOrExitManage"

where MyApp is a specifier identifying the application and PolicyOrExit is either "Policy" or "Exit". For example, in C++, the following could be used in the DECLARE_REGISTRY macro of a class (CMyCertManagePolicyModule) which implements ICertManageModule for a Policy module:

DECLARE_REGISTRY(
    CMyCertManagePolicyModule,
    L"MyCode.PolicyManage.1",
    L"MyCode.PolicyManage",
    IDS_CERTMANAGEPOLICYMODULE_DESC,
    THREADFLAGS_BOTH)

For the above sample, the IDS_CERTMANAGEPOLICYMODULE_DESC value is an application-specific identifier in the resource file (.rc) for a string which describes the class.

Implementers of ICertManageModule in Visual Basic must name their project in the form of

"MyManage"

where MyManage is a specifier identifying the application; further, the class implementing ICertManageModule must be named in the form "PolicyOrExitManage", where PolicyOrExit is either "Policy" or "Exit". For an example of a Policy module written in Visual Basic, the project could be named "MyCode", and the class implementing ICertManageModule would be named "PolicyManage".

String constants defined in certmod.h may be used to simplify following the naming convention.

Constant | Value
wszCERTMANAGEEXIT_POSTFIX | TEXT(".ExitManage")
wszCERTMANAGEPOLICY_POSTFIX | TEXT(".PolicyManage")

ICertManageModule is defined in certmod.h. When you create your program, however, use certsrv.h as the include file.

The Certificate Services interfaces support only the apartment-threading model.

The following methods, listed in v-table order, are provided by the ICertManageModule interface.

Method | Description
GetProperty | Retrieves the value of a property in the module.
SetProperty | Assigns a value to a property in the module.
Configure | Invokes module configuration user interface.

Note Only a stand-alone certification authority should utilize custom policy or exit modules; when running an enterprise certification authority, the use of Microsoft-provided policy and exit modules is strongly recommended.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certmod.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertManageModule::Configure

Platform SDK: Security

ICertManageModule::Configure [C++]

CCertManageModule.Configure [Visual Basic]

The Configure method displays the module user interface.

[C++]
HRESULT Configure(
  BSTR const strConfig,
  BSTR strStorageLocation,
  LONG Flags
);
[Visual Basic]
objManageModule.Configure( _
  strConfig As String, _
  strStorageLocation As String, _
  Flags As Long _
)

Parameters

[Visual Basic] objManageModule
Object expression that resolves to a CCertManageModule object.
[C++,Visual Basic] strConfig
[in] Represents the configuration string for the Certificate Services server in the form MACHINENAME\CANAME, where MACHINENAME is the Certificate Services server's network name, and CANAME is the common name of the certification authority (CA) as entered for the CA during Certificate Services setup. See ICertConfig for information about the configuration string name.
[C++,Visual Basic] strStorageLocation
[in] Location that provides storage for the property values, as described in the definition of strStorageLocation in ICertManageModule::GetProperty.
[C++,Visual Basic] Flags
[in] Value used to determine if the configuration interface is to be presented to the user. If this value is 0, the user will be presented with an interface for configuring the module. If this value is CMM_REFRESHONLY, Certificate Services will not display the user interface, but the latest changes to the configuration of the module will be in effect when future certificate requests are processed (this allows changes to be incorporated without requiring a response to a user interface).

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success.

[Visual Basic] None.

Remarks

The Configure method displays the module user interface (if one exists), allowing the user to view and change the module's configurable items. A module which implements ICertManageModule can have its Configure method called when the Certificate Services Manager Policy or Exit Module property page is active and the user chooses the 'Configure...' button. The Certificate Services Manager will pass the location referenced by strStorageLocation to this module, and the implementation of this method can then use this location as needed. Note that it is possible that a module may not have configurable items (hence, a user interface would not be necessary), but it would still be necessary to implement this method. The example below doesn't allow a user to make a configuration change, but it does implement this method.

Example Code [C++]

HRESULT
CCertManagePolicyModule::Configure(
            /* [in] */ const BSTR strConfig,
            /* [in] */ BSTR strStorageLocation,
            /* [in] */ LONG Flags)
{
    if ( CMM_REFRESHONLY != Flags )
        MessageBox(NULL,
                   L"This module has no configurable items",
                   L"MyModule",
                   (MB_OK|MB_ICONINFORMATION));

    return S_OK;
}

Example Code [Visual Basic]

Public Sub Configure( _
                strConfig As String, _
                strStorageLocation As String, _
                Flags As Long)

    MsgBox "This module has no configurable items.", _
           vbOKOnly, _
           "MyModule"

End Sub

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certmod.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertManageModule, ICertConfig


ICertManageModule::GetProperty

Platform SDK: Security

ICertManageModule::GetProperty [C++]

CCertManageModule.GetProperty [Visual Basic]

The GetProperty method retrieves a module's property value.

[C++]
HRESULT GetProperty(
  BSTR const strConfig,
  BSTR strStorageLocation,
  BSTR strPropertyName,
  LONG Flags,
  VARIANT *pvarProperty
);
[Visual Basic]
objManageModule.GetProperty( _
  strConfig As String, _
  strStorageLocation As String, _
  strPropertyName As String, _
  Flags As Long _
) As Variant

Parameters

[Visual Basic] objManageModule
Object expression that resolves to a CCertManageModule object.
[C++,Visual Basic] strConfig
[in] Represents the configuration string for the Certificate Services server in the form MACHINENAME\CANAME, where MACHINENAME is the Certificate Services server's network name, and CANAME is the common name of the certification authority (CA) as entered for the CA during Certificate Services setup. See ICertConfig for information about the configuration string name.
[C++,Visual Basic] strStorageLocation
[in] Registry key denoting the storage location in the HKEY_LOCAL_MACHINE hive for the property values. This value is in the form

SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\CAName\PolicyOrExiModules\MyModule.PolicyOrExit

where CAName is the name of the certification authority's configuration string, PolicyOrExit will be either "Policy" or "Exit" (depending on whether a Policy or Exit module applies to this implementation of ICertManageModule), and MyModule is the application-specific identifier for the module. Note that CAName is the sanitized name for the certification authority; see ICertConfig::GetConfig for details regarding the sanitized name. The use of this storage location is for future use.

[C++,Visual Basic] strPropertyName
[in] Name of the property being queried. Policy and exit modules should support the following properties.
Property name | Description
Name | Name of the module.
Description | Description of the module.
Copyright | Copyright pertaining to the module.
File Version | Version of the module file.
Product Version | Version of the module.

[C++,Visual Basic] Flags
[in] Reserved value; should be 0.
[C++] pvarProperty
[out] Pointer to Variant which is the retrieved value for the property specified by strPropertyName.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success.

[Visual Basic] The return value is a Variant representing the value of the property named strPropertyName.

Remarks

Implementing ICertManageModule allows the Certificate Services Manager to retrieve the module's properties by calling GetProperty. The properties can then be displayed in Certificate Services Manager property pages for Policy and Exit Modules. The Certificate Services Manager will pass the location referenced by strStorageLocation to this module, and in future versions the implementation of this method can then use this location as needed. The following example doesn't use strStorageLocation, but instead maintains the property values in memory.

Example Code [C++]

HRESULT
CCertManagePolicyModule::GetProperty(
            /* [in] */ const BSTR strConfig,
            /* [in] */ BSTR strStorageLocation,
            /* [in] */ BSTR strPropertyName,
            /* [in] */ LONG Flags,
            /* [retval][out] */ VARIANT *pvarProperty)
{
    // Array of property Names.
    // These values are defined in certmod.h.
    wchar_t const * awszPropName[] =
    {
        wszCMM_PROP_NAME,
        wszCMM_PROP_DESCRIPTION,
        wszCMM_PROP_COPYRIGHT,
        wszCMM_PROP_FILEVER,
        wszCMM_PROP_PRODUCTVER
    };

    // Array of property Values.
    // These values are module-specific, and
    // correspond to the property names in
    // awszPropName (same index).
    wchar_t const * awszPropValue[] =
   {
        L"MyModule",                      // NAME
        L"Description of MyModule",       // DESCRIPTION
        L"Copyright 1998",                // COPYRIGHT
        L"1.0",                           // FILE VERSION
        L"1.0"                            // PRODUCT VERSION
    };
    int     i;
    bool    bFound = FALSE;
    HRESULT hr;

    // Return appropriate error if strPropertyName is NULL.
    if (NULL == strPropertyName)
        return E_INVALIDARG;

    // Return appropriate error if pvarProperty is NULL.
    if (NULL == pvarProperty)
        return E_POINTER;
    // See if the requested property is in the Name array.
    for (i=0; i<sizeof(awszPropName)/sizeof(wchar_t *); i++)
        if (!wcscmp( strPropertyName, awszPropName[i]))
        {
            bFound = TRUE;  // Found the index for the property.
            break;
        }
    if ( !bFound )
        return S_FALSE;     // Requested property not found.

    // Allocate storage for the property value.
    pvarProperty->bstrVal = SysAllocString(awszPropValue[i]);
    if (NULL == pvarProperty->bstrVal)
        return E_OUTOFMEMORY;

    pvarProperty->vt = VT_BSTR;

    return S_OK;
}

Example Code [Visual Basic]

Public Function GetProperty( _
                strConfig As String, _
                strStorageLocation As String, _
                strPropertyName As String, _
                Flags As Long) As Variant
    Select Case strPropertyName
        Case "Name"
             GetProperty = "MyModule"
        Case "Description"
             GetProperty = "Description of MyModule"
        Case "Copyright"
             GetProperty = "Copyright 1999"
        Case "File Version"
             GetProperty = "1.0"
        Case "Product Version"
             GetProperty = "1.0"
        Case Else
             GetProperty = "Unknown Property: " & strPropertyName
    End Select

End Function

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certmod.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertManageModule::SetProperty, ICertConfig


ICertManageModule::SetProperty

Platform SDK: Security

ICertManageModule::SetProperty [C++]

CCertManageModule.SetProperty [Visual Basic]

The SetProperty method allows a module to set a property value.

[C++]
HRESULT SetProperty(
  BSTR const strConfig,
  BSTR strStorageLocation,
  BSTR strPropertyName,
  LONG Flags,
  const VARIANT *pvarProperty
);
[Visual Basic]
objManageModule.SetProperty( _
  strConfig As String, _
  strStorageLocation As String, _
  strPropertyName As String, _
  Flags As Long, _
  pvarProperty As Variant _
)

Parameters

[Visual Basic] objManageModule
Object expression that resolves to a CCertManageModule object.
[C++,Visual Basic] strConfig
[in] Represents the configuration string for the Certificate Services server in the form MACHINENAME\CANAME, where MACHINENAME is the Certificate Services server's network name, and CANAME is the common name of the certification authority (CA) as entered for the CA during Certificate Services setup. See ICertConfig for information about the configuration string name.
[C++,Visual Basic] strStorageLocation
[in] Location that provides storage for the property values, as described in the definition of strStorageLocation in ICertManageModule::GetProperty.
[C++,Visual Basic] strPropertyName
[in] Name of the property whose value is being assigned. Policy and exit modules should support the following properties, which are used by Certificate Services Manager.
Property name | Description
Name | Name of the module.
Description | Description of the module.
Copyright | Copyright pertaining to the module.
File Version | Version of the module file.
Product Version | Version of the module.

[C++,Visual Basic] Flags
[in] Reserved value; should be 0.
[C++,Visual Basic] pvarProperty
[in] Value which is being assigned to the property specified by strPropertyName.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success.

[Visual Basic,Java] None.

Remarks

This method is intended for future functionality. A minimal implementation is required, however, in order to meet the requirements of the ICertManageModule interface.

Example Code [C++]

HRESULT
CCertManagePolicyModule::SetProperty(
            /* [in] */ const BSTR strConfig,
            /* [in] */ BSTR strStorageLocation,
            /* [in] */ BSTR strPropertyName,
            /* [in] */ LONG Flags,
            /* [in] */ const VARIANT *pvarProperty)
{
    // This implementation fulfills the minimal requirement
    // needed for ICertManageModule::SetProperty.
    return S_OK;
}

Example Code [Visual Basic]

Public Sub SetProperty( _
                strConfig As String, _
                strStorageLocation As String, _
                strPropertyName As String, _
                Flags As Long, _
                pvarProperty As Variant)

    ' Do nothing.

End Sub

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certmod.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertManageModule::GetProperty, ICertConfig


ICertPolicy

Platform SDK: Security

ICertPolicy [C++]

CCertPolicy [Visual Basic]

The ICertPolicy interface is used by the server engine to notify the policy module that a new certificate request has arrived for consideration. The policy module can then return to the server that the request is good and should be issued, is bad and should be denied, or should be held for later consideration.

The pending request status will send a certificate into the certificate queue for consideration by the admin. Note that the admin may be automated to mark the request in some way and later resubmit the request to the policy module.

Beginning with Windows 2000, policy modules should implement both ICertPolicy and ICertManageModule.

ICertPolicy is defined in certpol.h. When you create your program, however, use certsrv.h as the include file.

The Certificate Services interfaces support only the apartment-threading model.

The following methods, listed in v-table order, are provided by the ICertPolicy interface.

Method | Description
Initialize | Called by the server engine to allow the policy module to perform initialization tasks.
VerifyRequest | Notifies the policy module that a new request has entered the system.
GetDescription | Returns a human readable description of the policy module and its function.
Shutdown | Called by the server engine before the server is terminated.

Remarks

No more than one Visual Basic policy module may be registered on the Certificate Services server at one time. If more than one such policy module is registered on the Certificate Services server, the Certification Authority MMC snap-in, Certificate Services application, or certutil command line program may produce errors. Note that the Microsoft Visual Basic development environment automatically registers a DLL when it is successfully built. As a result, you may encounter this situation when one Visual Basic policy module is already registered and another Visual Basic policy module is created. In order to avoid this situation, you must unregister one of the Visual Basic policy modules, by means of the command-line instruction 'regsvr32 /u filename.dll', where filename.dll is the name of the Visual Basic policy module that you do not intend to make active.

Note for Windows NT 4.0 In WindowsNT 4.0, you must use the value 3a428a00-7636-11d0-b413-00a0c91bbf8c for the CLSID when implementing ICertPolicy. Also, the ProgID for a class implementing ICertPolicy must conform to a naming convention. Specifically, the ProgID must be of the form:

"CertificateAuthority.Policy"

For example, in C++, the following can be used in the DECLARE_REGISTRY macro of a class (CMyCertPolicyModule) that implements ICertPolicy:

DECLARE_REGISTRY(
    CMyCertPolicyModule,
    L"CertificateAuthority.Policy.1",
    L"CertificateAuthority.Policy",
    IDS_CERTPOLICYMODULE_DESC,
    THREADFLAGS_BOTH)

For the above sample, the IDS_CERTPOLICYMODULE_DESC value is an application-specific identifier in the resource file (.rc) for a string which describes the class.

Implementers of ICertPolicy in Visual Basic must name their project in the form of

"CertificateAuthority"

and the class implementing ICertPolicy must be named "Policy".

Note for Windows 2000 Only a stand-alone certification authority should use custom policy or exit modules; when running an enterprise certification authority, the use of Microsoft-provided policy and exit modules is strongly recommended.

In Windows 2000, implementers of ICertPolicy should also implement ICertManageModule. Additionally, the ProgID for a class implementing ICertPolicy must conform to a naming convention. Specifically, the ProgID must be of the form:

"MyApp.Policy"

where MyApp is a specifier identifying the application. For example, in C++, the following could be used in the DECLARE_REGISTRY macro of a class (CMyCertPolicyModule) which implements ICertPolicy:

DECLARE_REGISTRY(
    CMyCertPolicyModule,
    L"MyCode.Policy.1",
    L"MyCode.Policy",
    IDS_CERTPOLICYMODULE_DESC,
    THREADFLAGS_BOTH)

For the above sample, the IDS_CERTPOLICYMODULE_DESC value is an application-specific identifier in the resource file (.rc) for a string which describes the class.

Implementers of ICertPolicy in Visual Basic must name their project in the form of

"MyApp"

where MyApp is a specifier identifying the application; further, the class implementing ICertPolicy must be named "Policy".

String constants defined in certmod.h may be used to simplify following the naming convention.

Constant | Value
wszCERTPOLICYMODULE_POSTFIX | TEXT(".Policy")

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certpol.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertPolicy::GetDescription

Platform SDK: Security

ICertPolicy::GetDescription [C++]

CCertPolicy.GetDescription [Visual Basic]

The GetDescription method returns a human readable description of the policy module and its function.

[C++]
HRESULT GetDescription(
  BSTR *pstrDescription
);
[Visual Basic]
objPolicy.GetDescription() As String

Parameters

[C++] pstrDescription
[out] Pointer to the BSTR representing the retrieved description.
[Visual Basic] objPolicy
Object expression that resolves to a CCertPolicy object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pstrDescription is set to the BSTR describing the policy module and its function.

[Visual Basic] Returns a string describing the policy module and its function.

Remarks

When you write custom policy modules, you should implement this functionality in your modules. The following examples are possible implementations.

Example Code [C++]

STDMETHODIMP
CCertPolicy::GetDescription(
    /* [out, retval] */ BSTR __RPC_FAR *pstrDescription)
{
    if (NULL == pstrDescription)
    {
        // Bad pointer address
        return ( E_POINTER );
    }
    if (NULL != *pstrDescription)
    {
        SysFreeString(*pstrDescription);
        *pstrDescription=NULL;
    }
    // wszMyModuleDesc defined elsewhere,
    // for example, #define wszMyModuleDesc  L"My Policy Module".
    *pstrDescription = SysAllocString(wszMyModuleDesc);
    if (NULL == *pstrDescription)
    {
        // Not enough memory
        return ( E_OUTOFMEMORY );
    }
    // Success
    return( S_OK );
}

Example Code [Visual Basic]

Public Function GetDescription() As String
    GetDescription = "My Visual Basic Policy Module"
End Function

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certpol.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertPolicy


ICertPolicy::Initialize

Platform SDK: Security

ICertPolicy::Initialize [C++]

CCertPolicy.Initialize [Visual Basic]

The Initialize method is called by the server engine to allow the policy module to perform initialization tasks.

[C++]
HRESULT Initialize(
  BSTR const strConfig
);
[Visual Basic]
objPolicy.Initialize( _
  strConfig As String _
)

Parameters

[Visual Basic] objPolicy
Object expression that resolves to a CCertPolicy object.
[C++,Visual Basic] strConfig
[in] Represents the name of the certification authority, as entered during Certificate Services setup. See ICertConfig for information about the configuration string name.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Remarks

When you write custom policy modules, you should implement this functionality in your modules. The following examples are possible implementations.

Example Code [C++]

STDMETHODIMP
CCertPolicy::Initialize(
    /* [in] */ BSTR const strConfig)
{
    // strConfig can be used by the Policy module.
    // Here, we are storing it in a BSTR member variable.
    // m_strConfig is an application-defined variable.
    m_strConfig = SysAllocString( strConfig );
    // Check to see if there was enough memory.
    if (NULL == m_strConfig)
        return ( E_OUTOFMEMORY );  // Not enough memory

    return( S_OK );
}

Example Code [Visual Basic]

Public Sub Initialize(strConfig As String)
    ' Do nothing.
End Sub

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certpol.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertPolicy, ICertConfig.


ICertPolicy::ShutDown

Platform SDK: Security

ICertPolicy::ShutDown [C++]

CCertPolicy.ShutDown [Visual Basic]

The ShutDown method is called by the server engine before the server is terminated. When ShutDown is called, the policy module should cleanup and stop. It is guaranteed that no requests will arrive after Shutdown is called.

[C++]
HRESULT ShutDown(void);
[Visual Basic]
objPolicy.ShutDown()

Parameters

[Visual Basic] objPolicy
Object expression that resolves to a CCertPolicy object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Remarks

When you write custom policy modules, you should implement this functionality in your modules. The following examples are possible implementations.

Example Code [C++]

STDMETHODIMP
CCertPolicy::ShutDown()
{
    // Clean up resources used by this process.
    MyCleanup();

    // Display message that this method has been called.
    if ( fDebug )
    {
        printf("Policy module Shutdown was called\n");
    }
    return( S_OK );
}

Example Code [Visual Basic]

Public Sub ShutDown()
    ' Do nothing.
End Sub

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certpol.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertPolicy


ICertPolicy::VerifyRequest

Platform SDK: Security

ICertPolicy::VerifyRequest [C++]

CCertPolicy.VerifyRequest [Visual Basic]

The VerifyRequest method notifies the policy module that a new request has entered the system. The policy module can then interact with that request by passing Context as a parameter when retrieving or setting properties on the request or associated certificate.

The returned disposition value indicates whether the request has been accepted, denied, or has been sent to the administration queue for later evaluation.

[C++]
HRESULT VerifyRequest(
  BSTR const strConfig,
  LONG Context,
  LONG bNewRequest,
  LONG Flags,
  LONG *pDisposition
);
[Visual Basic]
objPolicy.VerifyRequest( _
  strConfig As String, _
  Context As Long, _
  bNewRequest As Long, _
  Flags As Long _
) As Long

Parameters

[Visual Basic] objPolicy
Object expression that resolves to a CCertPolicy object.
[C++,Visual Basic] strConfig
[in] Represents the name of the certification authority, as entered during Certificate Services setup. For information about the configuration string name, see ICertConfig.
[C++,Visual Basic] Context
[in] Identifies the request and associated certificate under construction.
[C++,Visual Basic] bNewRequest
[in] If set to TRUE, specifies that the request is new. If set to FALSE, the request is being resubmitted to the policy module as a result of an ICertAdmin::ResubmitRequest call. A value of FALSE can be used to indicate that the admin wishes the request to be issued, or that request properties set by the admin should be examined. Note that TRUE is defined (in a Microsoft header file) for C/C++ programmers as 1, while Microsoft Visual Basic defines the 'True' keyword as -1. Visual Basic programmers of this method must check for 1 (instead of 'True') when examining this parameter for an intended TRUE setting. Visual Basic programmers of this method can use 0 or 'False' when examining this parameter for an intended FALSE setting. Java developers will need to use 1 for TRUE and 0 for FALSE when calling this method.
[C++,Visual Basic] Flags
[in] This parameter is reserved and must be set to 0.
[C++] pDisposition
[out] Pointer to the disposition value.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pDisposition is set to one of the values in the following table.

[Visual Basic] The return value specifies the disposition, which must be one of the following values.

Value | Meaning
VR_INSTANT_OK | The request should be issued.
VR_INSTANT_BAD | The request should be denied.
VR_PENDING | The request should be added to the admin queue.

Remarks

VerifyRequest is free to spawn off other processes or access an external database to do the request verification. If the verification requires out-of-band processing or human intervention, VerifyRequest can notify another process or leave any notice of the incoming request required. After the out-of-band processing is complete, a call to ICertAdmin::ResubmitRequest can be made, or the provided administration utility can be used to resubmit the request to the Policy Module. The policy module can examine the request again, access any necessary external data and return a value to indicate the certificate should be issued or denied.

When you write custom policy modules, you must implement VerifyRequest functionality in your modules. The following examples are possible implementations.

Example Code [C++]

STDMETHODIMP
CCertPolicy::VerifyRequest(
             BSTR const strConfig,
             LONG Context,
             LONG bNewRequest,
             LONG Flags,
             LONG __RPC_FAR *pDisposition)
{
    HRESULT            hr;
    long               nDisp = VR_INSTANT_BAD;
    ICertServerPolicy *pServer = NULL;
    BSTR               bstrPropName = NULL;
    VARIANT            varProp;

    // Verify that pointer is not NULL.
    if ( NULL == pDisposition )
    {
        hr = E_POINTER;  //E_POINTER is #defined in winerror.h
        goto error;
    }

    // Set disposition to pending.
    *pDisposition = VR_PENDING;

    // Obtain a pointer to the CertServerPolicy interface.
    hr = CoCreateInstance( CLSID_CCertServerPolicy,
                           NULL,
                           CLSCTX_INPROC_SERVER,
                           IID_ICertServerPolicy,
                           (void **) &pServer);
    if (FAILED( S_OK ))
    {
        printf("Failed CoCreateInstance for pServer - %x\n", hr );
        goto error;
    }

    // Set the context to refer to this request.
    hr = pServer->SetContext(Context);
    if (FAILED( S_OK ))
    {
        printf("Failed SetContext(%u) - %x\n", Context, hr );
        goto error;
    }

    // This policy will perform a database check on the CN.
    // Set the property name to Subject.Commonname.
    bstrPropName = SysAllocString(L"Subject.Commonname");
    if ( NULL == bstrPropName )
    {
        hr = E_OUTOFMEMORY; // #defined in winerror.h
        printf("Failed SysAllocString (no memory)\n" );
        goto error;
    }

    // Retrieve the certificate property for the CN.
    // Actual implementations may want to examine other properties.
    VariantInit( &varProp );
    hr = pServer->GetCertificateProperty( bstrPropName,
                                          PROPTYPE_STRING,
                                          &varProp );
    if (FAILED(hr))
    {
        printf("Failed GetCertificateProperty - %x\n", hr);
        goto error;
    }

    // For this simple sample, merely check CN in a database.
    // (Implementation not shown, as it is application-specific).
    hr = MyDatabaseCheck( varProp.bstrVal );
    if ( S_OK == hr )
        *pDisposition = VR_INSTANT_OK;   // Accepted.
    else
        *pDisposition = VR_INSTANT_BAD;  // Denied.

error:

    // Free resources.
    if (NULL != pServer)
        pServer->Release();

    VariantClear( &varProp );

    if ( NULL != bstrPropName )
        SysFreeString( bstrPropName );

    // Uninitialize COM.
    CoUninitialize();

    return(hr);

}

Example Code [Visual Basic]

Public Function VerifyRequest( _
             strConfig As String, _
             Context As Long, _
             bNewRequest As Long, _
             Flags As Long) As Long

    ' Go to ErrHandler for exceptions.
    On Error GoTo ErrHandler

    ' Consts for CCertServerPolicy.GetCertificateProperty().
    Const PROPTYPE_LONG = &H1
    Const PROPTYPE_DATE = &H2
    Const PROPTYPE_BINARY = &H3
    Const PROPTYPE_STRING = &H4

    ' Return values for the VerifyRequest function.
    Const VR_PENDING = 0
    Const VR_INSTANT_OK = 1
    Const VR_INSTANT_BAD = 2

    ' Object variable for CCertServerPolicy.
    Dim objSrvPol As CCertServerPolicy

    ' Variable for certificate property commonname.
    Dim varName As Variant

    ' Instantiate the CCertServerPolicy object.
    Set objSrvPol = New CCertServerPolicy

    ' Inform Cert Server of the context.
    objSrvPol.SetContext Context

    ' Retrieve the value for the subject commonname.
    varName = objSrvPol.GetCertificateProperty( _
                        "Subject.Commonname", _
                         PROPTYPE_STRING)

    ' Free resource.
    Set objSrvPol = Nothing

    ' Issue a certificate if the name is OK.
    ' MyDatabaseCheck is an application-specific
    ' routine.
    If (True = MyDatabaseCheck(varName)) Then
        VerifyRequest = VR_INSTANT_OK
    Else
        VerifyRequest = VR_INSTANT_BAD
    End If

    ' Processing complete; exit this function.
    Exit Function

ErrHandler:

    ' Display the error.
    MsgBox ("Error: " & Err.Number _
            & " " & Err.Description _
            & " " & Err.Source)

    ' Make the request pending.
    VerifyRequest = VR_PENDING

    ' Error handling complete; exit this function.
    Exit Function

End Function

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certpol.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertPolicy, ICertConfig


ICertRequest

Platform SDK: Security

ICertRequest [C++]

CCertRequest [Visual Basic,Java]

The ICertRequest interface encapsulates a single certificate request to a particular Certificate Services server. ICertRequest includes methods for submitting the request, checking the status, and retrieving the resultant certificate. In addition, the certification authority (CA) certificate for the Certificate Services server is available through this interface.

ICertRequest is defined in certcli.h. When you create your program, however, use certsrv.h as the include file. CertCli.dll provides the ICertRequest interface. In Windows 2000, the type information for this interface is also in CertCliL.dll, which is shipped with the Platform SDK.

The Certificate Services interfaces support only the apartment-threading model.

The following methods are provided by the ICertRequest interface.

Method | Description
GetCACertificate | Returns the CA certificate for the Certificate Services server.
GetCertificate | Returns the certificate issued for the request.
GetDispositionMessage | Gets a human-readable message giving the current disposition of the certificate request.
GetLastStatus | Gets the last return code for this request.
GetRequestId | Gets the current internal request number for the request and subsequent certificate.
RetrievePending | Attempts to retrieve the certificate issued for an earlier request, that may have initially been made pending.
Submit | Submits a request to the Certificate Services server.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certcli.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertRequest::GetCACertificate

Platform SDK: Security

ICertRequest::GetCACertificate [C++]

CCertRequest.GetCACertificate [Visual Basic,Java]

The GetCACertificate method returns the Certification Authority (CA) certificate for the Certificate Services server.

[C++]
HRESULT GetCACertificate(
  LONG fExchangeCertificate,
  BSTR const strConfig,
  LONG Flags,
  BSTR *pstrCertificate
);
[Visual Basic]
objRequest.GetCACertificate( fExchangeCertificate As Long, _
  strConfig As String, _
  Flags As Long ) As String
[Java]
java.lang.String GetCACertificate(
  int fExchangeCertificate,
  java.lang.String strConfig,
  int Flags
);

Parameters

[C++,Visual Basic,Java] fExchangeCertificate
[in] A boolean value specifying which certification authority (CA) certificate to return. If fExchangeCertificate is set to FALSE, the CA's signature certificate will be returned. The CA's Signature certificate can be used to verify signatures on certificates issued by the CA. For Windows 2000 or later, FALSE is the only value supported for fExchangeCertificate. For the version of Certificate Services which shipped with the Windows NT 4.0 option pack, if fExchangeCertificate is set to TRUE, the CA's Exchange certificate will be returned. The CA's Exchange certificate can be used to encrypt requests sent to the CA.

Note that TRUE is defined (in a Microsoft header file) for C/C++ programmers as 1, while Microsoft Visual Basic defines the 'True' keyword as -1. As a result, Visual Basic developers must use 1 (instead of 'True') to set this parameter to TRUE. However, to set this parameter to FALSE, Visual Basic developers can use 0 or 'False'. Java developers will need to use 1 for TRUE and 0 for FALSE when calling this method.

[C++,Visual Basic,Java] strConfig
[in] Represents a valid configuration string for the Certificate Services server in the form MACHINENAME\CANAME, where MACHINENAME is the server's network name, and CANAME is the common name of the certification authority, as entered during Certificate Services setup. See ICertConfig for information about the configuration string name.
[C++,Visual Basic,Java] Flags
[in] The following flags can be used to specify the format of the returned certificate.
Certificate Format Flag | Description
CR_OUT_BASE64HEADER | BASE64 format with begin/end.
CR_OUT_BASE64 | BASE64 format without begin/end.
CR_OUT_BINARY | Binary format.

Beginning with Certificate Services 2.0 (released with Windows 2000), the following flag can be used to specify that the complete certificate chain should be included with the requested CA certificate. Otherwise, just the requested CA certificate (in X.509 format) is returned.
Certificate Flag | Description
CR_OUT_CHAIN | Include complete certificate chain in a PKCS #7.

For example, to retrieve a binary CA certificate with complete certificate chain, in C++ you would write:

hResult = pCertReq->GetCACertificate(FALSE, bstrConfig, CR_OUT_BINARY | CR_OUT_CHAIN, &bstrCert);

In Visual Basic, you would write:

strCACert = objCertReq.GetCACertificate(0, _
"server01\myCAName", CR_OUT_BINARY Or CR_OUT_CHAIN )
[C++] pstrCertificate
[out] Pointer to the BSTR containing the CA certificate for the Certificate Services server, in the specified format.
[Visual Basic] objRequest
Object expression that resolves to an ICertRequest object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success. Upon successful completion of this function, *pstrCertificate is set to the BSTR containing the CA certificate. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable as pstrCertificate. You must free *pstrCertificate when done (by means of SysFreeString).

[Visual Basic,Java] The CA certificate for the Certificate Services server, in the specified format.

Remarks

This is an administrative task and administration tasks on Windows 2000 servers use DCOM, while Windows NT 4.0 servers use RPC. Attempts to use this method on a Windows 2000 server must be done from a computer running Windows 2000. Code calling this interface method as defined in an old version of certadm.h include file will run on both Windows NT 4.0 and Windows 2000 servers as long as the client and the server are both running Windows 2000 or both running Windows NT 4.0.

Example Code [C++]

    // Pointer to interface object.
    ICertRequest * pCertRequest = NULL;

    // Variable for machine\CAName.
    BSTR         bstrCA = NULL;

    // Variable for CA Certificate.
    BSTR         bstrCACert = NULL;

    HRESULT     hr;

    // Initialize COM.
    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    // Check status.
    if (FAILED(hr))
    {
        printf("Failed CoInitializeEx [%x]\n", hr);
        goto error;
    }

    // Instantiate the CertConfig object.
    hr = CoCreateInstance(CLSID_CCertRequest,
                          NULL,
                          CLSCTX_INPROC_SERVER,
                          IID_ICertRequest,
                          (void **)&pCertRequest);
    if (FAILED(hr))
    {
        printf("Failed CoCreateInstance pCertRequest [%x]\n", hr);
        goto error;
    }

    // Note use of two '\' in C++ to produce one '\'.
    bstrCA = SysAllocString(L"server01\\myCAName");

    // Retrieve the CA certificate.
    hr = pCertRequest->GetCACertificate(FALSE,
                                        bstrCA,
                                        CR_OUT_BASE64,
                                        &bstrCACert);
    if (FAILED(hr))
    {
        printf("Failed GetCACertificate [%x]\n", hr);
        goto error;
    }
    else
    {
        // Use CA Certificate as needed...
    }

    // Done processing.

error:

    // Free BSTR values.
    if (NULL != bstrCA)
        SysFreeString(bstrCA);

    if (NULL != bstrCACert)
        SysFreeString(bstrCACert);

    // Clean up object resources.
    if (NULL != pCertRequest)
        pCertRequest->Release();

    // Free COM resources.
    CoUninitialize();

    return hr;

Example Code [Visual Basic]

' Constants understood by GetCACertificate.
Const CR_OUT_BASE64HEADER = 0
Const CR_OUT_BASE64 = &H1
Const CR_OUT_BINARY = &H2
Const CR_OUT_CHAIN = &H100

' BASE64 example:
' Retrieve the CA certificate.
Dim strCACert As String
strCACert = objCertReq.GetCACertificate(0, _
                                        "server01\myCAName", _
                                        CR_OUT_BASE64HEADER)

' Use the CA certificate as needed.
' This sample displays the CA certificate in a message box.
MsgBox (strCACert)

' Binary example:
' If you wish to retrieve a binary certificate in Visual Basic, it is
' necessary to convert the string into a byte array.
' If you do not retrieve the certificate in this manner, the
' resulting certificate will be missing the last byte if
' an odd-number of bytes should have been returned. The following
' sample shows a work-around for this situation.

' Retrieve the CA certificate.
Dim strNewCACert As String
strNewCACert = objCertReq.GetCACertificate(0, _
                                           "server01\myCAName", _
                                           CR_OUT_BINARY)

' Determine the size of the needed array.
Dim ct As Integer
ct = LenB(strNewCACert)

' Dimension the byte array.
ReDim rgByte(ct) As Byte
' Assign the string contents to the byte array.
rgByte = strNewCACert

' Use the rgByte byte array as needed.
' ...

Example Code [Java]

// BASE64 sample.
final int CR_OUT_BASE64HEADER = 0;
final int CR_OUT_BASE64 = 0x01;
final int CR_OUT_BINARY = 0x02;
final int CR_OUT_CHAIN = 0x100;

// Declare and create an instance of the CCertRequest object.
// The CertCli library is a COM wrapper added to the project.
certcli.CCertRequest objRequest;
objRequest = new certcli.CCertRequest();
try
{
    java.lang.String strCACert;
    // Retrieve the CA certificate.
    strCACert = objCertReq.GetCACertificate(0,
                                            "server01\\myCAName",
                                            CR_OUT_BASE64);

    // Use the CA certificate; here. This example writes it to a file.
    File CACertfile = new File("d:\\myCACert.cer");
    FileOutputStream fos;
    fos = new FileOutputStream(CACertfile);
    // Array of bytes.
    byte rgByte[];
    // Convert the string to an array of bytes.
    rgByte = strCACert.getBytes();
    // Write the bytes to file.
    fos.write(rgByte);
    // Close the file.
    fos.close();
}
catch (com.ms.com.ComFailException e)
{
    System.out.println("ComFailure: " + e.getMessage());
    System.exit(-1);
}
catch (IOException e)
{
    System.out.println("IO Failure: " + e.getMessage());
}

// Free the object.
com.ms.com.ComLib.release(objRequest);
// Binary sample:
// If you wish to retrieve a binary certificate in Java, it is
// necessary to first place the certificate into a Variant, then into
// a byte array. If you do not retrieve the binary certificate in this
// manner, the resulting certificate will be missing the last byte if
// an odd-number of bytes should have been returned. The following
// sample shows a work-around for this situation.
// This Visual J++ source file will call
// CCertRequest::GetCACertificate to retrieve a binary CA
// certificate. Use the com.ms.com.Dispatch.invoke method
// in order to ensure that no bytes are lost when you are retrieving a
// string containing an odd-number of bytes.
import java.io.*;
import com.ms.com.*;

public class Class1
{
    public static void main (String[] args)
    {
        final int CR_OUT_BINARY = 0x02;

        try
        {
            // Declare and create an instance of the object.
            // The CertCli type library is a COM wrapper
            // that has been added to the project.
            certcli.CCertRequest objReq;
            objReq = new certcli.CCertRequest();

            // Declare an array for GetCACertificate's arguments.
            Object rgArg[];
            rgArg = new Object[3];

            // The first argument is for the
            // fExchangeCertificate value.
            rgArg[0] = new Integer(0);
            // The second argument is for the strConfig.
            rgArg[1] = new String("server01\\myCAName");
            // The third argument is for the Flags.
            rgArg[2] = new Integer(CR_OUT_BINARY);

            // Declare a Variant; upon success,
            // this will contain the CA certificate.
            Variant var1;
            // Retrieve the CA certificate.
            // Upon return, the Variant will be of type VT_BSTR.
            var1 = com.ms.com.Dispatch.invoke(objReq,
                                              "GetCACertificate",
                                              Dispatch.Method,
                                              rgArg,
                                              null);

            // Constants, as defined in WTypes.h.
            final int VT_ARRAY = 0x2000;
            final int VT_UI1 = 17;
            // Change the Variant type to a byte array.
            // Handled in this manner, no bytes will be lost.
            // If var1.toString() had instead been called and the
            // certificate contain an odd number of bytes, the last
            // byte would have been lost.
            var1.changeType(VT_UI1 | VT_ARRAY);
            // Place the contents of the Variant into a byte array.
            // Note that you must cast the return to a byte array.
            byte rgByte[];
            rgByte = (byte[])var1.toByteArray();

            // Write the bytes to a file.
            File CACertFile = new File("D:\\binCACert.cer");
            FileOutputStream fos;
            fos = new FileOutputStream(CACertFile);
            fos.write(rgByte);
            fos.close();

            // Release the Variant resource.
            var1.VariantClear();

            // Release the object.
            com.ms.com.ComLib.release(objReq);
        }
        catch (com.ms.com.ComFailException e)
        {
            System.out.println("ComFailure: " + e.getMessage());
        }
        catch (IOException e)
        {
            System.out.println("IOFailure: " + e.getMessage());
        }
    }
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certcli.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertConfig, ICertRequest, ICertRequest::GetCertificate


ICertRequest::GetCertificate

Platform SDK: Security

ICertRequest::GetCertificate [C++]

CCertRequest.GetCertificate [Visual Basic,Java]

The GetCertificate method returns the certificate issued for the request as an X.509 certificate, or optionally packaged in a #7 message containing the complete certificate chain for the Certificate Services server.

[C++]
HRESULT GetCertificate(
  LONG Flags,
  BSTR *pstrCertificate
);
[Visual Basic]
objRequest.GetCertificate( Flags As Long ) As String
[Java]
java.lang.String GetCertificate(
  int Flags
);

Parameters

[C++,Visual Basic,Java] Flags
[in] One of the following flags can be used to specify the format of the returned certificate.
Certificate Format Flag | Description
CR_OUT_BASE64HEADER | BASE64 format with begin/end
CR_OUT_BASE64 | BASE64 format without begin/end
CR_OUT_BINARY | Binary format

The following flag can be used to specify that the certificate chain should be included with the requested certificate, packaged as a PKCS #7 message. Otherwise, just the requested certificate (in X.509 format) is returned. Beginning with Certificate Services 2.0 (released with Windows 2000), the included certificate chain is guaranteed to be a complete chain. Earlier versions returned as much of the chain as the server was configured to understand.
Certificate Flag | Description
CR_OUT_CHAIN | Include complete certificate chain in a PKCS #7.

For example, to retrieve a binary certificate with complete certificate chain, in C++ you would write:

hResult = pCertReq->GetCertificate(CR_OUT_BINARY | CR_OUT_CHAIN, &bstrCert);

In Visual Basic, you would write:

strCACert = objCertReq.GetCertificate(CR_OUT_BINARY Or CR_OUT_CHAIN)
[C++] pstrCertificate
[out] Pointer to the BSTR containing the certificate, in the specified format.
[Visual Basic] objRequest
Object expression that resolves to an ICertRequest object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success. Upon successful completion of this function, *pstrCertificate is set to the BSTR containing the certificate for the request. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable as pstrCertificate. You must free *pstrCertificate when done (by means of SysFreeString).

[Visual Basic,Java] The certificate for the request, in the specified format.

Remarks

An application would call this method to retrieve the certificate issued by means of an earlier call to ICertRequest::Submit or ICertRequest::RetrievePending.

Example Code [C++]

    BSTR    bstrCert = NULL;
    // pCertRequest is previously instantiated ICertRequest object pointer.
    // Retrieve the certificate for the previous request.
    hr = pCertRequest->GetCertificate(CR_OUT_BASE64,
                                      &bstrCert);
    if (FAILED(hr))
    {
        printf("Failed GetCertificate [%x]\n", hr);
        goto error;
    }
    else
    {
        // Use Certificate as needed...
    }

    // Done processing.

error:

    // Free BSTR values.
    if (NULL != bstrCert)
        SysFreeString(bstrCert);
    // Free other resources, etc.

Example Code [Visual Basic]

' Constants understood by GetCertificate.
Const CR_OUT_BASE64HEADER = 0
Const CR_OUT_BASE64 = &H1
Const CR_OUT_BINARY = &H2
Const CR_OUT_CHAIN = &H100

' BASE64 example.
' Retrieve the certificate.
Dim strCert As String
strCert = objCertReq.GetCertificate(CR_OUT_BASE64 Or _
                                    CR_OUT_CHAIN)

' Binary example.
' If you wish to retrieve a binary certificate in Visual Basic, it is
' necessary to convert the string into a byte array.
' If you do not retrieve the certificate in this manner, the
' resulting certificate will be missing the last byte if
' an odd-number of bytes should have been returned. The following
' sample shows a work-around for this situation.
' Retrieve the certificate.
Dim strNewCert As String
strNewCert = objCertReq.GetCertificate(CR_OUT_BASE64HEADER Or _
                                       CR_OUT_CHAIN)

' Determine the size of the needed array.
Dim ct As Integer
ct = LenB(strNewCert)

' Dimension the byte array.
ReDim rgByte(ct) As Byte
' Assign the string contents to the byte array.
rgByte = strNewCert

' Use the rgByte byte array as needed.
' ...

Example Code [Java]

// BASE64 sample.
try
{
    // Retrieve the issued certificate.
    java.lang.String strCert;
    strCert = objCertReq.GetCertificate(CR_OUT_BASE64HEADER);

    // Use the certificate. This example writes it to a file.
    File Certfile = new File("d:\\myCert.cer");
    FileOutputStream fos;
    fos = new FileOutputStream(Certfile);
    // Array of bytes.
    byte rgByte[];
    // Convert the string to an array of bytes.
    rgByte = strCert.getBytes();
    // Write the bytes to file.
    fos.write(rgByte);
    // Close the file.
    fos.close();
}
catch (com.ms.com.ComFailException e)
{
    System.out.println("ComFailure: " + e.getMessage());
    System.exit(-1);
}
catch (IOException e)
{
    System.out.println("IO Failure: " + e.getMessage());
}
// Binary sample:
// If you wish to retrieve a binary certificate in Java, it is
// necessary to first place the certificate into a Variant, then into
// a byte array. If you do not retrieve the binary certificate in this
// manner, the resulting certificate will be missing the last byte if
// an odd-number of bytes should have been returned. The following
// sample shows a work-around for this situation.
// This Visual J++ source file will call
// CCertRequest::GetCertificate to retrieve a binary CA
// certificate. Use the com.ms.com.Dispatch.invoke method
// in order to ensure that no bytes are lost when you are retrieving a
// string containing an odd-number of bytes.
import java.io.*;
import com.ms.com.*;

public class Class1
{
    public static void main (String[] args)
    {
        final int CR_OUT_BINARY = 0x02;

        try
        {
            // This example expects arg[0] to be a request ID.
            if (0 == args.length)
            {
                throw new Exception(
                    "Include a request ID on the command line.");
            }
            Integer nReqID;
            nReqID = new Integer(args[0]);
            // Alternatively, you can hard-code nReqID's value:
            // nReqID = new Integer(1234);

            // Declare and instantiate the object.
            // The CertCli type library is a COM wrapper
            // that has been added to the project.
            certcli.CCertRequest objReq;
            objReq = new certcli.CCertRequest();

            // Retrieve the request status.
            int nDisp;
            nDisp = objReq.RetrievePending(nReqID.intValue(),
                                           "server01\\myCAName");
            // Check the disposition for the request.
            final int CR_DISP_ISSUED = 0x3;  // from CertCli.h
            if (CR_DISP_ISSUED != nDisp)
            {
                // The certificate hasn't been issued yet.
                throw new Exception(
                    "The certificate hasn't been issued yet.");
            }

            // Declare an array for GetCertificate's argument.
            Object rgArg[];
            rgArg = new Object[1];

            // The only argument is for the Request ID.
            rgArg[0] = nReqID;

            // Declare a Variant; upon success,
            // this will contain the certificate.
            Variant var1;
            // Retrieve the certificate.
            // Upon return, the Variant will be of type VT_BSTR.
            var1 = com.ms.com.Dispatch.invoke(objReq,
                                              "GetCertificate",
                                              Dispatch.Method,
                                              rgArg,
                                              null);

            // Constants, as defined in WTypes.h
            final int VT_ARRAY = 0x2000;
            final int VT_UI1 = 17;
            // Change the Variant type to a byte array.
            // Handled in this manner, no bytes will be lost.
            // If var1.toString() had instead been called and the
            // certificate contain an odd number of bytes, the last
            // byte would have been lost.
            var1.changeType(VT_UI1 | VT_ARRAY);
            // Place the Variant contents into a byte array.
            // Note you must cast the return to a byte array.
            byte rgByte[];
            rgByte = (byte[])var1.toByteArray();

            // Write the bytes to a file.
            File CertFile = new File("D:\\binCert.cer");
            FileOutputStream fos;
            fos = new FileOutputStream(CertFile);
            fos.write(rgByte);
            fos.close();

            // Release the Variant resource.
            var1.VariantClear();

            // Release the object.
            com.ms.com.ComLib.release(objReq);
        }
        catch (com.ms.com.ComFailException e)
        {
            System.out.println("ComFailure: " + e.getMessage());
        }
        catch (IOException e)
        {
            System.out.println("IOFailure: " + e.getMessage());
        }
        catch (Exception e)
        {
            System.out.println("Failure: " + e.getMessage());
        }
    }
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certcli.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertRequest, ICertRequest::GetCACertificate


ICertRequest::GetDispositionMessage

Platform SDK: Security

ICertRequest::GetDispositionMessage [C++]

CCertRequest.GetDispositionMessage [Visual Basic,Java]

The GetDispositionMessage method gets a human-readable message giving the current disposition of the certificate request. Note that the message returned here may have more detail than the returned error code. For example, ICertRequest::GetLastStatus may return an HRESULT, while GetDispositionMessage will return a detailed reason specifying why the request was denied.

[C++]
HRESULT GetDispositionMessage(
  BSTR *pstrDispositionMessage
);
[Visual Basic]
objRequest.GetDispositionMessage() As String
[Java]
java.lang.String GetDispositionMessage();

Parameters

[C++] pstrDispositionMessage
[out] Pointer to the BSTR containing the disposition message.
[Visual Basic] objRequest
Object expression that resolves to an ICertRequest object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success. Upon successful completion of this function, *pstrDispositionMessage is set to the BSTR containing a human-readable message giving the current disposition of the certificate request. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable as pstrDispositionMessage. You must free *pstrDispositionMessage when done (by means of SysFreeString).

[Visual Basic,Java] The return value is a string containing a human-readable message giving the current disposition of the certificate request.

Remarks

An application would call this method to obtain the message retrieved from the server by means of an earlier call to ICertRequest::Submit or ICertRequest::RetrievePending. Additionally, the message is stored in the Certificate Services database, and may be viewed by the Certification Authority MMC snap-in (choose the Request Disposition Message column). If the message contains localized text, it was localized on the server (based on the server's locale).

Example Code [C++]

    BSTR    bstrDispMsg = NULL;
    // pCertRequest is previously instantiated ICertRequest object pointer.
    // Retrieve the disposition message for the previous request.
    hr = pCertRequest->GetDispositionMessage(&bstrDispMsg);
    if (FAILED(hr))
    {
        printf("Failed GetDispositionMessage [%x]\n", hr);
        goto error;
    }
    else
    {
        // Use the disposition message as needed...
    }

    // Done processing.

error:

    // Free BSTR values.
    if (NULL != bstrCA)
        SysFreeString(bstrCA);

    if (NULL != bstrDispMsg)
        SysFreeString(bstrDispMsg);

Example Code [Visual Basic]

' Retrieve the disposition message.
Dim strDispMsg As String

strDispMsg = objCertReq.GetDispositionMessage()

' Use the disp msg as needed.
MsgBox (strDispMsg)

Example Code [Java]

java.lang.String strDispMsg;

// Retrieve and display the disposition message.
strDispMsg = objCertReq.GetDispositionMessage();
System.out.println(strDispMsg);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certcli.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertRequest, ICertRequest::GetLastStatus


ICertRequest::GetLastStatus

Platform SDK: Security

ICertRequest::GetLastStatus [C++]

CCertRequest.GetLastStatus [Visual Basic,Java]

The GetLastStatus method gets the last return code for this request. This returns the error code information, rather than the disposition of the request.

[C++]
HRESULT GetLastStatus(
  LONG *pStatus
);
[Visual Basic]
objRequest.GetLastStatus() As Long
[Java]
int GetLastStatus();

Parameters

[C++] pStatus
[out] Pointer to the request's status code.
[Visual Basic] objRequest
Object expression that resolves to an ICertRequest object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success. Upon successful completion of this function, *pStatus is set to the result code of the latest call to ICertRequest::Submit, ICertRequest::RetrievePending or ICertRequest::GetCACertificate.

[Visual Basic,Java] The return value is the result code of the latest call to CCertRequest.Submit, CCertRequest.RetrievePending or CCertRequest.GetCACertificate.

Remarks

The value retrieved by GetLastStatus depends on the most recent call to ICertRequest::Submit, ICertRequest::RetrievePending or ICertRequest::GetCACertificate. If a call to one of these methods fails on the server, call GetLastStatus to retrieve the error number. Some server failures (such as denied requests) return S_OK and a disposition other than CR_DISP_ISSUED from the method call, and you can use GetLastStatus to retrieve the specific cause of failure. If a call to one of these methods succeeds, then a subsequent call to GetLastStatus returns S_OK (which is zero).

Additionally, the request disposition is stored in the Certificate Services database, and can be viewed by means of the Certification Authority MMC snap-in (choose the Request Disposition column).

Example Code [C++]

HRESULT    hrServer, hr;
// pCertRequest is previously instantiated ICertRequest object pointer.
hr = pCertRequest->GetLastStatus((LONG *) &hrServer);
if (FAILED(hr))
{
    printf("Failed GetLastStatus [%x]\n", hr);
    goto error;
}
else
{
    // Use the HRESULT value as needed...
}

Example Code [Visual Basic]

Dim nLast As Long
nLast = objCertReq.GetLastStatus()

Example Code [Java]

int nLast;

// Retrieve and display the last status.
nLast = objCertReq.GetLastStatus();
System.out.println(nLast);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certcli.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertRequest, ICertRequest::Submit, ICertRequest::GetDispositionMessage


ICertRequest::GetRequestId

Platform SDK: Security

ICertRequest::GetRequestId [C++]

CCertRequest.GetRequestId [Visual Basic,Java]

The GetRequestId method gets the current internal request number for the request and subsequent certificate. This can be used to reference a request unambiguously to a server administrator, or other interface.

[C++]
HRESULT GetRequestId(
  LONG *pRequestId
);
[Visual Basic]
objRequest.GetRequestId() As Long
[Java]
int GetRequestId();

Parameters

[C++] pRequestId
[out] Pointer to the request ID value.
[Visual Basic] objRequest
Object expression that resolves to an ICertRequest object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success. Upon successful completion of this function, *pRequestId is set to the value of the request ID.

[Visual Basic,Java] The return value specifies the current internal request number for the request and subsequent certificate.

Example Code [C++]

long    nReqID;
// pCertRequest is previously instantiated ICertRequest object pointer.
// Retrieve the request ID for the previous request.
hr = pCertRequest->GetRequestId(&nReqID);
if (FAILED(hr))
{
    printf("Failed GetRequestId [%x]\n", hr);
    goto error;
}
else
{
    // Use the request ID as needed...
}

Example Code [Visual Basic]

' Retrieve the request ID.
Dim ReqID As Long

ReqID = objCertReq.GetRequestId()

' Use the request ID as needed.
MsgBox (ReqID)

Example Code [Java]

int nReqID;

// Retrieve the request ID.
nReqID = objCertReq.GetRequestId();
System.out.println("Request ID = " + nReqID);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certcli.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertRequest, ICertRequest::Submit


ICertRequest::RetrievePending

Platform SDK: Security

ICertRequest::RetrievePending [C++]

CCertRequest.RetrievePending [Visual Basic,Java]

The RetrievePending method retrieves a certificate's disposition status from an earlier request that may have previously returned CR_DISP_INCOMPLETE or CR_DISP_UNDER_SUBMISSION. If the resulting disposition status is CR_DISP_ISSUED, you can retrieve the issued certificate by calling ICertRequest::GetCertificate. If a disposition other than CR_DISP_ISSUED is returned, call ICertRequest::GetLastStatus, ICertRequest::GetDispositionMessage, or both methods to obtain further information.

[C++]
HRESULT RetrievePending(
  LONG RequestId,
  BSTR const strConfig,
  LONG *pDisposition
);
[Visual Basic]
objRequest.RetrievePending( RequestId As Long, _
  strConfig As String ) As Long
[Java]
int RetrievePending(
  int RequestId,
  java.lang.String strConfig
);

Parameters

[C++,Visual Basic,Java] RequestId
[in] The ID of the request that had previously returned CR_DISP_INCOMPLETE or CR_DISP_UNDER_SUBMISSION.
[C++,Visual Basic,Java] strConfig
[in] Represents a valid configuration string for the Certificate Services server in the form MACHINENAME\CANAME, where MACHINENAME is the server's network name, and CANAME is the common name of the certification authority, as entered during Certificate Services setup. See ICertConfig for information about the configuration string name.
[C++] pDisposition
[out] Pointer to the request's disposition value.
[Visual Basic] objRequest
Object expression that resolves to an ICertRequest object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success. Upon successful completion of this function, *pDisposition is set to one of the values in the following table.

[Visual Basic,Java] The return value specifies the disposition of the request. The disposition is one of the following values.

Return value | Meaning
CR_DISP_INCOMPLETE | Request did not complete
CR_DISP_ERROR | Request failed
CR_DISP_DENIED | Request denied
CR_DISP_ISSUED | Certificate issued
CR_DISP_ISSUED_OUT_OF_BAND | Certificate issued separately
CR_DISP_UNDER_SUBMISSION | Request taken under submission

Remarks

A successful call to this method generates an EXITEVENT_CERTRETRIEVEPENDING event. An active exit module will receive notification of this event (by means of a call to ICertExit::Notify) if the exit module specified this event when calling ICertExit::Initialize.

Example Code [C++]

BSTR    bstrCA = NULL;
long    nReqID, nDisp;

// In this example, the request ID is hard-coded.
nReqID = 1234;

// Note use of two '\' in C++ to produce one '\'.
bstrCA = SysAllocString(L"server01\\myCAName");

// pCertRequest is previously instantiated ICertRequest object pointer.
// Retrieve the status for the specified request.
hr = pCertRequest->RetrievePending( nReqID, bstrCA, &nDisp );
if (FAILED(hr))
{
    printf("Failed RetrievePending [%x]\n", hr);
    goto error;
}
else
{
    // Use the disposition value as needed...
}
// Free BSTR resource.
if ( NULL != bstrCA )
    SysFreeString( bstrCA );

Example Code [Visual Basic]

Dim nDisp, nReqID

' In this example, the Request ID is hard-coded.
nReqID = 1234
nDisp = objCertReq.RetrievePending( _
                   nReqID, _
                   "server01\myCAName")

Example Code [Java]

int nDisp, nReqID;

// Retrieve the disposition of a certificate request held pending.
// In this example, the request ID is hard-coded.
nReqID = 13;
nDisp = objCertReq.RetrievePending(nReqID,
                                   "server01\\myCAName");
System.out.println("RetrievePending returned: " + nDisp);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certcli.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertRequest, ICertConfig, ICertRequest::Submit


ICertRequest::Submit

Platform SDK: Security

ICertRequest::Submit [C++]

CCertRequest.Submit [Visual Basic,Java]

The Submit method submits a request to the Certificate Services server. If the resulting disposition status is CR_DISP_ISSUED, you can retrieve the issued certificate certificate by calling ICertRequest::GetCertificate.

[C++]
HRESULT Submit(
  LONG Flags,
  BSTR const strRequest,
  BSTR const strAttributes,
  BSTR const strConfig,
  LONG *pDisposition
);
[Visual Basic]
objRequest.Submit( Flags As Long, _
  strRequest As String, _
  strAttributes As String, _
  strConfig As String ) As Long
[Java]
int Submit(
  int Flags,
  java.lang.String strRequest,
  java.lang.String strAttributes,
  java.lang.String strConfig
);

Parameters

[C++,Visual Basic,Java] Flags
[in] Specifies the request format, type of request and whether the request is encrypted. One of the following format attribute flags can be used to specify how the request is encoded.
Format Attribute Flags | Description
CR_IN_BASE64HEADER | BASE64 format with begin/end
CR_IN_BASE64 | BASE64 format without begin/end
CR_IN_BINARY | Binary format
CR_IN_ENCODEANY | Try all of the CR_IN_BASE64HEADER, CR_IN_BASE64 or CR_IN_BINARY formats

One of the following format value flags can be used to specify the type of the request.
Format Value Flags | Description
CR_IN_PKCS7 | PKCS #7 request (renewal or registration agent)
CR_IN_PKCS10 | PKCS #10 request
CR_IN_KEYGEN | Keygen request (Netscape format)
CR_IN_FORMATANY | Try all of the CR_IN_PKCS7, CR_IN_PKCS10 or CR_IN_KEYGEN formats

[C++,Visual Basic,Java] strRequest
[in] Pointer to the string containing the certificate request.
[C++,Visual Basic,Java] strAttributes
[in] Pointer to the string containing optional extra attributes for the request. Each attribute is a name/value string pair. The colon character separates the name and value, and a newline character separates multiple name/value pairs. For example:

[C++,Java] "AttributeName1:AttributeValue1\nAttributeName2:AttributeValue2"

[Visual Basic] "AttributeName1:AttributeValue1" & vbNewLine & "AttributeName2:AttributeValue2"

When Certificate Services server parses attribute names, it ignores spaces, hyphens (minus signs), and case. For example, "AttributeName1", "Attribute Name1", and "Attribute-name1" are all equivalent. For attribute values, Certificate Services server ignores leading and trailing white space.

[C++,Visual Basic,Java] strConfig
[in] Represents a valid configuration string for the Certificate Services server in the form MACHINENAME\CANAME, where MACHINENAME is the server's network name, and CANAME is the common name of the certification authority, as entered during Certificate Services setup. See ICertConfig for information about the configuration string name.
[C++] pDisposition
[out] Pointer to the request's dispostion value.
[Visual Basic] objRequest
Object expression that resolves to an ICertRequest object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success. Upon successful completion of this function, *pDisposition is set to one of the values in the following table.

[Visual Basic,Java] The return value specifies the disposition of the request. The disposition is one of the following values.

Return value | Meaning
CR_DISP_INCOMPLETE | Request did not complete
CR_DISP_ERROR | Request failed
CR_DISP_DENIED | Request denied
CR_DISP_ISSUED | Certificate issued
CR_DISP_ISSUED_OUT_OF_BAND | Certificate issued separately
CR_DISP_UNDER_SUBMISSION | Request taken under submission

Example Code [C++]

    // Pointer to interface object.
    ICertRequest * pCertRequest = NULL;

    // variable for machine\CAName
    BSTR         bstrCA = NULL;

    // variable for request
    BSTR         bstrRequest = NULL;

    // variable for attributes
    BSTR         bstrAttribs = NULL;

    // variable for disposition code
    long        nDisp;

    HRESULT     hr;

    // Initialize COM.
    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    // Check status.
    if (FAILED(hr))
    {
        printf("Failed CoInitializeEx [%x]\n", hr);
        goto error;
    }

    // Instantiate the CertConfig object.
    hr = CoCreateInstance(CLSID_CCertRequest,
                          NULL,
                          CLSCTX_INPROC_SERVER,
                          IID_ICertRequest,
                          (void **)&pCertRequest);
    if (FAILED(hr))
    {
        printf("Failed CoCreateInstance pCertRequest [%x]\n", hr);
        goto error;
    }

    // Specify the certification authority.
    // Note use of two '\' in C++ to produce one '\'.
    bstrCA = SysAllocString(L"server01\\myCAName");

    // Create the request (not shown here) and assign to bstrRequest.
    // For instance, use ICEnroll::createPKCS10.

    // Generate the attributes. In this case, no attributes
    // are specified.
    bstrAttribs = SysAllocString(L"");

    // Submit the request.
    hr = pCertRequest->Submit(CR_IN_BASE64 | CR_IN_PKCS10,
                              bstrRequest,
                              bstrAttribs,
                              bstrCA,
                              &nDisp );
    if (FAILED(hr))
    {
        printf("Failed Submit [%x]\n", hr);
        goto error;
    }
    else
    {
        // Use the disposition value as needed...
    }

    // Done processing.

error:

    // Free BSTR values.
    if (NULL != bstrCA)
        SysFreeString(bstrCA);

    if (NULL != bstrRequest)
        SysFreeString(bstrRequest);

    if (NULL != bstrAttribs)
        SysFreeString(bstrAttribs);

    // Clean up object resources.
    if (NULL != pCertRequest)
        pCertRequest->Release();

    // Free COM resources.
    CoUninitialize();

Example Code [Visual Basic]

Const CR_IN_BASE64HEADER = 0
Const CR_IN_BASE64 = &H1
Const CR_IN_PKCS10 = &H100
Const CR_IN_KEYGEN = &H200

' Variable for CertRequest object.
' Reference the CertCli type library in the project.
Dim objCertReq As CCertRequest

' Variable for CertEnroll object.
' Reference the XEnroll type library in the project.
Dim objEnroll As CEnroll

' Instantiate the objects.
Set objCertReq = New CCertRequest
Set objEnroll = New CEnroll

' Build the DN.
' txtCN, txtOrg, txtOrgUnit, txtLocality, txtState, txtCountry,
' txtEmail are textbox controls on a Visual Basic form.
Dim strDN As String
strDN = "CN=" & txtCN.Text
strDN = strDN & ",O=" & txtOrg.Text
strDN = strDN & ",OU=" & txtOrgUnit.Text
strDN = strDN & ",L=" & txtLocality.Text
strDN = strDN & ",S=" & txtState.Text
strDN = strDN & ",C=" & txtCountry.Text
strDN = strDN & ",E=" & txtEMail.Text

' Create the PKCS10.
Dim strPKCS10 As String
strPKCS10 = objEnroll.createPKCS10( strDN, _
                                    "1.3.6.1.4.1.311.2.1.21" )

' Submit the PKCS10 to a certification authority.
Dim nDisp As Long
nDisp = objCertReq.Submit( _
                   CR_IN_BASE64 Or CR_IN_PKCS10, _
                   strPKCS10, _
                   "", _
                   "server01\myCAName")

Example Code [Java]

// Constants used by CCertRequest.Submit.
final int CR_IN_BASE64HEADER = 0;
final int CR_IN_BASE64 = 0x1;
final int CR_IN_PKCS10 = 0x100;
final int CR_IN_KEYGEN = 0x200;

// Declare and create an instance of the CCertRequest object.
// The CertCli library is a COM wrapper added to the project.
certcli.CCertRequest objCertReq;
objCertReq = new certcli.CCertRequest();
// Declare and create an instance of the CCertEnroll object.
// The Xenroll library is a COM wrapper added to the project.
xenroll.CEnroll objEnroll;
objEnroll = new xenroll.CEnroll();

// Build the distinquished name.
java.lang.String strDN;
strDN = "CN=Your Name";           // common name
strDN = strDN + ",OU=Your Unit";  // organizational unit
strDN = strDN + ",O=Your Org";    // organization
strDN = strDN + ",L=Redmond";     // locality
strDN = strDN + ",S=Washington";  // state
strDN = strDN + ",C=US";          // country/region

try
{
    // Create the PKCS10.
    java.lang.String strPKCS10;
    strPKCS10 = objEnroll.createPKCS10( strDN,
                     "1.3.6.1.4.1.311.2.1.21" );

    // Submit the PKCS10 to a certification authority.
    int nDisp;
    nDisp = objCertReq.Submit(
                       CR_IN_BASE64 | CR_IN_PKCS10,
                       strPKCS10,
                       "",
                       "server01\\myCAName");
}
catch (com.ms.com.ComFailException e)
{
    System.out.println(e.getMessage());
    System.exit(-1);
}

// Free the objects.
com.ms.com.ComLib.release(objCertReq);
com.ms.com.ComLib.release(objEnroll);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certcli.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertRequest, ICEnroll::createPKCS10, ICertConfig


ICertRequest2

[This is preliminary documentation and subject to change.]

The ICertRequest2 interface inherits all of the methods of ICertRequest and includes the following new methods.

Method | Description
GetCAProperty | Retrieves a property value from the Certification Authority (CA). This method's functionality is identical to ICertAdmin2::GetCAProperty.
GetCAPropertyDisplayName | Retrieves the display name for a property. This method's functionality is identical to ICertAdmin2::GetCAPropertyDisplayName.
GetCAPropertyFlags | Retrieves the property flags (denoting data type and indexed status) for a property. This method's functionality is identical to ICertAdmin2::GetCAPropertyFlags.
GetErrorMessageText | Retrieves message text for a given HRESULT error code.
GetIssuedCertificate | Retrieves the disposition of a certificate request.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Certcli.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertRequest2::GetCAProperty

[This is preliminary documentation and subject to change.]

The GetCAProperty method retrieves a property value for the Certification Authority (CA). This method's functionality is identical to ICertAdmin2::GetCAProperty; see ICertAdmin2::GetCAProperty for detailed information about this method.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Certcli.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertRequest2::GetCAPropertyDisplayName

[This is preliminary documentation and subject to change.]

The GetCAPropertyDisplayName method retrieves the property display name for a Certification Authority (CA) property. This method's functionality is identical to ICertAdmin2::GetCAPropertyDisplayName; see ICertAdmin2::GetCAPropertyDisplayName for detailed information about this method.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Certcli.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertRequest2::GetCAPropertyFlags

[This is preliminary documentation and subject to change.]

The GetCAPropertyFlags method retrieves the property flags for a Certification Authority (CA) property. This method's functionality is identical to ICertAdmin2::GetCAPropertyFlags; see ICertAdmin2::GetCAPropertyFlags for detailed information about this method.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Certcli.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertRequest2::GetErrorMessageText

[This is preliminary documentation and subject to change.]

The GetErrorMessageText method retrieves the error message text for an HRESULT error code. If the error message text is localized, it has been localized on the client.

HRESULT ICertRequest2::GetErrorMessageText(
  LONG hrMessage,
  LONG Flags,
  BSTR *pstrErrorMessageText
);

Parameters

hrMessage
[in] Value representing an HRESULT error.
Flags
[in] LONG value corresponding to one of the values in the following table.
Value | Description
Zero (0) | The error message text will not have the HRESULT hex and decimal values appended.
CR_GEMT_HRESULT_STRING | The error message text will have the HRESULT hex and decimal values appended.

pstrErrorMessageText
[out] Pointer to the BSTR representing the error message text for hrMessage. It is the responsibility of the caller to free the BSTR when done by calling SysFreeString.

Return Values

The return value is an HRESULT. A value of S_OK indicates the method was successful.

Example Code [C++]

BSTR    bstrErrMsgTxt = NULL;
HRESULT hr;

// Retrieve the error message text.
// The first parameter is hard-coded in this example, but
// could instead be a variable used in another method call.
hr = pCertRequest2->GetErrorMessageText(0x80070057,
                                        CR_GEMT_HRESULT_STRING,
                                        &bstrErrMsgTxt);
if (FAILED(hr))
{
    printf("Failed GetErrorMessageText\n");
    exit(1);  // Or other error action.
}

// Output the error message text.
printf("%ws\n", bstrErrMsgTxt);

// Free string when done.
SysFreeString(bstrErrMsgTxt);

Example Code [Visual Basic]

' Constant for GetErrorMessageText.
Const CR_GEMT_HRESULT_STRING As Long = &H1

' CertCli's type library is referenced in the project.
Dim objReq2 As CCertRequest
Set objReq2 = New CCertRequest

' Determine the error message text.
Dim strErrMsgTxt As String
strErrMsgTxt = objReq2.GetErrorMessageText(&H6BA, _
                                           CR_GEMT_HRESULT_STRING)

' Display the error message text.
MsgBox (strErrMsgTxt)

' When done, free the object.
Set objReq2 = Nothing

Example Code [Java]

final int CR_GEMT_HRESULT_STRING = 0x00000001;

try
{
    // Declare and and create instance of the CCertAdm object.
    certcli.CCertRequest objReq2;
    objReq2 = new certcli.CCertRequest();

    java.lang.String strErrMsgTxt;
    // Retrieve the error message text.
    strErrMsgTxt = objReq2.GetErrorMessageText(
                            0x80070057,
                            CR_GEMT_HRESULT_STRING);

    // Display the error message text.
    System.out.println(strErrMsgTxt);

    // Release the object.
    com.ms.com.ComLib.release(objReq2);

}
catch (com.ms.com.ComFailException e)
{
    System.out.println("COM error: " + e.getMessage());
}

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Certcli.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertRequest2::GetIssuedCertificate

[This is preliminary documentation and subject to change.]

The GetIssuedCertificate method is used to retrieve a certificate's disposition by specifying either the request ID or the certificate serial number. This method effectively is the same as calling ICertAdmin2::RetrievePending, with the additional capability of specifying a serial number for the certificate in question.

HRESULT ICertRequest2::GetIssuedCertificate(
  BSTR const strConfig,
  LONG RequestId,
  BSTR const strSerialNumber,
  LONG *pDisposition
);

Parameters

strConfig
[in] Represents a valid configuration string for the certification authority (CA) in the form MACHINENAME\CANAME, where MACHINENAME is the Certificate Services server's network name, and CANAME is the common name of the certification authority, as entered during Certificate Services setup. See ICertConfig for information about the configuration string name.
RequestId
[in] LONG value representing the certificate request ID in the Certificates Services database. Use -1 for this value if the serial number (passed in as strSerialNumber) is to be used instead of the request ID.
strSerialNumber
[in] BSTR value representing the certificate serial number, as issued by the CA. You must specify a value of -1 for RequestId in order for strSerialNumber to be used.
pDisposition
[out] Pointer to LONG value representing the certificate's disposition. The disposition is one of the following values.
Disposition Value | Meaning
CR_DISP_DENIED | Request denied.
CR_DISP_ERROR | Request failed.
CR_DISP_INCOMPLETE | Request did not complete.
CR_DISP_ISSUED | Certificate issued.
CR_DISP_ISSUED_OUT_OF_BAND | Certificate issued separately.
CR_DISP_UNDER_SUBMISSION | Request taken under submission.

Return Values

The return value is an HRESULT. A value of S_OK indicates the method was successful.

Example Code [C++]

// BSTR for certificate serial number.
BSTR    bstrSerial = SysAllocString(L"1234567890123456");

LONG    nDisp;   // For certificate disposition
HRESULT hr;

// Retrieve the status for the specified request.
hr = pCertRequest2->GetIssuedCertificate(bstrCA,
                                         -1,
                                         bstrSerial,
                                         &nDisp );
if (FAILED(hr))
{
    printf("Failed GetIssuedCertificate\n");
    exit(1);  // Or other error action as needed.
}
else
{
    // Check disposition value.
    if (CR_DISP_ISSUED == nDisp)
    {
        // The certificate was issued.
        // Call GetCertificate to get the certificate.
        // ...
    }
}

// Free BSTR.
SysFreeString(bstrSerial);

Example Code [Visual Basic]

' Constants for GetIssuedCertificate.
Const CR_DISP_INCOMPLETE As Long = 0
Const CR_DISP_ERROR As Long = &H1
Const CR_DISP_DENIED As Long = &H2
Const CR_DISP_ISSUED As Long = &H3
Const CR_DISP_ISSUED_OUT_OF_BAND As Long = &H4
Const CR_DISP_UNDER_SUBMISSION As Long = &H5
Const CR_DISP_REVOKED As Long = &H6

' CertCli's type library is referenced in the project.
Dim objReq2 As CCertRequest
Set objReq2 = New CCertRequest

' Retrieve the disposition of a certificate.
' This example will use the serial number.
Dim nDisp As Long
nDisp = objReq2.GetIssuedCertificate("SERVER01\MyCA", _
                                     -1, _
                                     "0B4C655E000000000004")
If (CR_DISP_ISSUED = nDisp) Then
    ' The certificate has been issued.
    ' Call GetCertificate to retrieve it.
    ' ...
End If

' When done, free the object.
Set objReq2 = Nothing

Example Code [Java]

// Constants for GetIssuedCertificate.
final int CR_DISP_INCOMPLETE = 0x00000000;
final int CR_DISP_ERROR = 0x00000001;
final int CR_DISP_DENIED = 0x00000002;
final int CR_DISP_ISSUED = 0x00000003;
final int CR_DISP_ISSUED_OUT_OF_BAND = 0x00000004;
final int CR_DISP_UNDER_SUBMISSION = 0x00000005;
final int CR_DISP_REVOKED = 0x00000006;

try
{
    // Declare and and create instance of the CCertAdm object.
    certcli.CCertRequest objReq2;
    objReq2 = new certcli.CCertRequest();

    int nDisp;
    // Retrieve the status for the specified certificate.
    nDisp = objReq2.GetIssuedCertificate(
                    "\\\\SERVER01\\MyCA",
                    -1,
                    "0B4C655E000000000004");

    if (CR_DISP_ISSUED == nDisp)
    {
        // The certificate has been issued and is still valid.
        // Use GetCertificate to retrieve it.
        // ...
    }

    // Release the object.
    com.ms.com.ComLib.release(objReq2);

}
catch (com.ms.com.ComFailException e)
{
    System.out.println("COM error: " + e.getMessage());
}

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Certcli.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertServerExit

Platform SDK: Security

ICertServerExit [C++]

CCertServerExit [Visual Basic]

The ICertServerExit interface is exported by the server engine and is called by exit modules. ICertServerExit allows exit modules to get and enumerate elements of requests and certificates.

ICertServerExit is defined in certif.h. When you create your program, however, use certsrv.h as the include file. CertCli.dll provides the ICertServerExit interface. In Windows 2000, the type information for this interface is also in CertCliL.dll, which is shipped with the Platform SDK.

The Certificate Services interfaces support only the apartment-threading model.

The following methods are provided by the ICertServerExit interface.

Method | Description
EnumerateAttributes | Returns the name of the next request attribute to be enumerated.
EnumerateAttributesClose | Frees any resources connected with attribute enumeration.
EnumerateAttributesSetup | Initializes the internal enumeration pointer to the first attribute associated with the current context.
EnumerateExtensions | Returns the object identifier (OID) of the next certificate extension to be enumerated.
EnumerateExtensionsClose | Frees any resources connected with extension enumeration.
EnumerateExtensionsSetup | Initializes the internal enumeration pointer to the first certificate extension associated with the current context.
GetCertificateExtension | Gets a specified certificate extension.
GetCertificateExtensionFlags | Gets the flags from the extension acquired by the most recent call to GetCertificateExtension.
GetCertificateProperty | Returns a named certificate property.
GetRequestAttribute | Returns a named request attribute.
GetRequestProperty | Returns a named request property.
SetContext | Sets the current instantiation of the interface to operate on the specified request context.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertServerExit::EnumerateAttributes

Platform SDK: Security

ICertServerExit::EnumerateAttributes [C++]

CCertServerExit.EnumerateAttributes [Visual Basic]

The EnumerateAttributes method returns the name of the next request attribute within the current context, then increments the internal pointer to the following attribute. Before calling EnumerateAttributes, an application calls ICertServerExit::EnumerateAttributesSetup. When done enumerating, an application calls ICertServerExit::EnumerateAttributesClose.

[C++]
HRESULT EnumerateAttributes(
  BSTR *pstrAttributeName
);
[Visual Basic]
objServerExit.EnumerateAttributes() As String

Parameters

[C++] pstrAttributeName
[out] Pointer to the enumerated attribute name.
[Visual Basic] objServerExit
Object expression that resolves to an ICertServerExit object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pstrAttributeName is set to the BSTR containing the name of the enumerated attribute. A value of S_FALSE is returned if the last attribute was already enumerated. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable as pstrAttributeName. You must free *pstrAttributeName when done (by means of SysFreeString).

[Visual Basic] Returns a string specifying the name of the enumerated attribute, or an empty string if the last attribute was already enumerated.

Example Code [C++]

BSTR     bstrAttrib = NULL;
BSTR     bstrAttValue = NULL;
HRESULT  hr;

// Enumerate the attributes.
while (S_OK==
    (hr=pCertServerExit->EnumerateAttributes(&bstrAttrib)))
{
  // Retrieve the attribute value.
  if (FAILED(pCertServerExit->GetRequestAttribute(
                              bstrAttrib,
                              &bstrAttValue)))
       printf("Failed GetRequestAttributes\n");
  else
       printf("Attribute: %ws\tValue: %ws\n",
               bstrAttrib,
               bstrAttValue);
}
// Determine if hr was S_FALSE, meaning the enumeration
// was completed, or some other error.
if (S_FALSE != hr)
    printf("Failed EnumerateAttributes - %x\n", hr);
// Free BSTR resources.
if (NULL != bstrAttrib)
    SysFreeString(bstrAttrib);
if (NULL != bstrAttValue)
    SysFreeString(bstrAttValue);

Example Code [Visual Basic]

objSrvExit.EnumerateAttributesSetup 0

' Retrieve an attribute ID.
Dim strAttribID As String
strAttribID = objSrvExit.EnumerateAttributes()
Do
    ' Check to see if enumeration is done.
    If ("" = strAttribID) Then
      Exit Do
    End If
    ' Retrieve the value associated with this attribute ID.
    Dim varAttrib As Variant
    varAttrib = objSrvExit.GetRequestAttribute(strAttribID)
    ' Use the attribute ID and value as needed.

    ' Get the next attribute.
    strAttribID = objSrvExit.EnumerateAttributes()
Loop

objSrvExit.EnumerateAttributesClose

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerExit, ICertServerExit::EnumerateAttributesClose, ICertServerExit::EnumerateAttributesSetup, ICertServerExit::GetRequestAttribute


ICertServerExit::EnumerateAttributesClose

Platform SDK: Security

ICertServerExit::EnumerateAttributesClose [C++]

CCertServerExit.EnumerateAttributesClose [Visual Basic]

The EnumerateAttributesClose method frees any resources connected with attribute enumeration. All applications that use ICertServerExit::EnumerateAttributesSetup or ICertServerExit::EnumerateAttributes should call EnumerateAttributesClose when finished enumerating.

[C++]
HRESULT EnumerateAttributesClose(void);
[Visual Basic]
objServerExit.EnumerateAttributesClose()

Parameters

[Visual Basic] objServerExit
Object expression that resolves to an ICertServerExit object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Example Code [C++]

// Close the enumeration.
// hr is defined as an HRESULT.
hr = pCertServerExit->EnumerateAttributesClose();
if (FAILED(hr))
{
    printf("Failed EnumerateAttributesClose [%x]\n", hr);
    goto error;
}

Example Code [Visual Basic]

' Close the enumeration.
objSrvExit.EnumerateAttributesClose

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerExit, ICertServerExit::EnumerateAttributes, ICertServerExit::EnumerateAttributesSetup


ICertServerExit::EnumerateAttributesSetup

Platform SDK: Security

ICertServerExit::EnumerateAttributesSetup [C++]

CCertServerExit.EnumerateAttributesSetup [Visual Basic]

The EnumerateAttributesSetup method initializes the internal enumeration pointer to the first request attribute associated with the current context.

[C++]
HRESULT EnumerateAttributesSetup(
  LONG Flags
);
[Visual Basic]
objServerExit.EnumerateAttributesSetup( Flags As Long )

Parameters

[C++,Visual Basic] Flags
[in] This parameter is reserved and must be set to 0.
[Visual Basic] objServerExit
Object expression that resolves to an ICertServerExit object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Remarks

You must call ICertServerExit::SetContext prior to using this method.

Example Code [C++]

// Set up the enumeration.
hr = pCertServerExit->EnumerateAttributesSetup(0);
if (FAILED(hr))
{
    printf("Failed EnumerateAttributesSetup [%x]\n", hr);
    goto error;
}

Example Code [Visual Basic]

' Set up the enumeration.
objSrvExit.EnumerateAttributesSetup 0

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerExit, ICertServerExit::EnumerateAttributes, ICertServerExit::EnumerateAttributesSetup


ICertServerExit::EnumerateExtensions

Platform SDK: Security

ICertServerExit::EnumerateExtensions [C++]

CCertServerExit.EnumerateExtensions [Visual Basic]

The EnumerateExtensions method returns the OID string (also known as the extension name) of the next certificate extension to be enumerated, then increments the internal pointer to the following extension. Before calling EnumerateExtensions, an application calls ICertServerExit::EnumerateExtensionsSetup. When done enumerating, an application calls ICertServerExit::EnumerateExtensionsClose.

[C++]
HRESULT EnumerateExtensions(
  BSTR *pstrExtensionName
);
[Visual Basic]
objServerExit.EnumerateExtensions() As String

Parameters

[C++] pstrExtensionName
[out] Pointer to the enumerated extension name.
[Visual Basic] objServerExit
Object expression that resolves to an ICertServerExit object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pstrExtensionName is set to the BSTR containing the name of the enumerated extension. A value of S_FALSE is returned if the last extension was already enumerated. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable as pstrExtensionName. You must free *pstrExtensionName when done (by means of SysFreeString).

[Visual Basic] Returns a string specifying the name of the enumerated extension, or an empty string if the last extension was already enumerated.

Remarks

This method enumerates certificate extensions recorded in the database, even those that are disabled and do not appear in the certificate. To see if an extention is disabled, use ICertServerExit::GetCertificateExtensionFlags to test the the extension's EXTENSION_DISABLE_FLAG bit.

Example Code [C++]

BSTR     bstrExt = NULL;
VARIANT  varExt;
LONG     ExtFlags;
HRESULT  hr;

VariantInit(&varExt);

// Enumerate the extensions.
while (S_OK==
      (hr=pCertServerExit->EnumerateExtensions(&bstrExt)))
{
  // Retrieve the extension data.
  if (FAILED(pCertServerExit->GetCertificateExtension(
                              bstrExt,
                              PROPTYPE_BINARY,
                              &varExt)))
      printf("Failed GetCertificateExtension\n");
  else
  {
     // Retrieve the extension flags.
    if (FAILED(pCertServerExit->GetCertificateExtensionFlags(
                                &ExtFlags)))
        printf("Failed GetCertificateExtensionFlags\n");
    else
        // This sample will display the extension OID string,
        // the extension flags (in hex) and
        // the length of the BSTR binary ASN-encode extension.
        printf("Extension: %ws\tFlags:%x\tLength:%u\n",
               bstrExt,
               ExtFlags,
               SysStringByteLen(varExt.bstrVal));
  }
}
// Determine if hr was S_FALSE, meaning the enumeration
// was completed, or some other error.
if (S_FALSE != hr)
    printf("Failed EnumerateExtensions - %x\n", hr);
// Free BSTR resource.
if (NULL != bstrExt)
    SysFreeString(bstrExt);
// Free VARIANT resource.
    VariantClear(&varExt);

Example Code [Visual Basic]

objSrvExit.EnumerateExtensionsSetup 0

' Enumerate the extensions.
Dim strExt As String
strExt = objSrvExit.EnumerateExtensions()
Do
    If ("" = strExt) Then
        Exit Do
    End If
    ' Use the extension as neeeded.

    ' Retrieve the next extension.
    strExt = objSrvExit.EnumerateExtensions()
Loop

objSrvExit.EnumerateExtensionsClose

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerExit, ICertServerExit::EnumerateExtensionsClose, ICertServerExit::EnumerateExtensionsSetup, ICertServerExit::GetCertificateExtension, ICertServerExit::GetCertificateExtensionFlags


ICertServerExit::EnumerateExtensionsClose

Platform SDK: Security

ICertServerExit::EnumerateExtensionsClose [C++]

CCertServerExit.EnumerateExtensionsClose [Visual Basic]

The EnumerateExtensionsClose method frees any resources connected with extension enumeration. All applications that use ICertServerExit::EnumerateExtensionsSetup ICertServerExit::EnumerateExtensions should call EnumerateExtensionsClose when finished enumerating.

[C++]
HRESULT EnumerateExtensionsClose(void);
[Visual Basic]
objServerExit.EnumerateExtensionsClose()

Parameters

[C++] None.

[Visual Basic] objServerExit
Object expression that resolves to an ICertServerExit object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Example Code [C++]

// Close the enumeration.
// hr is defined as an HRESULT.
hr = pCertServerExit->EnumerateExtensionsClose();
if (FAILED(hr))
{
    printf("Failed EnumerateExtensionsClose [%x]\n", hr);
    goto error;
}

Example Code [Visual Basic]

' Close the enumeration.
objSrvExit.EnumerateExtensionsClose

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerExit, ICertServerExit::EnumerateExtensionsSetup, ICertServerExit::EnumerateExtensions


ICertServerExit::EnumerateExtensionsSetup

Platform SDK: Security

ICertServerExit::EnumerateExtensionsSetup [C++]

CCertServerExit.EnumerateExtensionsSetup [Visual Basic]

The EnumerateExtensionsSetup method initializes the internal enumeration pointer to the first certificate extension associated with the current context. The enumeration process enumerates certificate extensions recorded in the database, even those that are disabled and do not appear in the certificate.

[C++]
HRESULT EnumerateExtensionsSetup(
  LONG Flags
);
[Visual Basic]
objServerExit.EnumerateExtensionsSetup( Flags As Long )

Parameters

[C++,Visual Basic] Flags
[in] This parameter is reserved and must be set to 0.
[Visual Basic] objServerExit
Object expression that resolves to an ICertServerExit object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Remarks

You must call ICertServerExit::SetContext before using this method.

Example Code [C++]

// Set the context. The value nContext (long) would be the same
// as the context parameter in ICertExit::Notify.
// hr is defined as an HRESULT.
hr = pCertServerExit->SetContext( nContext );
if (FAILED(hr))
{
    printf("Failed SetContext [%x]\n", hr);
    goto error;
}

// Setup the enumeration.
hr = pCertServerExit->EnumerateExtensionsSetup( 0 );
if (FAILED(hr))
{
    printf("Failed EnumerateExtensionsSetup [%x]\n", hr);
    goto error;
}

Example Code [Visual Basic]

' Set up the enumeration.
objSrvExit.EnumerateExtensionsSetup 0

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerExit, ICertServerExit::EnumerateExtensions, ICertServerExit::EnumerateExtensionsClose


ICertServerExit::GetCertificateExtension

Platform SDK: Security

ICertServerExit::GetCertificateExtension [C++]

CCertServerExit.GetCertificateExtension [Visual Basic]

The GetCertificateExtension method gets a specified certificate extension. Note that certificate extensions are distinct from certificate properties. Properties are generic data attached to the request object. Some of these properties are encoded into the certificate (example: BeginDate), while others are just used to mark requests in the queue and log. Extensions that are not disabled are encoded into the certificate. Extensions are always marked with an object identifier, and always have a critical/non-critical flag.

[C++]
HRESULT GetCertificateExtension(
  const BSTR strExtensionName,
  LONG Type,
  VARIANT *pvarValue
);
[Visual Basic]
objServerExit.GetCertificateExtension( strExtensionName As String, _
  Type As Long ) As Variant

Parameters

[C++,Visual Basic] strExtensionName
[in] A string specifying the name of the extension.
[C++,Visual Basic] Type
[in] Specifies the type of the extension. The type can be one of the following types.
Type | Description
PROPTYPE_LONG | Signed Long data
PROPTYPE_DATE | Date / Time
PROPTYPE_BINARY | Binary data
PROPTYPE_STRING | Unicode String data

[C++] pvarValue
[out] Pointer to a Variant that receives the requested extension value.
[Visual Basic] objServerExit
Object expression that resolves to an ICertServerExit object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pvarValue is set to a VARIANT containing the extension value.

[Visual Basic] The return value is the requested extension value.

Remarks

You must call ICertServerExit::SetContext prior to using this method.

Example Code [C++]

VARIANT  varExt;
HRESULT  hr;

VariantInit(&varExt);
// Get the Extension value
// bstrExtName is BSTR assigned by EnumerateExtensions.
// pCertServerExit has been used to call SetContext previously.
hr = pCertServerExit->GetCertificateExtension(bstrExtName,
                                              PROPTYPE_BINARY,
                                              &varExt);

if (FAILED(hr))
{
    printf("Failed GetCertificateExtension [%x]\n", hr);
    goto error;
}
// Successful call; Use the value in varExt as needed.
// ...

// When done, clear the Variant
VariantClear(&varExt);

Example Code [Visual Basic]

'Constants used by GetCertificateExtension.
Const PROPTYPE_LONG = &H1
Const PROPTYPE_DATE = &H2
Const PROPTYPE_BINARY = &H3
Const PROPTYPE_STRING = &H4

Dim varExt As Variant

' Retrieve the extension value.
' strExt was set by an earlier call to
' CCertServerExit.EnumerateExtensions.
' objSrvExit has been used to call SetContext previously.
varExt = objSrvExit.GetCertificateExtension(strExt, _
                                            PROPTYPE_BINARY)

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerExit, ICertServerExit::GetCertificateExtensionFlags, ICertServerExit::SetContext


ICertServerExit::GetCertificateExtensionFlags

Platform SDK: Security

ICertServerExit::GetCertificateExtensionFlags [C++]

CCertServerExit.GetCertificateExtensionFlags [Visual Basic]

The GetCertificateExtensionFlags method gets the flags from the extension acquired by the most recent call to ICertServerExit::GetCertificateExtension.

[C++]
HRESULT GetCertificateExtensionFlags(
  LONG *pExtFlags
);
[Visual Basic]
objServerExit.GetCertificateExtensionFlags() As Long

Parameters

[C++] pExtFlags
[out] Pointer to a Long variable which will contain the extension flags.
[Visual Basic] objServerExit
Object expression that resolves to an ICertServerExit object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pExtFlags is set to the value containing the flags from the extension acquired by the most recent call to ICertServerExit::GetCertificateExtension.

[Visual Basic] The return value is the flags from the extension acquired by the most recent call to ICertServerExit::GetCertificateExtension.

Remarks

There are two kinds of flags used in extensions; policy flags and origin flags.

Flag type | Explanation
Policy | Provides information about the certificate extension. Policy flags can be set by the policy module.
Origin | Indicates the module that set the certificate extension. Origin flags are only set by the server engine.

One or more policy flags can be returned from an extension. The following are predefined policy flags.

Policy flag value | Explanation
EXTENSION_CRITICAL_FLAG | This is a critical extension.
EXTENSION_DISABLE_FLAG | Extension will not be used.

One of the following origin flags can also be returned.

Origin flag value | Explanation
EXTENSION_ORIGIN_REQUEST | The extension was extracted from an array of extensions stored in the szOID_CERT_EXTENSIONS (1.3.6.1.4.1.311.2.1.14) or szOID_RSA_certExtensions (1.2.840.113549.1.9.14) attribute of a PKCS #10 request.
EXTENSION_ORIGIN_POLICY | Policy module set the extension.
EXTENSION_ORIGIN_ADMIN | Admin set the extension. See ICertAdmin::SetCertificateExtension
EXTENSION_ORIGIN_SERVER | Server engine set the extension.
EXTENSION_ORIGIN_RENEWALCERT | The extension was extracted from the certificate stored in the szOID_RENEWAL_CERTIFICATE (1.3.6.1.4.1.311.13.1) attribute of a PKCS #10 renewal request.
EXTENSION_ORIGIN_IMPORTEDCERT | The extension was extracted from an imported certificate (the certificate was passed to ICertAdmin::ImportCertificate).
EXTENSION_ORIGIN_PKCS7 | The extension was extracted from an array of extensions stored in the szOID_CERT_EXTENSIONS (1.3.6.1.4.1.311.2.1.14) or szOID_RSA_certExtensions (1.2.840.113549.1.9.14) attribute of a PKCS #7 request.

Pre-defined masks are provided for ease of use in determining which flags are set in the return value. The following masks are provided.

Mask Value | Explanation
EXTENSION_POLICY_MASK | This value (0x0000FFFF) is used to examine policy flags.
EXTENSION_ORIGIN_MASK | This value (0x000F0000) is used to examine origin flags.

It is safe to use the high 8 bits of EXTENSION_POLICY_MASK for custom data. These bits will be saved persistently in the database but will not be written to the certificate extensions.

You must call ICertServerExit::SetContext prior to using this method.

Example Code [C++]

HRESULT  hr;
LONG     ExtFlags;

// pCertServerExit has been used to call SetContext previously.
hr = pCertServerExit->GetCertificateExtensionFlags(&ExtFlags);

// More than one policy flag may be set.
LONG ExtPolicyFlags = ExtFlags & EXTENSION_POLICY_MASK;

if (ExtPolicyFlags & EXTENSION_CRITICAL_FLAG)
{
    // Perform the desired operation.
}

if (ExtPolicyFlags & EXTENSION_DISABLE_FLAG)
{
    // Perform the desired operation.
}

// Only one origin flag can be set.
switch (ExtFlags & EXTENSION_ORIGIN_MASK)
{
    case EXTENSION_ORIGIN_REQUEST:
        // Extension was set in certificate request.
        break;
    case EXTENSION_ORIGIN_POLICY:
        // Extension was set by policy module.
        break;
    case EXTENSION_ORIGIN_ADMIN:
        // Extension was set by admin.
        break;
    case EXTENSION_ORIGIN_SERVER:
        // Extension was set by server engine.
        break;
    case EXTENSION_ORIGIN_RENEWALCERT:
        // Extension was set by renewal certificate.
        break;
    case EXTENSION_ORIGIN_IMPORTEDCERT:
        // Extension was set by imported certificate.
        break;
    case EXTENSION_ORIGIN_PKCS7:
        // Extension was set by PKCS7.
        break;
    default:
        break;
}

Example Code [Visual Basic]

' Constants used by GetCertificateExtensionFlags.
Const EXTENSION_CRITICAL_FLAG = &H1
Const EXTENSION_DISABLE_FLAG = &H2
Const EXTENSION_POLICY_MASK = &HFFFF
Const EXTENSION_ORIGIN_REQUEST = &H10000
Const EXTENSION_ORIGIN_POLICY = &H20000
Const EXTENSION_ORIGIN_ADMIN = &H30000
Const EXTENSION_ORIGIN_SERVER = &H40000
Const EXTENSION_ORIGIN_RENEWALCERT = &H50000
Const EXTENSION_ORIGIN_IMPORTEDCERT = &H60000
Const EXTENSION_ORIGIN_PKCS7 = &H70000
Const EXTENSION_ORIGIN_MASK = &HF0000

' Retrieve the extension flags.
Dim ExtFlags As Long
' objSrvExit has been used to call SetContext previously.
ExtFlags = objSrvExit.GetCertificateExtensionFlags()

' Examine the criticality and enabledness.
Dim ExtPol As Long
ExtPol = ExtFlags And EXTENSION_POLICY_MASK
If (ExtPol And EXTENSION_CRITICAL_FLAG) Then
        ' The extension is critical.
        ' ...
End If

If (ExtPol And EXTENSION_DISABLE_FLAG) Then
        ' The extension is disabled.
        ' ...
End If

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerExit::GetCertificateExtension, IEnumCERTVIEWEXTENSION::GetFlags, ICertAdmin::SetCertificateExtension


ICertServerExit::GetCertificateProperty

Platform SDK: Security

ICertServerExit::GetCertificateProperty [C++]

CCertServerExit.GetCertificateProperty [Visual Basic]

The GetCertificateProperty method returns a named property from a certificate.

[C++]
HRESULT GetCertificateProperty(
  const BSTR strPropertyName,
  LONG PropertyType,
  VARIANT *pvarPropertyValue
);
[Visual Basic]
objServerExit.GetCertificateProperty( _
  strPropertyName As String, _
  PropertyType As Long ) As Variant

Parameters

[C++,Visual Basic] strPropertyName
[in] Specifies the named property to retrieve. There is a stock set of certificate properties, referred to as the name properties, that are always valid and can be retrieved by calling this method. For information about these properties, see Name Properties. Other properties that can be retrieved include the certificate properties.

Certificate Properties

The following properties are unique to certificates and can be read by GetCertificateProperty.
Property Name | Data Type | Description
NotBefore | Date / Time | Certificate start validity date
NotAfter | Date / Time | Certificate expiration date
PublicKeyAlgorithm | String | Subject key algorithm object identifier (OID)
RawCertificate | Binary | Raw certificate bytes
RawPublicKey | Binary | Subject key
RawPublicKeyAlgorithmParameters | Binary | Subject key algorithm parameters
RequestID | Signed Long | Internal request ID
SerialNumber | String | Certificate serial number

The certificate's DistinguishedName, RawName and SerialNumber properties are accessible by ICertServerExit::GetCertificateProperty only after the policy module has finished processing the request and the certificate is issued.

The following properties apply to the certification authority.
Property Name | Data Type | Description
CAType Long Type of certification authority (CA). Can be one of the following values (defined in certsrv.h):

ENUM_ENTERPRISE_ROOTCA

ENUM_ENTERPRISE_SUBCA

ENUM_STANDALONE_ROOTCA

ENUM_STANDALONE_SUBCA
CertCount | Long | Number of CA certificates. This value will be 1 plus the number of times that the CA has been renewed. For information on renewal, see Certification Authority Renewal.
CertState * Long CA certificate state. Can be one of the following values/meanings:

CA_DISP_ERROR: The CA certificate was never issued.

CA_DISP_REVOKED: The CA certificate has been revoked.

CA_DISP_VALID: The CA certificate is still valid.

CA_DISP_INVALID: The CA certificate has expired.
CertSuffix * | String | Suffix for the CA certificate. The suffix is an empty string for CA certificates with an index of 0; otherwise, the suffix (in the form of "(nn)", where nn is the certificate index) is applied to all URLs pointing to CA certificates stored in files or directory service objects. For non-LDAP URLs, the suffix typically appears before the ".crt" text. For LDAP URLs, the suffix is typically appended to the first 'CN=' in the full distinguished name.
CRLIndex * | Long | Certificate revocation list (CRL) index. Appending a certificate index to this property name allows you to retrieve the CRL index. The CRL index does not necessarily match the certificate index. For details, see Certification Authority Renewal.
CRLState * Long CRL state. Can be one of the following values:

CA_DISP_ERROR: The CRL is managed by another CA certificate.

CA_DISP_REVOKED: All unexpired CA certificates using this CA certificate's CRL have been revoked.

CA_DISP_VALID: The CA certificate is still being used to publish CRLs as needed.

CA_DISP_INVALID: All CA certificates using this CA certificate's CRL are expired.
CRLSuffix * | String | Suffix for the CA CRL. The suffix is an empty string for CRLs with an index of 0; otherwise, the suffix (in the form of "(nn)", where nn is the CRL index) is applied to all URLs pointing to CRLs stored in files or directory service objects. For non-LDAP URLs, the suffix typically appears before the ".crl" text. For LDAP URLs, the suffix typically is appended to the first 'CN=' in the full distinguished name.
fUseDS Long Indicates whether the CA uses a directory service. Can be either of the following values:

0=no
1=yes
MachineDNSName | String | DNS name of server hosting the CA.
ModuleRegistryLocation | String | Registry location available for use by the module.
RawCACertificate * | Binary | CA certificate.
RawCRL * | Binary | CA's certificate revocation list (CRL).
RequesterCAAccess Long Indicates whether the requester is authorized to request the certificate. Can be either of the following values:

0=no
1=yes

(The MMC snap-in for Certification Authority can be used to control certificate request permissions.)
SanitizedCAName | String | Sanitized name for the CA. For details about sanitized CA names, see ICertConfig::GetConfig.
SanitizedShortName | String | Sanitized name for the CA, shortened and containing a hash value to ensure uniqueness.

Note that an asterisk (*) indicates that this property name may be appended with '.#', where # represents a CA certificate index (or, in the case of the CRLSuffix property, a CRL index). For information about certificate and CRL indices, see Certification Authority Renewal.

[C++,Visual Basic] PropertyType
[in] Specifies the property type. The type can be one of the following.
Type Specifier | Data Type
PROPTYPE_LONG | Signed Long data
PROPTYPE_DATE | Date / Time
PROPTYPE_BINARY | Binary data
PROPTYPE_STRING | Unicode String data

[C++] pvarPropertyValue
[out] Pointer to VARIANT which will contain the property value.
[Visual Basic] objServerExit
Object expression that resolves to an ICertServerExit object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pvarPropertyValue is set to the Variant containing the requested property value.

[Visual Basic] The return value is the requested property value.

Remarks

You must call ICertServerExit::SetContext prior to using this method.

Example Code [C++]

BSTR    bstrPropName = NULL;
VARIANT varProp;

VariantInit(&varProp);

// Set the property name to RequestID.
bstrPropName = SysAllocString(L"RequestID");

// Retrieve the certificate property.
// pCertServerExit has been used to call SetContext previously.
hr = pCertServerExit->GetCertificateProperty(bstrPropName,
                                             PROPTYPE_LONG,
                                             &varProp );
if (FAILED(hr))
{
    printf("Failed GetCertificateProperty [%x]\n", hr);
    goto error;
}
else
{
    // Successfully retrieved property; use varProp as needed.
    // ...
}

// Done processing.
if (NULL != bstrPropName)
    SysFreeString(bstrPropName);
VariantClear(&varProp);

Example Code [Visual Basic]

' Constants of interest to GetCertificateProperty.
Const PROPTYPE_LONG = &H1
Const PROPTYPE_DATE = &H2
Const PROPTYPE_BINARY = &H3
Const PROPTYPE_STRING = &H4

' Retrieve the certificate's serial number.
Dim strSerialNumber As String
' objSrvExit has been used to call SetContext previously.
strSerialNumber = objSrvExit.GetCertificateProperty( _
                             "SerialNumber", _
                             PROPTYPE_STRING)

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerExit, ICertServerExit::SetContext, Name Properties


ICertServerExit::GetRequestAttribute

Platform SDK: Security

ICertServerExit::GetRequestAttribute [C++]

CCertServerExit.GetRequestAttribute [Visual Basic]

The GetRequestAttribute method returns a named attribute value from a request. Prior to calling this method, it is necessary to call ICertServerExit::SetContext.

[C++]
HRESULT GetRequestAttribute(
  const BSTR strAttributeName,
  BSTR *pstrAttributeValue
);
[Visual Basic]
objServerExit.GetRequestAttribute( strAttributeName As String ) As String

Parameters

[C++,Visual Basic] strAttributeName
[in] Specifies the name of the attribute to retrieve.
[C++] pstrAttributeValue
[out] Pointer to BSTR which will contain the attribute value.
[Visual Basic] objServerExit
Object expression that resolves to an ICertServerExit object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pstrAttributeValue is set to the BSTR containing the attribute value. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable as pstrAttributeValue. You must free *pstrAttributeValue when done (by means of SysFreeString).

[Visual Basic] The return value is a String representing the attribute value.

Remarks

You must call ICertServerExit::SetContext prior to using this method.

Keygen Request Attributes

The following request attributes are unique to KEYGEN style requests.

Property Name | Type | Description
Challenge | String | Challenge string accompanying the request.
ExpectedChallenge | String | If the challenge string is incorrect, then the server will set the value of this request attribute to the expected challenge so that failure can be diagnosed.

Example Code [C++]

BSTR       bstrAttribValue = NULL;
HRESULT    hr;

// Get the request attribute
// bstrAttribName is BSTR assigned by EnumerateAttributes.
// Also, ICertServerExit::SetContext has already been
// called by pCertServerExit.
hr = pCertServerExit->GetRequestAttribute(bstrAttribName,
                                          &bstrAttribValue);

if (FAILED(hr))
{
    printf("Failed GetRequestAttribute [%x]\n", hr);
    goto error;
}
else
{
    // Successful call; Use bstrAttribValue as needed.
    // ...
}

// Done processing, free BSTR.
if (NULL != bstrAttribValue)
    SysFreeString(bstrAttribValue);

Example Code [Visual Basic]

' Retrieve the value associated with strAttribID.
' strAttribID was set by an earlier call to
' CCertServerExit.EnumerateAttributes.
' objSrvExit has also called SetContext to specify the context.
Dim varAttrib As Variant
varAttrib = objSrvExit.GetRequestAttribute(strAttribID)

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerExit, ICertServerExit::SetContext


ICertServerExit::GetRequestProperty

Platform SDK: Security

ICertServerExit::GetRequestProperty [C++]

CCertServerExit.GetRequestProperty [Visual Basic]

The GetRequestProperty method returns a named property from a request. Note that the request is used to hold all associated states for the request and the eventual granted certificate that is not a part of the certificate. Thus, data such as revocation times and disposition data are kept in the request data object.

[C++]
HRESULT GetRequestProperty(
  const BSTR strPropertyName,
  LONG PropertyType,
  VARIANT *pvarPropertyValue
);
[Visual Basic]
objServerExit.GetRequestProperty( _
  strPropertyName As String, _
  PropertyType As Long ) As Variant

Parameters

[C++,Visual Basic] strPropertyName
[in] Specifies the property to retrieve. There is a stock set of certificate properties, referred to as the name properties, that are always valid and can be retrieved by calling this method. For information about these properties, see Name Properties.

Other properties valid for certificate requests include the request properties.

Note The request's DistinguishedName and RawName properties are accessible by ICertServerExit::GetRequestProperty only if the certificate is requested using a PKCS #10 certificate request or another supported request format that contains encoded subject name information. Note that KeyGen requests do not contain encoded subject name information.

Request Properties

The following properties are unique to requests and can be accessed by GetRequestProperty.
Property Name | Data Type | Description
Disposition | Signed Long | Current request disposition
DispositionMessage | String | Informational disposition message
RawCACertificate | Binary | Certificate for the issuing CA
RawRequest | Binary | Raw request bytes
RequestAttributes | String | Attribute string (may be truncated)
RequesterName | String | Login name of requester
RequestID | Signed Long | Internal requestID
RequestType | Signed Long | Indicates PKCS #10 or KeyGen request
ResolvedWhen | Date / Time | When resolved
StatusCode | Signed Long | Windows error for last operation
SubmittedWhen | Date / Time | When arrived

The RequestType property will be one of the following values.
Format value flags | Description
CR_IN_PKCS7 | PKCS #7 renewal or registration request
CR_IN_PKCS10 | PKCS #10 request
CR_IN_KEYGEN | Keygen request (Netscape format)

In addition, other properties may be set by a specific request type, request extensions, or by named attributes set in the header of a request.

[C++,Visual Basic] PropertyType
[in] Specifies the property type. The type can be one of the following types.
Type Specifier | Data Type
PROPTYPE_LONG | Signed Long data
PROPTYPE_DATE | Date / Time
PROPTYPE_BINARY | Binary data
PROPTYPE_STRING | Unicode String data

[C++] pvarPropertyValue
[out] Pointer to the VARIANT which will contain the request property type.
[Visual Basic] objServerExit
Object expression that resolves to an ICertServerExit object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pvarPropertyValue is set to the Variant containing the request property value.

[Visual Basic] The return value is the request property value.

Remarks

You must call ICertServerExit::SetContext prior to using this method.

Example Code [C++]

BSTR      bstrPropName = NULL;
VARIANT   varProp;

VariantInit( &varProp );

bstrPropName = SysAllocString(L"RequestID");

// Retrieve the request property.
// pCertServerExit has been used to call SetContext previously.
hr = pCertServerExit->GetRequestProperty( bstrPropName,
                                          PROPTYPE_LONG,
                                          &varProp );
if (FAILED(hr))
{
    printf("Failed GetRequestProperty [%x]\n", hr);
    goto error;
}
else
{
    // Successfully retrieved property; use varProp as needed.
    // ...
}

// Done processing.
VariantClear( &varProp );
if ( NULL != bstrPropName )
    SysFreeString( bstrPropName );

Example Code [Visual Basic]

' Constants of interest to GetRequestProperty.
Const PROPTYPE_LONG = &H1
Const PROPTYPE_DATE = &H2
Const PROPTYPE_BINARY = &H3
Const PROPTYPE_STRING = &H4

' Retrieve a request property.
' objSrvExit has been used to call SetContext previously.
Dim ReqID As Long
ReqID = objSrvExit.GetRequestProperty("RequestID", PROPTYPE_LONG)

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerExit, ICertServerExit::SetContext, Name Properties


ICertServerExit::SetContext

Platform SDK: Security

ICertServerExit::SetContext [C++]

CCertServerExit.SetContext [Visual Basic]

The SetContext method causes the current instantiation of the interface to operate on the request referenced by Context. This must be identical to a value given by the Context parameter in ICertExit::Notify. This method must be called before calling any of the other ICertServerExit methods, in order that the interface reference a valid request.

[C++]
HRESULT SetContext(
  LONG   Context
);
[Visual Basic]
objServerExit.SetContext( Context As Long )

Parameters

[C++,Visual Basic] Context
[in] Specifies the request and associated certificate under construction.
[Visual Basic] objServerExit
Object expression that resolves to an ICertServerExit object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Example Code [C++]

// Set the context. The value nContext (long) would be the same
// as the context parameter in ICertExit::Notify.
// hr is defined as an HRESULT.
hr = pCertServerExit->SetContext( nContext );
if (FAILED(hr))
{
    printf("Failed SetContext [%x]\n", hr);
    goto error;
}

Example Code [Visual Basic]

' Object variable for CCertServerExit.
' Reference CertCli.dll in the project.
Dim objSrvExit As CCertServerExit

' Create an instance of the CCertServerExit object.
Set objSrvExit = New CCertServerExit

' Inform Cert Server of the context.
' The variable Context is provided to CCertExit.Notify.
objSrvExit.SetContext Context

' Use object as needed…
' When done, free resource.
Set objSrvExit = Nothing

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerExit, ICertExit::Notify, ICertPolicy::VerifyRequest


ICertServerPolicy

Platform SDK: Security

ICertServerPolicy [C++]

CCertServerPolicy [Visual Basic]

The ICertServerPolicy interface is exported by the server engine and is called by the policy module. It allows the policy module to get and enumerate elements of requests and certificates, to get and set certificate extensions, and to set certain certificate properties.

From the time the ICertPolicy::VerifyRequest method is called until it returns, the unresolved request and certificate under construction can be accessed through a Context data object. Because the policy module can add to or override request properties by calling ICertServerPolicy::SetCertificateProperty, certificate properties can differ from request properties.

ICertServerPolicy is defined in certif.h. When you create your program, however, use certsrv.h as the include file. CertCli.dll provides the ICertServerPolicy interface. In Windows 2000, the type information for this interface is also in CertCliL.dll, which is shipped with the Platform SDK.

The Certificate Services interfaces support only the apartment-threading model.

The following methods are provided by the ICertServerPolicy interface.

Method | Description
EnumerateAttributes | Returns the name of the next attribute to be enumerated.
EnumerateAttributesClose | Frees any resources connected with attribute enumeration.
EnumerateAttributesSetup | Initializes the internal enumeration pointer to the first request attribute associated with the current context.
EnumerateExtensions | Returns the OID of the next certificate extension to be enumerated.
EnumerateExtensionsClose | Frees any resources connected with extension enumeration.
EnumerateExtensionsSetup | Initializes the internal enumeration pointer to the first certificate extension associated with the current context.
GetCertificateExtension | Gets a specified certificate extension.
GetCertificateExtensionFlags | Gets the flags from the extension acquired by the most recent call to GetCertificateExtension.
GetCertificateProperty | Returns a named certificate property.
GetRequestAttribute | Returns a named request attribute.
GetRequestProperty | Returns a named request property.
SetCertificateExtension | Adds a new extension to the certificate to be issued.
SetCertificateProperty | Causes the server engine to add a named property to a certificate.
SetContext | Sets the current instantiation of the interface to operate on the specified request context.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertRequest, ICertPolicy::VerifyRequest, ICertRequest::Submit, ICertAdmin::ResubmitRequest, ICertAdmin::SetRequestAttributes


ICertServerPolicy::EnumerateAttributes

Platform SDK: Security

ICertServerPolicy::EnumerateAttributes [C++]

CCertServerPolicy.EnumerateAttributes [Visual Basic]

The EnumerateAttributes method returns the name of the next request attribute within the current context, then increments the internal pointer to the following attribute. Before calling EnumerateAttributes, an application calls ICertServerPolicy::EnumerateAttributesSetup. When done enumerating, an application calls ICertServerPolicy::EnumerateAttributesClose.

[C++]
HRESULT EnumerateAttributes(
  BSTR *pstrAttributeName
);
[Visual Basic]
objServerPolicy.EnumerateAttributes() As String

Parameters

[C++] pstrAttributeName
[out] Pointer to the enumerated attribute name.
[Visual Basic] objServerPolicy
Object expression that resolves to an ICertServerPolicy object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pstrAttributeNameis set to the BSTR containing the name of the enumerated attribute. A value of S_FALSE is returned if the last attribute was already enumerated. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable as pstrAttributeName. You must free *pstrAttributeName when done (by means of SysFreeString).

[Visual Basic] Returns a string specifying the name of the enumerated attribute, or an empty string if the last attribute was already enumerated.

Example Code [C++]

BSTR     bstrAttrib = NULL;
BSTR     bstrAttValue = NULL;
HRESULT  hr;

// Enumerate the attributes.
while (S_OK==
    (hr=pCertServerPol->EnumerateAttributes(&bstrAttrib)))
{
  // Retrieve the attribute value.
  if (FAILED(pCertServerPol->GetRequestAttribute(
                             bstrAttrib,
                             &bstrAttValue)))
       printf("Failed GetRequestAttributes\n");
  else
       printf("Attribute: %ws\tValue: %ws\n",
               bstrAttrib,
               bstrAttValue);
}
// Determine if hr was S_FALSE, meaning the enumeration
// was completed, or some other error.
if (S_FALSE != hr)
    printf("Failed EnumerateAttributes - %x\n", hr);
// Free BSTR resources.
if (NULL != bstrAttrib)
    SysFreeString(bstrAttrib);
if (NULL != bstrAttValue)
    SysFreeString(bstrAttValue);

Example Code [Visual Basic]

objSrvPol.EnumerateAttributesSetup 0

' Retrieve an attribute ID.
Dim strAttribID As String
strAttribID = objSrvPol.EnumerateAttributes()
Do
    ' Check to see if enumeration is done.
    If ("" = strAttribID) Then
      Exit Do
    End If
    ' Retrieve the value associated with this attribute ID.
    Dim varAttrib As Variant
    varAttrib = objSrvPol.GetRequestAttribute(strAttribID)
    ' Use the attributeID and value as needed.

    ' Get the next attribute.
    strAttribID = objSrvPol.EnumerateAttributes()
Loop

objSrvPol.EnumerateAttributesClose

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerPolicy, ICertServerPolicy::EnumerateAttributesClose, ICertServerPolicy::EnumerateAttributesSetup


ICertServerPolicy::EnumerateAttributesClose

Platform SDK: Security

ICertServerPolicy::EnumerateAttributesClose [C++]

CCertServerPolicy.EnumerateAttributesClose [Visual Basic]

The EnumerateAttributesClose method frees any resources connected with attribute enumeration. All applications that use ICertServerPolicy::EnumerateAttributesSetup ICertServerPolicy::EnumerateAttributes should call this method when finished enumerating.

[C++]
HRESULT EnumerateAttributesClose(void);
[Visual Basic]
objServerPolicy.EnumerateAttributesClose()

Parameters

[Visual Basic] objServerPolicy
Object expression that resolves to an ICertServerPolicy object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Example Code [C++]

// Close the enumeration.
// hr is defined as an HRESULT.
hr = pCertServerPolicy->EnumerateAttributesClose();
if (FAILED(hr))
{
    printf("Failed EnumerateAttributesClose [%x]\n", hr);
    goto error;
}

Example Code [Visual Basic]

' Close the enumeration.
objSrvPol.EnumerateAttributesClose

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerPolicy, ICertServerPolicy::EnumerateAttributesSetup, ICertServerPolicy::EnumerateAttributes


ICertServerPolicy::EnumerateAttributesSetup

Platform SDK: Security

ICertServerPolicy::EnumerateAttributesSetup [C++]

CCertServerPolicy.EnumerateAttributesSetup [Visual Basic]

The EnumerateAttributesSetup method initializes the internal enumeration pointer to the first request attribute associated with the current context.

[C++]
HRESULT EnumerateAttributesSetup(
  LONG Flags
);
[Visual Basic]
objServerPolicy.EnumerateAttributesSetup( Flags As Long )

Parameters

[C++,Visual Basic] Flags
[in] This parameter is reserved and must be set to 0.
[Visual Basic] objServerPolicy
Object expression that resolves to an ICertServerPolicy object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Remarks

You must call ICertServerPolicy::SetContext prior to using this method.

Example Code [C++]

// Set the context. The value nContext (long) would be the same
// as the context parameter in ICertPolicy::VerifyRequest.
// hr is defined as an HRESULT.
// pCertServerPolicy has been used to call SetContext previously.
hr = pCertServerPolicy->SetContext(nContext);
if (FAILED(hr))
{
    printf("Failed SetContext [%x]\n", hr);
    goto error;
}

// Setup the enumeration.
hr = pCertServerPolicy->EnumerateAttributesSetup(0);
if (FAILED(hr))
{
    printf("Failed EnumerateAttributesSetup [%x]\n", hr);
    goto error;
}

Example Code [Visual Basic]

' Set up the attributes enumeration.
' objSrvPol has been used to call SetContext previously.
objSrvPol.EnumerateAttributesSetup (0)

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerPolicy, ICertServerPolicy::EnumerateAttributes, ICertServerPolicy::EnumerateAttributesClose, ICertServerPolicy::SetContext


ICertServerPolicy::EnumerateExtensions

Platform SDK: Security

ICertServerPolicy::EnumerateExtensions [C++]

CCertServerPolicy.EnumerateExtensions [Visual Basic]

The EnumerateExtensions method returns the OID string (also known as the extension name) of the next certificate extension to be enumerated, then increments the internal pointer to the following extension. Before calling EnumerateExtensions, an application calls ICertServerPolicy::EnumerateExtensionsSetup. When done enumerating, an application calls ICertServerPolicy::EnumerateExtensionsClose.

[C++]
HRESULT EnumerateExtensions(
  BSTR *pstrExtensionName
);
[Visual Basic]
objServerPolicy.EnumerateExtensions() As String

Parameters

[C++] pstrExtensionName
[out] Pointer to the enumerated extension name.
[Visual Basic] objServerPolicy
Object expression that resolves to an ICertServerPolicy object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pstrExtensionName is set to the BSTR containing the name of the enumerated extension. A value of S_FALSE is returned if the last extension was already enumerated. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable as pstrExtensionName. You must free *pstrExtensionName when done (by means of SysFreeString).

[Visual Basic] Returns a string specifying the name of the enumerated extension, or an empty string if the last extension was already enumerated.

Remarks

This method enumerates certificate extensions recorded in the database, even those that are disabled and do not appear in the certificate. To see if an extension is disabled, use ICertServerPolicy::GetCertificateExtensionFlags to test the extension's EXTENSION_DISABLE_FLAG bit.

Example Code [C++]

BSTR     bstrExt = NULL;
VARIANT  varExt;
LONG     ExtFlags;
HRESULT  hr;

VariantInit(&varExt);

// Enumerate the extensions.
while (S_OK==
      (hr=pCertServerPol->EnumerateExtensions(&bstrExt)))
{
  // Retrieve the extension data.
  if (FAILED(pCertServerPol->GetCertificateExtension(
                             bstrExt,
                             PROPTYPE_BINARY,
                             &varExt)))
      printf("Failed GetCertificateExtension\n");
  else
  {
     // Retrieve the extension flags.
    if (FAILED(pCertServerPol->GetCertificateExtensionFlags(
                               &ExtFlags)))
        printf("Failed GetCertificateExtensionFlags\n");
    else
        // This sample will display the extension OID string,
        // the extension flags (in hex) and
        // the length of the BSTR binary ASN-encode extension.
        printf("Extension: %ws\tFlags:%x\tLength:%u\n",
               bstrExt,
               ExtFlags,
               SysStringByteLen(varExt.bstrVal));
  }
}
// Determine if hr was S_FALSE, meaning the enumeration
// was completed, or some other error.
if (S_FALSE != hr)
    printf("Failed EnumerateExtensions - %x\n", hr);
// Free BSTR resource.
if (NULL != bstrExt)
    SysFreeString(bstrExt);
// Free VARIANT resource.
    VariantClear(&varExt);

Example Code [Visual Basic]

objSrvPol.EnumerateExtensionsSetup 0

' Enumerate the extensions.
Dim strExt As String
strExt = objSrvPol.EnumerateExtensions()
Do
    If ("" = strExt) Then
        Exit Do
    End If
    ' Use the extension as needed

    ' Retrieve the next extension.
    strExt = objSrvPol.EnumerateExtensions()
Loop

objSrvPol.EnumerateExtensionsClose

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerPolicy, ICertServerPolicy::EnumerateExtensionsClose. ICertServerPolicy::EnumerateExtensionsSetup, ICertServerPolicy::GetCertificateExtension, ICertServerPolicy::GetCertificateExtensionFlags


ICertServerPolicy::EnumerateExtensionsClose

Platform SDK: Security

ICertServerPolicy::EnumerateExtensionsClose [C++]

CCertServerPolicy.EnumerateExtensionsClose [Visual Basic]

The EnumerateExtensionsClose method frees any resources connected with extension enumeration. All applications that use ICertServerPolicy::EnumerateExtensionsSetup or ICertServerPolicy::EnumerateExtensions should call this method when finished enumerating.

[C++]
HRESULT EnumerateExtensionsClose(void);
[Visual Basic]
objServerPolicy.EnumerateExtensionsClose()

Parameters

[Visual Basic] objServerPolicy
Object expression that resolves to an ICertServerPolicy object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Example Code [C++]

// Close the enumeration.
// hr is defined as an HRESULT.
hr = pCertServerPolicy->EnumerateExtensionsClose();
if (FAILED(hr))
{
    printf("Failed EnumerateExtensionsClose [%x]\n", hr);
    goto error;
}

Example Code [Visual Basic]

' Close the enumeration.
objSrvPol.EnumerateExtensionsClose

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerPolicy, ICertServerExit::EnumerateExtensionsSetup, ICertServerPolicy::EnumerateExtensions


ICertServerPolicy::EnumerateExtensionsSetup

Platform SDK: Security

ICertServerPolicy::EnumerateExtensionsSetup [C++]

CCertServerPolicy.EnumerateExtensionsSetup [Visual Basic]

The EnumerateExtensionsSetup method initializes the internal enumeration pointer to the first certificate extension associated with the current context.

[C++]
HRESULT EnumerateExtensionsSetup(
  LONG Flags
);
[Visual Basic]
objServerPolicy.EnumerateExtensionsSetup( Flags As Long )

Parameters

[C++,Visual Basic] Flags
[in] This parameter is reserved and must be set to 0.
[Visual Basic] objServerPolicy
Object expression that resolves to an ICertServerPolicy object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Remarks

You must call ICertServerPolicy::SetContext prior to using this method.

Example Code [C++]

// Set the context. The value nContext (long) would be the same
// as the context parameter in ICertPolicy::VerifyRequest.
// hr is defined as an HRESULT.
// pCertServerPolicy has been used to call SetContext previously.
hr = pCertServerPolicy->SetContext( nContext );
if (FAILED(hr))
{
    printf("Failed SetContext [%x]\n", hr);
    goto error;
}
// Setup the enumeration.
hr = pCertServerPolicy->EnumerateExtensionsSetup( 0 );
if (FAILED(hr))
{
    printf("Failed EnumerateExtensionsSetup [%x]\n", hr);
    goto error;
}

Example Code [Visual Basic]

' Set up the extensions enumeration.
' objSrvPol has been used to call SetContext previously.
objSrvPol.EnumerateExtensionsSetup (0)

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerPolicy, ICertServerPolicy::EnumerateExtensions, ICertServerPolicy::EnumerateExtensionsSetup, ICertServerPolicy::SetContext


ICertServerPolicy::GetCertificateExtension

Platform SDK: Security

ICertServerPolicy::GetCertificateExtension [C++]

CCertServerPolicy.GetCertificateExtension [Visual Basic]

The GetCertificateExtension method gets a specified certificate extension. Note that certificate extensions are distinct from certificate properties. Properties are generic data attached to the request object. Some of these properties are encoded into the certificate (example: BeginDate), while others are just used to mark requests in the queue and log. Extensions that are not disabled are encoded into the certificate. Extensions are always marked with an object identifier, and always have a critical/non-critical flag.

[C++]
HRESULT GetCertificateExtension(
  const BSTR strExtensionName,
  LONG Type,
  VARIANT *pvarValue
);
[Visual Basic]
objServerPolicy.GetCertificateExtension( _
  strExtensionName As String, _
  Type As Long ) As Variant

Parameters

[C++,Visual Basic] strExtensionName
[in] A string specifying the name of the extension.
[C++,Visual Basic] Type
[in] Specifies the type of the extension. The type can be one of the following types.
Type | Description
PROPTYPE_LONG | Signed Long data
PROPTYPE_DATE | Date / Time
PROPTYPE_BINARY | Binary data
PROPTYPE_STRING | Unicode String data

[C++] pvarValue
[out] Pointer to a Variant that receives the requested extension value.
[Visual Basic] objServerPolicy
Object expression that resolves to an ICertServerPolicy object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pvarValue is set to a VARIANT containing the extension value.

[Visual Basic] The return value is the requested extension value.

Remarks

You must call ICertServerPolicy::SetContext prior to using this method.

Example Code [C++]

VARIANT    varExt;
HRESULT    hr;

VariantInit(&varExt);
// Get the Extension value.
// bstrExtName is BSTR assigned by EnumerateExtensions.
// pCertServerPolicy has been used to call SetContext previously.
hr = pCertServerPolicy->GetCertificateExtension(bstrExtName,
                                                PROPTYPE_BINARY,
                                                &varExt);

if (FAILED(hr))
{
    printf("Failed GetCertificateExtension [%x]\n", hr);
    goto error;
}
// Successful call; use the value in varExt as needed.
// ...

// When done, clear the Variant
VariantClear(&varExt);

Example Code [Visual Basic]

Dim varExt As Variant

' Retrieve a certificate extension.
' strExt was set by an earlier call to
' CCertServerPolicy.EnumerateExtensions.
' objSrvPol has been used to call SetContext previously.
varExt = objSrvPol.GetCertificateExtension( _
                   strExt, _
                   PROPTYPE_BINARY)

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerPolicy, ICertServerPolicy::GetCertificateExtensionFlags, ICertServerPolicy::SetContext


ICertServerPolicy::GetCertificateExtensionFlags

Platform SDK: Security

ICertServerPolicy::GetCertificateExtensionFlags [C++]

CCertServerPolicy.GetCertificateExtensionFlags [Visual Basic]

The GetCertificateExtensionFlags method gets the flags from the extension acquired by the most recent call to ICertServerPolicy::GetCertificateExtension.

[C++]
HRESULT GetCertificateExtensionFlags(
  LONG *pExtFlags
);
[Visual Basic]
objServerPolicy.GetCertificateExtensionFlags() As Long

Parameters

[C++] pExtFlags
[out] Pointer to a Long variable which will contain the extension flags.
[Visual Basic] objServerPolicy
Object expression that resolves to an ICertServerPolicy object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pExtFlags is set to the value containing the flags from the extension acquired by the most recent call to GetCertificateExtension.

[Visual Basic] The return value is the flags from the extension acquired by the most recent call to GetCertificateExtension.

Remarks

There are two kinds of flags used in extensions; policy flags and origin flags.

Flag type | Explanation
Policy | Provides information about the certificate extension. Policy flags can be set by the policy module.
Origin | Indicates the module that set the certificate extension. Origin flags are only set by the server engine.

One or more policy flags can be returned from an extension. The following are predefined policy flags.

Policy flag value | Explanation
EXTENSION_CRITICAL_FLAG | This is a critical extension.
EXTENSION_DISABLE_FLAG | Extension will not be used.

One of the following origin flags can also be returned.

Origin flag value | Explanation
EXTENSION_ORIGIN_REQUEST | The extension was extracted from an array of extensions stored in the szOID_CERT_EXTENSIONS (1.3.6.1.4.1.311.2.1.14) or szOID_RSA_certExtensions (1.2.840.113549.1.9.14) attribute of a PKCS #10 request.
EXTENSION_ORIGIN_POLICY | Policy module set the extension.
EXTENSION_ORIGIN_ADMIN | Admin set the extension. See ICertAdmin::SetCertificateExtension
EXTENSION_ORIGIN_SERVER | Server engine set the extension.
EXTENSION_ORIGIN_RENEWALCERT | The extension was extracted from the certificate stored in the szOID_RENEWAL_CERTIFICATE (1.3.6.1.4.1.311.13.1) attribute of a PKCS #10 renewal request.
EXTENSION_ORIGIN_IMPORTEDCERT | The extension was extracted from an imported certificate (the certificate was passed to ICertAdmin::ImportCertificate).
EXTENSION_ORIGIN_PKCS7 | The extension was extracted from an array of extensions stored in the szOID_CERT_EXTENSIONS (1.3.6.1.4.1.311.2.1.14) or szOID_RSA_certExtensions (1.2.840.113549.1.9.14) attribute of a PKCS #7 request.

Pre-defined masks are provided for ease of use in determining which flags are set in the return value. The following masks are provided.

Mask Value | Explanation
EXTENSION_POLICY_MASK | This value (0x0000FFFF) is used to examine policy flags.
EXTENSION_ORIGIN_MASK | This value (0x000F0000) is used to examine origin flags.

It is safe to use the high 8 bits of EXTENSION_POLICY_MASK for custom data. These bits will be saved persistently in the database, but will not be written to the certificate extensions.

You must call ICertServerPolicy::SetContext before using this method.

Example Code [C++]

HRESULT  hr;
LONG     ExtFlags;
// pCertServerPolicy has been used to call SetContext previously.
hr = pCertServerPolicy->GetCertificateExtensionFlags( &ExtFlags);

// More than one policy flag might be set.
LONG ExtPolicyFlags = ExtFlags & EXTENSION_POLICY_MASK;

if (ExtPolicyFlags & EXTENSION_CRITICAL_FLAG)
{
    // Do something.
}

if (ExtPolicyFlags & EXTENSION_DISABLE_FLAG)
{
    // Do something.
}

// only one origin flag can be set
switch (ExtFlags & EXTENSION_ORIGIN_MASK)
{
    case EXTENSION_ORIGIN_REQUEST:
        // Extension was set in certificate request.
        break;
    case EXTENSION_ORIGIN_POLICY:
        // Extension was set by policy module.
        break;
    case EXTENSION_ORIGIN_ADMIN:
        // Extension was set by admin.
        break;
    case EXTENSION_ORIGIN_SERVER:
        // Extension was set by server engine.
        break;
    default:
        break;
}

Example Code [Visual Basic]

' Constants used by GetCertificateExtensionFlags.
Const EXTENSION_CRITICAL_FLAG = &H1
Const EXTENSION_DISABLE_FLAG = &H2
Const EXTENSION_POLICY_MASK = &HFFFF
Const EXTENSION_ORIGIN_REQUEST = &H10000
Const EXTENSION_ORIGIN_POLICY = &H20000
Const EXTENSION_ORIGIN_ADMIN = &H30000
Const EXTENSION_ORIGIN_SERVER = &H40000
Const EXTENSION_ORIGIN_RENEWALCERT = &H50000
Const EXTENSION_ORIGIN_IMPORTEDCERT = &H60000
Const EXTENSION_ORIGIN_PKCS7 = &H70000
Const EXTENSION_ORIGIN_MASK = &HF0000

' Retrieve the extension flags.
Dim ExtFlags As Long
' objSrvPol has been used to call SetContext previously.
ExtFlags = objSrvPol.GetCertificateExtensionFlags()

' Examine the criticality and enabledness.
Dim ExtPol As Long
ExtPol = ExtFlags And EXTENSION_POLICY_MASK
If (ExtPol And EXTENSION_CRITICAL_FLAG) Then
        ' The extension is critical.
        ' ...
End If

If (ExtPol And EXTENSION_DISABLE_FLAG) Then
        ' The extension is disabled.
        ' ...
End If

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerPolicy, ICertServerPolicy::GetCertificateExtension, IEnumCERTVIEWEXTENSION::GetFlags, ICertAdmin::SetCertificateExtension, ICertServerPolicy::SetContext


ICertServerPolicy::GetCertificateProperty

Platform SDK: Security

ICertServerPolicy::GetCertificateProperty [C++]

CCertServerPolicy.GetCertificateProperty [Visual Basic]

The GetCertificateProperty method returns a named property from a certificate.

[C++]
HRESULT GetCertificateProperty(
  const BSTR strPropertyName,
  LONG PropertyType,
  VARIANT *pvarPropertyValue
);
[Visual Basic]
objServerPolicy.GetCertificateProperty( _
  strPropertyName As String, _
  PropertyType As Long ) As Variant

Parameters

[C++,Visual Basic] strPropertyName
[in] Specifies the named property to retrieve. There is a stock set of certificate properties, referred to as the name properties, that are always valid and can be retrieved by calling this method. For information about these properties, see Name Properties. Other properties which can be retrieved include the certificate properties.

Note The certificate's DistinguishedName and RawName properties are accessible by ICertServerPolicy::GetCertificateProperty only after the policy module has finished processing the request and the certificate is issued. The issued certificate's DistinguishedName and RawName properties can also be read by an exit module by means of ICertServerExit::GetCertificateProperty.

Certificate Properties

The following properties are unique to certificates and can be read by GetCertificateProperty.
Property Name | Data Type | Description
RequestID | Signed Long | Internal request ID
NotBefore | Date / Time | Certificate start validity date
NotAfter | Date / Time | Certificate expiration date
RawPublicKey | Binary | Subject key
PublicKeyAlgorithm | String | Subject key algorithm object ID (OID)
RawPublicKeyAlgorithmParameters | Binary | Subject key algorithm parameters

The following properties apply to the certification authority.
Property Name | Data Type | Description
CAType Long Type of certification authority (CA). Can be one of the following values (defined in certsrv.h):

ENUM_ENTERPRISE_ROOTCA

ENUM_ENTERPRISE_SUBCA

ENUM_STANDALONE_ROOTCA

ENUM_STANDALONE_SUBCA
CertCount | Long | Number of CA certificates. This value will be 1 plus the number of times that the CA has been renewed. For information on renewal, see Certification Authority Renewal.
CertState * Long CA certificate state. Can be one of the following values/meanings:

CA_DISP_ERROR: The CA certificate was never issued.

CA_DISP_REVOKED: The CA certificate has been revoked.

CA_DISP_VALID: The CA certificate is still valid.

CA_DISP_INVALID: The CA certificate has expired.
CertSuffix * | String | Suffix for the CA certificate. The suffix is an empty string for CA certificates with an index of 0; otherwise, the suffix (in the form of "(nn)", where nn is the certificate index) is applied to all URLs pointing to CA certificates stored in files or directory service objects. For non-LDAP URLs, the suffix typically appears before the ".crt" text. For LDAP URLs, the suffix is typically appended to the first 'CN=' in the full distinguished name.
CRLIndex * | Long | Certificate revocation list (CRL) index. Appending a certificate index to this property name allows you to retrieve the CRL index. The CRL index does not necessarily match the certificate index. For details, see Certification Authority Renewal.
CRLState * Long CRL state. Can be one of the following values:

CA_DISP_ERROR: The CRL is managed by another CA certificate.

CA_DISP_REVOKED: All unexpired CA certificates using this CA certificate's CRL have been revoked.

CA_DISP_VALID: The CA certificate is still being used to publish CRLs as needed.

CA_DISP_INVALID: All CA certificates using this CA certificate's CRL are expired.
CRLSuffix * | String | Suffix for the CA CRL. The suffix is an empty string for CRLs with an index of 0; otherwise, the suffix (in the form of "(nn)", where nn is the CRL index) is applied to all URLs pointing to CRLs stored in files or directory service objects. For non-LDAP URLs, the suffix typically appears before the ".crl" text. For LDAP URLs, the suffix typically is appended to the first 'CN=' in the full distinguished name.
fUseDS Long Indicates whether the CA uses a directory service. Can be either of the following values:

0=no
1=yes
MachineDNSName | String | DNS name of server hosting the CA.
ModuleRegistryLocation | String | Registry location available for use by the module.
RawCACertificate * | Binary | CA certificate.
RawCRL * | Binary | CA's certificate revocation list (CRL).
RequesterCAAccess Long Indicates whether the requester is authorized to request the certificate. Can be either of the following values:

0=no
1=yes

(The MMC snap-in for Certification Authority can be used to control certificate request permissions.)
SanitizedCAName | String | Sanitized name for the CA. For details about sanitized CA names, see ICertConfig::GetConfig.
SanitizedShortName | String | Sanitized name for the CA, shortened and containing a hash value to ensure uniqueness.

Note that an asterisk (*) indicates that this property name may be appended with '.#', where # represents a CA certificate index (or, in the case of the CRLSuffix property, a CRL index). For information about certificate and CRL indices, see Certification Authority Renewal.

Note There are additional certificate properties that cannot be accessed by ICertServerPolicy::GetCertificateProperty. These properties are not set until after the policy module returns VR_INSTANT_OK and the certificate is issued. See ICertServerExit::GetCertificateProperty for a complete list of all the properties in an issued certificate.

[C++,Visual Basic] PropertyType
[in] Specifies the property type. The type can be one of the following types.
Type Specifier | Data Type
PROPTYPE_LONG | Signed Long data
PROPTYPE_DATE | Date / Time
PROPTYPE_BINARY | Binary data
PROPTYPE_STRING | Unicode String data

[C++] pvarPropertyValue
[out] Pointer to VARIANT which will contain the property value.
[Visual Basic] objServerPolicy
Object expression that resolves to an ICertServerPolicy object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pvarPropertyValue is set to the VARIANT containing the requested property value.

[Visual Basic] The return value is the requested property value.

You must call ICertServerPolicy::SetContext prior to using this method.

Example Code [C++]

BSTR    bstrPropName = NULL;
VARIANT varProp;

VariantInit( &varProp );

// Set the property name to RequestID.
bstrPropName = SysAllocString(L"RequestID");

// Retrieve the certificate property.
// pCertServerPolicy has been used to call SetContext previously.
hr = pCertServerPolicy->GetCertificateProperty( bstrPropName,
                                                PROPTYPE_LONG,
                                                &varProp );
if (FAILED(hr))
{
    printf("Failed GetCertificateProperty [%x]\n", hr);
    goto error;
}
else
{
    // Successfully retrieved property; use varProp as needed.
    // ...
}

// Done processing.
if ( NULL != bstrPropName )
    SysFreeString( bstrPropName );
VariantClear( &varProp );

Example Code [Visual Basic]

' Consts for CCertServerPolicy.GetCertificateProperty().
Const PROPTYPE_LONG = &H1
Const PROPTYPE_DATE = &H2
Const PROPTYPE_BINARY = &H3
Const PROPTYPE_STRING = &H4

' Retrieve a certificate property value.
Dim strRegLoc As String
' objSrvPol has been used to call SetContext previously.
strRegLoc = objSrvPol.GetCertificateProperty( _
                      "ModuleRegistryLocation", _
                      PROPTYPE_STRING)

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerPolicy, ICertServerPolicy::SetContext, Name Properties


ICertServerPolicy::GetRequestAttribute

Platform SDK: Security

ICertServerPolicy::GetRequestAttribute [C++]

CCertServerPolicy.GetRequestAttribute [Visual Basic]

The GetRequestAttribute method returns a named attribute from a request.

[C++]
HRESULT GetRequestAttribute(
  const BSTR strAttributeName,
  BSTR *pstrAttributeValue
);
[Visual Basic]
objServerPolicy.GetRequestAttribute( _
  strAttributeName As String ) As String

Parameters

[C++,Visual Basic] strAttributeName
[in] Specifies the name of the attribute to retrieve.
[C++] pstrAttributeValue
[out] Pointer to BSTR which will contain the attribute value. You must free when pstrAttributeValue done.
[Visual Basic] objServerPolicy
Object expression that resolves to an ICertServerPolicy object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pstrAttributeValue is set to the BSTR containing the attribute value. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable as pstrAttributeValue. You must free *pstrAttributeValue when done (by means of SysFreeString).

[Visual Basic] The return value is a String representing the attribute value.

You must call ICertServerPolicy::SetContext prior to using this method.

Keygen Request Attributes

The following request attributes are unique to KEYGEN style requests.

Property Name | Type | Description
Challenge | String | Challenge string accompanying the request.
ExpectedChallenge | String | If the challenge string is incorrect, then the server will set the value of this request attribute to the expected challenge so that failure can be diagnosed.

Example Code [C++]

BSTR     bstrAttribValue = NULL;
HRESULT  hr;

// Get the request attribute.
// bstrAttribName is BSTR assigned by EnumerateAttributes.
// pCertServerPolicy has been used to call SetContext previously.
hr = pCertServerPolicy->GetRequestAttribute(bstrAttribName,
                                            &bstrAttribValue);

if (FAILED(hr))
{
    printf("Failed GetRequestAttribute [%x]\n", hr);
    goto error;
}
else
{
    // Successful call; use the bstrAttribValue as needed.
    // ...
}

// Done processing, free BSTR.
if (NULL != bstrAttribValue)
    SysFreeString(bstrAttribValue);

Example Code [Visual Basic]

' Retrieve the value associated with strAttribID.
' strAttribID was set by an earlier call to
' CCertServerPolicy.EnumerateAttributes.
' objSrvPol has been used to call SetContext previously.
Dim strAttrib As String
strAttrib = objSrvPol.GetRequestAttribute(strAttribID)

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerPolicy, ICertServerPolicy::SetContext


ICertServerPolicy::GetRequestProperty

Platform SDK: Security

ICertServerPolicy::GetRequestProperty [C++]

CCertServerPolicy.GetRequestProperty [Visual Basic]

The GetRequestProperty method returns a named property from a request. Note that the request is used to hold all associated states for the request and the eventual granted certificate that is not a part of the certificate. Thus, data such as revocation times and disposition data are kept in the request data object.

[C++]
HRESULT GetRequestProperty(
  const BSTR strPropertyName,
  LONG PropertyType,
  VARIANT *pvarPropertyValue
);
[Visual Basic]
objServerPolicy.GetRequestProperty( _
  strPropertyName As String, _
  PropertyType As Long ) As Variant

Parameters

[C++,Visual Basic] strPropertyName
[in] Specifies the property to retrieve. There is a stock set of certificate properties, referred to as the name properties, that are always valid and can be retrieved by calling this method. For information about these properties, see Name Properties.

Other properties valid for certificate requests include the request properties.

Note The request's DistinguishedName and RawName properties are accessible by ICertServerPolicy::GetRequestProperty only if the certificate is requested using a PKCS #10 certificate request or another supported request format that contains encoded subject name information. Note that KeyGen requests do not contain encoded subject name information.

Request Properties

The following properties are unique to requests and can be accessed by GetRequestProperty.
Property Name | Data Type | Description
RequestID | Signed Long | Internal requestID
RawRequest | Binary | Raw request bytes
RequestAttributes | String | Attribute string (may be truncated)
RequestType | Signed Long | Indicates PKCS #10 or KeyGen request
SubmittedWhen | Date / Time | When arrived
RequesterName | String | Login name of requester

The RequestType property can be set to one of the following values.
Format value flags | Description
CR_IN_PKCS7 | PKCS #7 renewal or registration request
CR_IN_PKCS10 | PKCS #10 request
CR_IN_KEYGEN | Keygen request (Netscape format)

Note There are additional request properties that cannot be accessed by GetRequestProperty. These properties are not set until after the policy module finishes processing the request. See GetRequestProperty for a complete list of all the request properties.

In addition, other properties may be set by a specific request type, request extensions, or by named attributes set in the header of a request.

[C++,Visual Basic] PropertyType
[in] Specifies the property type. The type can be one of the following types.
Type Specifier | Data Type
PROPTYPE_LONG | Signed Long data
PROPTYPE_DATE | Date / Time
PROPTYPE_BINARY | Binary data
PROPTYPE_STRING | Unicode String data

[C++] pvarPropertyValue
[out] Pointer to the VARIANT which will contain the request property type.
[Visual Basic] objServerPolicy
Object expression that resolves to an ICertServerPolicy object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful, and *pvarPropertyValue is set to the Variant containing the request property value.

[Visual Basic] The return value is the request property value.

Remarks

You must call ICertServerPolicy::SetContext prior to using this method.

Example Code [C++]

BSTR      bstrPropName = NULL;
VARIANT   varProp;

VariantInit( &varProp );

bstrPropName = SysAllocString(L"RequestID");

// Retrieve the request property.
// pCertServerPolicy has been used to call SetContext previously.
hr = pCertServerPolicy->GetRequestProperty( bstrPropName,
                                          PROPTYPE_LONG,
                                          &varProp );
if (FAILED(hr))
{
    printf("Failed GetRequestProperty [%x]\n", hr);
    goto error;
}
else
{
    // Successfully retrieved property; use varProp as needed.
    // ...
}

// Done processing.
VariantClear( &varProp );
if ( NULL != bstrPropName )
    SysFreeString( bstrPropName );

Example Code [Visual Basic]

' Consts for CCertServerPolicy.GetRequestProperty().
Const PROPTYPE_LONG = &H1
Const PROPTYPE_DATE = &H2
Const PROPTYPE_BINARY = &H3
Const PROPTYPE_STRING = &H4

' Retrieve a request property value.
Dim strEMail As String
' objSrvPol has been used to call SetContext previously.
strEMail = objSrvPol.GetRequestProperty( _
                      "EMail", _
                      PROPTYPE_STRING)

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerPolicy, ICertServerPolicy::SetContext, Name Properties


ICertServerPolicy::SetCertificateExtension

Platform SDK: Security

ICertServerPolicy::SetCertificateExtension [C++]

CCertServerPolicy.SetCertificateExtension [Visual Basic]

The SetCertificateExtension method adds a new extension to the certificate to be issued.

[C++]
HRESULT SetCertificateExtension(
  const BSTR strExtensionName,
  LONG Type,
  LONG ExtFlags,
  const VARIANT *pvarValue
);
[Visual Basic]
objServerPolicy.SetCertificateExtension( _
  strExtensionName As String, _
  Type As Long, _
  ExtFlags As Long, _
  pvarValue As Variant )

Parameters

[C++,Visual Basic] strExtensionName
[in] Specifies the object identifier (OID) for the extension to set. The string must be 31 or less non-null characters in length.
[C++,Visual Basic] Type
[in] Specifies the type of extension being set. The Type parameter must agree with the data type of pvarValue that is set in the vt field of the VARIANT structure. The Type parameter can be set to one of the following types.
Type | Description
PROPTYPE_LONG | Signed Long data
PROPTYPE_DATE | Date / Time
PROPTYPE_BINARY | Binary data
PROPTYPE_STRING | Unicode String data

[C++,Visual Basic] ExtFlags
[in] Specifies the flags for the extension being set. Use a value of 0 if no flag is to be set, or one of the following flag values. You can join these flags together by means of the OR operator, and you can also join them by the OR operator with policy private extension flags (the high 8 bits of the EXTENSION_POLICY_MASK field).
Flag value | Explanation
EXTENSION_CRITICAL_FLAG | This is a critical extension
EXTENSION_DISABLE_FLAG | Extension will not be used

Note When ExtFlags is set to EXTENSION_DISABLE_FLAG, the extension will be disabled in the server log and will not be added to the certificate.

[C++,Visual Basic] pvarValue
[in] Specifies the value associated with the extension. Note the value's VARIANT type must agree with the Type parameter, as shown in the following table.
Type | Variant Type
PROPTYPE_LONG | VT_I4
PROPTYPE_DATE | VT_DATE
PROPTYPE_BINARY | VT_BSTR
PROPTYPE_STRING | VT_BSTR

[Visual Basic] objServerPolicy
Object expression that resolves to an ICertServerPolicy object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Remarks

You must call ICertServerPolicy::SetContext prior to using this method.

The following code sets a URL string and extension critical flag into the certificate:

Example Code [C++]

HRESULT hr;
BSTR strExtensionName = SysAllocString(L"2.29.38.4");
VARIANT varExt;

VariantInit( &varExt );
varExt.vt = VT_BSTR;    // initialize type tag field
varExt.bstrVal = SysAllocString(L"http://example.microsoft.com");

// pCertServerPolicy has been used to call SetContext previously.
hr = pCertServerPolicy->SetCertificateExtension(
    strExtensionName,      // extension name
    PROPTYPE_STRING,
    EXTENSION_CRITICAL_FLAG,
    &varExt);

if (FAILED(hr))
{
    printf("Failed SetCertificateExtension [%x]\n", hr);
    goto error;
}

// Free resources when done.
if (NULL != strExtensionName)
    SysFreeString(strExtensionName);
VariantClear(&varExt);

Example Code [Visual Basic]

Const EXTENSION_CRITICAL_FLAG = &H1
Const EXTENSION_DISABLE_FLAG = &H2

' objSrvPol has been used to call SetContext previously.
objSrvPol.SetCertificateExtension "2.29.38.4", _
                                  PROPTYPE_STRING, _
                                  EXTENSION_CRITICAL_FLAG, _
                                  "http://example.microsoft.com"

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerPolicy, ICertServerPolicy::SetContext


ICertServerPolicy::SetCertificateProperty

Platform SDK: Security

ICertServerPolicy::SetCertificateProperty [C++]

CCertServerPolicy.SetCertificateProperty [Visual Basic]

The SetCertificateProperty method causes the server engine to set a named property associated with a certificate.

[C++]
HRESULT SetCertificateProperty(
  const BSTR strPropertyName,
  LONG PropertyType,
  const VARIANT *pvarPropertyValue
);
[Visual Basic]
objServerPolicy.SetCertificateProperty( _
  strPropertyName As String, _
  PropertyType As Long, _
  pvarPropertyValue As Variant )

Parameters

[C++,Visual Basic] strPropertyName
[in] Specifies the property to set. There is a stock set of certificate properties, referred to as the name properties, that are always valid and can be set by calling this method. For information about these properties, see Name Properties.

Other properties valid for certificates that may be set by SetCertificateProperty include the Certificate Properties listed later in this topic.

Certificate Properties

The following properties are unique to certificates and can be set by SetCertificateProperty.
Property Name | Data Type | Description
NotBefore | Date / Time | Certificate start validity date
NotAfter | Date / Time | Certificate expiration date

Note SetCertificateProperty can set only the NotBefore and NotAfter certificate properties. See ICertServerExit::GetCertificateProperty for a complete list of all the properties in an issued certificate.

[C++,Visual Basic] PropertyType
[in] Specifies the type of the property being set. The Type parameter must agree with the data type of pvarValue that is set in the vt field of the VARIANT structure. The Type parameter can be set to one of the following types.
Type Specifier | Data Type
PROPTYPE_LONG | Signed Long data
PROPTYPE_DATE | Date / Time
PROPTYPE_BINARY | Binary data
PROPTYPE_STRING | Unicode String data

[C++,Visual Basic] pvarPropertyValue
[in] Specifies the value to set the property to.
[Visual Basic] objServerPolicy
Object expression that resolves to an ICertServerPolicy object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Remarks

You must call ICertServerPolicy::SetContext prior to using this method.

The NotBefore and NotAfter certificate properties constrain the lifetime during which a certificate is valid. The data type for these properties is a VARIANT Date (floating point) derived from COleDateTime in OLE Automation.

The following restrictions apply when setting the NotBefore and NotAfter certificate properties with SetCertificateProperty:

  • The NotBefore date cannot be set to a date earlier than the certification authority (CA) certificate's NotBefore date.
  • The NotAfter date cannot be set to a date later than the CA certificate's NotAfter date.
  • The NotBefore date cannot be set to a date earlier than it already is set, even if the new date is later than the CA certificate's NotBefore date.
  • The NotAfter date cannot be set to a date later than it already is set, even if the new date is before the CA certificate's NotAfter date.

Example Code [C++]

// Intermediate variable.
SYSTEMTIME st;

// BSTR for property name.
BSTR       bstrProp = SysAllocString(L"NotBefore");

// Value to contain property value.
VARIANT    var;

VariantInit( &var );
var.vt = VT_DATE;

// Set the 'NotBefore' property to Noon on Jan. 1, 2000.
// Zero out values first (avoids setting minutes, seconds, etc).
memset( &st, 0, sizeof(SYSTEMTIME));
// Set the values of interest.
st.wYear = 2000;
st.wMonth = 1;     // Jan.
st.wDay = 1;       // 1st day of month.
st.wHour = 12;     // Noon.
// Place the date into VARIANT required format.
if ( !SystemTimeToVariantTime( &st, &var.date))
{
    printf("Unable to convert time\n");
    goto error;
}

// Set the NotBefore property in the certificate:

// pCertServerPolicy has been used to call SetContext previously.
hr = pCertServerPolicy->SetCertificateProperty(bstrProp,
                                               PROPTYPE_DATE,
                                               &var);
if (FAILED(hr))
{
    printf("Failed SetCertificateProperty [%x]\n", hr);
    goto error;
}

// free resources, etc.
VariantClear( &var );
if ( NULL != bstrProp )
    SysFreeString( bstrProp );

Example Code [Visual Basic]

' Set the 'NotBefore' property to Noon on Jan. 1, 2000.
Dim varNotBefore As Variant

varNotBefore = #1/1/2000 12:00:00 PM#
' objSrvPol has been used to call SetContext previously.
objSrvPol.SetCertificateProperty "NotBefore", _
                                 PROPTYPE_DATE, _
                                 varNotBefore

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerExit::GetCertificateProperty, ICertServerPolicy, ICertServerPolicy::SetContext, Name Properties


ICertServerPolicy::SetContext

Platform SDK: Security

ICertServerPolicy::SetContext [C++]

CCertServerPolicy.SetContext [Visual Basic]

The SetContext method causes the current instantiation of the interface to operate on the request referenced by Context. This must be identical to a value given by the Context parameter in ICertPolicy::VerifyRequest. This method must be called before calling any of the other ICertServerPolicy methods, in order that the interface reference a valid request.

[C++]
HRESULT SetContext(
  LONG Context
);
[Visual Basic]
objServerPolicy.SetContext( Context As Long )

Parameters

[C++,Visual Basic] Context
[in] Specifies the request and associated certificate under construction.
[Visual Basic] objServerPolicy
Object expression that resolves to an ICertServerPolicy object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates the method was successful.

[Visual Basic] None.

Example Code [C++]

// Set the context. The value nContext (long) would be the same
// as the context parameter in ICertPolicy::VerifyRequest.
// hr is defined as an HRESULT.
hr = pCertServerPolicy->SetContext( nContext );
if (FAILED(hr))
{
    printf("Failed SetContext [%x]\n", hr);
    goto error;
}

Example Code [Visual Basic]

' Object variable for CCertServerPolicy.
' Reference CertCli.dll in the project.
Dim objSrvPol As CCertServerPolicy

' Instantiate the CCertServerPolicy object.
Set objSrvPol = New CCertServerPolicy

' Inform Cert Server of the context.
' The variable Context is provided to CCertPolicy.VerifyRequest.
objSrvPol.SetContext Context

' Use object as needed…
' When done, free resource.
Set objSrvPol = Nothing

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Certif.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertServerPolicy, ICertPolicy::VerifyRequest


ICertView

Platform SDK: Security

ICertView [C++]

CCertView [Visual Basic,Java]

The ICertView interface allows properly authorized clients to create a view of the Certificate Services database. (See Viewing the Certificate Services Database.) ICertView allows the client to retrieve a customized view of the database or to retrieve the database in its entirety. In C++, ICertView is instantiated through a call to the COM function CoCreateInstance. If, on the other hand, you are using Visual Basic, you will need to reference the CertAdm Type library in your project and then instantiate the object (CCertView) by a call to 'New'. The sample code for ICertView::OpenConnection illustrates both the C++ and Visual Basic instantiation techniques.

ICertView is defined in certview.h. When you create your program, however, use certsrv.h as the include file. CertAdm.dll provides the ICertView interface. The type information for this interface is also in CertAdmL.dll, which is shipped with the Platform SDK.

The Certificate Services interfaces support only the apartment-threading model.

The following methods are provided by the ICertView interface.

Method | Description
EnumCertViewColumn | Obtains a pointer to IEnumCERTVIEWCOLUMN for schema enumeration.
GetColumnCount | Retrieves the count of columns in the view.
GetColumnIndex | Retrieves the zero-based index of a named column.
OpenConnection | Establishes a connection with a Certificate Services server.
OpenView | Opens a view to a Certificate Services database and obtains a pointer to IEnumCERTVIEWROW.
SetRestriction | Sets sorting and qualifying restrictions on a column.
SetResultColumn | Specifies a column for use in a customized view.
SetResultColumnCount | Sets the number of columns in a customized view.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWCOLUMN, IEnumCERTVIEWROW


ICertView::EnumCertViewColumn

Platform SDK: Security

ICertView::EnumCertViewColumn [C++]

CCertView.EnumCertViewColumn [Visual Basic,Java]

The EnumCertViewColumn method obtains a pointer to the IEnumCERTVIEWCOLUMN interface for schema enumeration. Note that obtaining a pointer to the IEnumCERTVIEWCOLUMN interface with this method doesn't allow the column values to be enumerated, only the database schema. Use IEnumCERTVIEWROW::EnumCertViewColumn if you need to enumerate the data values.

[C++]
HRESULT EnumCertViewColumn(
  BOOL fResultColumn,
  IEnumCERTVIEWCOLUMN **ppenum
);
[Visual Basic]
objView.EnumCertViewColumn( fResultColumn As Boolean ) As IEnumCERTVIEWCOLUMN
[Java]
IEnumCERTVIEWCOLUMN EnumCertViewColumn(
  int fResultColumn
);

Parameters

[C++,Visual Basic,Java] fResultColumn
[in] If this value is TRUE, the view is based on a result set; a value of FALSE means the view is based on the full database schema. A result set is used for customizing the view of the Certificate Services data. If fResultColumn is TRUE, you must first call ICertView::OpenView before you call EnumCertViewColumn. Note that TRUE is defined (in a Microsoft header file) for C/C++ programmers as 1, while Microsoft Visual Basic defines the 'True' keyword as -1. As a result, Visual Basic developers must use 1 (instead of 'True') to set this parameter to TRUE. However, to set this parameter to FALSE, Visual Basic developers can use 0 or 'False'. Java developers will need to use 1 for TRUE and 0 for FALSE when calling this method.
[C++] ppenum
[out] Pointer to a pointer of IEnumCERTVIEWCOLUMN type. This function will fail if ppenum is NULL.
[Visual Basic] objView
Object expression that resolves to an ICertView object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success. Upon successful completion of this function, *ppenum is set to a pointer of IEnumCERTVIEWCOLUMN type.

[Visual Basic,Java] The return value is an IEnumCERTVIEWCOLUMN object.

Remarks

The IEnumCERTVIEWCOLUMN object can be used to enumerate the view's columns and retrieve each column's information.

Example Code [C++]

// pCertView is previously instantiated pointer to ICertView.
// Also, pCertView has been used to call ICertView::OpenView.
IEnumCERTVIEWCOLUMN * pEnumCertViewCol = NULL;
HRESULT               hr;
hr = pCertView->EnumCertViewColumn(TRUE, &pEnumCertViewCol);
if (S_OK != hr)
    printf("Failed EnumCERTVIEWCOLUMN call!\n");
    // call error handler...
else
    // Use pEnumCertViewCol to access IEnumCERTVIEWCOLUMN methods.
// Done using object; free resources.
if (NULL != pEnumCertViewCol)
    pEnumCertViewCol->Release();

Example Code [Visual Basic]

Dim objCol As IEnumCERTVIEWCOLUMN

' objView is ICertView object, and it has
' already called ICertView::OpenView.
Set objCol = objView.EnumCertViewColumn(1)
' Use object as needed.
' ...

' Done processing - free resource.
Set objCol = Nothing

Example Code [Java]

certadm.IEnumCERTVIEWCOLUMN objCol;

// objView has already been used to call OpenView.
objCol = objView.EnumCertViewColumn(1);

// Use object as needed.

// Done processing. Free the object.
com.ms.com.ComLib.release(objCol);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertView, EnumCERTVIEWCOLUMN


ICertView::GetColumnCount

Platform SDK: Security

ICertView::GetColumnCount [C++]

CCertView.GetColumnCount [Visual Basic,Java]

The GetColumnCount method retrieves the count of columns in the view of the Certificate Services database.

[C++]
HRESULT GetColumnCount(
  LONG fResultColumn,
  LONG *pcColumn
);
[Visual Basic]
objView.GetColumnCount( fResultColumn As Long ) As Long
[Java]
int GetColumnCount(
  int fResultColumn
);

Parameters

[C++,Visual Basic,Java] fResultColumn
[in] Boolean value. If this value is TRUE, the view is based on a result set; a value of FALSE means the view is based on the full database schema. A result set is used for customizing the view to the Certificate Services data. Note that TRUE is defined (in a Microsoft header file) for C/C++ programmers as 1, while Microsoft Visual Basic defines the 'True' keyword as -1. As a result, Visual Basic developers must use 1 (instead of 'True') to set this parameter to TRUE. However, to set this parameter to FALSE, Visual Basic developers can use 0 or 'False'. Java developers will need to use 1 for TRUE and 0 for FALSE when calling this method.
[C++] pcColumn
[out] Pointer to a variable that will contain the number of columns in the view. This function will fail if pcColumn is NULL.
[Visual Basic] objView
Object expression that resolves to an ICertView object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success. Upon successful completion of this function, *pcColumn is set to the value containing the number of columns in the view.

[Visual Basic,Java] The return value is the number of columns in the view.

Remarks

This function is used to determine the number of columns in the view. The number will represent the count of a result set's columns if fResultColumn is TRUE or the count of the full database schema's columns if fResultColumn is FALSE.

Example Code [C++]

// pCertView is pointer to ICertView.
LONG        cCol
HRESULT    hr;
hr = pCertView->GetColumnCount(TRUE, &cCol);
if (S_OK != hr)
    printf("Failed GetColumnCount - %x\n", hr);
else
    printf("Number of columns in the view is: %d\n", cCol);

Example Code [Visual Basic]

 ' Retrieve the column count.
Dim nCols As Long
nCols = objView.GetColumnCount(1)

' Display the column count.
MsgBox nCols, vbOKOnly, "Number of columns"

Example Code [Java]

int nCol;

// Retrieve and display the column count.
nCol = objView.GetColumnCount(1);
System.out.println("Number of columns: " + nCol);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertView, ICertView::SetResultColumnCount


ICertView::GetColumnIndex

Platform SDK: Security

ICertView::GetColumnIndex [C++]

CCertView.GetColumnIndex [Visual Basic,Java]

The GetColumnIndex method retrieves the zero-based index of a column.

[C++]
HRESULT GetColumnIndex(
  LONG fResultColumn,
  BSTR const strColumnName,
  LONG *pColumnIndex
);
[Visual Basic]
objView.GetColumnIndex( fResultColumn As Long, _
  strColumnName As String ) As Long
[Java]
int GetColumnIndex(
  int fResultColumn,
  java.lang.String strColumnName
);

Parameters

[C++,Visual Basic,Java] fResultColumn
[in] If this value is TRUE, the view is based on a result set; a value of FALSE means the view is based on the full database schema. Note that TRUE is defined (in a Microsoft header file) for C/C++ programmers as 1, while Microsoft Visual Basic defines the 'True' keyword as -1. As a result, Visual Basic developers must use 1 (instead of 'True') to set this parameter to TRUE. However, to set this parameter to FALSE, Visual Basic developers can use 0 or 'False'. Java developers will need to use 1 for TRUE and 0 for FALSE when calling this method.
[C++,Visual Basic,Java] strColumnName
[in] Value representing the nonlocalized name of a column in the view.
[C++] pColumnIndex
[out] Address of variable that will contain the index of the column specified in strColumnName. This function will fail if pColumnIndex is NULL.
[Visual Basic] objView
Object expression that resolves to an ICertView object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success.

[Visual Basic,Java] The return value is the zero-based index of the column.

Remarks

This function is used to determine the index of the view column specified by strColumnName. The column indices are zero-based (the first column is index 0).

Example Code [C++]

// pCertView is pointer to ICertView.
LONG        index:
BSTR        bstrCol = NULL;
HRESULT     hr;
bstrCol = SysAllocString(TEXT("RequestID"));
hr = pView->GetColumnIndex(FALSE, bstrCol, &nIndex);
if (FAILED(hr))
{
    printf("Failed GetColumnIndex - %x\n", hr );
    goto error;
}
printf("Column %ws has index %d\n", bstrCol, nIndex);

// Free resource.
if (NULL != bstrCol)
    SysFreeString(bstrCol);

Example Code [Visual Basic]

' Retrieve the column index for RequestID.
Dim nIndex As Long
nIndex = objView.GetColumnIndex(False, "RequestID")

' Display the column index.
MsgBox nIndex, vbOKOnly, "Column index for RequestID"

Example Code [Java]

int nIndex;

// Retrieve the column index for the RequestID column.
nIndex = objView.GetColumnIndex(0, "RequestID");
System.out.println("Column index for RequestID is: " + nIndex);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertView, ICertView::SetRestriction


ICertView::OpenConnection

Platform SDK: Security

ICertView::OpenConnection [C++]

CCertView.OpenConnection [Visual Basic,Java]

The OpenConnection method establishes a connection with a Certificate Services certification authority (CA).

[C++]
HRESULT OpenConnection(
  BSTR const strConfig
);
[Visual Basic]
objView.OpenConnection( strConfig As String )
[Java]
OpenConnection(
  java.lang.String strConfig
);

Parameters

[C++,Visual Basic,Java] strConfig
[in] Represents a valid configuration string for the Certificate Services server being opened by the ICertView interface. The configuration string is in the form MACHINENAME\CANAME, where MACHINENAME is the server's network name, and CANAME is the common name of the certification authority, as entered during Certificate Services setup. See ICertConfig for information about the configuration string name.
[Visual Basic] objView
Object expression that resolves to an ICertView object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success.

[Visual Basic,Java] None.

Remarks

Upon successful completion of this function, the ICertView object will have a connection to the Certificate Services server referenced by strConfig.

[C++] To close the connection, call Release.

[Visual Basic] To close the connection, set the object to Nothing.

Example Code [C++]

ICertView *   pCertView = NULL;
BSTR          strCertServ = NULL;
HRESULT       hr;

// Initialize COM.
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

if (FAILED(hr))
{
    printf("Failed CoInitializeEx\n");
    goto error;
}
// Get pointer to the ICertView interface.
hr = CoCreateInstance(CLSID_CCertView,
                      NULL,
                      CLSCTX_INPROC_SERVER,
                      IID_ICertView,
                      (void **)&pCertView);
if (FAILED(hr))
{
    printf("Failed CoCreateInstance\n");
    goto error;
}
// The use of '\\' is necessary to represent a single backslash.
strCertServ = SysAllocString(TEXT("Server01\\ABCCertServ"));
// Open the connection to the Certificate Services server.
hr = pCertView->OpenConnection(strCertServ);
if (FAILED(hr))
{
    printf("Failed OpenConnection!\n");
    goto error;
}
else
    // Established successful connection; use view as appropriate.
    // ...
    // Done using objects; free resources.
error:
    if (NULL != pCertView)
        pCertView->Release();
    if (NULL != strCertServ)
        SysFreeString(strCertServ);
    // Free COM resources.
    CoUninitialize();

Example Code [Visual Basic]

' Declare the CertView object variable.
' Remember to reference CertAdm type library in project.
Dim objView As CCertView

' Instantiate the view object.
Set objView = New CCertView

' Open a connection.
objView.OpenConnection ("Server01\ABCCertServ")

' Use the object as needed.
' When done processing, free the object.
Set objView = Nothing

Example Code [Java]

// Declare and create an instance of the CCertView object.
// The CertAdm library is a COM wrapper added to the project.
certadm.CCertView objView;
objView = new certadm.CCertView();

try
{
    // Open a connection.
    objView.OpenConnection("server01\\myCAName");
}
catch (com.ms.com.ComFailException e)
{
    System.out.println(e.getMessage());
    System.exit(-1);
}

// Use the view object as needed.
// When done, free the object.
com.ms.com.ComLib.release(objView);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertView, ICertView::OpenView, ICertConfig


ICertView::OpenView

Platform SDK: Security

ICertView::OpenView [C++]

CCertView.OpenView [Visual Basic,Java]

The OpenView method opens a view to a Certificate Services database and instantiates the IEnumCERTVIEWROW interface.

[C++]
HRESULT OpenView(
  IEnumCERTVIEWROW **ppenum
);
[Visual Basic]
objView.OpenView() As IEnumCERTVIEWROW
[Java]
IEnumCERTVIEWROW OpenView();

Parameters

[C++] ppenum
[out] Pointer to a pointer of IEnumCERTVIEWROW type.
[Visual Basic] objView
Object expression that resolves to an ICertView object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success.

[Visual Basic,Java] The return value is an IEnumCERTVIEWROW object.

Remarks

The IEnumCERTVIEWROW object is used to enumerate the data rows in the view. The IEnumCERTVIEWROW object will be positioned to the beginning of the Certificate Services view's rows, so that a call to the object's IEnumCERTVIEWROW::Next method will reference the first row.

Before the OpenView method is called, it is necessary to call the ICertView::OpenConnection method. If you want the view to contain a non-default column set or a subset of the rows, call ICertView::SetResultColumnCount, ICertView::SetResultColumn, and ICertView::SetRestriction after ICertView::OpenConnection and before OpenView.

Example Code [C++]

// pCertView is previously instantiated pointer to ICertView.
IEnumCERTVIEWROW * pEnumRow = NULL;
HRESULT    hr;

hr = pCertView->OpenView(&pEnumRow);
if (S_OK != hr)
    printf("Failed ICertView::OpenView - %x\n", hr);
else
    // use pEnumRow as needed, to enumerate data rows
    // ...
// Done processing, free resources.
if (NULL != pEnumRow)
    pEnumRow->Release();

Example Code [Visual Basic]

' Declare the IEnumCERTVIEWROW object variable.
Dim objRow As IEnumCERTVIEWROW

' Instantiate the row object.
Set objRow = objView.OpenView

' Use the object as needed.
' When done processing, free the object.
Set objRow = Nothing

Example Code [Java]

certadm.IEnumCERTVIEWROW objRow;

// Open the view.
objRow = objView.OpenView();
// Use the row enumerator object as needed.
// When done, free the object.
com.ms.com.ComLib.release(objRow);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertView, ICertView::OpenConnection, IEnumCERTVIEWROW, IEnumCERTVIEWROW::Next


ICertView::SetRestriction

Platform SDK: Security

ICertView::SetRestriction [C++]

CCertView.SetRestriction [Visual Basic,Java]

The SetRestriction method sets sorting and qualifying restrictions on a column.

[C++]
HRESULT SetRestriction(
  LONG ColumnIndex,
  LONG SeekOperator,
  LONG SortOrder,
  VARIANT const *pvarValue
);
[Visual Basic]
objView.SetRestriction( ColumnIndex As Long, _
  SeekOperator As Long, _
  SortOrder As Long, _
  pvarValue As Variant )
[Java]
SetRestriction(
  int ColumnIndex,
  int SeekOperator,
  int SortOrder,
  Variant pvarValue
);

Parameters

[C++,Visual Basic,Java] ColumnIndex
[in] Must be a valid column index number for the view or a predefined column specifier. If ColumnIndex is not negative, this value represents the zero-based index of the column that is receiving the restriction.

If ColumnIndex is negative, all other parameters are ignored, and it must be one of the values listed in the following table.
Value for ColumnIndex | Action
CV_COLUMN_LOG_DEFAULT | Restricts view to requests that have been resolved. A request is resolved if it has resulted in an issued certificate or a failed request; revoked certificates are considered resolved.
CV_COLUMN_LOG_FAILED_DEFAULT | Restricts view to requests that have failed.
CV_COLUMN_QUEUE_DEFAULT | Restricts view to requests that have not been resolved; if a request has resulted in either an issued certificate or a failed request, it will not be part of the view.

[C++,Visual Basic,Java] SeekOperator
[in] This value is used with pvarValue and is used to define the data-query qualifier for the column. This value must be one of the values listed in the following table.
Value | Meaning
CVR_SEEK_EQ | Equal to
CVR_SEEK_LE | Less than or equal to
CVR_SEEK_LT | Less than
CVR_SEEK_GE | Greater than or equal to
CVR_SEEK_GT | Greater than

[C++,Visual Basic,Java] SortOrder
[in] Zero or one restriction can include a SortOrder specifying CVR_SORT_ASCEND or CVR_SORT_DESCEND, and it can be specified only on an indexed column. All other restrictions must use CVR_SORT_NONE.
Value | Meaning
CVR_SORT_ASCEND | Ascending
CVR_SORT_DESCEND | Descending
CVR_SORT_NONE | No sort order

[C++,Visual Basic,Java] pvarValue
[in] Variant for the data query qualifier applied to this column. This value, along with the value of SeekOperator, determines which data is returned to the Certificate Services view.
[Visual Basic] objView
Object expression that resolves to an ICertView object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success.

[Visual Basic,Java] None.

Remarks

The ICertView object maintains an array of restrictions, allowing multiple columns to contain restrictions. A column can contain more than one restriction. After the column restrictions are established, a call to the ICertView::OpenView method will retrieve the data, with each column's restrictions used as part of the database query.

Before the SetRestriction method is called, it is necessary to call the ICertView::OpenConnection method.

Example Code [C++]

    // This example restricts the data,
    // to rows that have RequestIDs greater than 5.
    // pCertView is pointer to ICertView.
    HRESULT    hr;
    VARIANT    varRest;
    LONG       nIndex;
    BSTR       bstrCol = NULL;

    // Use one column in the result set.
    hr = pCertView->SetResultColumnCount(1);
    if (FAILED(hr))
    {
        printf("Failed SetResultColumnCount - %x\n", hr);
        goto error;
    }
    // Determine the column index for RequestID column.
    bstrCol = SysAllocString(TEXT("RequestID"));
    hr = pCertView->GetColumnIndex(FALSE, bstrCol, &nIndex);
    if (FAILED(hr))
    {
        printf("Failed GetColumnIndex - %x\n", hr);
        goto error;
    }
    // Place this column into the result set.
    pCertView->SetResultColumn(nIndex);
    // Set a restriction on this column.
    VariantInit(&varRest);
    varRest.vt = VT_I4;
    varRest.lVal = 5;
    // Restrict view to requests with ID greater than 5.
    hr = pCertView->SetRestriction(nIndex,
                                   CVR_SEEK_GT,
                                   CVR_SORT_NONE,
                                   &varRest);
    if (S_OK != hr)
        printf("Failed ICertView::SetRestriction - %x\n", hr);
    else
        // Call OpenView, process rows, release resources, etc.
        // ...
error:
    // Done processing, clear resources.
    VariantClear(&varRest);
    if (NULL != bstrCol)
        SysFreeString(bstrCol);

Example Code [Visual Basic]

' This example restricts the data,
' to rows that have RequestIDs greater than 5.

' Const values recognized by CertView
Const CVR_SEEK_EQ = &H1
Const CVR_SEEK_LT = &H2
Const CVR_SEEK_LE = &H4
Const CVR_SEEK_GE = &H8
Const CVR_SEEK_GT = &H10
Const CVR_SORT_NONE = &H0
Const CVR_SORT_ASCEND = &H1
Const CVR_SORT_DESCEND = &H2

' Declare the CertView object variable
Dim objView As CCertView

' Instantiate the view object.
Set objView = New CCertView

' Open a connection.
objView.OpenConnection ("Server01\CA")

' This sample result set will contain 1 column.
objView.SetResultColumnCount (1)

' Retrieve the column index for RequestID.
Dim nIndex As Long
nIndex = objView.GetColumnIndex(False, "RequestID")

' Place this column into the result set.
objView.SetResultColumn (nIndex)

' Add a restriction.
Dim varRest As Variant
' Restrict view to records with
' RequestIDs greater than this value.
varRest = 5

' Add this restriction to the view.
objView.SetRestriction nIndex, _
                       CVR_SEEK_GT, _
                       CVR_SORT_ASCEND, _
                       varRest

' Instantiate the row object by means of OpenView,
' retrieve column data, etc (not shown).
' ...

' Done processing; free resources.
Set objView = Nothing

Example Code [Java]

// Constant values recognized by CertView.
final int CVR_SEEK_EQ = 0x1;
final int CVR_SEEK_LT = 0x2;
final int CVR_SEEK_LE = 0x4;
final int CVR_SEEK_GE = 0x8;
final int CVR_SEEK_GT = 0x10;
final int CVR_SORT_NONE = 0x0;
final int CVR_SORT_ASCEND = 0x1;
final int CVR_SORT_DESCEND = 0x2;

// Declare and create an instance of the CCertView object.
// The CertAdm library is a COM wrapper added to the project.
certadm.CCertView objView;
objView = new certadm.CCertView();

// Open a connection.
objView.OpenConnection("server01\\myCAName");

// This sample result set will contain 1 column.
objView.SetResultColumnCount(1);

// Retrieve the column index for RequestID.
int nIndex;
nIndex = objView.GetColumnIndex(0, "RequestID");

// Place this column into the result set.
objView.SetResultColumn(nIndex);

// Add a restriction.
// Restrict view to records with
// RequestIDs greater than 5.
com.ms.com.Variant varRest;
varRest = new com.ms.com.Variant(5);

// Add this restriction to the view.
objView.SetRestriction(nIndex,
                       CVR_SEEK_GT,
                       CVR_SORT_ASCEND,
                       varRest);

// Create an instance of the row object by means of OpenView,
// retrieve column data, etc (not shown).
// ...
// Clear the Variant when done.
varRest.VariantClear();

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertView, ICertView::OpenConnection, ICertView::OpenView, IEnumCertViewColumn::IsIndexed, ICertView::SetResultColumn


ICertView::SetResultColumn

Platform SDK: Security

ICertView::SetResultColumn [C++]

CCertView.SetResultColumn [Visual Basic,Java]

The SetResultColumn method specifies a column for use in a customized view of the Certificate Services database.

[C++]
HRESULT SetResultColumn(
  LONG ColumnIndex
);
[Visual Basic]
objView.SetResultColumn( ColumnIndex As Long )
[Java]
SetResultColumn(
  int ColumnIndex
);

Parameters

[C++,Visual Basic,Java] ColumnIndex
[in] Zero-based index of a column to include in the view's result set. Before calling the SetResultColumn method, it is necessary to call the ICertView::SetResultColumnCount method in order to specify the number of columns in the result set.
[Visual Basic] objView
Object expression that resolves to an ICertView object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success.

[Visual Basic,Java] None.

Remarks

On successful completion of this method, the column specified by ColumnIndex will be included in the view's result set.

The ICertView::SetResultColumnCount method must be called before calling SetResultColumn. After the caller has specified which columns are included in the result set by means of calls to SetResultColumn, the ICertView::OpenView method can be called to retrieve a row enumerator for the result set. (Optionally, before calling OpenView, the caller can specify sorting/qualifying criteria through calls to the ICertView::SetRestriction method.)

This function will fail if the ICertView::SetResultColumnCount method has been called with a parameter value of CV_COLUMN_LOG_DEFAULT, CV_COLUMN_LOG_FAILED_DEFAULT, or CV_COLUMN_QUEUE_DEFAULT. This function will fail if the caller attempts to include more columns in the result set than have been specified in the call to the ICertView::SetResultColumnCount method.

Example Code [C++]

    HRESULT    hr;
    LONG       nCount;
    LONG       i;

    // Determine the number of columns in the entire database.
    // pCertView is a pointer to ICertView.
    hr = pCertView->GetColumnCount(FALSE, &nCount);
    if (FAILED(hr))
    {
        printf("Failed GetColumnCount - %x\n", hr);
        goto error;
    }
    hr = pCertView->SetResultColumnCount( nCount );
    if (FAILED(hr))
    {
        printf("Failed SetResultColumnCount - %x\n", hr);
        goto error;
    }
    // Place each column in the view.
    for (i = 0; i < nCount; i++)
    {
        hr = pCertView->SetResultColumn(i);
        if (FAILED(hr))
        {
            printf("Failed SetResultColumn (%d) - %x\n", i, hr );
            goto error;
        }
    }
    // Call ICertView::OpenView, etc.
    // ...

error:
    // Clean up resources, etc.

Example Code [Visual Basic]

Dim objView As CCertView
Set objView = New CCertView

objView.OpenConnection ("Server01\CA")

' Determine number of columns in the entire database.
Dim nCount As Long
nCount = objView.GetColumnCount(False)

' Set the number of columns in the view.
objView.SetResultColumnCount (nCount)

' Place each column in the view.
For i = 0 To nCount - 1
    objView.SetResultColumn (i)
Next i

' Call OpenView, etc.
' ...

Example Code [Java]

// Determine the number of columns in the database.
// OpenConnection has already been called.
int nCol;
nCol = objView.GetColumnCount(0);

// Set the number of columns in the view.
objView.SetResultColumnCount(nCol);

// Place each column in the view.
for (int i=0; i < nCol; i++)
    objView.SetResultColumn(i);
// Call OpenView, etc.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertView, ICertView::OpenView, ICertView::SetRestriction, ICertView::SetResultColumnCount


ICertView::SetResultColumnCount

Platform SDK: Security

ICertView::SetResultColumnCount [C++]

CCertView.SetResultColumnCount [Visual Basic,Java]

The SetResultColumnCount method sets the number of columns in a customized view of the Certificate Services database.

[C++]
HRESULT SetResultColumnCount(
  LONG cResultColumn
);
[Visual Basic]
objView.SetResultColumnCount( cResultColumn As Long )
[Java]
SetResultColumnCount(
  int cResultColumn
);

Parameters

[C++,Visual Basic,Java] cResultColumn
[in] Value representing how many columns will be in the view's result set. This value must not be negative, with the following exceptions:
  • cResultColumn is CV_COLUMN_LOG_DEFAULT. In this case the number of columns in the result set will be the number of columns in the Certificate Services's default result set for requests that have been resolved. A request is resolved if it has resulted in an issued certificate or a failed request; revoked certificates are considered resolved.
  • cResultColumn is CV_COLUMN_LOG_FAILED_DEFAULT. In this case the number of columns in the result set will be the number of columns in the Certificate Services's default result set for requests that have failed.
  • cResultColumn is CV_COLUMN_QUEUE_DEFAULT. In this case the number of columns in the result set will be the number of columns in the Certificate Services's default result set for requests that have not been resolved.

This function will fail for any other negative values for cResultColumn. If cResultColumn is not negative, the ICertView::SetResultColumn method must be called to specify the columns to include in the view's result set.

[Visual Basic] objView
Object expression that resolves to an ICertView object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success.

[Visual Basic,Java] None.

Remarks

Upon successful completion of this function, the number of columns in the view's result set will be cResultColumn if cResultColumn is positive. If cResultColumn is a valid negative number, the number of columns in the view's result set will correspond to a predefined result set (see the Parameters section for cResultColumn).

The ICertView::OpenConnection method must be called before calling SetResultColumnCount. This function will fail if called more than once on an open connection.

Example Code [C++]

HRESULT    hr;
// Specify the result set for logged requests.
// pCertView is pointer to ICertView (which has an Open Connection)
hr = pCertView->SetResultColumnCount(CV_COLUMN_LOG_DEFAULT);
if (S_OK != hr)
    printf("Failed ICertView::SetResultColumnCount - %x\n", hr);
else
    // Retrieve data rows by means of ICertView::OpenView.
    // ...

Example Code [Visual Basic]

' Consts for CertView.
Const CV_COLUMN_QUEUE_DEFAULT = -1
Const CV_COLUMN_LOG_DEFAULT = -2
Const CV_COLUMN_LOG_FAILED_DEFAULT =-3

' This sample utilizes the default log view.
objView.SetResultColumnCount (CV_COLUMN_LOG_DEFAULT)

Example Code [Java]

// Contstants use by CCertView.SetResultColumnCount.
final int CV_COLUMN_QUEUE_DEFAULT = -1;
final int CV_COLUMN_LOG_DEFAULT = -2;
final int CV_COLUMN_LOG_FAILED_DEFAULT = -3;

// This sample uses the default log view.
objView.SetResultColumnCount(CV_COLUMN_LOG_DEFAULT);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertView, ICertView::OpenConnection, ICertView::SetRestriction, ICertView::SetResultColumn


ICertView2

[This is preliminary documentation and subject to change.]

The ICertView2 interface inherits all of the methods of ICertView and includes the following new method.

Method | Description
SetTable | Specifies which table will be used by subsequent ICertView2 methods.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.


ICertView2::SetTable

[This is preliminary documentation and subject to change.]

The SetTable method is used to specify which Certificate Services database table will be used for subsequent operations. To use this method, call it after ICertView2::OpenConnection, but before any other ICertView2 method. If this method is not called, then the default table (CVRC_TABLE_REQCERT) will be used by the ICertView2 methods.

HRESULT ICertView2::SetTable(
  LONG Table
);

Parameters

Table
[in] LONG value representing the Certificate Services database table to use for subsequent operations. This value must be one of the values in the following table.
Table Identifier | Description
CVRC_TABLE_ATTRIBUTES | The attributes table is used for subsequent ICertView2 operations.
CVRC_TABLE_CRL | The certificate revocation list (CRL) table is used for subsequent ICertView2 operations.
CVRC_TABLE_EXTENSIONS | The extensions table is used for subsequent ICertView2 operations.
CVRC_TABLE_REQCERT | The table of pending requests, denied requests, issued certificates and revoked certificates is used for subsequent ICertView2 operations.

Return Values

The return value is an HRESULT. A value of S_OK indicates the method was successful.

Example Code [C++]

HRESULT hr;

// Specify the certificate revocation list table.
hr = pCertView2->SetTable(CVRC_TABLE_CRL);
if (FAILED(hr))
{
    printf("Failed SetTable\n");
    exit(1);  // Or other error action.
}

Example Code [Visual Basic]

' Constants of table identifiers.
Const CVRC_TABLE_REQCERT As Long = 0
Const CVRC_TABLE_EXTENSIONS As Long = &H3000
Const CVRC_TABLE_ATTRIBUTES As Long = &H4000
Const CVRC_TABLE_CRL As Long = &H5000

' CertAdm's type library is referenced in the project.
Dim objView2 As CCertView
Set objView2 = New CCertView

' Open a connection.
objView2.OpenConnection ("\\SERVER01\MyCA")
' Specify the certificate revocation list table.
objView2.SetTable (CVRC_TABLE_CRL)

' Use the other CCertView methods as needed.
' ...

' When done, free the object.
Set objView2 = Nothing

Example Code [Java]

final int CVRC_TABLE_REQCERT    = 0;
final int CVRC_TABLE_EXTENSIONS = 0x3000;
final int CVRC_TABLE_ATTRIBUTES = 0x4000;
final int CVRC_TABLE_CRL        = 0x5000;

try
{
    // Declare and create an instance of the object.
    certadm.CCertView objView2;
    objView2 = new certadm.CCertView();

    // Open a connection.
    objView2.OpenConnection("\\\\SERVER01\\MyCA");

    // Specify the certificate revocation list table.
    objView2.SetTable(CVRC_TABLE_CRL);

    // Use the other methods as needed...

    // Free the object when done.
    com.ms.com.ComLib.release(objView2);
}
catch (com.ms.com.ComFailException e)
{
    System.out.println(e.getMessage());
}

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.


IEnumCERTVIEWATTRIBUTE

Platform SDK: Security

IEnumCERTVIEWATTRIBUTE [C++]

IEnumCERTVIEWATTRIBUTE [Visual Basic,Java]

The IEnumCERTVIEWATTRIBUTE interface is used to access the certificate attributes for a row in the Certificate Services's view. An IEnumCERTVIEWATTRIBUTE interface is instantiated through a call to IEnumCERTVIEWROW::EnumCertViewAttribute.

IEnumCERTVIEWATTRIBUTE is defined in certview.h. When you create your program, however, use certsrv.h as the include file. CertAdm.dll provides the IEnumCERTVIEWATTRIBUTE interface. The type information for this interface is also in CertAdmL.dll, which is shipped with the Platform SDK.

The Certificate Services interfaces support only the apartment-threading model.

The following methods are provided by the IEnumCERTVIEWATTRIBUTE interface.

Method | Description
Clone | Creates a copy of the IEnumCERTVIEWATTRIBUTE object.
GetName | Retrieves the name of the attribute.
GetValue | Retrieves the attribute value.
Next | Positions the IEnumCERTVIEWATTRIBUTE object to the next attribute.
Reset | Resets the IEnumCERTVIEWATTRIBUTE enumeration sequence to the beginning.
Skip | Skips a specified number of attributes in the IEnumCERTVIEWATTRIBUTE enumeration sequence.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWROW::EnumCertViewAttribute


IEnumCERTVIEWATTRIBUTE::Clone

Platform SDK: Security

IEnumCERTVIEWATTRIBUTE::Clone [C++]

IEnumCERTVIEWATTRIBUTE.Clone [Visual Basic,Java]

The Clone method creates a copy of the IEnumCERTVIEWATTRIBUTE object in its current state.

[C++]
HRESULT Clone(
  IEnumCERTVIEWATTRIBUTE **ppenum
);
[Visual Basic]
objCERTVIEWATTRIBUTE.Clone() As IEnumCERTVIEWATTRIBUTE
[Java]
IEnumCERTVIEWATTRIBUTE Clone();

Parameters

[C++] ppenum
[out] Pointer to a pointer of IEnumCERTVIEWATTRIBUTE type. This function will fail if ppenum is NULL.
[Visual Basic] objCERTVIEWATTRIBUTE
Object expression that resolves to an IEnumCERTVIEWATTRIBUTE object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success.

[Visual Basic,Java] The return value is a cloned IEnumCERTVIEWATTRIBUTE object.

Remarks

This function is used to clone the IEnumCERTVIEWATTRIBUTE object.

Example Code [C++]

// pEnumAttr is previously instantied IEnumCERTVIEWATTRIBUTE object
IEnumCERTVIEWATTRIBUTE * pEnumAttr2 = NULL;
HRESULT    hr;
hr = pEnumAttr->Clone(&pEnumAttr2);
if (S_OK != hr)
    printf("Unable to clone IEnumCERTVIEWATTRIBUTE\n");
else
    // use cloned object as needed
    // ...
// done using cloned object, free memory
if (NULL != pEnumAttr2)
    pEnumAttr2->Release();

Example Code [Visual Basic]

Dim objAttrib2 As IEnumCERTVIEWATTRIBUTE
Set objAttrib2 = objAttrib.Clone()

' Use the cloned attribute object as needed.
' ...
' When done, free the cloned attribute object.
Set objAttrib2 = Nothing
certadm.IEnumCERTVIEWATTRIBUTE objAttrib2;

// Clone an attribute enumerator.
objAttrib2 = objAttrib.Clone();

// When done, free the cloned object.
com.ms.com.ComLib.release(objAttrib2);

Example Code [Java]

certadm.IEnumCERTVIEWATTRIBUTE objAttrib2;

// Clone an attribute enumerator.
objAttrib2 = objAttrib.Clone();

// When done, free the cloned object.
com.ms.com.ComLib.release(objAttrib2);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWATTRIBUTE


IEnumCERTVIEWATTRIBUTE::GetName

Platform SDK: Security

IEnumCERTVIEWATTRIBUTE::GetName [C++]

IEnumCERTVIEWATTRIBUTE.GetName [Visual Basic,Java]

The GetName method retrieves the name of the attribute.

[C++]
HRESULT GetName(
  BSTR *pstrOut
);
[Visual Basic]
objCERTVIEWATTRIBUTE.GetName() As String
[Java]
java.lang.String GetName();

Parameters

[C++] pstrOut
[out] Pointer to a variable of BSTR type that will contain the name of the attribute.
[Visual Basic] objCERTVIEWATTRIBUTE
Object expression that resolves to an IEnumCERTVIEWATTRIBUTE object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success and *pstrOut is set to the BSTR representing the name of the attribute. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable as pstrOut. You must free *pstrOut when done (by means of SysFreeString).

[Visual Basic,Java] The return value is a String representing the name of the attribute.

Remarks

This function is used to retrieve the name of the attribute currently referenced by the IEnumCERTVIEWATTRIBUTE object.

If the IEnumCERTVIEWATTRIBUTE object is not referencing a valid attribute, GetName will fail. Use the IEnumCERTVIEWATTRIBUTE::Next method to reference a valid attribute.

Example Code [C++]

BSTR    bstrAttribName = NULL;

// pEnumAttr is previously instantiated IEnumCERTVIEWATTRIBUTE object
hr = pEnumAttr->GetName(&bstrAttribName);
if (S_OK != hr)
    printf("Failed call to GetName - %x\n", hr);
else
    printf("Attribute name is %ws\n", bstrAttribName );

// free memory when done
if (NULL != bstrAttribName)
    SysFreeString(bstrAttribName);

Example Code [Visual Basic]

Dim strAttrName As String
strAttrName = objAttrib.GetName()
' Use the attribute name as needed.
MsgBox (strAttrName)

Example Code [Java]

java.lang.String strAttrName;

// Retrieve and display the attribute name.
strAttrName = objAttrib.GetName();
System.out.println("Attribute Name " + strAttrName);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWATTRIBUTE, IEnumCERTVIEWATTRIBUTE::GetValue, IEnumCERTVIEWATTRIBUTE::Next


IEnumCERTVIEWATTRIBUTE::GetValue

Platform SDK: Security

IEnumCERTVIEWATTRIBUTE::GetValue [C++]

IEnumCERTVIEWATTRIBUTE.GetValue [Visual Basic,Java]

The GetValue method retrieves the attribute value.

[C++]
HRESULT GetValue(
  BSTR *pstrOut
);
[Visual Basic]
objCERTVIEWATTRIBUTE.GetValue() As String
[Java]
java.lang.String GetValue();

Parameters

[C++] pstrOut
[out] Pointer to a BSTR type that will contain the value of the attribute.
[Visual Basic] objCERTVIEWATTRIBUTE
Object expression that resolves to an IEnumCERTVIEWATTRIBUTE object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success and *pstrOut is set to the BSTR representing value of the attribute. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable as pstrOut. You must free *pstrOut when done (by means of SysFreeString).

[Visual Basic,Java] The return value is a String representing the value of the attribute.

Remarks

This function is used to retrieve the data in the attribute currently being referenced by the IEnumCERTVIEWATTRIBUTE object.

If the IEnumCERTVIEWATTRIBUTE object is not referencing a valid attribute, GetValue will fail. Use IEnumCERTVIEWATTRIBUTE::Next to reference a valid attribute.

ExampleCode [C++]

BSTR    bstrAttribValue = NULL;

// pEnumAttr is previously instantiated IEnumCERTVIEWATTRIBUTE object
hr = pEnumAttr->GetValue(&bstrAttribValue);
if (S_OK != hr)
    printf("Failed call to GetValue - %x\n", hr);
else
    printf("Attribute value is %ws\n",bstrAttribValue);

// free memory when done
if (NULL != bstrAttribValue)
    SysFreeString(bstrAttribValue);

ExampleCode [Visual Basic]

Dim strAttrValue As String
strAttrValue = objAttrib.GetValue()
' Use the attribute value as needed.
MsgBox (strAttrValue)

Example Code [Java]

java.lang.String strAttrValue;

// Retrieve and display the attribute value.
strAttrValue = objAttrib.GetValue();
System.out.println("Attribute Value " + strAttrValue);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWATTRIBUTE , IEnumCERTVIEWATTRIBUTE::GetName, IEnumCERTVIEWATTRIBUTE::Next


IEnumCERTVIEWATTRIBUTE::Next

Platform SDK: Security

IEnumCERTVIEWATTRIBUTE::Next [C++]

IEnumCERTVIEWATTRIBUTE.Next [Visual Basic,Java]

The Next method positions the IEnumCERTVIEWATTRIBUTE object to the next attribute.

[C++]
HRESULT Next(
  LONG *pIndex
);
[Visual Basic]
objCERTVIEWATTRIBUTE.Next() As Long
[Java]
int Next();

Parameters

[C++] pIndex
[out] Pointer to variable that will contain the index value of the next attribute being referenced. If there are no more attributes to enumerate, this variable is set to –1. This function fails if pIndex is NULL.
[Visual Basic] objCERTVIEWATTRIBUTE
Object expression that resolves to an IEnumCERTVIEWATTRIBUTE object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success and that the next attribute is now being referenced by the IEnumCERTVIEWATTRIBUTE object. If there are no more attributes, S_FALSE is returned, and *pIndex is set to a value of –1.

[Visual Basic,Java] The return value is the index value of the next attribute that will be referenced by the IEnumCERTVIEWATTRIBUTE object. If there are no more attributes to enumerate, the return value will be –1.

Remarks

Upon successful completion of this function, the IEnumCERTVIEWATTRIBUTE object will reference the next attribute. When the attribute is referenced, the attribute name and value can be accessed through the IEnumCERTVIEWATTRIBUTE::GetName and IEnumCERTVIEWATTRIBUTE::GetValue methods.

Example Code [C++]

LONG       Index;
HRESULT    hr;
BSTR       bstrAttribName = NULL;

// pEnumAttr is previously instantiated IEnumCERTVIEWATTRIBUTE object
while (S_OK == pEnumAttr->Next(&Index))
{
    // retrieve the attribute name
    hr = pEnumAttr->GetName(&bstrAttribName);
    if (FAILED(hr))
        printf("Failed GetName -  %x\n", hr );
    else
        printf("Attribute name: %ws\n", bstrAttribName);
}

// Free resources.
if (NULL != bstrAttribName)
    SysFreeString(bstrAttribName);

ExampleCode [Visual Basic]

Dim nIndex As Long
nIndex = objAttrib.Next()
Do While (nIndex <> -1)
    ' Use this attribute as needed.
    ' ...
    ' Move to the next attribute.
    nIndex = objAttrib.Next()
Loop

Example Code [Java]

// Iterate through the attributes.
nIndex = objAttrib.Next();
while (-1 != nIndex)
{
    // Use the attribute as needed. This example
    // displays the attribute name and value.
    System.out.println(objAttrib.GetName() + ":" +
                       objAttrib.GetValue());

    // Move to the next attribute.
    nIndex = objAttrib.Next();
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWATTRIBUTE, IEnumCERTVIEWATTRIBUTE::GetName, IEnumCERTVIEWATTRIBUTE::GetValue, IEnumCERTVIEWATTRIBUTE::Skip, IEnumCERTVIEWATTRIBUTE::Reset


IEnumCERTVIEWATTRIBUTE::Reset

Platform SDK: Security

IEnumCERTVIEWATTRIBUTE::Reset [C++]

IEnumCERTVIEWATTRIBUTE.Reset [Visual Basic,Java]

The Reset method resets the IEnumCERTVIEWATTRIBUTE enumeration sequence to the beginning.

[C++]
HRESULT Reset();
[Visual Basic]
objCERTVIEWATTRIBUTE.Reset()
[Java]
void Reset();

Parameters

[Visual Basic] objCERTVIEWATTRIBUTE
Object expression that resolves to an IEnumCERTVIEWATTRIBUTE object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success.

[Visual Basic,Java] None.

Remarks

Upon successful completion of this function, the IEnumCERTVIEWATTRIBUTE object will be positioned to the beginning of the object's attributes. To reference the first attribute after calling the IEnumCERTVIEWATTRIBUTE::Reset method, call the IEnumCERTVIEWATTRIBUTE::Next method. When a valid attribute is referenced, data can be retrieved by calls to the IEnumCERTVIEWATTRIBUTE::GetName and IEnumCERTVIEWATTRIBUTE::GetValue methods.

Example Code [C++]

// pEnumAttr is previously instantiated IEnumCERTVIEWATTRIBUTE object
HRESULT  hr;
LONG     Index;

hr = pEnumAttr->Reset();
if (S_OK != hr)
    printf("Unable to reset pEnumAttr - %x\n", hr );
    // call appropriate error handler / exit routine
else
{
    // reset to beginning of attributes again
    while (S_OK == pEnumAttr->Next(&Index))
    {
        // Use each attribute as needed.
    }
}

Example Code [Visual Basic]

objAttrib.Reset

Example Code [Java]

objAttrib.Reset();

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWATTRIBUTE, IEnumCERTVIEWATTRIBUTE::GetName, IEnumCERTVIEWATTRIBUTE::GetValue, IEnumCERTVIEWATTRIBUTE::Next, IEnumCERTVIEWATTRIBUTE::Reset, IEnumCERTVIEWATTRIBUTE::Skip


IEnumCERTVIEWATTRIBUTE::Skip

Platform SDK: Security

IEnumCERTVIEWATTRIBUTE::Skip [C++]

IEnumCERTVIEWATTRIBUTE.Skip [Visual Basic,Java]

The Skip method skips a specified number of attributes in the IEnumCERTVIEWATTRIBUTE enumeration sequence.

[C++]
HRESULT Skip(
  LONG celt
);
[Visual Basic]
objCERTVIEWATTRIBUTE.Skip( celt As Long )
[Java]
void Skip(
  int celt
);

Parameters

[C++,Visual Basic,Java] celt
[in] Number of attributes for the IEnumCERTVIEWATTRIBUTE object to skip. A positive value for celt causes the IEnumCERTVIEWATTRIBUTE object to skip forward in the enumeration sequence; a negative value for celt causes the IEnumCERTVIEWATTRIBUTE object to skip backward in the enumeration sequence.
[Visual Basic] objCERTVIEWATTRIBUTE
Object expression that resolves to an IEnumCERTVIEWATTRIBUTE object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success. A return value of E_INVALIDARG indicates that a negative value for celt caused the IEnumCERTVIEWATTRIBUTE object's index to become less than zero.

[Visual Basic,Java] None.

Remarks

Upon successful completion of this function, the IEnumCERTVIEWATTRIBUTE object will have skipped celt attributes in the enumeration sequence. To access the attribute contents after a call to the IEnumCERTVIEWATTRIBUTE::Skip method, call the IEnumCERTVIEWATTRIBUTE::Next method.

The IEnumCERTVIEWATTRIBUTE object maintains an internal value representing the zero-based index of the attribute to be accessed when the IEnumCERTVIEWATTRIBUTE::Next method is called. A call to the IEnumCERTVIEWATTRIBUTE::Skip method causes this index to increase by celt if celt is positive, or to decrease by celt if celt is negative.

If celt causes the index to be less than zero, the behavior of subsequent calls to IEnumCERTVIEWATTRIBUTE::Next is undefined.

Positive values for celt are not validated, but if a positive value for celt causes the internal value to exceed the index for the last column in the enumeration sequence, a subsequent call to the IEnumCERTVIEWATTRIBUTE::Next method will fail.

Example Code [C++]

HRESULT  hr;
LONG     Index;

// pEnumAttr is previously instantiated IEnumCERTVIEWATTRIBUTE object
// skip the next 5 attributes
hr = pEnumAttr->Skip(5);
if (S_OK == hr)
{
    // get the next attribute
    hr = pEnumAttr->Next(&Index);
    if (S_OK == hr)
    {
        // Use this attribute as needed.
    }
}

Example Code [Visual Basic]

' Skip two items in the attribute enumeration sequence.
objAttrib.Skip (2)

Example Code [Java]

// Skip two items in the attribute enumeration sequence.
objAttrib.Skip(2);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWATTRIBUTE, IEnumCERTVIEWATTRIBUTE:Next, IEnumCERTVIEWATTRIBUTE::Reset, IEnumCERTVIEWATTRIBUTE::Skip


IEnumCERTVIEWCOLUMN

Platform SDK: Security

IEnumCERTVIEWCOLUMN [C++]

IEnumCERTVIEWCOLUMN [Visual Basic,Java]

The IEnumCERTVIEWCOLUMN interface is used to access the data columns of a row in the Certificate Services's view. An IEnumCERTVIEWCOLUMN interface is instantiated through a call to the ICertView::EnumCertViewColumn method, the IEnumCERTVIEWROW::EnumCertViewColumn method, or the IEnumCERTVIEWCOLUMN::Clone method.

IEnumCERTVIEWCOLUMN is defined in certview.h. When you create your program, however, use certsrv.h as the include file. CertAdm.dll provides the IEnumCERTVIEWCOLUMN interface. The type information for this interface is also in CertAdmL.dll, which is shipped with the Platform SDK.

The Certificate Services interfaces support only the apartment-threading model.

The following methods are provided by the IEnumCERTVIEWCOLUMN interface.

Method | Description
Clone | Creates a copy of the IEnumCERTVIEWCOLUMN object.
GetDisplayName | Retrieves the localized name of the column.
GetMaxLength | Retrieves the maximum allowable length for the column data.
GetName | Retrieves the name of the column.
GetType | Retrieves the data type of the column.
GetValue | Retrieves the data value of the column.
IsIndexed | Reports whether column is indexed.
Next | Positions the IEnumCERTVIEWCOLUMN object to the next column.
Reset | Resets the IEnumCERTVIEWCOLUMN enumeration sequence to the beginning.
Skip | Skips a specified number of columns in the IEnumCERTVIEWCOLUMN enumeration sequence.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertView::EnumCertViewColumn, IEnumCERTVIEWROW::EnumCertViewColumn


IEnumCERTVIEWCOLUMN::Clone

Platform SDK: Security

IEnumCERTVIEWCOLUMN::Clone [C++]

IEnumCERTVIEWCOLUMN.Clone [Visual Basic,Java]

The Clone method creates a copy of the IEnumCERTVIEWCOLUMN object in its current state.

[C++]
HRESULT Clone(
  IEnumCERTVIEWCOLUMN **ppenum
);
[Visual Basic]
objCERTVIEWCOLUMN.Clone() As IEnumCERTVIEWCOLUMN
[Java]
IEnumCERTVIEWCOLUMN Clone();

Parameters

[C++] ppenum
[out] Pointer to a pointer of IEnumCERTVIEWCOLUMN type; upon successful completion of this function, *ppenum is set to the cloned object. This function will fail if ppenum is NULL.
[Visual Basic] objCERTVIEWCOLUMN
Object expression that resolves to an IEnumCERTVIEWCOLUMN object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success.

[Visual Basic,Java] The return value is a cloned IEnumCERTVIEWCOLUMN object.

Remarks

This function is used to clone the IEnumCERTVIEWCOLUMN object.

Example Code [C++]

// pEnumCol is previously instantiated IEnumCERTVIEWCOLUMN object
IEnumCERTVIEWCOLUMN * pEnumCol2 = NULL;
HRESULT    hr;
hr = pEnumCol->Clone(&pEnumCol2);
if (S_OK != hr)
    printf("Unable to clone IEnumCERTVIEWCOLUMN\n");
else
    // use cloned object as needed
    // ...
    // done using cloned object, free memory
if (NULL != pEnumCol2)
    pEnumCol2->Release();

Example Code [Visual Basic]

Dim objColNew As IEnumCERTVIEWCOLUMN

' Clone a column enumerator.
Set objColNew = objCol.Clone()
' Use cloned object as needed.
' ...

' Free object when done.
Set objColNew = Nothing

Example Code [Java]

certadm.IEnumCERTVIEWCOLUMN objCol2;

// Clone a column enumerator.
objCol2 = objCol.Clone();
// Use cloned object as needed.

// Free object when done.
com.ms.com.ComLib.release(objCol2);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IenumCERTVIEWCOLUMN


IEnumCERTVIEWCOLUMN::GetDisplayName

Platform SDK: Security

IEnumCERTVIEWCOLUMN::GetDisplayName [C++]

IEnumCERTVIEWCOLUMN.GetDisplayName [Visual Basic,Java]

The GetDisplayName method retrieves the localized name of the column.

[C++]
HRESULT GetDisplayName(
  BSTR *pstrOut
);
[Visual Basic]
objCERTVIEWCOLUMN.GetDisplayName() As String
[Java]
java.lang.String GetDisplayName();

Parameters

[C++] pstrOut
[out] Pointer to a BSTR type that will contain the localized name of the column.
[Visual Basic] objCERTVIEWCOLUMN
Object expression that resolves to an IEnumCERTVIEWCOLUMN object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success and *pstrOut is set to the BSTR representing the localized name of the column. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable as pstrOut. You must free *pstrOut when done (by means of SysFreeString).

[Visual Basic,Java] The return value is a String representing the localized name of the column.

Remarks

This function is used to retrieve the localized name of the Certificate Services view column currently referenced by the IEnumCERTVIEWCOLUMN object.

If the IEnumCERTVIEWCOLUMN object is not referencing a valid column, GetDisplayName will fail. Use the IEnumCERTVIEWCOLUMN::Next method to reference a valid column.

Example Code [C++]

BSTR     bstrDisplay = NULL;
HRESULT  hr;

// pEnumCol is previously instantiated IEnumCERTVIEWCOLUMN object.
hr = pEnumCol->GetDisplayName(&bstrDisplay);
if (S_OK == hr)
    printf("Column name is %ws\n", bstrDisplay);

// Done processing, clear resources.
if (NULL != bstrDisplay)
    SysFreeString(bstrDisplay);

Example Code [Visual Basic]

' Retrieve the display (localized) name.
Dim strDisplayName As String
strDisplayName = objCol.GetDisplayName()
MsgBox (strDisplayName)

Example Code [Java]

java.lang.String strDisplayName;

// Retrieve the (localized) name.
strDisplayName = objCol.GetDisplayName();
System.out.println(strDisplayName);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWCOLUMN object, IEnumCERTVIEWCOLUMN::GetName , IEnumCERTVIEWCOLUMN::GetType, IEnumCERTVIEWCOLUMN::GetValue, IEnumCERTVIEWCOLUMN::Next


IEnumCERTVIEWCOLUMN::GetMaxLength

Platform SDK: Security

IEnumCERTVIEWCOLUMN::GetMaxLength [C++]

IEnumCERTVIEWCOLUMN.GetMaxLength [Visual Basic,Java]

The GetMaxLength method retrieves the maximum allowable length for the column data. The returned value is in bytes. If the column data's type is PROPTYPE_STRING, divide the number of bytes by sizeof(WCHAR) to determine the maximum number of Unicode characters.

[C++]
HRESULT GetMaxLength(
  LONG *pMaxLength
);
[Visual Basic]
objCERTVIEWCOLUMN.GetMaxLength() As Long
[Java]
int GetMaxLength();

Parameters

[C++] pMaxLength
[out] Pointer to a Long value that will contain the maximum allowable length for the column data. This function will fail if pMaxLength is NULL.
[Visual Basic] objCERTVIEWCOLUMN
Object expression that resolves to an IEnumCERTVIEWCOLUMN object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success. Upon successful completion of this function, *pMaxLength is set to the value containing the maximum allowable length for the column data.

[Visual Basic,Java] The return value is the maximum allowable length for the column data.

Remarks

This function is used to determine the maximum allowable data length for the column currently being referenced by the IEnumCERTVIEWCOLUMN object.

If the IEnumCERTVIEWCOLUMN object is not referencing a valid column, GetMaxLength will fail. Use the IEnumCERTVIEWCOLUMN::Next method to reference a valid column.

Example Code [C++]

// pEnumCol is previously instantiated IEnumCERTVIEWCOLUMN object
HRESULT  hr;
LONG     nLength;

// determine database length
hr = pEnumCol->GetMaxLength(&nLength);
if (S_OK == hr)
    printf("max length is %d\n", nLength);

Example Code [Visual Basic]

' Retrieve the column data's maximum length.
Dim nMax As Long
nMax = objCol.GetMaxLength()
MsgBox (nMax)

Example Code [Java]

int nMax;

// Determine the column data's maximum length.
nMax = objCol.GetMaxLength();
System.out.println("Max length is " + nMax);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWCOLUMN::Next, IEnumCERTVIEWCOLUMN, IEnumCERTVIEWCOLUMN::IsIndexed


IEnumCERTVIEWCOLUMN::GetName

Platform SDK: Security

IEnumCERTVIEWCOLUMN::GetName [C++]

IEnumCERTVIEWCOLUMN.GetName [Visual Basic,Java]

The GetName method retrieves the name of the column.

[C++]
HRESULT GetName(
  BSTR *pstrOut
);
[Visual Basic]
objCERTVIEWCOLUMN.GetName() As String
[Java]
java.lang.String GetName();

Parameters

[C++] pstrOut
[out] Pointer to a BSTR type that will contain the name of the column.
[Visual Basic] objCERTVIEWCOLUMN
Object expression that resolves to an IEnumCERTVIEWCOLUMN object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success and *pstrOut is set to the BSTR representing the name of the column. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable as pstrOut. You must free *pstrOut when done (by means of SysFreeString).

[Visual Basic,Java] The return value is a String representing the name of the column.

Remarks

This function is used to retrieve the nonlocalized name of the Certificate Services view column currently referenced by the IEnumCERTVIEWCOLUMN object.

If the IEnumCERTVIEWCOLUMN object is not referencing a valid column, GetName will fail. Use the IEnumCERTVIEWCOLUMN::Next method to reference a valid column.

Example Code [C++]

BSTR       bstrColName = NULL;
HRESULT    hr;

// pEnumCol is previously instantiated IEnumCERTVIEWCOLUMN object
hr = pEnumCol->GetName(&bstrColName);
if (S_OK == hr)
    printf("Column name is %ws\n", bstrColName);

// done processing, clear resources
if (NULL != bstrColName)
    SysFreeString(bstrColName);

Example Code [Visual Basic]

' Retrieve the column name.
Dim strName As String
strName = objCol.GetName()
MsgBox (strName)

Example Code [Java]

java.lang.String strName;

// Retrieve and display the column name.
strName = objCol.GetName();
System.out.println(strName);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWCOLUMN object, IEnumCERTVIEWCOLUMN::GetDisplayName, IEnumCERTVIEWCOLUMN::GetType, IEnumCERTVIEWCOLUMN::GetValue, IEnumCERTVIEWCOLUMN::Next


IEnumCERTVIEWCOLUMN::GetType

Platform SDK: Security

IEnumCERTVIEWCOLUMN::GetType [C++]

IEnumCERTVIEWCOLUMN.GetType [Visual Basic,Java]

The GetType method retrieves the data type of the column.

[C++]
HRESULT GetType(
  LONG *pType
);
[Visual Basic]
objCERTVIEWCOLUMN.GetType() As Long
[Java]
int GetType();

Parameters

[C++] pType
[out] Pointer to a Long type that will denote the data type of the referenced view column. This function will fail if pType is NULL.
[Visual Basic] objCERTVIEWCOLUMN
Object expression that resolves to an IEnumCERTVIEWCOLUMN object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success.

[Visual Basic,Java] The return value represents the data type of the column.

Remarks

This function is used to determine the data type of the Certificate Services view column currently referenced by the IEnumCERTVIEWCOLUMN object. The valid data types are listed in the following table.

Data Type | Meaning
PROPTYPE_BINARY | Binary data
PROPTYPE_DATE | Date+Time
PROPTYPE_LONG | Signed Long
PROPTYPE_STRING | Unicode String

If the IEnumCERTVIEWCOLUMN object is not referencing a valid column, GetType will fail. Use the IEnumCERTVIEWCOLUMN::Next method to reference a valid column.

Example Code [C++]

LONG     nType;
HRESULT  hr;

// pEnumCol is previously instantiated IEnumCERTVIEWCOLUMN object
hr = pEnumCol->GetType(&nType);
if (S_OK == hr)
{
    switch (nType)
    {
        case PROPTYPE_BINARY:
            printf("Type is Binary\n");
            break;
        case PROPTYPE_DATE:
            printf("Type is Date+Time\n");
            break;
        case PROPTYPE_LONG:
            printf("Type is Signed long\n");
            break;
        case PROPTYPE_STRING:
            printf("Type is Unicode String\n");
            break;
        default:
            printf("Type is unknown\n");
            break;
    }
}

Example Code [Visual Basic]

' Constants for values of interest.
Const PROPTYPE_LONG  As Long = &H1
Const PROPTYPE_DATE  As Long = &H2
Const PROPTYPE_BINARY As Long = &H3
Const PROPTYPE_STRING As Long = &H4

' Determine the column data type.
Dim nType As Long

nType = objCol.GetType()

' Compare the column data type with the constants.
Select Case nType
    Case PROPTYPE_LONG:
        MsgBox ("Data type is Long")
    Case PROPTYPE_DATE:
        MsgBox ("Data type is Date")
    Case PROPTYPE_BINARY:
        MsgBox ("Data type is Binary")
    Case PROPTYPE_STRING:
        MsgBox ("Data type is String")
    Case Else
        MsgBox("Unexpected data type")
End Select

Example Code [Java]

// Constants for values of interest.
final int PROPTYPE_LONG = 0x1;
final int PROPTYPE_DATE = 0x2;
final int PROPTYPE_BINARY = 0x3;
final int PROPTYPE_STRING = 0x4;

int nType;

// Determine the column data type.
nType = objCol.GetType();

// Compare the column data type with the constants.
switch (nType)
{
    case PROPTYPE_LONG:
        System.out.println("Data type is Long");
        break;
    case PROPTYPE_DATE:
        System.out.println("Data type is Date");
        break;
    case PROPTYPE_BINARY:
        System.out.println("Data type is Binary");
        break;
    case PROPTYPE_STRING:
        System.out.println("Data type is String");
        break;
    default:
        System.out.println("Unexpected data type");
        break;
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWCOLUMN, IEnumCERTVIEWCOLUMN::GetName, IEnumCERTVIEWCOLUMN::GetValue, IEnumCERTVIEWCOLUMN::Next


IEnumCERTVIEWCOLUMN::GetValue

Platform SDK: Security

IEnumCERTVIEWCOLUMN::GetValue [C++]

IEnumCERTVIEWCOLUMN.GetValue [Visual Basic,Java]

The GetValue method retrieves the data value contained in the column.

[C++]
HRESULT GetValue(
  LONG Flags,
  VARIANT *pvarValue
);
[Visual Basic]
objCERTVIEWCOLUMN.GetValue( Flags As Long ) As Variant
[Java]
com.ms.com.Variant GetValue(
  int Flags
);

Parameters

[C++,Visual Basic,Java] Flags
[in] Identifier that denotes the output format for the data stored in pvarValue. This can be one of the following values.
Flag | Meaning
CV_OUT_BASE64 | BASE64 without BEGIN/END
CV_OUT_BASE64HEADER | BASE64 with BEGIN CERTIFICATE and END CERTIFICATE
CV_OUT_BASE64REQUESTHEADER | BASE64 with BEGIN NEW CERTIFICATE REQUEST and END NEW CERTIFICATE REQUEST
CV_OUT_BASE64X509CRLHEADER | BASE64 with BEGIN X509 CRL and END X509 CRL
CV_OUT_BINARY | binary
CV_OUT_HEX | hex string
CV_OUT_HEXADDR | hex string with address/offset
CV_OUT_HEXASCII | hex string with ASCII
CV_OUT_HEXASCIIADDR | hex string with ASCII and address/offset

[C++] pvarValue
[out] Pointer to value of VARIANT type that will receive the data in the Certificate Services view's column. This function will fail if pvarValue is NULL. Upon successful completion of this function, *pvarValue is set to a value of VARIANT type that will contain the data in the Certificate Services view's column. GetValue calls VariantClear on pvarValue, so in loop conditions the caller need not call VariantClear before calling GetValue. The caller is responsible for calling VariantInit before pvarValue is first used as a parameter by GetValue; the caller is also responsible for calling VariantClear when done with pvarValue (such as before exiting a function).
[Visual Basic] objCERTVIEWCOLUMN
Object expression that resolves to an IEnumCERTVIEWCOLUMN object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success.

[Visual Basic,Java] The return value is a VARIANT representing the data in the column.

Remarks

This function is used to retrieve the data in the column currently being referenced by the IEnumCERTVIEWCOLUMN object.

If the IEnumCERTVIEWCOLUMN object is not referencing a valid column, GetValue will fail. Use the IEnumCERTVIEWCOLUMN::Next method to reference a valid column.

Example Code [C++]

HRESULT     hr;
VARIANT     var;
SYSTEMTIME  systime;

VariantInit(&var);

// pEnumCol is previously instantiated IEnumCERTVIEWCOLUMN object
hr = pEnumCol->GetValue(CV_OUT_HEX, &var);
if ( FAILED (hr) )
{
    printf("Failed GetValue - %x\n", hr);
    goto error;
}
switch( var.vt )
{
    case VT_EMPTY:
        printf( "VT_EMPTY\n" );
        break;
    case VT_BSTR:
        printf("%ws\n", var.bstrVal );
        break;
    case VT_DATE:
        VariantTimeToSystemTime( var.date, &systime );
        printf("%d.%d.%d %02d:%02d:%02d\n",
               systime.wMonth,
               systime.wDay,
               systime.wYear,
               systime.wHour,
               systime.wMinute,
               systime.wSecond );
        break;
    case VT_I2:
        printf("%d\n", var.iVal );
        break;
    case VT_I4:
        printf("%d\n", var.lVal );
        break;
    default:
        printf("type is:%i\n", var.vt );
        break;
}
// done processing, clear resources
VariantClear( &var );

Example Code [Visual Basic]

' Constants used by GetValue.
Const CV_OUT_BASE64HEADER = 0
Const CV_OUT_BASE64 = &H1
Const CV_OUT_BINARY = &H2
Const CV_OUT_BASE64REQUESTHEADER = &H3
Const CV_OUT_HEX = &H4
Const CV_OUT_HEXASCII = &H5
Const CV_OUT_BASE64X509CRLHEADER = &H9
Const CV_OUT_HEXADDR = &HA
Const CV_OUT_HEXASCIIADDR = &HB
' Retrieve the data.
Dim var1 As Variant
var1 = objEnumCol.GetValue(CV_OUT_HEX)
' Use the data as needed...

Example Code [Java]

// Constants used by IEnumCERTVIEWCOLUMN.GetValue method.
final int CV_OUT_BASE64HEADER = 0;
final int CV_OUT_BASE64 = 0x1;
final int CV_OUT_BINARY = 0x2;
final int CV_OUT_BASE64REQUESTHEADER = 0x3;
final int CV_OUT_HEX = 0x4;
final int CV_OUT_HEXASCII = 0x5;
final int CV_OUT_BASE64X509CRLHEADER = 0x9;
final int CV_OUT_HEXADDR = 0xa;
final int CV_OUT_HEXASCIIADDR = 0xb;

com.ms.com.Variant var1;

// Retrieve the value contained in the column.
var1 = objCol.GetValue(CV_OUT_HEX);
System.out.println(var1);
// Clear the Variant when done.
var1.VariantClear();

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWCOLUMN, IEnumCERTVIEWCOLUMN::GetName, IEnumCERTVIEWCOLUMN::GetType, IEnumCERTVIEWCOLUMN::Next


IEnumCERTVIEWCOLUMN::IsIndexed

Platform SDK: Security

IEnumCERTVIEWCOLUMN::IsIndexed [C++]

IEnumCERTVIEWCOLUMN.IsIndexed [Visual Basic,Java]

The IsIndexed method reports whether the column is indexed.

[C++]
HRESULT IsIndexed(
  LONG *pIndexed
);
[Visual Basic]
objCERTVIEWCOLUMN.IsIndexed() As Long
[Java]
int IsIndexed();

Parameters

[C++] pIndexed
[out] Pointer to a Long variable. This function will fail if pIndexed is NULL.
[Visual Basic] objCERTVIEWCOLUMN
Object expression that resolves to an IEnumCERTVIEWCOLUMN object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success. If the column is indexed, *pIndex is set to a value of TRUE; if the column is not indexed, *pIndex is set to a value of FALSE.

[Visual Basic,Java] The return value is 1 if the column is indexed, or 0 otherwise.

Remarks

This function is used to determine if a Certificate Services view's column is indexed.

If the IEnumCERTVIEWCOLUMN object is not referencing a valid column, IsIndexed will fail. Use the IEnumCERTVIEWCOLUMN::Next method to reference a valid column.

Example Code [C++]

HRESULT  hr;
LONG     bIsindexed;

// pEnumCol is previously instantiated IEnumCERTVIEWCOLUMN object
hr = pEnumCol->IsIndexed(&bIsindexed);
if (S_OK == hr)
    printf( bIsindexed ? "Indexed\n" : "Not indexed\n");

Example Code [Visual Basic]

' Determine if the column is indexed.
Dim nIsIndexed As Long
nIsIndexed = objCol.IsIndexed()
If (nIsIndexed = 1) Then
    MsgBox ("Column is indexed")
Else
    MsgBox ("Column is not indexed")
End If

Example Code [Java]

int nIsIndexed;

// Determine if the column is indexed.
nIsIndexed = objCol.IsIndexed();
System.out.println((1 == nIsIndexed) ? "Column is indexed" : "Column is not indexed");

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWCOLUMN, IEnumCERTVIEWCOLUMN::GetMaxLength, IEnumCERTVIEWCOLUMN::Next


IEnumCERTVIEWCOLUMN::Next

Platform SDK: Security

IEnumCERTVIEWCOLUMN::Next [C++]

IEnumCERTVIEWCOLUMN.Next [Visual Basic,Java]

The Next method positions the IEnumCERTVIEWCOLUMN object to the next column.

[C++]
HRESULT Next(
  LONG *pIndex
);
[Visual Basic]
objCERTVIEWCOLUMN.Next() As Long
[Java]
int Next();

Parameters

[C++] pIndex
[out] Pointer to variable that will contain the index value of the next column referenced by the IEnumCERTVIEWCOLUMN object. If there are no more columns to enumerate, this variable will be set to –1. This function will fail if pIndex is NULL.
[Visual Basic] objCERTVIEWCOLUMN
Object expression that resolves to an IEnumCERTVIEWCOLUMN object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success and that the next column is now being referenced by the IEnumCERTVIEWCOLUMN object. If there are no more columns to enumerate, S_FALSE is returned, and *pIndex is set to a value of –1.

[Visual Basic,Java] The return value is the index value of the next column that will be referenced by the IEnumCERTVIEWCOLUMN object. If there are no more rows to enumerate, the return value will be –1.

Remarks

Upon successful completion of this function, the Certificate Services view's IEnumCERTVIEWCOLUMN object will be referencing the next column. When the IEnumCERTVIEWCOLUMN is referencing a column, the column information can be retrieved through IEnumCERTVIEWCOLUMN::GetName, IEnumCERTVIEWCOLUMN::GetType, and IEnumCERTVIEWCOLUMN::GetValue.

Example Code [C++]

LONG       nLength;
LONG       nType;
LONG       bIsindexed;
LONG       Index;

HRESULT    hr;

BSTR       bstrColName = NULL;

// pEnumCol is previously instantiated IEnumCERTVIEWCOLUMN object
// examine each column
while (S_OK == pEnumCol->Next(&Index))
{
    // determine database length
    hr = pEnumCol->GetMaxLength(&nLength);
    if (FAILED(hr))
    {
        printf("Failed GetMaxLength %x\n", hr);
        goto error;
    }

    // determine data type
    hr = pEnumCol->GetType(&nType);
    if (FAILED(hr))
    {
        printf("Failed GetType %x\n", hr);
        goto error;
    }

    // determine if column is indexed
    hr = pEnumCol->IsIndexed(&bIsindexed);
    if (FAILED(hr))
    {
        printf("Failed IsIndexed %x\n", hr);
        goto error;
    }

    // retrieve column name
    hr = pEnumCol->GetName(&bstrColName);
    if (FAILED(hr))
    {
        printf("Failed GetName %x\n", hr);
        goto error;
    }

    // print this column's info on one line
    // print name and length
    printf("Column %ws has max length %d",
            bstrColName,
            nLength);

    // print data type
    switch (nType)
    {
        case PROPTYPE_BINARY:
            printf(" Type is Binary");
            break;
        case PROPTYPE_DATE:
            printf(" Type is Date+Time");
            break;
        case PROPTYPE_LONG:
            printf(" Type is Signed long");
            break;
        case PROPTYPE_STRING:
            printf(" Type is Unicode String");
            break;
        default:
            printf(" Type is unknown");
            break;
    }

    // print index status
    printf(bIsindexed ? " Indexed" : " Not indexed");
    // print new line marker
    printf("\n");

}

error:

// done processing, clear resources
if (NULL != bstrColName)
    SysFreeString(bstrColName);

Example Code [Visual Basic]

' Iterate through the columns.
Dim nIndex As Long
nIndex = objCol.Next()
Do While (nIndex <> -1)
    ' Use this column as needed.
    ' ...
    ' Move to the next column.
    nIndex = objCol.Next()
Loop

Example Code [Java]

int nIndex;

// Iterate through the columns.
nIndex = objCol.Next();
while (-1 != nIndex)
{
    // Use the column as needed. This example displays
    // the column name.
    System.out.println(objCol.GetName());
    // Move to the next column.
    nIndex = objCol.Next();
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWCOLUMN, IEnumCERTVIEWCOLUMN::GetName, IEnumCERTVIEWCOLUMN::GetType, IEnumCERTVIEWCOLUMN::GetValue


IEnumCERTVIEWCOLUMN::Reset

Platform SDK: Security

IEnumCERTVIEWCOLUMN::Reset [C++]

IEnumCERTVIEWCOLUMN.Reset [Visual Basic,Java]

The Reset method resets the IEnumCERTVIEWCOLUMN enumeration sequence to the beginning.

[C++]
HRESULT Reset();
[Visual Basic]
objCERTVIEWCOLUMN.Reset()
[Java]
void Reset();

Parameters

[Visual Basic] objCERTVIEWCOLUMN
Object expression that resolves to an IEnumCERTVIEWCOLUMN object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success.

[Visual Basic,Java] None.

Remarks

Upon successful completion of this function, the IEnumCERTVIEWCOLUMN object will be positioned to the beginning the IEnumCERTVIEWCOLUMN object's columns. To access the data in the first column after calling the Reset method, call the IEnumCERTVIEWCOLUMN::Next method. When a valid column is being referenced by the IEnumCERTVIWCOLUMN object, data can be retrieved through calls to IEnumCERTVIEWCOLUMN::GetName, IEnumCERTVIEWCOLUMN::GetType, and IEnumCERTVIEWCOLUMN::GetValue.

Example Code [C++]

// pEnumCol is previously instantiated IEnumCERTVIEWCOLUMN object
HRESULT    hr;
LONG        Index;
hr = pEnumCol->Reset();
if (S_OK != hr)
    printf("Unable to reset pEnumCol\n");
    // call appropriate error handler / exit routine
else
{
    // now at the beginning of the columns
    // enumerate each column
    while (S_OK == pEnumCol->Next(&Index))
    {
        // Use each column as needed.
    }
}

Example Code [Visual Basic]

objCol.Reset

Example Code [Java]

objCol.Reset();

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWCOLUMN::GetName, IEnumCERTVIEWCOLUMN::GetType, IEnumCERTVIEWCOLUMN::GetValue, IEnumCERTVIEWCOLUMN::Next, IEnumCERTVIEWCOLUMN::Skip


IEnumCERTVIEWCOLUMN::Skip

Platform SDK: Security

IEnumCERTVIEWCOLUMN::Skip [C++]

IEnumCERTVIEWCOLUMN.Skip [Visual Basic,Java]

The Skip method skips a specified number of columns in the IEnumCERTVIEWCOLUMN enumeration sequence.

[C++]
HRESULT Skip(
  LONG celt
);
[Visual Basic]
objCERTVIEWCOLUMN.Skip( celt As Long )
[Java]
void Skip(
  int celt
);

Parameters

[C++,Visual Basic,Java] celt
[in] Number of columns for the IEnumCERTVIEWCOLUMN object to skip. A positive value for celt causes the IEnumCERTVIEWCOLUMN object to skip forward in the enumeration sequence; a negative value for celt causes the IEnumCERTVIEWCOLUMN object to skip backward in the enumeration sequence.
[Visual Basic] objCERTVIEWCOLUMN
Object expression that resolves to an IEnumCERTVIEWCOLUMN object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success. A return value of E_INVALIDARG indicates that a negative value for celt caused the IEnumCERTVIEWCOLUMN object's index to become less than zero.

[Visual Basic,Java] None.

Remarks

Upon successful completion of this function, the IEnumCERTVIEWCOLUMN object will have skipped celt columns in the enumeration sequence. To access the column contents after a call to the IEnumCERTVIEWCOLUMN::Skip method, call the IEnumCERTVIEWCOLUMN::Next method.

The IEnumCERTVIEWCOLUMN object maintains an internal value representing the zero-based index of the column to be accessed when the IEnumCERTVIEWCOLUMN::Next method is called. A call to the IEnumCERTVIEWCOLUMN::Skip method causes this index to increase by celt if celt is positive, or to decrease by celt if celt is negative.

If celt causes the index to be less than zero, the behavior of subsequent calls to IEnumCERTVIEWCOLUMN::Next is undefined.

Positive values for celt are not validated, but if a positive value for celt causes the internal value to exceed the index for the last column in the enumeration sequence, a subsequent call to the IEnumCERTVIEWCOLUMN::Next method will fail.

Example Code [C++]

HRESULT  hr;
LONG     Index;

// pEnumCol is previously instantiated IEnumCERTVIEWCOLUMN object
// skip the next five columns
hr = pEnumCol->Skip(5);
if (S_OK == hr)
{
    // get the next column
    hr = pEnumCol->Next(&Index);
    if (S_OK == hr)
    {
        // Use this column as needed.
    }
}

Example Code [Visual Basic]

' Skip four columns in the enumeration sequence.
objCol.Skip (4)

Example Code [Java]

// Skip four columns in the enumeration sequence.
objCol.Skip(4);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWCOLUMN, IEnumCERTVIEWCOLUMN:Next, IEnumCERTVIEWCOLUMN::Reset, IEnumCERTVIEWCOLUMN::Skip


IEnumCERTVIEWEXTENSION

Platform SDK: Security

IEnumCERTVIEWEXTENSION [C++]

IEnumCERTVIEWEXTENSION [Visual Basic,Java]

The IEnumCERTVIEWEXTENSION object is used to access the certificate extension data for a row in the Certificate Services view. An IEnumCERTVIEWEXTENSION interface is instantiated through a call to IEnumCERTVIEWROW::EnumCertViewExtension.

IEnumCERTVIEWEXTENSION is defined in certview.h. When you create your program, however, use certsrv.h as the include file. CertAdm.dll provides the IEnumCERTVIEWEXTENSION interface. The type information for this interface is also in CertAdmL.dll, which is shipped with the Platform SDK.

The Certificate Services interfaces support only the apartment-threading model.

The following methods are provided by the IEnumCERTVIEWEXTENSION interface.

Method | Description
Clone | Creates a copy of the IEnumCERTVIEWEXTENSION object.
GetFlags | Retrieves the policy and origin flags of the extension.
GetName | Retrieves the name of the extension.
GetValue | Retrieves the extension value.
Next | Positions the IEnumCERTVIEWEXTENSION object to the next extension.
Reset | Resets the IEnumCERTVIEWEXTENSION enumeration sequence to the beginning.
Skip | Skips a specified number of extensions in the IEnumCERTVIEWEXTENSION enumeration sequence.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWROW::IEnumCertViewExtension


IEnumCERTVIEWEXTENSION::Clone

Platform SDK: Security

IEnumCERTVIEWEXTENSION::Clone [C++]

IEnumCERTVIEWEXTENSION.Clone [Visual Basic,Java]

The Clone method creates a copy of the IEnumCERTVIEWEXTENSION object in its current state.

[C++]
HRESULT Clone(
  IEnumCERTVIEWEXTENSION **ppenum
);
[Visual Basic]
objCERTVIEWEXTENSION.Clone() As IEnumCERTVIEWEXTENSION
[Java]
IEnumCERTVIEWEXTENSION Clone();

Parameters

[C++] ppenum
[out] Pointer to a pointer of IEnumCERTVIEWEXTENSION type; upon successful completion of this function, *ppenum is set to the cloned object. This function will fail if ppenum is NULL.
[Visual Basic] objCERTVIEWEXTENSION
Object expression that resolves to an IEnumCERTVIEWEXTENSION object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success.

[Visual Basic,Java] The return value is a cloned IEnumCERTVIEWEXTENSION object.

Remarks

This function is used to clone the IEnumCERTVIEWEXTENSION object.

Example Code [C++]

IEnumCERTVIEWEXTENSION * pEnumExt2 = NULL;
HRESULT                  hr;

// pEnumExt is previously instantiated IEnumCERTVIEWEXTENSION object
hr = pEnumExt->Clone(&pEnumExt2);
if (S_OK != hr)
    printf("Unable to clone IEnumCERTVIEWEXTENSION\n");
else
    // use cloned object as needed
    //...

// done using cloned object, free memory
if (NULL != pEnumExt2)
    pEnumExt2->Release();

Example Code [Visual Basic]

' Clone an extension enumerator.
Dim objExtNew As IEnumCERTVIEWEXTENSION
Set objExtNew = objExt.Clone()
' Use the cloned object as needed.
' ...
' Free the object when done.
Set objExtNew = Nothing

Example Code [Java]

certadm.IEnumCERTVIEWEXTENSION objExt2;

// Clone an extension object.
objExt2 = objExt.Clone();

// Use the cloned object as needed.

// When done, free the cloned object.
com.ms.com.ComLib.release(objExt2);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWEXTENSION


IEnumCERTVIEWEXTENSION::GetFlags

Platform SDK: Security

IEnumCERTVIEWEXTENSION::GetFlags [C++]

IEnumCERTVIEWEXTENSION.GetFlags [Visual Basic,Java]

The GetFlags method retrieves the policy and origin flags of the extension. Both the policy and origin flags are stored in one variable, and bitmasks are provided to retrieve the individual values.

[C++]
HRESULT GetFlags(
  LONG *pFlags
);
[Visual Basic]
objCERTVIEWEXTENSION.GetFlags() As Long
[Java]
int GetFlags();

Parameters

[C++] pFlags
[out] Pointer to a Long type that will contain the policy and origin flags of the extension. This function will fail if pFlags is NULL.
[Visual Basic] objCERTVIEWEXTENSION
Object expression that resolves to an IEnumCERTVIEWEXTENSION object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success.

[Visual Basic,Java] The return value represents the policy and origin values of the extension.

Remarks

This function is used to determine both the policy and origin flags of the extension currently referenced by the IEnumCERTVIEWEXTENSION object.

There are two kinds of flags used in extensions: policy flags and origin flags.

Flag type | Explanation
Policy | Provides information about the certificate extension. Policy flags can be set by the policy module.
Origin | Indicates the module that set the certificate extension. Origin flags are only set by the server engine.

One or more policy flags can be returned from an extension. The following are predefined policy flags.

Policy flag value | Explanation
EXTENSION_CRITICAL_FLAG | This is a critical extension.
EXTENSION_DISABLE_FLAG | Extension will not be used.

One of the following origin flags can also be returned.

Origin flag value | Explanation
EXTENSION_ORIGIN_REQUEST | The extension was extracted from an array of extensions stored in the szOID_CERT_EXTENSIONS (1.3.6.1.4.1.311.2.1.14) or szOID_RSA_certExtensions (1.2.840.113549.1.9.14) attribute of a PKCS #10 request.
EXTENSION_ORIGIN_POLICY | Policy module set the extension.
EXTENSION_ORIGIN_ADMIN | Administrator set the extension.
EXTENSION_ORIGIN_SERVER | Server engine set the extension.
EXTENSION_ORIGIN_RENEWALCERT | The extension was extracted from the certificate stored in the szOID_RENEWAL_CERTIFICATE (1.3.6.1.4.1.311.13.1) attribute of a PKCS #10 renewal request.
EXTENSION_ORIGIN_IMPORTEDCERT | The extension was extracted from an imported certificate (the certificate was passed to ICertAdmin::ImportCertificate).
EXTENSION_ORIGIN_PKCS7 | The extension was extracted from an array of extensions stored in the szOID_CERT_EXTENSIONS (1.3.6.1.4.1.311.2.1.14) or szOID_RSA_certExtensions (1.2.840.113549.1.9.14) attribute of a PKCS #7 request.

Pre-defined masks are provided for ease of use in determining which flags are set in the return value. The following masks are provided.

Mask value | Explanation
EXTENSION_POLICY_MASK | This value (0x0000FFFF) is used to examine policy flags.
EXTENSION_ORIGIN_MASK | This value (0x000F0000) is used to examine origin flags.

If the IEnumCERTVIEWEXTENSION object is not referencing a valid extension, GetFlags will fail. Use the IEnumCERTVIEWEXTENSION::Next method to reference a valid extension.

Example Code [C++]

HRESULT  hr;
LONG     ExtFlags;

// pEnumExt is previously instantiated IEnumCERTVIEWEXTENSION object
hr = pEnumExt->GetFlags(&ExtFlags);
if (S_OK != hr)
    printf("Failed GetFlags - %x\n", hr);
else
{
    LONG ExtPol, ExtOrig;

    ExtPol = ExtFlags & EXTENSION_POLICY_MASK;
    if (ExtPol & EXTENSION_CRITICAL_FLAG)
        printf("The extension is critical\n");
    if (ExtPol & EXTENSION_DISABLE_FLAG )
        printf("The extension is disabled\n");

    ExtOrig = ExtFlags & EXTENSION_ORIGIN_MASK;
    switch (ExtOrig)
    {
        case EXTENSION_ORIGIN_REQUEST:
            printf("Extension originated by PKCS #10 Request\n");
            break;
        case EXTENSION_ORIGIN_POLICY:
            printf("Extension originated by Policy\n");
            break;
        case EXTENSION_ORIGIN_ADMIN:
            printf("Extension originated by Admin\n");
            break;
        case EXTENSION_ORIGIN_SERVER:
            printf("Extension originated by Server\n");
            break;
        case EXTENSION_ORIGIN_RENEWALCERT:
            printf("Extension originated by Renewal Request\n");
            break;
        case EXTENSION_ORIGIN_IMPORTEDCERT:
            printf("Extension originated by an imported certificate\n");
            break;
        case EXTENSION_ORIGIN_PKCS7:
            printf("Extension originated by PKCS #7 Request\n");
            break;
        default:
            printf("Unknown extension origin\n");
            break;
    }
}

Example Code [Visual Basic]

' Constants for values of interest.
Const EXTENSION_CRITICAL_FLAG As Long = &H1
Const EXTENSION_DISABLE_FLAG As Long = &H2
Const EXTENSION_POLICY_MASK As Long = &HFFFF
Const EXTENSION_ORIGIN_REQUEST As Long = &H10000
Const EXTENSION_ORIGIN_POLICY As Long = &H20000
Const EXTENSION_ORIGIN_ADMIN As Long = &H30000
Const EXTENSION_ORIGIN_SERVER As Long = &H40000
Const EXTENSION_ORIGIN_RENEWALCERT As Long = &H50000
Const EXTENSION_ORIGIN_IMPORTEDCERT As Long = &H60000
Const EXTENSION_ORIGIN_PKCS7 As Long = &H70000
Const EXTENSION_ORIGIN_MASK As Long = &HF0000

' Retrieve the extension policy/origin flags.
Dim nExtFlags As Long
nExtFlags = objExt.GetFlags()

' Output policy settings.
Dim ExtPol As Long
ExtPol = nExtFlags And EXTENSION_POLICY_MASK
If (ExtPol And EXTENSION_CRITICAL_FLAG) Then
    MsgBox ("Extension is critical")
End If
If (ExtPol And EXTENSION_DISABLE_FLAG) Then
    MsgBox ("Extension is disabled")
End If

' Ouput origin.
Dim ExtOrig As Long
ExtOrig = nExtFlags And EXTENSION_ORIGIN_MASK

' Compare the output origin with the constants.
Select Case ExtOrig
    Case EXTENSION_ORIGIN_REQUEST
        MsgBox ("The origin is from a PKCS #10 request")
    Case EXTENSION_ORIGIN_POLICY
        MsgBox ("The origin is from a policy module")
    Case EXTENSION_ORIGIN_ADMIN
        MsgBox ("The origin is from an administrator")
    Case EXTENSION_ORIGIN_SERVER
        MsgBox ("The origin is from the server engine")
    Case EXTENSION_ORIGIN_RENEWALCERT
        MsgBox ("The origin is from a renewal request")
    Case EXTENSION_ORIGIN_IMPORTEDCERT
        MsgBox ("The origin is from an imported certificate")
    Case EXTENSION_ORIGIN_PKCS7
        MsgBox ("The origin is from a PKCS #7 request")
    Case Else
        MsgBox ("Unexpected origin")
End Select

Example Code [Java]

// Constants of interest.
final int EXTENSION_CRITICAL_FLAG = 0x1;
final int EXTENSION_DISABLE_FLAG = 0x2;
final int EXTENSION_POLICY_MASK = 0xFFFF;
final int EXTENSION_ORIGIN_REQUEST = 0x10000;
final int EXTENSION_ORIGIN_POLICY = 0x20000;
final int EXTENSION_ORIGIN_ADMIN = 0x30000;
final int EXTENSION_ORIGIN_SERVER = 0x40000;
final int EXTENSION_ORIGIN_RENEWALCERT = 0x50000;
final int EXTENSION_ORIGIN_IMPORTEDCERT = 0x60000;
final int EXTENSION_ORIGIN_PKCS7 = 0x70000;
final int EXTENSION_ORIGIN_MASK = 0xF0000;

// Retrieve the extension and policy flags.
int nExtFlags;
nExtFlags = objExt.GetFlags();

// Print the policy settings of the extension.
int ExtPol;
ExtPol = nExtFlags & EXTENSION_POLICY_MASK;
if (EXTENSION_CRITICAL_FLAG == (ExtPol & EXTENSION_CRITICAL_FLAG))
    System.out.println("Extension is critical");
if (EXTENSION_DISABLE_FLAG == (ExtPol & EXTENSION_DISABLE_FLAG))
    System.out.println("Extension is disabled");

// Print the origin of the extension.
int ExtOrig;
ExtOrig = nExtFlags & EXTENSION_ORIGIN_MASK;
switch (ExtOrig)
{
    case EXTENSION_ORIGIN_REQUEST:
        System.out.println("Extension was set by a PKCS #10 request.");
        break;
    case EXTENSION_ORIGIN_POLICY:
        System.out.println("Extension was set by the policy module.");
        break;
    case EXTENSION_ORIGIN_ADMIN:
        System.out.println("Extension was set by the administrator.");
        break;
    case EXTENSION_ORIGIN_SERVER:
        System.out.println("Extension was set by the server.");
        break;
    case EXTENSION_ORIGIN_RENEWALCERT:
        System.out.println("Extension was set by a renewal request.");
        break;
    case EXTENSION_ORIGIN_IMPORTEDCERT:
        System.out.println("Extension was set by an imported certificate.");
        break;
    case EXTENSION_ORIGIN_PKCS7:
        System.out.println("Extension was set by a PKCS #7 request.");
        break;
    default:
        System.out.println("The origin of the extension is unknown.");
        break;
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWEXTENSION, IEnumCERTVIEWEXTENSION::GetName, IEnumCERTVIEWEXTENSION::GetValue, IEnumCERTVIEWEXTENSION::Next


IEnumCERTVIEWEXTENSION::GetName

Platform SDK: Security

IEnumCERTVIEWEXTENSION::GetName [C++]

IEnumCERTVIEWEXTENSION.GetName [Visual Basic,Java]

The GetName method retrieves the name of the extension, as an object identifier (OID) string. The returned extension name is an object identifier (OID) string, as in L"2.5.29.31".

[C++]
HRESULT GetName(
  BSTR *pstrOut
);
[Visual Basic]
objCERTVIEWEXTENSION.GetName() As String
[Java]
java.lang.String GetName(
);

Parameters

[C++] pstrOut
[out] Pointer to a value of BSTR type that will contain the name of the extension.
[Visual Basic] objCERTVIEWEXTENSION
Object expression that resolves to an IEnumCERTVIEWEXTENSION object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success and *pstrOut is set to the BSTR representing the name of the extension. To use this method, create a variable of BSTR type, set the variable equal to NULL, and pass the address of this variable as pstrOut. You must free *pstrOut when done (by means of SysFreeString).

[Visual Basic,Java] The return value is a String representing the name of the extension.

Remarks

This function is used to retrieve the name of the extension currently referenced by the IEnumCERTVIEWEXTENSION object.

If the IEnumCERTVIEWEXTENSION object is not referencing a valid extension, GetName will fail. Use the IEnumCERTVIEWEXTENSION::Next method to reference a valid extension.

Example Code [C++]

BSTR  bstrExtName = NULL;

// pEnumExt is previously instantiated IEnumCERTVIEWEXTENSION object
hr = pEnumExt->GetName(&bstrExtName);
if (S_OK == hr)
    printf("Extentsion name is: %ws\n", bstrExtName);
else
    printf("GetName failed: %x\n", hr);

// free memory when done
if (NULL != bstrExtName)
    SysFreeString(bstrExtName);

Example Code [Visual Basic]

' Retrieve the extension name.
Dim strExtName As String
strExtName = objExt.GetName()
MsgBox (strExtName)

Example Code [Java]

java.lang.String strExtName;

// Retrieve and display the extension name.
strExtName = objExt.GetName();
System.out.println(strExtName);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWEXTENSION, IEnumCERTVIEWEXTENSION::GetFlags, IEnumCERTVIEWEXTENSION::GetValue, IEnumCERTVIEWEXTENSION::Next


IEnumCERTVIEWEXTENSION::GetValue

Platform SDK: Security

IEnumCERTVIEWEXTENSION::GetValue [C++]

IEnumCERTVIEWEXTENSION.GetValue [Visual Basic,Java]

The GetValue method retrieves the extension value.

[C++]
HRESULT GetValue(
  LONG Type,
  LONG Flags,
  VARIANT *pvarValue
);
[Visual Basic]
objCERTVIEWEXTENSION.GetValue( Type As Long, _
  Flags As Long ) As Variant
[Java]
com.ms.com.Variant GetValue(
  int Type,
  int Flags
);

Parameters

[C++,Visual Basic,Java] Type
[in] Data type identifier for the returned data in pvarValue. By using this flag, you can specify that the extension data be decoded before being returned in pvarValue. Type can be one of the following values. (If PROPTYPE_BINARY is specified, the data is not decoded but instead returned in its raw format.).
Data Type | Meaning
PROPTYPE_BINARY | Binary data
PROPTYPE_DATE | Date+Time
PROPTYPE_LONG | Signed Long
PROPTYPE_STRING | Unicode String

[C++,Visual Basic,Java] Flags
[in] Identifier that denotes the output format for the data stored in pvarValue. This can be one of the following values.
Flag | Meaning
CV_OUT_BASE64 | BASE64 without BEGIN/END
CV_OUT_BASE64HEADER | BASE64 with BEGIN CERTIFICATE and END CERTIFICATE
CV_OUT_BASE64REQUESTHEADER | BASE64 with BEGIN NEW CERTIFICATE REQUEST and END NEW CERTIFICATE REQUEST
CV_OUT_BINARY | binary
CV_OUT_HEX | hex string
CV_OUT_HEXADDR | hex string with address/offset
CV_OUT_HEXASCII | hex string with ASCII
CV_OUT_HEXASCIIADDR | hex string with ASCII and address/offset

[C++] pvarValue
[out] Pointer to value of VARIANT type that will receive the data for the currently referenced extension. This function will fail if pvarValue is NULL. Upon successful completion of this function, *pvarValue is set to a value of VARIANT type that will contain the extension data currently referenced by the IEnumCERTVIEWEXTENSION object. GetValue calls VariantClear on pvarValue, so in loop conditions, you do not need to call VariantClear before calling GetValue. You are responsible for calling VariantInit before pvarValue is first used as a parameter by GetValue; you are also responsible for calling VariantClear when done with pvarValue.
[Visual Basic] objCERTVIEWEXTENSION
Object expression that resolves to an IEnumCERTVIEWEXTENSION object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success.

[Visual Basic,Java] The return value is a VARIANT representing the data in the extension.

Remarks

This function is used to retrieve the data in the extension currently being referenced by the IEnumCERTVIEWEXTENSION object.

If the IEnumCERTVIEWEXTENSION object is not referencing a valid extension, GetValue will fail. Use the IEnumCERTVIEWEXTENSION::Next method to reference a valid extension. This method will fail if the IEnumCERTVIEWEXTENSION instance was instantiated by a call to ICertView::EnumCertViewColumn because instances instantiated by ICertView::EnumCertViewColumn contain only schema information.

Example Code [C++]

VARIANT     var;
LONG        Index;
HRESULT     hr;
SYSTEMTIME  systime;

VariantInit(&var);

// Enumerate each extension
// pEnumExt is previously instantiated IEnumCERTVIEWEXTENSION object
while (S_OK == pEnumExt->Next(&Index))
{
    hr = pEnumExt->GetValue(PROPTYPE_BINARY, CV_OUT_HEX, &var);
    if (FAILED(hr))
    {
        printf("Failed GetValue - %x\n", hr);
        break;
    }
    switch(var.vt)
    {
        case VT_EMPTY:
            printf("VT_EMPTY\n");
            break;
        case VT_BSTR:
            printf("BSTR:%ws\n", var.bstrVal);
            break;
        case VT_DATE:
            VariantTimeToSystemTime(var.date, &systime);
            printf("%d.%d.%d %02d:%02d:%02d\n",
                   systime.wMonth,
                   systime.wDay,
                   systime.wYear,
                   systime.wHour,
                   systime.wMinute,
                   systime.wSecond );
            break;
        case VT_I2:
            printf("%d\n", var.iVal);
            break;
        case VT_I4:
            printf("%d\n", var.lVal);
            break;
        default:
            printf("type is:%i\n", var.vt);
            break;
    }
}
// Free resources.
VariantClear( &var );

Example Code [Visual Basic]

' Constants of interest.
Const CV_OUT_BASE64HEADER As Long = &H0
Const CV_OUT_BASE64 As Long = &H1
Const CV_OUT_BINARY As Long = &H2
Const CV_OUT_BASE64REQUESTHEADER As Long = &H3
Const CV_OUT_HEX As Long = &H4
Const CV_OUT_HEXASCII As Long = &H5
Const PROPTYPE_LONG As Long = &H1
Const PROPTYPE_DATE As Long = &H2
Const PROPTYPE_BINARY As Long = &H3
Const PROPTYPE_STRING As Long = &H4

Dim var1 As Variant
Dim nIndex As Long

nIndex = objExt.Next()
Do While (nIndex <> -1)
    ' Use this extension as needed.
    var1 = objExt.GetValue(PROPTYPE_BINARY, _
                           CV_OUT_HEX)
    ' Use the value as needed.
    ' ...
    ' Retrieve the next extension.
    nIndex = objExt.Next()
Loop

Example Code [Java]

// Constants for values of interest.
final int CV_OUT_BASE64HEADER = 0x0;
final int CV_OUT_BASE64 = 0x1;
final int CV_OUT_BINARY = 0x2;
final int CV_OUT_BASE64REQUESTHEADER = 0x3;
final int CV_OUT_HEX = 0x4;
final int CV_OUT_HEXASCII = 0x5;
final int PROPTYPE_LONG = 0x1;
final int PROPTYPE_DATE = 0x2;
final int PROPTYPE_BINARY = 0x3;
final int PROPTYPE_STRING = 0x4;

com.ms.com.Variant var1;
int nIndex;
// Iterate through the extensions.
nIndex = objExt.Next();
while (-1 != nIndex)
{
    // Retrieve the extension value.
    var1 = objExt.GetValue(PROPTYPE_BINARY,
                           CV_OUT_HEX);
    // Use the value as needed. This example displays it.
    System.out.println(var1);
    // Move to the next extension.
    nIndex = objExt.Next();
}
// Clear the Variant when done.
var1.VariantClear();

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

EnumCERTVIEWEXTENSION, IEnumCERTVIEWEXTENSION::GetFlags, IEnumCERTVIEWEXTENSION::GetName, IEnumCERTVIEWEXTENSION::Next


IEnumCERTVIEWEXTENSION::Next

Platform SDK: Security

IEnumCERTVIEWEXTENSION::Next [C++]

IEnumCERTVIEWEXTENSION.Next [Visual Basic,Java]

The Next method positions the IEnumCERTVIEWEXTENSION object to the next extension.

[C++]
HRESULT Next(
  LONG *pIndex
);
[Visual Basic]
objCERTVIEWEXTENSION.Next() As Long
[Java]
int Next(
);

Parameters

[C++] pIndex
[out] Pointer to a Long variable that will contain the index value of the next extension referenced. If there are no more extensions to enumerate, this variable will be set to – 1. This function will fail if pIndex is NULL.
[Visual Basic] objCERTVIEWEXTENSION
Object expression that resolves to an IEnumCERTVIEWEXTENSION object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success and that the next extension is now being referenced. If there are no more attributes, S_FALSE is returned, and *pIndex is set to a value of – 1.

[Visual Basic,Java] The return value is the index value of the next column that will be referenced by the IEnumCERTVIEWEXTENSION object. If there are no more extensions to enumerate, the return value will be – 1.

Remarks

Upon successful completion of this function, the IEnumCERTVIEWEXTENSION object will be referencing the next extension. When the extension is referenced, the extension name, flags, and value can be accessed through IEnumCERTVIEWEXTENSION::GetFlags, IEnumCERTVIEWEXTENSION::GetName, and IEnumCERTVIEWEXTENSION::GetValue.

Example Code [C++]

LONG  Index;
LONG  nCount;

// determine the number of extensions
nCount = 0;
// pEnumExt is previously instantiated IEnumCERTVIEWEXTENSION object
while (S_OK == pEnumExt->Next(&Index))
{
    nCount++;
}
printf("Number of extensions is %d\n", nCount);

Example Code [Visual Basic]

Dim nIndex As Long
nIndex = objExt.Next()
Do While (nIndex <> -1)
    ' Use this extension as needed.
    ' ...
    ' Move to the next extension.
    nIndex = objExt.Next()
Loop

Example Code [Java]

int nIndex;

// Iterate through the extensions.
nIndex = objExt.Next();
while (-1 != nIndex)
{
    // Use the extension as needed. This example
    // displays the extension name.
    System.out.println(objExt.GetName());
    // Move to the next extension.
    nIndex = objExt.Next();
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWEXTENSION, IEnumCERTVIEWEXTENSION::GetFlags, IEnumCERTVIEWEXTENSION::GetName, IEnumCERTVIEWEXTENSION::GetValue, IEnumCERTVIEWEXTENSION::Reset, IEnumCERTVIEWEXTENSION::Skip


IEnumCERTVIEWEXTENSION::Reset

Platform SDK: Security

IEnumCERTVIEWEXTENSION::Reset [C++]

IEnumCERTVIEWEXTENSION.Reset [Visual Basic,Java]

The Reset method resets the IEnumCERTVIEWEXTENSION enumeration sequence to the beginning.

[C++]
HRESULT Reset();
[Visual Basic]
objCERTVIEWEXTENSION.Reset()
[Java]
void Reset();

Parameters

[Visual Basic] objCERTVIEWEXTENSION
Object expression that resolves to an IEnumCERTVIEWEXTENSION object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success.

[Visual Basic,Java] None.

Remarks

Upon successful completion of this function, the IEnumCERTVIEWEXTENSION object will be positioned to the beginning of the object's extensions. To reference the first extension after calling the Reset method, call the IEnumCERTVIEWEXTENSION::Next method. When a valid extension is referenced by the IEnumCERTVIEWEXTENSION object, information can be retrieved through calls to IEnumCERTVIEWEXTENSION::GetFlags, IEnumCERTVIEWEXTENSION::GetName, and IEnumCERTVIEWEXTENSION::GetValue.

Example Code [C++]

HRESULT  hr;
LONG     Index;

// pEnumExt is previously instantiated IEnumCERTVIEWEXTENSION object
hr = pEnumExt->Reset();
if (S_OK != hr)
    printf("Unable to reset pEnumExt - %x\n", hr);
    // call appropriate error handler / exit routine
else
{
    // reset to beginning of extensions again
    while (S_OK == pEnumExt->Next(&Index))
    {
        // Use each extension as needed.
    }
}

Example Code [Visual Basic]

objExt.Reset

Example Code [Java]

objExt.Reset();

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWEXTENSION, IEnumCERTVIEWEXTENSION::GetFlags, IEnumCERTVIEWEXTENSION::GetName, IEnumCERTVIEWEXTENSION::GetValue, IEnumCERTVIEWEXTENSION::Next, IEnumCERTVIEWEXTENSION::Skip


IEnumCERTVIEWEXTENSION::Skip

Platform SDK: Security

IEnumCERTVIEWEXTENSION::Skip [C++]

IEnumCERTVIEWEXTENSION.Skip [Visual Basic,Java]

The Skip method skips a specified number of extensions in the IEnumCERTVIEWEXTENSION enumeration sequence.

[C++]
HRESULT Skip(
  LONG celt
);
[Visual Basic]
objCERTVIEWEXTENSION.Skip( celt As Long )
[Java]
void Skip(
  int celt
);

Parameters

[C++,Visual Basic,Java] celt
[in] Number of extensions for the IEnumCERTVIEWEXTENSION object to skip. A positive value for celt causes the IEnumCERTVIEWEXTENSION object to skip forward in the enumeration sequence; a negative value for celt causes the IEnumCERTVIEWEXTENSION object to skip backward in the enumeration sequence.
[Visual Basic] objCERTVIEWEXTENSION
Object expression that resolves to an IEnumCERTVIEWEXTENSION object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success. A return value of E_INVALIDARG indicates that a negative value for celt caused the IEnumCERTVIEWEXTENSION object's index to become less than zero.

[Visual Basic,Java] None.

Remarks

Upon successful completion of this function, the IEnumCERTVIEWEXTENSION object will have skipped celt extensions in the enumeration sequence. To access the extension contents after a call to the Skip method, call the IEnumCERTVIEWEXTENSION::Next method.

The IEnumCERTVIEWEXTENSION object maintains an internal value representing the zero-based index of the extension to be accessed when the IEnumCERTVIEWEXTENSION::Next method is called. A call to the IEnumCERTVIEWEXTENSION::Skip method causes this index to increase by celt if celt is positive, or to decrease by celt if celt is negative.

If celt causes the index to be less than zero, the behavior of subsequent calls to IEnumCERTVIEWEXTENSION::Next is undefined.

Positive values for celt are not validated, but if a positive value for celt causes the internal value to exceed the index for the last column in the enumeration sequence, a subsequent call to the IEnumCERTVIEWEXTENSION::Next method will fail.

Example Code [C++]

HRESULT  hr;
LONG     Index;

// pEnumExt is previously instantiated IEnumCERTVIEWEXTENSION object
// skip the next 5 extensions
hr = pEnumExt->Skip(5);
if (S_OK == hr)
{
    // get the next extension
    hr = pEnumExt->Next(&Index);
    if (S_OK == hr)
    {
        // Use this extension as needed.
    }
}

Example Code [Visual Basic]

' Skip three items in the enumeration sequence.
objExt.Skip (3)

Example Code [Java]

// Skip two extensions in the enumeration sequence.

objExt.Skip(2);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWEXTENSION, IEnumCERTVIEWEXTENSION::Next, IEnumCERTVIEWEXTENSION::Reset


IEnumCERTVIEWROW

Platform SDK: Security

IEnumCERTVIEWROW [C++]

IEnumCERTVIEWROW [Visual Basic,Java]

The IEnumCERTVIEWROW interface is used to enumerate the rows of the Certificate Services view, allowing access to the data. An IEnumCERTVIEWROW interface is instantiated through a call to the ICertView::OpenView method. Once a row is enumerated, an enumerator to the column data can be instantiated through the IEnumCERTVIEWROW::EnumCertViewColumn method. IEnumCERTVIEWROW also provides methods to retrieve a certificate's attributes and extensions.

IEnumCERTVIEWROW is defined in certview.h. When you create your program, however, use certsrv.h as the include file. CertAdm.dll provides the IEnumCERTVIEWROW interface. The type information for this interface is also in CertAdmL.dll, which is shipped with the Platform SDK.

The Certificate Services interfaces support only the apartment-threading model.

The following methods are provided by the IEnumCERTVIEWROW interface.

Method | Description
Clone | Reserved for future use.
EnumCertViewAttribute | Obtains a pointer to the IEnumCERTVIEWATTRIBUTE interface.
EnumCertViewColumn | Obtains a pointer to the IEnumCERTVIEWCOLUMN interface.
EnumCertViewExtension | Obtains a pointer to the IEnumCERTVIEWEXTENSION interface.
GetMaxIndex | Retrieves the maximum valid index in a view.
Next | Positions the IEnumCERTVIEWROW object to the next row.
Reset | Resets the IEnumCERTVIEWROW enumeration sequence to the beginning.
Skip | Skips a specified number of rows in the IEnumCERTVIEWROW enumeration sequence.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

ICertView::OpenView


IEnumCERTVIEWROW::EnumCertViewAttribute

Platform SDK: Security

IEnumCERTVIEWROW::EnumCertViewAttribute [C++]

IEnumCERTVIEWROW.EnumCertViewAttribute [Visual Basic,Java]

The EnumCertViewAttribute method obtains an instance of the IEnumCERTVIEWATTRIBUTE object.

[C++]
HRESULT EnumCertViewAttribute(
  LONG Flags,
  IEnumCERTVIEWATTRIBUTE **ppenum
);
[Visual Basic]
objCERTVIEWROW.EnumCertViewAttribute( Flags As Long ) As IEnumCERTVIEWATTRIBUTE
[Java]
IEnumCERTVIEWATTRIBUTE EnumCertViewAttribute(
  int Flags
);

Parameters

[C++,Visual Basic,Java] Flags
[in] Long value. Must be zero.
[C++] ppenum
[out] Pointer to pointer of IEnumCERTVIEWATTRIBUTE type. Upon successful completion of this function, *ppenum is set to a pointer of IEnumCERTVIEWATTRIBUTE type.
[Visual Basic] objCERTVIEWROW
Object expression that resolves to an IEnumCERTVIEWROW object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success.

[Visual Basic,Java] The returned object is a IEnumCERTVIEWATTRIBUTE object.

Remarks

The IEnumCERTVIEWATTRIBUTE object can be used to enumerate the certificate's attributes.

Example Code [C++]

// pEnumRow is previously instantiated pointer to IEnumCERTVIEWROW
HRESULT                  hr;
LONG                     Index;
IEnumCERTVIEWATTRIBUTE * pEnumAttr = NULL;

// obtain enumerator for attributes
hr = pEnumRow->EnumCertViewAttribute(0, &pEnumAttr);
if (FAILED(hr))
{
    printf("Failed EnumCertViewAttribute - %x\n", hr);
    goto error;
}
// enumerate each attribute
while (S_OK == pEnumAttr->Next(&Index))
{
    // Use this attribute as needed.
}
error:

// Free resources.
if (NULL != pEnumAttr)
    pEnumAttr->Release();

Example Code [Visual Basic]

' Initialize an IEnumCERTVIEWATTRIBUTE object.
Dim objAttrib As IEnumCERTVIEWATTRIBUTE
Set objAttrib = objRow.EnumCertViewAttribute(0)
' Use objAttrib as needed.
' ...
' Free objAttrib when done.
Set objAttrib = Nothing

Example Code [Java]

certadm.IEnumCERTVIEWATTRIBUTE objAttrib;

objAttrib = objRow.EnumCertViewAttribute(0);
// Use the attribute enumerator object as needed.

// When done, free the object.
com.ms.com.ComLib.release(objAttrib);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWATTRIBUTE, IEnumCERTVIEWROW


IEnumCERTVIEWROW::EnumCertViewColumn

Platform SDK: Security

IEnumCERTVIEWROW::EnumCertViewColumn [C++]

IEnumCERTVIEWROW.EnumCertViewColumn [Visual Basic,Java]

The EnumCertViewColumn method obtains an instance of the IEnumCERTVIEWCOLUMN object.

[C++]
HRESULT EnumCertViewColumn(
  IEnumCERTVIEWCOLUMN **ppenum
);
[Visual Basic]
objCERTVIEWROW.EnumCertViewColumn() As IEnumCERTVIEWCOLUMN
[Java]
IEnumCERTVIEWCOLUMN EnumCertViewColumn();

Parameters

[C++] ppenum
[out] Pointer to pointer of IEnumCERTVIEWCOLUMN type.
[Visual Basic] objCERTVIEWROW
Object expression that resolves to an IEnumCERTVIEWROW object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success.

[Visual Basic,Java] The return value is a IEnumCERTVIEWCOLUMN object.

Remarks

The IEnumCERTVIEWCOLUMN object is used to enumerate the view's columns for the purposes of retrieving data elements.

Example Code [C++]

// pEnumRow is previously instantiated pointer to IEnumCERTVIEWROW
HRESULT               hr;
LONG                  Index;
IEnumCERTVIEWCOLUMN * pEnumCol = NULL;
// obtain enumerator for columns
hr = pEnumRow->EnumCertViewColumn(&pEnumCol);
if ( FAILED( hr ))
{
    printf("Failed EnumCertViewColumn - %x\n", hr );
    goto error;
}
// enumerate each column
while (S_OK == pEnumCol->Next(&Index))
{
    // Use this column as needed.
}
error:

// Free resources.
if ( NULL != pEnumCol )
    pEnumCol->Release();

Example Code [Visual Basic]

' Initialize an IEnumCERTVIEWCOLUMN object.
Dim objCol As IEnumCERTVIEWCOLUMN
Set objCol = objRow.EnumCertViewColumn()
' Use objCol as needed.
' ...
' Free objCol when done.
Set objCol = Nothing

Example Code [Java]

certadm.IEnumCERTVIEWCOLUMN objCol;

objCol = objRow.EnumCertViewColumn();
// Use the column enumerator object as needed.

// When done, free the object.
com.ms.com.ComLib.release(objCol);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWCOLUMN, IEnumCERTVIEWROW


IEnumCERTVIEWROW::EnumCertViewExtension

Platform SDK: Security

IEnumCERTVIEWROW::EnumCertViewExtension [C++]

IEnumCERTVIEWROW.EnumCertViewExtension [Visual Basic,Java]

The EnumCertViewExtension method obtains an instance of the IEnumCERTVIEWEXTENSION object.

[C++]
EnumCertViewExtension(
  LONG Flags,
  IEnumCERTVIEWEXTENSION **ppenum
);
[Visual Basic]
objCERTVIEWROW.EnumCertViewExtension( Flags As Long ) As IEnumCERTVIEWEXTENSION
[Java]
IEnumCERTVIEWEXTENSION EnumCertViewExtension(
  int Flags
);

Parameters

[C++,Visual Basic,Java] Flags
[in] LONG value. Must be zero.
[C++] ppenum
[out] Pointer to pointer of IEnumCERTVIEWEXTENSION type.
[Visual Basic] objCERTVIEWROW
Object expression that resolves to an IEnumCERTVIEWROW object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success.

[Visual Basic,Java] The return value is a IEnumCERTVIEWEXTENSION object.

Remarks

The IEnumCERTVIEWEXTENSION object is used to enumerate the view's extensions.

Example Code [C++]

// pEnumRow is previously instantiated pointer to IEnumCERTVIEWROW.
LONG       Index;
HRESULT    hr;
IEnumCERTVIEWEXTENSION * pEnumExt = NULL;
// Obtain enumerator for extensions.
hr = pEnumRow->EnumCertViewExtension(0, &pEnumExt);
if (FAILED(hr))
{
    printf("Failed EnumCertViewExtension - %x\n", hr);
    goto error;
}
// Enumerate each extension.
while (S_OK == pEnumExt->Next(&Index))
{
    // Use this extension as needed.
}
error:

// Free resources.
if (NULL != pEnumExt)
    pEnumExt->Release();

Example Code [Visual Basic]

' Initialize an IEnumCERTVIEWEXTENSION object.
Dim objExt As IEnumCERTVIEWEXTENSION
Set objExt = objRow.EnumCertViewExtension(0)
' Use objExt as needed.
' ...
' Free objExt when done.
Set objExt = Nothing

Example Code [Java]

certadm.IEnumCERTVIEWEXTENSION objExt;
objExt = objRow.EnumCertViewExtension(0);

// Use the extension enumerator object as needed.

// When done, free the object.
com.ms.com.ComLib.release(objExt);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWEXTENSION, IEnumCERTVIEWROW


IEnumCERTVIEWROW::GetMaxIndex

Platform SDK: Security

IEnumCERTVIEWROW::GetMaxIndex [C++]

IEnumCERTVIEWROW.GetMaxIndex [Visual Basic,Java]

The GetMaxIndex method retrieves the maximum row index for a view.

[C++]
HRESULT GetMaxIndex(
  LONG *pIndex
);
[Visual Basic]
objCERTVIEWROW.GetMaxIndex() As Long
[Java]
int GetMaxIndex();

Parameters

[C++] pIndex
[out] Pointer to Long variable that will contain the maximum index value for the view. This function will fail if pIndex is NULL.
[Visual Basic] objCERTVIEWROW
Object expression that resolves to an IEnumCERTVIEWROW object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success, and *pIndex is set to the maximum index value for the view. If traversal to the last row hasn't occurred, this method fails with a return value of E_UNEXPECTED.

[Visual Basic,Java] The return value is the maximum index value for the view. This method fails if traversal to the last row hasn't occurred.

Remarks

Use this function to determine the maximum row index of the view. Successful completion of this function is dependent on reaching the last row of the view (by means of calls to IEnumCERTVIEWROW::Next). The maximum row index can be useful to size a scroll bar or display window, but it can also be expensive to compute, because it requires evaluating the entire query. For some queries, column data for each row must be examined to determine whether it is included in the view. Once the user has paged through all of the data or explicitly requested to proceed to the end, the maximum row index is preserved.

Example Code [C++]

long nMax;

// Determine the maximum row index.
hr = pRow->GetMaxIndex(&nMax);
if (FAILED(hr))
    printf("Failed GetMaxIndex [%x]\n", hr);
else
    printf("Max index is: %d\n", nMax);

Example Code [Visual Basic]

Dim lMax As Long

lMax = objRow.GetMaxIndex()
MsgBox lMax, vbOKOnly, "Max Index"

Example Code [Java]

// Determine the maximum row index.
try
{
    int nMax;
    nMax = objRow.GetMaxIndex();
    System.out.println(nMax);
}
catch (com.ms.com.ComFailException e)
{
    // The last row may not have been traversed yet.
    System.out.println("Failed GetMaxIndex " + e.getMessage());
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWROW::Next


IEnumCERTVIEWROW::Next

Platform SDK: Security

IEnumCERTVIEWROW::Next [C++]

IEnumCERTVIEWROW.Next [Visual Basic,Java]

The Next method positions the IEnumCERTVIEWROW object to the next row.

[C++]
HRESULT Next(
  LONG *pIndex
);
[Visual Basic]
objCERTVIEWROW.Next() As Long
[Java]
int Next();

Parameters

[C++] pIndex
[out] Pointer to Long variable that will contain the index value of the next row that will be referenced by the IEnumCERTVIEWROW object. If there are no more rows to enumerate, this variable will be set to – 1. This function will fail if pIndex is NULL.
[Visual Basic] objCERTVIEWROW
Object expression that resolves to an IEnumCERTVIEWROW object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success and that the next row is now being referenced by the IEnumCERTVIEWROW object. If there are no more rows to enumerate, S_FALSE is returned, and *pIndex is set to a value of– 1.

[Visual Basic,Java] The return value is the index value of the next row that will be referenced by the IEnumCERTVIEWROW object. If there are no more rows to enumerate, the return value will be – 1.

Remarks

Upon successful completion of this function, the IEnumCERTVIEWROW object will have moved to the next data row. Once the row is referenced, the column data can be retrieved through calls to IEnumCERTVIEWCOLUMN. Note that looping through all the database rows can be expensive to compute, depending of the query involved and the database size.

Example Code [C++]

// pEnumRow is previously instantiated pointer to IEnumCERTVIEWROW.
LONG  Index;
LONG  nCount;

// Ensure enumerator is at first row.
if (FAILED(pEnumRow->Reset()))
    printf("Failed to Reset\n");
else
{
    nCount = 0;
    // Count the database records by enumerating the rows.
    while (S_OK == pEnumRow->Next(&Index))
        nCount++;
    // Display number of records.
    printf("Number of records is %d\n", nCount);
}

Example Code [Visual Basic]

Dim nIndex As Long
nIndex = objRow.Next()

Do While (nIndex <> -1)
    ' Use the newly traversed row as needed.
    ' ...
    ' Move to the next row.
    nIndex = objRow.Next()
Loop

Example Code [Java]

int nIndex, cRow=0;

// Traverse the rows. This may be a lengthy process
// depending on the database size and the query involved.
nIndex = objRow.Next();
while (-1 != nIndex)
{
    cRow++;
    nIndex = objRow.Next();
}
System.out.println("Number of rows = " + cRow);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWCOLUMN, IEnumCERTVIEWROW, IEnumCERTVIEWROW::Reset, IEnumCERTVIEWROW::Skip


IEnumCERTVIEWROW::Reset

Platform SDK: Security

IEnumCERTVIEWROW::Reset [C++]

IEnumCERTVIEWROW.Reset [Visual Basic,Java]

The Reset method resets the IEnumCERTVIEWROW enumeration sequence to the beginning.

[C++]
HRESULT Reset();
[Visual Basic]
objCERTVIEWROW.Reset()
[Java]
void Reset();

Parameters

[Visual Basic] objCERTVIEWROW
Object expression that resolves to an IEnumCERTVIEWROW object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success.

[Visual Basic,Java] None.

Remarks

Upon successful completion of this function, the IEnumCERTVIEWROW object will be positioned to the beginning the Certificate Services view's rows. To access the data in the first row after calling the Reset method, call the IEnumCERTVIEWROW::Next method. After a valid row has been referenced by the IEnumCERTVIEWROW object, data can be retrieved through calls to IEnumCERTVIEWCOLUMN.

Example Code [C++]

// pEnumRow is previously instantiated pointer to IEnumCERTVIEWROW.
HRESULT hr;
LONG    Index;

// Ensure enumerator is at first row.
hr = pEnumRow->Reset();
if (FAILED(hr))
    printf("Failed to Reset\n");
else
{
    printf("Reset to beginning\n");
    // Retrieve first record.
    hr = pEnumRow->Next(&Index);
    // Examine hr for success and process row.
    // ...
}

Example Code [Visual Basic]

' Reset the IEnumCERTVIEWROW object.
objRow.Reset

Example Code [Java]

objRow.Reset();

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWCOLUMN, IEnumCERTVIEWROW, IEnumCERTVIEWROW::Next, IEnumCERTVIEWROW::Skip


IEnumCERTVIEWROW::Skip

Platform SDK: Security

IEnumCERTVIEWROW::Skip [C++]

IEnumCERTVIEWROW.Skip [Visual Basic,Java]

The Skip method skips a specified number of rows in the IEnumCERTVIEWROW enumeration sequence.

[C++]
HRESULT Skip(
  LONG celt
);
[Visual Basic]
objCERTVIEWROW.Skip( celt As Long )
[Java]
void Skip(
  int celt
);

Parameters

[C++,Visual Basic,Java] celt
[in] Number of rows for the IEnumCERTVIEWROW object to skip. A positive value for celt causes the IEnumCERTVIEWROW object to skip forward in the enumeration sequence; a negative value for celt causes the IEnumCERTVIEWROW object to skip backward in the enumeration sequence.
[Visual Basic] objCERTVIEWROW
Object expression that resolves to an IEnumCERTVIEWROW object.

Return Values

[C++] The return value is an HRESULT. A value of S_OK indicates success. A return value of E_INVALIDARG indicates that a negative value for celt caused the IEnumCERTVIEWROW object's index to become less than zero.

[Visual Basic,Java] None.

Remarks

Upon successful completion of this function, the IEnumCERTVIEWROW object will have skipped celt rows in the enumeration sequence. To access the row contents after a call to the IEnumCERTVIEWROW::Skip method, call the IEnumCERTVIEWROW::Next method.

The IEnumCERTVIEWROW object maintains an internal value representing the zero-based index of the row to be accessed when the IEnumCERTVIEWROW::Next method is called. A call to the IEnumCERTVIEWROW::Skip method causes this index to increase by celt if celt is positive, or to decrease by celt if celt is negative.

Negative values for celt are validated, and this function will fail if celt causes the index to be less than zero.

Positive values for celt are not validated, but if a positive value for celt causes the internal value to exceed the index for the last row in the enumeration sequence, a subsequent call to the IEnumCERTVIEWROW::Next method will fail.

Example Code [C++]

// pEnumRow is previously instantiated pointer to IEnumCERTVIEWROW.
HRESULT  hr;
LONG     Index;
// Reposition the row enumerator to the beginning of the rows.
hr = pEnumRow->Reset();
if (FAILED(hr))
{
    printf("Unable to reset pEnumRow\n");
    goto error;
}
// Skip some rows.
hr = pEnumRow->Skip(5);
if (FAILED(hr))
{
    printf("Unable to skip rows\n");
    goto error;
}

// Get the next row.
hr = pEnumRow->Next(&Index);
if (S_OK == hr)
{
    // Use this row as needed.
}

error:

if (NULL != pEnumRow)
    pEnumRow->Release();

Example Code [Visual Basic]

' Skip five rows.
objRow.Skip (5)

Example Code [Java]

// Skip three rows.
objRow.Skip(3);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certview.h; include Certsrv.h.
Library: Use Certidl.lib.

See Also

IEnumCERTVIEWROW, IEnumCERTVIEWROW:Next, IEnumCERTVIEWROW::Reset, IEnumCERTVIEWROW::Skip


Backup and Restore Functions

Certificate Services includes a group of functions for backing up and restoring the Certificate Services database. These Certificate Services backup and restore functions are contained in certadm.dll. Unlike the other API elements associated with Certificate Services, these functions are not encapsulated in an object that can be used to call class methods. Instead, you can call the backup and restore APIs by first loading the certadm.dll library into memory (by calling LoadLibrary), and then determining the address of the functions (by calling GetProcAddress). When done calling the Certificate Services backup and restore functions, call FreeLibrary to free certadm.dll resources from memory.

Note that the backup and restore functions provided by certadm.dll do not backup or restore the Certificate Services private key(s). For information on backing up the Certificate Services private keys, see Backing Up and Restoring the Certificate Services Private Key.

To call the backup and restore functions, you must have backup and restore privileges. For details, see Setting the Backup and Restore Privileges.

Note If CoInitializeEx was previously called in the same thread used to call the Certificate Services backup and restore APIs, the COINIT_APARTMENTTHREADED flag must have been passed to CoInitializeEx; that is, when using the same thread, you cannot call the Certificate Services backup and restore API if the thread has previously passed in the COINIT_MULTITHREADED flag in a call to CoInitializeEx.

The Certificate Services Backup APIs are defined in certbcli.h. When you create your program, however, use certsrv.h as the include file.

The following APIs are exported by certadm.dll.

Function | Description
CertSrvBackupClose | Closes an opened file.
CertSrvBackupEnd | Ends a backup session.
CertSrvBackupFree | Frees a buffer allocated by the backup and restore APIs.
CertSrvBackupGetBackupLogs | Returns the list of log file names which need to be backed up.
CertSrvBackupGetDatabaseNames | Returns the list of database file names which need to be backed up.
CertSrvBackupGetDynamicFileList | Returns the list of dynamic (non-database related) file names which need to be backed up.
CertSrvBackupOpenFile | Opens a file in preparation for backing it up.
CertSrvBackupPrepare | Prepares the database for the online backup.
CertSrvBackupRead | Reads the contents of an opened file.
CertSrvBackupTruncateLogs | Truncates the log files.
CertSrvIsServerOnline | Determines if a Certificate Services server is online (actively running).
CertSrvRestoreEnd | Ends a restore session.
CertSrvRestoreGetDatabaseLocations | Retrieves database locations (used for both backup and restore scenarios).
CertSrvRestorePrepare | Begins a restore session.
CertSrvRestoreRegister | Registers a restore operation.
CertSrvRestoreRegisterComplete | Completes a previously registered restore operation.
CertSrvServerControl | Sends a control command to the Certificate Services instance.


CertSrvBackupClose

This function closes the file opened by CertSrvBackupOpenFile.

HRESULT CertSrvBackupClose(
  HCSBC hbc
);

Parameters

hbc
[in] Handle to a Certificate Services backup context.

Return Values

The return value is an HRESULT. A value of S_OK indicates success.

Remarks

Upon completion of backing up a file, the file needs to be closed. For every successful call to CertSrvBackupOpenFile, there should be a call to CertSrvBackupClose.

Example Code

FNCERTSRVBACKUPCLOSE* pfnClose;
char * szBackupCloseFunc = "CertSrvBackupClose";
HRESULT    hr=0;

// Get the address for the desired function.
// hInst was set by calling LoadLibrary for CertAdm.dll.
pfnClose = (FNCERTSRVBACKUPCLOSE*)GetProcAddress(hInst,
                                   szBackupCloseFunc);
if ( NULL == pfnClose )
{
    printf("Failed GetProcAddress - %s, error=%d\n",
            szBackupCloseFunc,
            GetLastError() );
    exit(1);  // Or other appropriate error action.
}
// Close the file.
// hCSBC represents an HCSBC used in
// an earlier call to CertSrvBackupOpenFile.
hr = pfnClose(hCSBC);
if (FAILED(hr))
{
    printf("Failed pfnClose call [%x]\n", hr);
    exit(1);  // Or other appropriate error action.
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certbcli.h; include Certsrv.h.
Library: Included as a resource in Certadm.dll.
Unicode: Implemented only as Unicode.

See Also

CertSrvBackupOpenFile, CertSrvBackupRead, Using the Certificate Services Backup and Restore Functions


CertSrvBackupEnd

This function ends a Certificate Services backup session.

HRESULT CertSrvBackupEnd(
  HCSBC hbc
);

Parameters

hbc
[in] Handle to a Certificate Services backup context.

Return Values

The return value is an HRESULT. A value of S_OK indicates success.

Remarks

Upon completion of a backup session, the session needs to be terminated by means of CertSrvBackupEnd. For every successful call to CertSrvBackupPrepare, there should be a call to CertSrvBackupEnd.

Example Code

FNCERTSRVBACKUPEND* pfnBackupEnd;
char * szBackEndFunc = "CertSrvBackupEnd";
HRESULT    hr=0;

// Get the address for the desired function.
// hInst was set by calling LoadLibrary for CertAdm.dll.
pfnBackupEnd = (FNCERTSRVBACKUPEND*)GetProcAddress(hInst,
                                       szBackEndFunc);
if (NULL == pfnBackupEnd)
{
    printf("Failed GetProcAddress - %s, error=%d\n",
           szBackEndFunc,
           GetLastError() );
    exit(1);  // Or other appropriate error action.
}

// When done, release the HCSBC.
// hCSBC would have been created by an earlier call
// to CertSrvBackupPrepare.
hr = pfnBackupEnd(hCSBC);
if (FAILED(hr))
{
    printf("Failed pfnBackupEnd call [%x]\n", hr);
    exit(1);  // Or other appropriate error action.
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certbcli.h; include Certsrv.h.
Library: Included as a resource in Certadm.dll.
Unicode: Implemented only as Unicode.

See Also

CertSrvBackupPrepare, Using the Certificate Services Backup and Restore Functions


CertSrvBackupFree

This function is used to free memory allocated from certain Certificate Services Backup APIs.

VOID CertSrvBackupFree(
  VOID *pv
);

Parameters

pv
[in] Pointer to memory to be freed.

Remarks

Call this function when finished with memory allocated by means of the following functions:

  • CertSrvBackupGetBackupLogs
  • CertSrvBackupGetDatabaseNames
  • CertSrvBackupGetDynamicFileList
  • CertSrvServerControl
  • CertSrvRestoreGetDatabaseLocations

Example Code

FNCERTSRVBACKUPFREE* pfnBackupFree;

char * szBackupFreeFunc = "CertSrvBackupFree";

// Get the address for the desired function.
// hInst was set by calling LoadLibrary for CertAdm.dll.
pfnBackupFree = (FNCERTSRVBACKUPFREE*)GetProcAddress(hInst,
                      szBackupFreeFunc);
if ( NULL == pfnBackupFree )
{
    printf("Failed GetProcAddress - %s, error=%d\n",
           szBackupFreeFunc,
           GetLastError() );
    exit(1);
}

// Use the backup APIs.
// ...

// Free allocated memory.
// pBuff was allocated by another certsrv backup function.
pfnBackupFree(pBuff);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certbcli.h; include Certsrv.h.
Library: Included as a resource in Certadm.dll.
Unicode: Implemented only as Unicode.

See Also

CertSrvBackupGetBackupLogs, CertSrvBackupGetDatabaseNames, CertSrvBackupGetDynamicFileList, CertSrvServerControl, CertSrvRestoreGetDatabaseLocations, Using the Certificate Services Backup and Restore Functions


CertSrvBackupGetBackupLogs

This function retrieves the list of Certificate Services log file names which need to be backed up for the given backup context.

HRESULT CertSrvBackupGetBackupLogs(
  HCSBC hbc,
  WCHAR **ppwszzBackupLogFiles,
  DWORD *pcbSize
);

Parameters

hbc
[in] Handle to a Certificate Services backup context.
ppwszzBackupLogFiles
[out] Pointer to WCHAR pointer that will receive the list of null-terminated log file names. There is a null character after every file name and an extra null character at the end of the list. The file name will be in the UNC form "## \\server\sharepoint\…path…\filename.ext". The text "##" denotes a Certificate Services Backup file type (CSBFT_*) and is stored as a single non-null Unicode character prefixed onto each UNC path. This type tag is defined in certbcli.h and can be one of the following values for this function.
Value | Description
CSBFT_LOG | Certificate Services database log filename including path.
CSBFT_PATCH_FILE | Certificate Services database patch filename including path.

You must free this allocated memory when done by calling CertSrvBackupFree.

Setting *ppwszzBackupLogFiles to NULL before calling this function is optional.

pcbSize
[out] Pointer to the DWORD value which specifies the number of bytes in ppwszzBackupLogFiles.

Return Values

The return value is an HRESULT. A value of S_OK indicates success.

Remarks

The log files represent database activity (request submissions, certificate revocation, and so on) which has occurred since the last log file truncation. Log file volume increases as database activity occurs; the log files can be decreased in size by performing a backup and then calling CertSrvBackupTruncateLogs.

This function's name in the certadm.dll is CertSrvBackupGetBackupLogsW. You must use this form of the name when calling GetProcAddress. Also, this function is defined as type FNCERTSRVBACKUPGETBACKUPLOGSW in the certbcli.h header file.

Example Code

FNCERTSRVBACKUPGETBACKUPLOGSW* pfnGetBackupLogs;
char * szGetBackupLogsFunc = "CertSrvBackupGetBackupLogsW";

WCHAR *    pwszzLogFiles;

DWORD      nListBytes=0;

HRESULT    hr=0;

// Get the address for the desired function.
// hInst was set by calling LoadLibrary for CertAdm.dll.
pfnGetBackupLogs = (FNCERTSRVBACKUPGETBACKUPLOGSW*)GetProcAddress(hInst,
                               szGetBackupLogsFunc);
if ( NULL == pfnGetBackupLogs )
{
    printf("Failed GetProcAddress - %s, error=%d\n",
           szGetBackupLogsFunc,
           GetLastError() );
    exit(1); // Or other appropriate error action.
}

// Determine the names of the log files.
// hCSBC was set by an earlier call to CertSrvbackupPrepare.
hr = pfnGetBackupLogs(hCSBC, &pwszzLogFiles, &nListBytes);
if (FAILED(hr))
{
    printf("Failed pfnGetBackupLogs call [%x]\n", hr);
    exit(1); // Or other appropriate error action.
}
else
{
    printf("%d bytes for log file names\n", nListBytes);
    WCHAR * pwszLog = pwszzLogFiles;
    // Process the list.
    while ( L'\0' != *pwszLog )
    {
        // Use the file name referenced by pwszLog.
        // Here it is merely displayed.
        printf("%02x: %ws\n", *pwszLog, &pwszLog[1]);
        // Move to the next logfile name.
        // + 1 moves past the null terminator.
        pwszLog+=(wcslen(pwszLog)) + 1;
    }

    // Free the allocated memory.
    // pfnBackupFree is the address of the CertSrvBackupFree function.
    pfnBackupFree(pwszzLogFiles);
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certbcli.h; include Certsrv.h.
Library: Included as a resource in Certadm.dll.
Unicode: Implemented only as Unicode.

See Also

CertSrvBackupFree, CertSrvBackupOpenFile, CertSrvBackupTruncateLogs, Using the Certificate Services Backup and Restore Functions


CertSrvBackupGetDatabaseNames

This function retrieves the list of Certificate Services database file names which need to be backed up for the given backup context.

HRESULT CertSrvBackupGetDatabaseNames(
  HCSBC hbc,
  WCHAR **ppwszzAttachmentInformation,
  DWORD *pcbSize
);

Parameters

hbc
[in] Handle to a Certificate Services backup context.
ppwszzAttachmentInformation
[out] Pointer to WCHAR pointer that will receive the list of null-terminated database file names. There is a null character after every file name and an extra null character at the end of the list. The file name will be in the UNC form "## \\server\sharepoint\…path…\filename.ext". The text "##" denotes a Certificate Services Backup file type (CSBFT_*) and is stored as a single non-null Unicode character prefixed onto each UNC path. The type tag is defined in certbcli.h and can be the following value for this function.
Value | Description
CSBFT_CERTSERVER_DATABASE | Certificate Services database filename including path.

You must free this allocated memory when done by calling CertSrvBackupFree. Before calling this function, setting *ppwszzAttachmentInformation to NULL is optional.

pcbSize
[out] Pointer to the DWORD value which specifies the number of bytes in ppwszzAttachmentInformation.

Return Values

The return value is an HRESULT. A value of S_OK indicates success.

Remarks

Use this function to retrieve a list of the Certificate Services database file names.

This function's name in the certadm.dll is CertSrvBackupGetDatabaseNamesW. You must use this form of the name when calling GetProcAddress. Also, this function is defined as type FNCERTSRVBACKUPGETDATABASENAMESW in the certbcli.h header file.

Example Code

FNCERTSRVBACKUPGETDATABASENAMESW* pfnGetDBNames;
char * szGetDBNamesFunc = "CertSrvBackupGetDatabaseNamesW";
WCHAR *    pwszzDBFiles;
DWORD      nListBytes=0;
HRESULT    hr=0;

// Get the address for the desired function.
// hInst was set by calling LoadLibrary for CertAdm.dll.
pfnGetDBNames = (FNCERTSRVBACKUPGETDATABASENAMESW*)GetProcAddress(hInst,
                                            szGetDBNamesFunc);
if ( NULL == pfnGetDBNames )
{
    printf("Failed GetProcAddress - %s, error=%d\n",
           szGetDBNamesFunc,
           GetLastError() );
    exit(1); // Or other appropriate error action.
}

// Determine the names of the database files.
// hCSBC was set by an earlier call to CertSrvBackupPrepare
hr = pfnGetDBNames(hCSBC, &pwszzDBFiles, &nListBytes);
if (FAILED(hr))
{
    printf("Failed pfnGetDBNames call [%x]\n", hr);
    exit(1); // Or other appropriate error action.
}
else
{
    printf("%d bytes for DB file names\n", nListBytes);
    WCHAR * pwszFile = pwszzDBFiles;
    // Process the list.
    while ( L'\0' != *pwszFile )
    {
        // Use the file name referenced by pwszFile.
        // Here it is merely displayed.
        printf("%02x: %ws\n", *pwszFile, &pwszFile[1]);
        // Move to the next database file name.
        // + 1 moves past the null terminator.
        pwszFile+=(wcslen(pwszFile)) + 1;
    }
    // Free the allocated memory.
    // pfnBackupFree is the address of the CertSrvBackupFree function.
    pfnBackupFree(pwszzDBFiles);
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certbcli.h; include Certsrv.h.
Library: Included as a resource in Certadm.dll.
Unicode: Implemented only as Unicode.

See Also

CertSrvBackupFree, CertSrvBackupOpenFile, Using the Certificate Services Backup and Restore Functions


CertSrvBackupGetDynamicFileList

This function retrieves the list of Certificate Services dynamic file names which need to be backed up for the given backup context. The dynamic files are those that are not included in the Certificate Services database backup.

HRESULT CertSrvBackupGetDynamicFileList(
  HCSBC hbc,
  WCHAR **ppwszzFileList,
  DWORD *pcbSize
);

Parameters

hbc
[in] Handle to a Certificate Services backup context.
ppwszzFileList
[out] Pointer to WCHAR pointer that will receive the list of null-terminated dynamic file names used by Certificate Services. There is a null character after every file name and an extra null character at the end of the list. The file name will be in the UNC form "\\server\sharepoint\…path…\filename.ext". You must free this allocated memory when done by calling CertSrvBackupFree.

Before calling this function, setting *ppwszzFileList to NULL is optional.

pcbSize
[out] Pointer to the DWORD value which specifies the number of bytes in ppwszzFileList.

Return Values

The return value is an HRESULT. A value of S_OK indicates success.

Remarks

Use this function to retrieve a list of the Certificate Services dynamic file names. These files are separate from the Certificate Services database and log files, and they are not backed up by the Certificate Services backup APIs. As a result, some other means must be used to back up the dynamic files. An example of a Certificate Services dynamic file is the certificate revocation list (CRL).

This function's name in the certadm.dll is CertSrvBackupGetDynamicFileListW. You must use this form of the name when calling GetProcAddress. Also, this function is defined as type FNCERTSRVBACKUPGETDYNAMICFILELISTW in the certbcli.h header file.

Example Code

FNCERTSRVBACKUPGETDYNAMICFILELISTW* pfnGetDynFiles;
char * szGetDynFilesFunc = "CertSrvBackupGetDynamicFileListW";
WCHAR *    pwszzDynFiles;
DWORD      nListBytes=0;
HRESULT    hr=0;

// Get the address for the desired function.
// hInst was set by calling LoadLibrary for CertAdm.dll.
pfnGetDynFiles = (FNCERTSRVBACKUPGETDYNAMICFILELISTW*)GetProcAddress(hInst,
                                                 szGetDynFilesFunc);
if ( NULL == pfnGetDynFiles )
{
    printf("Failed GetProcAddress - %s, error=%d\n",
           szGetDynFilesFunc,
           GetLastError() );
    exit(1); // Or other appropriate error action.
}

// Determine the names of the dynamic files.
// hCSBC was set by an earlier call to CertSrvBackupPrepare
hr = pfnGetDynFiles(hCSBC, &pwszzDynFiles, &nListBytes);
if (FAILED(hr))
{
    printf("Failed pfnGetDynFiles call [%x]\n", hr);
    exit(1); // Or other appropriate error action.
}
else
{
    printf("%d bytes for dynamic file names\n", nListBytes);
    WCHAR * pwszFile = pwszzDynFiles;
    // Process the list.
    while ( L'\0' != *pwszFile )
    {
        // Use the file name referenced by pwszFile.
        // Here it is merely displayed.
        printf("%ws\n", pwszFile);
        // Move to the next dynamic file name.
        // + 1 moves past the null terminator.
        pwszFile+=(wcslen(pwszFile)) + 1;
    }
    // Free the allocated memory.
    // pfnBackupFree is the address of the CertSrvBackupFree function.
    pfnBackupFree(pwszzDynFiles);
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certbcli.h; include Certsrv.h.
Library: Included as a resource in Certadm.dll.
Unicode: Implemented only as Unicode.

See Also

CertSrvBackupFree, Using the Certificate Services Backup and Restore Functions


CertSrvBackupOpenFile

This function is used to open a file for backup.

HRESULT CertSrvBackupOpenFile(
  HCSBC hbc,
  WCHAR const *pwszAttachmentName,
  DWORD cbReadHintSize,
  LARGE_INTEGER *pliFileSize
);

Parameters

hbc
[in] Handle to a Certificate Services backup context.
pwszAttachmentName
[in] File name to open for backup purposes. This file name would be parsed from a list produced by means of CertSrvBackupGetBackupLogs or CertSrvBackupGetDatabaseNames. Note that the names returned by CertSrvBackupLogs and CertSrvBackupGetDatabaseNames must have the single-WCHAR CSBFT_* prefix stripped before CertSrvBackupOpenFile is called.
cbReadHintSize
[in] Number of bytes used as a hint when the file is read by CertSrvBackupRead. The cbReadHintSize parameter passed to the first CertSrvBackupOpenFile call for the backup context is used to size the read buffer. Pass 0 for this parameter, and the buffer will be sized at a reasonably efficient size chosen by CertSrvBackupOpenFile. If insufficient memory is available, the buffer size will be reduced until memory allocation succeeds or until the buffer size reaches its minimum possible value. Pass a non-zero size to cause CertSrvBackupOpenFile to size the buffer to a power of 2 near the value of cbReadHintSize. The current implementation will choose only powers of 2 between 64K and 4MB.
pliFileSize
[out] Pointer to LARGE_INTEGER value which represents the number of bytes in the file.

Return Values

The return value is an HRESULT. A value of S_OK indicates success.

Remarks

Use this function to open a file for backup purposes. When done using the file, call CertSrvBackupClose to close the file.

This function's name in certadm.dll is CertSrvBackupOpenFileW. You must use this form of the name when calling GetProcAddress. Also, this function is defined as type FNCERTSRVBACKUPOPENFILEW in the certbcli.h header file.

Example Code

FNCERTSRVBACKUPOPENFILEW* pfnOpenFile;
char * szBackupOpenFunc = "CertSrvBackupOpenFileW";
LARGE_INTEGER liFileSize;
HRESULT       hr=0;

// Get the address for the desired function.
// hInst was set by calling LoadLibrary for CertAdm.dll.
pfnOpenFile = (FNCERTSRVBACKUPOPENFILEW*)GetProcAddress(hInst,
                                         szBackupOpenFunc);
if ( NULL == pfnOpenFile )
{
    printf("Failed GetProcAddress - %s, error=%d\n",
            szBackupOpenFunc,
            GetLastError() );
    exit(1); // Or other appropriate error action.
}

// Open the file.
// hCSBC was set by an earlier call to CertSrvBackupPrepare.
// pwszFile specifies the name of a file.
// This name could have resulted from parsing the
// output from CertSrvBackupGetDatabaseNames, etc.
hr = pfnOpenFile(hCSBC,
                pwszFile,
                0,
                &liFileSize);
if (FAILED(hr))
{
    printf("Failed pfnOpenFile call [%x] %ws\n",
           hr,
           pwszFile);
           exit(1); // Or other appropriate error action.
}

// Use the opened file as needed.
// When done using the file, call CertSrvBackupClose.
// ...

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certbcli.h; include Certsrv.h.
Library: Included as a resource in Certadm.dll.
Unicode: Implemented only as Unicode.

See Also

CertSrvBackupRead, CertSrvBackupClose, Using the Certificate Services Backup and Restore Functions


CertSrvBackupPrepare

This function is used to prepare a Certificate Services server for backup operations.

HRESULT CertSrvBackupPrepare(
  WCHAR const *pwszServerName,
  ULONG grbitJet,
  ULONG dwBackupFlags,
  HCSBC *phbc
);

Parameters

pwszServerName
[in] Pointer to the machine name of the server to prepare for online backup. This name can be the NetBIOS name or the DNS name. Currently only one certification authority (CA) can run on a server, but future releases may allow multiple CAs to run on the same server; in that event, all CAs on pwszServerName will be backed up.
grbitJet
[in] Value used by the database engine; this value should be set to zero.
dwBackupFlags
[in] Specifies the backup type. This can be either of the following values.
Value | Meaning
CSBACKUP_TYPE_FULL | Backup the Certificate Services database, logs and related files.
CSBACKUP_TYPE_LOGS_ONLY | Backup the log files only.

phbc
[out] Pointer to a Certificate Services backup context handle (HCSBC).

Return Values

The return value is an HRESULT. A value of S_OK indicates success, and *phbc will be set to an HCSBC which can be used by other Certificate Services backup APIs.

Remarks

Before a Certificate Services backup can occur, it is necessary to create an HCSBC by means of CertSrvBackupPrepare. The resulting HCSBC is a necessary parameter of Certificate Services backup functions which can be used to list, open, read, and close files, as well as truncate the log files.

Note When the backup session is completed, it is necessary to call CertSrvBackupEnd to release the HCSBC which resulted from the call to CertSrvBackupPrepare.

This function's name in certadm.dll is CertSrvBackupPrepareW. You must use this form of the name when calling GetProcAddress. Also, this function is defined as type FNCERTSRVBACKUPPREPAREW in the certbcli.h header file.

To execute this call, you must have the backup privilege. For details, see Setting the Backup and Restore Privileges.

Example Code

WCHAR *    wszServer = L"MyCertServerMachine";
FNCERTSRVBACKUPPREPAREW* pfnBackupPrepare;
char * szBackPrepFunc = "CertSrvBackupPrepareW";
HINSTANCE  hInst=0;
HCSBC      hCSBC=NULL;
HRESULT    hr=0;

// Load the DLL.
hInst = LoadLibrary(L"certadm.dll");
if ( NULL == hInst )
{
    printf("Failed LoadLibrary, error=%d\n",
            GetLastError() );
    exit(1); // Or other appropriate error action.
}
// Get the address for the desired function.
pfnBackupPrepare = (FNCERTSRVBACKUPPREPAREW*)GetProcAddress( hInst,
                                        szBackPrepFunc );
if ( NULL == pfnBackupPrepare )
{
    printf("Failed GetProcAddress - %s, error=%d\n",
           szBackPrepFunc,
           GetLastError() );
    exit(1); // Or other appropriate error action.
}

// Prepare CertServ for backup.
hr = pfnBackupPrepare(wszServer,
                      0,
                      CSBACKUP_TYPE_FULL,
                      &hCSBC);
if (FAILED(hr))
{
    printf("Failed pfnBackupPrepare call [%x]\n", hr);
    exit(1); // Or other appropriate error action.
}

// Use the HCSBC for backup operations.
// ...

// When done processing, release the HCSBC context
// by calling CertSrvBackupEnd (not shown here).
// ...

// Done processing, free the DLL.
if (hInst)
    FreeLibrary(hInst);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certbcli.h; include Certsrv.h.
Library: Included as a resource in Certadm.dll.
Unicode: Implemented only as Unicode.

See Also

CertSrvBackupEnd, Using the Certificate Services Backup and Restore Functions


CertSrvBackupRead

This function is used to read bytes from a Certificate Services file.

HRESULT CertSrvBackupRead(
  HCSBC hbc,
  VOID *pvBuffer,
  DWORD cbBuffer,
  DWORD *pcbRead
);

Parameters

hbc
[in] Handle to a Certificate Services backup context.
pvBuffer
[out] Void pointer to storage which will contain bytes read from the file being backed up.
cbBuffer
[in] Size of the storage area referenced by pvBuffer.
pcbRead
[out] Pointer to DWORD value which represents the actual number of bytes read by CertSrvBackupRead. The number of bytes read can be less than the size of the storage area allocated to pvBuffer if the end of the file has been reached.

Return Values

The return value is an HRESULT. A value of S_OK indicates success.

Remarks

After opening the file for backup purposes (using CertSrvBackupOpenFile), call CertSrvBackupRead to retrieve the contents of the file, and call an application-specific routine to write the contents to a backup medium. CertSrvBackupRead and the application-specific routine can be placed in a loop until all the bytes of the file are read and backed up. When done reading the file, close it by calling CertSrvBackupClose.

Example Code

#define BUFFSIZE 524288

FNCERTSRVBACKUPREAD* pfnRead;
char * szBackupReadFunc = "CertSrvBackupRead";
BYTE       ReadBuff[BUFFSIZE];
DWORD      cbRead=0;
HRESULT    hr=0;

// Get the address for the desired function.
// hInst was set by calling LoadLibrary for CertAdm.dll.
pfnRead = (FNCERTSRVBACKUPREAD*)GetProcAddress(hInst,
                                          szBackupReadFunc);
if ( NULL == pfnRead )
{
    printf("Failed GetProcAddress - %s, error=%d\n",
           szBackupReadFunc,
           GetLastError() );
    exit(1); // Or other appropriate error action.
}

// Read the file.
// hCSBC represents an HCSBC used in
// an earlier call to CertSrvBackupOpenFile.
// To read the entire file, this code
// would be placed in a loop.
hr = pfnRead( hCSBC,
              &ReadBuff,
              BUFFSIZE,
              &cbRead );
if (FAILED(hr))
{
    printf("Failed pfnRead call [%x]\n", hr);
    exit(1); // Or other appropriate error action.
}

// Use the bytes read as needed. For example,
// in an application-specific routine to back
// up the file contents.
// ...

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certbcli.h; include Certsrv.h.
Library: Included as a resource in Certadm.dll.
Unicode: Implemented only as Unicode.

See Also

CertSrvBackupOpenFile, CertSrvBackupClose, Using the Certificate Services Backup and Restore Functions


CertSrvBackupTruncateLogs

This function is used to eliminate redundant records and reduce the disk storage space used by log files. Before truncating the log files, ensure that a backup of all files returned by CertSrvBackupGetDatabaseNames and CertSrvBackupGetBackupLogs has been secured.

HRESULT CertSrvBackupTruncateLogs(
    HCSBC hbc
);

Parameters

hbc
[in] Handle to a Certificate Services backup context.

Return Values

The return value is an HRESULT. A value of S_OK indicates success.

Remarks

After securing a backup of the database and log files, the log files can optionally be truncated. Log file volume increases with database activity, and truncating the log files will reduce the redundant records in the log files (thereby decreasing the disk space used to store the log files).

The log files are provided for database integrity and efficiency. If a less-than-graceful exit occurs with the Certificate Services application, the next time Certificate Services is started, the database replays the log files to prevent data corruption from being introduced into the database.

Depending on the volume of the log files, the log file replay can be a time-consuming process. During this replay, the certification authority will be unavailable for other activity. Note that if the Certificate Services application is properly halted (such as by stopping the service or by shutting down the operating system properly), the log files are not replayed the next time it is started.

Note If you call CertSrvBackupTruncateLogs without backing up all files returned from CertSrvBackupGetDatabaseNames and CertSrvBackupGetBackupLogs, you will not be able to restore the backup set successfully, resulting in an unusable Certificate Services machine. Therefore, call CertSrvBackupTruncateLogs only when the backup set contains all files returned from CertSrvBackupGetDatabaseNames and CertSrvBackupGetBackupLogs.

Example Code

FNCERTSRVBACKUPTRUNCATELOGS* pfnTruncateLogs;
char * szTruncateLogsFunc = "CertSrvBackupTruncateLogs";

HRESULT    hr=0;

// Get the address for the desired function.
// hInst was set by calling LoadLibrary for CertAdm.dll.
pfnTruncateLogs = (FNCERTSRVBACKUPTRUNCATELOGS*)GetProcAddress( hInst,
                                           szTruncateLogsFunc );
if ( NULL == pfnTruncateLogs )
{
    printf("Failed GetProcAddress - %s, error=%d\n",
           szTruncateLogsFunc,
           GetLastError() );
    exit(1); // Or other appropriate error action.
}

// After they have been backed up, truncate the logs.
// hCSBC is a previously set HCSBC variable.
hr = pfnTruncateLogs(hCSBC);
if (FAILED(hr))
{
    printf("Failed pfnTruncateLogs call [%x]\n", hr);
    exit(1); // Or other appropriate error action.
}
else
    printf("Logs truncated\n");

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certbcli.h; include Certsrv.h.
Library: Included as a resource in Certadm.dll.
Unicode: Implemented only as Unicode.

See Also

CertSrvBackupGetBackupLogs, Using the Certificate Services Backup and Restore Functions


CertSrvIsServerOnline

This function is used to determine if a Certificate Services server is online; if the Certificate Services server is not online, backup operations will not be successful.

HRESULT CertSrvIsServerOnline(
  WCHAR const *pwszServerName,
  BOOL *pfServerOnline
);

Parameters

pwszServerName
[in] Pointer to the machine name of the server to check for online status. This name can be the NetBIOS name or the DNS name.
pfServerOnline
[out] Pointer to boolean value which will be TRUE if the Certificate Services server is online and FALSE if it is not online.

Return Values

The return value is an HRESULT. This function will fail if Certificate Services is not running. If Certificate Services is running and ready to accept requests, this function will return S_OK, and *pfServerOnline will point to a value of TRUE. If Certificate Services is running in suspended (or paused) mode, this function will return S_OK, and *pfServerOnline will point to a value of FALSE.

Remarks

Call this function to determine if a Certificate Services server is online and available for backup operations.

This function's name in certadm.dll is CertSrvIsServerOnlineW. You must use this form of the name when calling GetProcAddress. Also, this function is defined as type FNCERTSRVISSERVERONLINEW in the certbcli.h header file.

Example Code

FNCERTSRVISSERVERONLINEW* pfnOnline = NULL;
char * szOnlineFunc = "CertSrvIsServerOnlineW";
BOOL       bOnline = 0;
HRESULT    hr = 0;

// Get the address of the function.
// hInst was set by calling LoadLibrary for CertAdm.dll.
pfnOnline = (FNCERTSRVISSERVERONLINEW*) GetProcAddress(hInst,
                                        szOnlineFunc );
if ( NULL == pfnOnline )
{
    printf("Failed GetProcAddress - %s, error=%d\n",
           szOnlineFunc,
           GetLastError() );
    exit(1);  // Or other appropriate error action.
}

// Call the function; wszServer was set earlier to the server name.
hr = pfnOnline(wszServer, &bOnline);
if (FAILED(hr))
{
    printf("Failed pfnOnline, hr=%x, err=%d\n",
           hr,
           GetLastError());
    exit(1);  // Or other appropriate error action.
}

// Display the online status.
printf("Server is %s\n",
       (bOnline ? "Online" : "Suspended" ));

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certbcli.h; include Certsrv.h.
Library: Included as a resource in Certadm.dll.
Unicode: Implemented only as Unicode.

See Also

CertSrvBackupPrepare, Using the Certificate Services Backup and Restore Functions


CertSrvRestoreEnd

This function ends a Certificate Services restore session.

HRESULT CertSrvRestoreEnd(
    HCSBC hbc
);

Parameters

hbc
[in] Handle to a Certificate Services backup context.

Return Values

The return value is an HRESULT. A value of S_OK indicates success.

Remarks

When a restore session is complete, terminate the session by calling CertSrvRestoreEnd. For every successful call to CertSrvRestorePrepare, there should be a call to CertSrvRestoreEnd.

Note

When a restore is complete, it is important that you make a new full backup of the Certificate Services database. This is necessary to truncate the restored log files and to establish a base backup set for future restores. Backups performed after a restore cannot be mixed with backups (full or incremental) taken before the restore; that is, after a certificate services database is restored and has progressed to a subsequent state, you cannot use the pre-restoration backups to restore the database to that subsequent state.

Example Code

FNCERTSRVRESTOREEND*  pfnRestoreEnd;
char * szRestoreEndFunc = "CertSrvRestoreEnd";
HRESULT    hr=0;

// Get the address for the desired function.
// hInst was set by calling LoadLibrary for CertAdm.dll.
pfnRestoreEnd = (FNCERTSRVRESTOREEND*)GetProcAddress(hInst,
                                  szRestoreEndFunc);
if ( NULL == pfnRestoreEnd )
{
    printf("Failed GetProcAddress - %s, error=%d\n",
           szRestoreEndFunc,
           GetLastError() );
    exit(1); // Or other appropriate error action.
}

// When done, release the HCSBC.
// hCSBC would have been set by an earlier call
// to CertSrvRestorePrepare.
hr = pfnRestoreEnd(hCSBC);
if (FAILED(hr))
{
    printf("Failed pfnRestoreEnd call [%x]\n", hr);
    exit(1); // Or other appropriate error action.
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certbcli.h; include Certsrv.h.
Library: Included as a resource in Certadm.dll.
Unicode: Implemented only as Unicode.

See Also

CertSrvRestorePrepare, Using the Certificate Services Backup and Restore Functions


CertSrvRestoreGetDatabaseLocations

This function is used both in backup and restore scenarios and retrieves the list of Certificate Services database location names for all the files being backed up or restored.

HRESULT CertSrvRestoreGetDatabaseLocations(
  HCSBC hbc,
  WCHAR **ppwszzDatabaseLocationList,
  DWORD *pcbSize
);

Parameters

hbc
[in] Handle to a Certificate Services backup or restore context.
ppwszzDatabaseLocationList
[out] Pointer to WCHAR pointer that will receive the list of null-terminated database location names, log directory name, and system (or checkpoint) directory name. There is a null character after every name and an extra null character at the end of the list. The location name will be in the UNC form "## \\server\sharepoint\…path…\filename.ext". The directory names will have the same form but without the trailing "\filename.ext". The text "##" denotes a Certificate Services Backup file type (CSBFT_*) and is stored as a single non-null Unicode character prefixed onto each UNC path. The type tag is defined in certbcli.h and can be one of the following values for this function.
Value | Description
CSBFT_CERTSERVER_DATABASE | Certificate Services database filename including path.
CSBFT_CHECKPOINT_DIR | Certificate Services database system (or checkpoint) directory
CSBFT_LOG_DIR | Certificate Services database log directory.

You must free this allocated memory when done by calling CertSrvBackupFree.

Setting *ppwszzDatabaseLocationList to NULL before calling this function is optional.

pcbSize
[out] Pointer to the DWORD value which specifies the number of bytes in ppwszzDatabaseLocationList.

Return Values

The return value is an HRESULT. A value of S_OK indicates success.

Remarks

Use this function to retrieve a list of the Certificate Services database location names. Certificate Services must be running for this method to succeed.

This function's name in certadm.dll is CertSrvRestoreGetDatabaseLocationsW. You must use this form of the name when calling GetProcAddress. Also, this function is defined as type FNCERTSRVRESTOREGETDATABASELOCATIONSW in the certbcli.h header file.

Example Code

FNCERTSRVRESTOREGETDATABASELOCATIONSW* pfnGetDBLocs;
char *  szGetDBLocsFunc = "CertSrvRestoreGetDatabaseLocationsW";
WCHAR * pwszzDBLocs;
DWORD   nListBytes=0;
HRESULT hr=0;

// Get the address for the desired function.
// hInst was set by calling LoadLibrary for CertAdm.dll.
pfnGetDBLocs = (FNCERTSRVRESTOREGETDATABASELOCATIONSW*)GetProcAddress(hInst,
                                    szGetDBLocsFunc);
if ( NULL == pfnGetDBLocs )
{
    printf("Failed GetProcAddress - %s, error=%d\n",
           szGetDBLocsFunc,
           GetLastError() );
    exit(1); // Or other appropriate error action.
}

// Determine the names of the database locations.
// hCSBC was set by an earlier call to CertSrvRestorePrepare.
hr = pfnGetDBLocs(hCSBC, &pwszzDBLocs, &nListBytes);
if (FAILED(hr))
{
    printf("Failed pfnGetDBLocs call [%x]\n", hr);
    exit(1); // Or other appropriate error action.
}
else
{
    printf("%d bytes for DB locations\n", nListBytes);
    WCHAR * pwszFile = pwszzDBLocs;
    // Process the list.
    while ( L'\0' != *pwszFile )
    {
        // Use the file name referenced by pwszFile.
        // Here it is merely displayed.
        printf("%02x: %ws\n", *pwszFile, &pwszFile[1]);
        // Move to the next database file name.
        // + 1 moves past the null terminator.
        pwszFile+=(wcslen(pwszFile)) + 1;
    }
    // Free the allocated memory.
    // pfnBackupFree is the address of the CertSrvBackupFree function.
    pfnBackupFree(pwszzDBLocs);
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certbcli.h; include Certsrv.h.
Library: Included as a resource in Certadm.dll.
Unicode: Implemented only as Unicode.

See Also

CertSrvBackupFree, Using the Certificate Services Backup and Restore Functions


CertSrvRestorePrepare

This function is used to prepare a Certificate Services instance for restore operations.

HRESULT CertSrvRestorePrepare(
  WCHAR const *pwszServerName,
  ULONG dwRestoreFlags,
  HCSBC *phbc
);

Parameters

pwszServerName
[in] Pointer to the machine name of the server to prepare for restore operations. This name can be the NetBIOS name or the DNS name.
dwRestoreFlags
[in] Bit field representing the combination of values in the following table.
Value | Meaning
CSRESTORE_TYPE_FULL | Restore Certificate Services database, logs and related files.

phbc
[out] Pointer to a Certificate Services backup context handle (HCSBC).

Return Values

The return value is an HRESULT. A value of S_OK indicates success, and *phbc is set to an HCSBC which can be used by other Certificate Services restore APIs.

Remarks

Before a Certificate Services restore operation can occur, it is necessary to create an HCSBC by means of CertSrvBackupRestore. This HCSBC can be used by various Certificate Services restore functions.

Note When the restore session is completed, it is necessary to call CertSrvRestoreEnd to release the HCSBC which resulted from the call to CertSrvRestorePrepare.

This function's name in certadm.dll is CertSrvRestorePrepareW. You must use this form of the name when calling GetProcAddress. Also, this function is defined as type FNCERTSRVRESTOREPREPAREW in the certbcli.h header file.

To execute this call, you must have the restore privilege. For details, see Setting the Backup and Restore Privileges.

Example Code

FNCERTSRVRESTOREPREPAREW*  pfnRestorePrepare;
char * szRestorePrepFunc = "CertSrvRestorePrepareW";
HCSBC      hCSBC=NULL;
HINSTANCE  hInst=0;
HRESULT    hr=0;

// Load the DLL.
hInst = LoadLibrary(L"certadm.dll");
if ( NULL == hInst )
{
    printf("Failed LoadLibrary,error=%d\n",
           GetLastError() );
    exit(1); // Or other appropriate error action.
}

// Get the address for the desired function.
pfnRestorePrepare = (FNCERTSRVRESTOREPREPAREW*)GetProcAddress( hInst,
                                          szRestorePrepFunc );
if ( NULL == pfnRestorePrepare )
{
    printf("Failed GetProcAddress - %s, error=%d\n",
           szRestorePrepFunc,
           GetLastError() );
    exit(1); // Or other appropriate error action.
}

// Prepare CertServ for restoration.
hr = pfnRestorePrepare(wszServer,
                       CSRESTORE_TYPE_FULL,
                       &hCSBC);

if (FAILED(hr))
{
    printf("Failed pfnRestorePrepare call [%x]\n", hr);
    exit(1); // Or other appropriate error action.
}

// Use the HCSBC for restore operations.
// ...

// When done processing, release the HCSBC context
// by calling CertSrvRestoreEnd (not shown here).
// ...

// Free the DLL.
if (hInst)
    FreeLibrary(hInst);

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certbcli.h; include Certsrv.h.
Library: Included as a resource in Certadm.dll.
Unicode: Implemented only as Unicode.

See Also

CertSrvRestoreEnd, Using the Certificate Services Backup and Restore Functions


CertSrvRestoreRegister

This function registers a Certificate Services restore.

HRESULT CertSrvRestoreRegister(
  HCSBC hbc,
  WCHAR const *pwszCheckPointFilePath,
  WCHAR const *pwszLogPath,
  CSEDB_RSTMAPW rgrstmap[],
  LONG crstmap,
  WCHAR const *pwszBackupLogPath,
  ULONG genLow,
  ULONG genHigh
);

Parameters

hbc
[in] Handle to the Certificate Services restore context. You must set this handle by calling CertSrvRestorePrepare before using it in CertSrvRestoreRegister.
pwszCheckPointFilePath
[in] Pointer to value representing the restore path for the check point file.
pwszLogPath
[in] Pointer to value representing the current log file directory.
rgrstmap
[in] Restore map. If you are performing a full database restoration, this parameter specifies the name of the backup database, as well as a new name for the database once it is restored. The backup database name is referenced by rgrstmap.pwszDatabaseName, and the new database name is referenced by rgrstmap.pwszNewDatabaseName. If the intent is to maintain the same name for both the backup database and the restored database, set rgrstmap.pwszNewDatabaseName to the same value as rgrstmap.pwszDatabaseName. The value for the backup database name is constructed from the path returned by the backup client's call to CertSrvRestoreGetDatabaseLocations. CertSrvRestoreGetDatabaseLocations would have been called during a full backup, and the backup client would have saved the returned path.

If you are performing an incremental restoration, set this parameter to NULL.

crstmap
[in] Indicates whether there is a new restore map. This value represents the number of array elements in rgrstmap. Set this value to 1 if a you are performing a full restoration, or 0 if you are performing an incremental restoration.
pwszBackupLogPath
[in] Pointer to value representing the path for the backup log directory.
genLow
[in] Lowest log number that was restored in this restore session. Log files are in the form of edbXXXXX.log, where XXXXX is a 5 hexidecimal digit value. For example, edb00001.log is the first log file created by the internal database. For purposes of this function, a value of 1 in genLow corresponds to the log file edb00001.log.
genHigh
[in] Highest log number that was restored in this restore session.

Return Values

The return value is an HRESULT. A value of S_OK indicates success.

Remarks

Use this function to register a restore operation. All subsequent restore operations will be interlocked. The restore target will be prevented from starting (or successfully executing another call to CertSrvRestoreRegister) until CertSrvRestoreRegisterComplete is called.

When restoring more than one incremental backup, the order in which the incremental backups are registered doesn't matter. However, the full database backup must be registered before registering the incremental backups.

This function's name in certadm.dll is CertSrvRestoreRegisterW, which will be the necessary text when calling GetProcAddress. Also, this function is defined as type FNCERTSRVRESTOREREGISTERW in the certbcli.h header file.

Example Code

FNCERTSRVRESTOREREGISTERW* pfnRestoreRegister;
char *    szRestoreRegFunc = "CertSrvRestoreRegisterW";
// wszMyDBName is the returned path from the backup client's
// call to CertSrvRestoreGetDatabaseLocations. This value would
// have been saved during a full backup operation.
CSEDB_RSTMAP rgrstmap[1] = { wszMyDBName, // database name
                             wszMyDBName  // new name same as old
                           };
HRESULT    hr=0;

// Get the address for the desired function.
// hInst was set by calling LoadLibrary for CertAdm.dll.
pfnRestoreRegister = (FNCERTSRVRESTOREREGISTERW*)
                      GetProcAddress(hInst,
                                     szRestoreRegFunc);
if ( NULL == pfnRestoreRegister )
{
    printf("Failed GetProcAddress - %s, error=%d\n",
           szRestoreRegFunc,
           GetLastError() );
    exit(1); // Or other appropriate error action.
}

// Register a restore operation.
// hCSBC is an HCSBC created previously by CertSrvRestorePrepare
hr = pfnRestoreRegister( hCSBC,
                         NULL,
                         wszMyRestoreLogPath, // defined elsewhere
                         rgrstmap,
                         1,
                         wszMyBackupLogPath, // defined elsewhere
                         1,    // edb00001.log
                         0x1a  // edb0001a.log
                       );

if (FAILED(hr))
{
    printf("Failed pfnRestoreRegister - %x\n", hr);
    exit(1); // Or other appropriate error action.
}

// Continue processing.
// When done, call CertSrvRestoreRegisterComplete (not shown).
// ...

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certbcli.h; include Certsrv.h.
Library: Included as a resource in Certadm.dll.
Unicode: Implemented only as Unicode.

See Also

CertSrvRestoreRegisterComplete, Using the Certificate Services Backup and Restore Functions


CertSrvRestoreRegisterComplete

This function completes a registered Certificate Services restore operation.

HRESULT CertSrvRestoreRegisterComplete(
  HCSBC hbc,
  HRESULT hrRestoreState
);

Parameters

hbc
[in] Handle to a Certificate Services restore context. You must set this handle by calling CertSrvRestoreRegister before using it in CertSrvRestoreRegisterComplete.
hrRestoreState
[in] HRESULT value indicating the success code for the restore operation. Set this value to S_OK if the restore operation was successful.

Return Values

The return value is an HRESULT. A value of S_OK indicates success.

Remarks

Use this function to complete a registered restore operation. If a registered restore operation is not completed, Certificate Services will not start.

Example Code

FNCERTSRVRESTOREREGISTERCOMPLETE* pfnRestRegComplete;
char * szResRegCompleteFunc = "CertSrvRestoreRegisterComplete";
HRESULT    hr=0;

// Get the address for the desired function.
// hInst was set by calling LoadLibrary for CertAdm.dll.
pfnRestRegComplete = (FNCERTSRVRESTOREREGISTERCOMPLETE*)
                     GetProcAddress( hInst, szResRegCompleteFunc );
if ( NULL == pfnRestRegComplete )
{
    printf("Failed GetProcAddress - %s, error=%d\n",
           szResRegCompleteFunc,
           GetLastError() );
    exit(1); // Or other appropriate error action.
}

// Complete a registered restoration operation.
// hCSBC is an HCSBC variable used in a previous
// call to CertSrvRestoreRegister.
hr = pfnRestRegComplete(hCSBC, S_OK);
if (FAILED(hr))
{
    printf("Failed pfnRestRegComplete call [%x]\n", hr);
    exit(1); // Or other appropriate error action.
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certbcli.h; include Certsrv.h.
Library: Included as a resource in Certadm.dll.
Unicode: Implemented only as Unicode.

See Also

CertSrvRestoreRegister, Using the Certificate Services Backup and Restore Functions


CertSrvServerControl

This function is used to issue a service control command to programmatically stop Certificate Services.

HRESULT CertSrvServerControl(
  WCHAR const *pwszServerName,
  DWORD dwControlFlags,
  DWORD *pcbOut,
  BYTE **ppbOut
);

Parameters

pwszServerName
[in] Pointer to name or configuration string of the server to be issued the control command.
dwControlFlags
[in] Value representing the control command being issued to the Certificate Services server specified by pwszServerName. The following value is supported for dwControlFlags.
Value | Description
CSCONTROL_SHUTDOWN | Stop Certificate Services.

pcbOut
[out] For future use, this parameter will be the number of bytes allocated to ppbOut. The current implementation does not allocate memory to ppbOut. You can set this value to NULL.
ppbOut
[out] For future use, this parameter will be the pointer to pointer to bytes representing the output from the issued command. The current implementation does not allocate memory to ppbOut. You can set this value to NULL.

Return Values

The return value is an HRESULT. A value of S_OK indicates success.

Remarks

The purpose of this function is to allow a backup or restore application to programmatically stop the Certificate Services application (thereby not requiring the use of the service controller APIs). Stopping Certificate Services in this manner will also work when Certificate Services is running in console mode; the service controller APIs cannot control applications running in console mode.

This function's name in certadm.dll is CertSrvServerControlW. You must use this form of the name when calling GetProcAddress. Also, this function is defined as type FNCERTSRVSERVERCONTROLW in the certbcli.h header file.

Example Code

FNCERTSRVSERVERCONTROLW* pfnControl;
char * szControlFunc = "CertSrvServerControlW";
HRESULT    hr=0;

// Get the address for the desired function.
// hInst was set by calling LoadLibrary for CertAdm.dll.
pfnControl = (FNCERTSRVSERVERCONTROLW*)GetProcAddress(hInst,
                                           szControlFunc);
if ( NULL == pfnControl )
{
    printf("Failed GetProcAddress - %s, error=%d\n",
           szControlFunc,
           GetLastError() );
    exit(1); // Or other appropriate error action.
}

// Issue a command to stop the service.
hr = pfnControl( L"MyCertServMachine",
                 CSCONTROL_SHUTDOWN,
                 NULL,
                 NULL);

if ( FAILED( hr ) )
{
    printf("Failed pfnControl call [%x]\n", hr);
    exit(1); // Or other appropriate error action.
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Certbcli.h; include Certsrv.h.
Library: Included as a resource in Certadm.dll.
Unicode: Implemented only as Unicode.

See Also

Using the Certificate Services Backup and Restore Functions


Name Properties

Name properties are properties of certificates and certificate requests that represent data about the subject, that is, the owner of the certificate or the individual for whom a certificate is requested. Each name property is identified by a property name. These names are not localizable; however, name properties typically correspond to a Certificate Services database column, and you can use the Certification Authority MMC snap-in, the command line tool 'certutil -schema', or the IEnumCERTVIEWCOLUMN::GetDisplayName method to display localized versions of the database column names.

The property name (but not the aliases) may have "Subject." as an optional prefix. For example, to refer to the subject's common name, you can use either "CommonName" or "Subject.CommonName".

In addition to its name, each property has some number of aliases that Certificate Services recognizes as alternate names for the property. Note that object identifiers (OIDs) are acceptable aliases, as are the szOID_* constants. These constants are definitions (in wincrypt.h) that represent the OIDs; for example, szOID_COMMON_NAME is defined as "2.5.4.3". Consequently, you can use the szOID_* constants as aliases in place of the OIDs they represent.

Property Name | Aliases | Data Type | Description
"Subject.CommonName" | "CommonName" "CN" "2.5.4.3" szOID_COMMON_NAME | String (max. 64 chars) | For user certificates, the person's full name (for example, John H. Doe). For machine certificates, fully qualified hostname/path used in DNS (Domain Name System) lookups (for example, example.microsoft.com).
"Subject.Country" | "Country" "C" "2.5.4.6" szOID_COUNTRY_NAME | String (max 2 chars) | The subject's country or region. This is an X.500 two-character country/region code (for example US for United States or CA for Canada). Many of these two-character codes are defined in the ISO 3166 standard. Additionally, the current locale's code is available through a call to the Win32 function GetLocaleInfo (by specifying an LCType of LOCALE_SISO3166CTRYNAME).
"Subject.DeviceSerialNumber" | "DeviceSerialNumber" "2.5.4.5" szOID_DEVICE_SERIAL_NUMBER | String (max 1024 chars) | Device serial number.
"Subject.DomainComponent" | "DomainComponent" "DC" "0.9.2342.19200300.100.1.25" szOID_DOMAIN_COMPONENT | String (max 128 chars) | Component of a Domain Name System (DNS) name.
"Subject.EMail" | "EMail" "E" "1.2.840.113549.1.9.1" szOID_RSA_emailAddr | String (max 128 chars) | E-mail address (for example, "someone@microsoft.com").
"Subject.GivenName" | "GivenName" "G" "2.5.4.42" szOID_GIVEN_NAME | String (max 16 chars) | First name of the subject.
"Subject.Initials" | "Initials" "I" "2.5.4.43" szOID_INITIALS | String (max 5 chars) | Initials of the subject (optional).
"Subject.Locality" | "Locality" "L" "2.5.4.7" szOID_LOCALITY_NAME | String (max 128 chars) | Name of the subject's city.
"Subject.Organization" | "Organization" "Org" "O" "2.5.4.10" szOID_ORGANIZATION_NAME | String (max 64 chars) | Legal name of the subject's organization.
"Subject.OrgUnit" | "OrgUnit" "OrganizationUnit" "OrganizationalUnit" "OU" "2.5.4.11" szOID_ORGANIZATIONAL_UNIT_NAME | String (max 64 chars) | Name of the subject's sub-organization or department.
"Subject.State" | "State" "ST" "S" "2.5.4.8" szOID_STATE_OR_PROVINCE_NAME | String (max 128 chars) | Full name of the subject's state or province (for example, California).
"Subject.StreetAddress" | "StreetAddress" "Street" "2.5.4.9" szOID_STREET_ADDRESS | String (max 30 chars) | Subject's street address or PO Box.
"Subject.SurName" | "SurName" "SN" "2.5.4.4" szOID_SUR_NAME | String (max 40 chars) | Last name of the subject.
"Subject.Title" | "Title" "T" "2.5.4.12" szOID_TITLE | String (max 64 chars) | Title of individual who requested the certificate (optional).
"Subject.UnstructuredAddress" | "UnstructuredAddress" "1.2.840.113549.1.9.8" szOID_RSA_unstructAddr | String (max 1024 chars) | Unstructured address.
"Subject.UnstructuredName" | "UnstructuredName" "1.2.840.113549.1.9.2" szOID_RSA_unstructName | String (max 1024 chars) | Unstructured name.

The following properties are related to the subject, although they are not name properties. The policy module cannot set these properties directly.

Property | Data Type | Description
"Request.DistinguishedName" | String (max 8192 chars) | The relative distinguished name for the request, a textual representation of the subject in the request. This representation consists of name properties, for example, "CN=MyName, OU=MyOrgUnit, C=US". The Certificate Services application sets this property before calling the policy module, by calling CertNameToStr using the RawRequest's Subject.
"Request.RawName" | Binary (max 4096 bytes) | ASN.1 binary subject BLOB extracted from the request. The Certificate Services application sets this property before calling the policy module; its value is determined by the RawRequest's Subject.
"DistinguishedName" | String (max 8192 chars) | The relative distinguished name for the certificate, a textual representation of the subject in the certificate. This representation consists of name properties; for example, "CN=MyName, OU=MyOrgUnit, C=US". The Certificate Services application sets this property after calling the policy module, by calling CertNameToStr using the RawName.
"RawName" | Binary (max 4096 bytes) | ASN.1 binary subject BLOB used to construct the certificate. The Certificate Services application sets this property after calling the policy module; its value is determined by the values of specific name properties (Subject.CommonName, etc.) as directed by the SubjectTemplate.

Which relative distinguished name components appear in the DistinguishedName property and the order in which they appear are controlled by the "SubjectTemplate" registry value contained in the HKLM\System\CurrentControlSet\Services\CertSvc\Configuration\<CA Name> registry key.

When Certificate Services parses attribute names, it ignores spaces, hyphens (minus signs), and case. For example, "AttributeName1", "Attribute Name1", and "Attribute-name1" are all equivalent. For attribute values, Certificate Services ignores leading and trailing white space.

Note for Microsoft Windows NT 4.0 (Certificate Services 1.0) All of the preceding properties except DistinguishedName, RawName, and Country support multi-valued syntax using an ANSI punctuation character as the separator. By default, this character must be a comma; however, you can specify a different separator character by changing the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\<CA Name>\SubjectNameSeparator (REG_SZ) entry in the system registry. This entry is set to a single-character string and contains a comma by default. The first character of this string must be an ANSI punctuation character to enable the multi-valued syntax. If some other character appears first or if the registry entry is empty or missing, multi-valued syntax is disabled.

Note for Microsoft Windows 2000 (Certificate Services 2.0) or later All of the preceding properties except DistinguishedName, RawName, and Country support multi-valued syntax using a newline character; the newline separator cannot be disabled or changed.

See Also

ICertServerExit::GetCertificateProperty, ICertServerExit::GetRequestProperty, ICertServerPolicy::GetCertificateProperty, ICertServerPolicy::GetRequestProperty, ICertServerPolicy::SetCertificateProperty, Certificate Properties


Certificate Properties

Certificate Services supports the use of certificates as defined in the ITU-T recommendation X.509 (also, ISO/IEC 9594-8). The following are properties that are contained in a standard X.509 certificate.

Field | Description
Version | Version number of the certificate format.
Serial Number | Serial number of the certificate. This number is assigned by the issuer and is unique within the issuer's list of issued certificates.
Algorithm Identifier and Parameters | Signature algorithm and any parameters used by the issuer.
Issuer | Name of the certification authority which issued the certificate.
Not Before (Date) | Certificate not valid before this date.
Not After (Date) | Certificate not valid after this date.
Subject Name | Name of the person or entity to whom the certificate is being issued. This field can also include the certificate recipient's organization, organization unit, locality, state or province, and country/region.
Subject Public Key Algorithm and Parameters | The algorithm and any parameters used for the subject's public key.
Subject Public Key | The actual public key (a bit string).
Signature | Signature as provided by the issuer.

A certificate can contain the following items, depending on the X.509 version of the certificate.

Optional field | Description
Issuer Unique ID | Used to make the issuer name unambigous if it has been used by more than one entity. Present only in versions X.509 2.0 or above.
Subject unique ID | Used to make the subject name unambigous if it has been used by more than one entity. Present only in X.509 2.0 or above.
Extensions | For specifying any desired custom properties. Any number of extension fields can be included in the certificate. Present only in version X.509 3.0.

Note Microsoft Certificate Services issues X.509 version 3 certificates.

See Also

Name Properties


Common HRESULT Values

The following table lists the values of common HRESULT values. More values are contained in the header file winerror.h.

Name | Description | Value
S_OK | Operation successful | 0x00000000
E_UNEXPECTED | Unexpected failure | 0x8000FFFF
E_NOTIMPL | Not implemented | 0x80004001
E_OUTOFMEMORY | Failed to allocate necessary memory | 0x8007000E
E_INVALIDARG | One or more arguments are invalid | 0x80070057
E_NOINTERFACE | No such interface supported | 0x80004002
E_POINTER | Invalid pointer | 0x80004003
E_HANDLE | Invalid handle | 0x80070006
E_ABORT | Operation aborted | 0x80004004
E_FAIL | Unspecified failure | 0x80004005
E_ACCESSDENIED | General access denied error | 0x80070005


Certificate Enrollment Control

Purpose

The Certificate Enrollment Control (CEC) is provided for corporate developers and independent software vendors (ISVs) who want to write custom modules and applications that must request that a certificate be issued to the named user (subject).

About Certificate Enrollment Control

General information about Certificate Enrollment Control.

Using Certificate Enrollment Control

Creating instances of the Certificate Enrollment Control object and using its methods and properties.

Certificate Enrollment Control Reference

Documentation of Certificate Enrollment Control interfaces, methods, and properties.

Feedback

Make error reports and feature requests directly to Microsoft.


About Certificate Enrollment Control

The Certificate Enrollment Control is designed to make it easier to develop an application that must request that a certificate be issued to a named subject. It is designed to accept data in the form of a binary string (BSTR), from a Web page or from either a Microsoft® Visual Basic® or C++ user interface. The output from the Certificate Enrollment Control is a PKCS #10 certificate request that can be sent on to a certification authority (CA), as shown in the following illustration.

Necessary information about the user (certificate subject) is collected by the User Interface, and is provided as a BSTR input to the Certificate Enrollment Control. The Certificate Enrollment Control generates the appropriate (signature or key exchange or both) key pair and then generates and signs a PKCS #10 certificate request, using the generated private key. The Certificate Enrollment Control then links the key pair to a dummy (temporary) certificate, which is stored in the request store until the issued certificate is returned from a certification authority. Next, the application sends the PKCS #10 to a CA.

If the CA approves the certificate request, the CA creates a certificate, that contains the public key. The CA also signs the certificate.

When the requested certificate is returned from the CA, the application passes the PKCS #7 message back to the Certificate Enrollment Control, where the certificate (or chain of certificates) is pulled from the PKCS #7 message. The certificate is stored in a certificate store, as are any other certificates in the chain of trust. The returned certificate is not modified in any way. Any certificate-aware application can now access this certificate from the store.


Using Certificate Enrollment Control

The Certificate Enrollment Control is a single object with many properties and several methods that can be used to determine how the Certificate Enrollment Control processes the user information, the type of certificate to be requested, how the keys are to be generated, where the certificate is to be stored, and related processes. There are two primary uses of the Certificate Enrollment Control: to create a certificate request (PKCS #10), and to receive the returned certificate and store it in a certificate store. For details and syntax for creating an instance of the Certificate Enrollment Control object, setting its properties, and using its methods, see the following topics.

Information | Topic
Creating an instance of the Certificate Enrollment Control object in different programming languages | Creating an Instance of the Certificate Enrollment Control Object
Using Certificate Enrollment Control properties in different programming languages | Using the Certificate Enrollment Control Properties
Collecting the necessary information and submitting a certificate request in different programming languages. | Creating the Certificate Request
Extracting and storing the completed certificate | Receiving the Returned Certificate
Retrieving information from return values in different languages | Method Return Values
Checking for errors | Error Checking


Creating an Instance of the Certificate Enrollment Control Object

The following sections provide information on creating an instance of the Certificate Enrollment Control in C++, Microsoft® Visual Basic®, or Visual Basic Scripting Edition (VBScript).

  • The Certificate Enrollment Control Instantiated in C++
  • The Certificate Enrollment Control Instantiated in Visual Basic
  • The Certificate Enrollment Control Instantiated in VBScript


The Certificate Enrollment Control Instantiated in C++

The Certificate Enrollment Control is provided to C and C++ developers by the header file xenroll.h and the link library uuid.lib.

The following example uses CoCreateInstance to create an instance of the Certificate Enrollment Control object. When the object is no longer needed, it is freed from memory by a call to the Release method.

Example in C++

#include <xenroll.h>

HRESULT __cdecl main()
{
    // pointer to interface object
    ICEnroll * pEnroll = NULL;

    // variable for return value
    HRESULT    hr;

    // Initialize COM.
    hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );

    // Check status.
    if ( FAILED( hr ) )
    {
        printf("Failed CoInitializeEx - [%x]\n", hr);
        goto error;
    }

    // Create an instance of the object.
    hr = CoCreateInstance( CLSID_CEnroll,
                           NULL,
                           CLSCTX_INPROC_SERVER,
                           IID_ICEnroll,
                           (void **)&pEnroll);

    // Check status.
    if ( FAILED( hr ) )
    {
        printf("Failed CoCreateInstance - pEnroll [%x]\n", hr);
        goto error;
    }
    else
    {
        // Successfully instantiated object.
        printf("Obtained pointer to Enrollment interface\n");
        // Use object as needed.
        // ...
    }

error:

    // Done processing.
    // Clean up resources.
    if ( NULL != pEnroll )
        pEnroll->Release();

    // Free COM resources.
    CoUninitialize();

    return hr;
}

Beginning with Microsoft® Windows® 2000, a second interface, ICEnroll2, is supported. The ICEnroll2 interface is derived from ICEnroll, so all methods and properties supported by ICEnroll are supported by ICEnroll2. Additionally, several new methods and properties are supported by ICEnroll2. To use the ICEnroll2 interface, declare a pointer of type ICEnroll2, and use the IID of IID_ICEnroll2 in the call to CoCreateInstance. For example:

ICEnroll2 * pEnroll2 = NULL;

hr = CoCreateInstance( CLSID_CEnroll,
                       NULL,
                       CLSCTX_INPROC_SERVER,
                       IID_ICEnroll2,
                       (void **)&pEnroll2);
// Check hr for success (not shown here).
// Use object as needed.
// …
// Done processing, free resources associated with this object.
if ( NULL != pEnroll2 )
    pEnroll2->Release();

Beginning with Microsoft® Windows® 2000, a third interface, ICEnroll3, is supported. The ICEnroll3 interface is derived from ICEnroll2, so all methods and properties supported by ICEnroll2 (and therefore ICEnroll) are supported by ICEnroll3. Additionally, several new methods and properties are supported by ICEnroll3. To use the ICEnroll3 interface, declare a pointer of type ICEnroll3, and use the IID of IID_ICEnroll3 in the call to CoCreateInstance. For example:

ICEnroll3 * pEnroll3 = NULL;

hr = CoCreateInstance( CLSID_CEnroll,
                       NULL,
                       CLSCTX_INPROC_SERVER,
                       IID_ICEnroll3,
                       (void **)&pEnroll3);
// Check hr for success (not shown here).
// Use object as needed.
// …
// Done processing; free resources associated with this object.
if ( NULL != pEnroll3 )
    pEnroll3->Release();


The Certificate Enrollment Control Instantiated in Visual Basic

The Certificate Enrollment Control object does not support early binding in Visual Basic; instead, users of the Certificate Enrollment Control object in Visual Basic must use late binding (through the CreateObject command). The following example uses CreateObject to create an instance of the Certificate Enrollment Control object. When the object is no longer needed, it is freed from memory by setting it to the Visual Basic value Nothing.

Example in Visual Basic

Private Sub Command1_Click()
    ' Declare the object variable.
    Dim objXen As Object

    ' Before creating object, enable error handler.
    On Error GoTo Err_Object

    ' Create an instance of the object.
    Set objXen = CreateObject("CEnroll.CEnroll.1")

    ' Disable error handler.
    On Error GoTo 0

    ' Object successfully instantiated.
    ' use object as needed
    ' ...

    ' Done processing, free resource.
    Set objXen = Nothing

    Exit Sub

Err_Object:

    MsgBox ("Unable to create CEnroll object")

End Sub


The Certificate Enrollment Control Instantiated in VBScript

The following Visual Basic Script example uses the OBJECT tag to create an instance of the Certificate Enrollment Control object. The object is freed from memory when it goes out of scope.

Example in VBScript

<HTML>
<HEAD>
<TITLE>VBScript Certificate Enrollment Control Sample
</TITLE>
<OBJECT classid="clsid:43F8F289-7A20-11D0-8F06-00C04FC295E1"
    codebase="xenroll.dll"
    id=Enroll >
</OBJECT>
<BR>
Certificate Enrollment Control Instantiation Sample
<BR>
<BR>

<SCRIPT language="VBScript">
<!--
' Declare a local variable.
Dim varName
' Enable error handling.
On Error Resume Next
' Attempt to use the control, in this case to retrieve a property.
varName = Enroll.MyStoreName
' If above line failed, Err.Number will not be 0.
if ( Err.Number <> 0 ) then
    MsgBox("Error!")
    Err.clear
else
    ' The control property was successfully retrieved,
    ' display the property value.
    varName = "MyStoreName is " & varName
    MsgBox( varName )
end if
-->
</SCRIPT>
<BR>
</HEAD>
</HTML>


Using the Certificate Enrollment Control Properties

Each Certificate Enrollment Control property is read/write and has an initialized default as well as a set of acceptable values. You can set a property to any value within this set in order to modify the behavior of methods that use the property. To get a desired behavior, set the property before you call the method that uses that property's value.

Note, however, that after calling the following methods

  • acceptPKCS7
  • acceptFilePKCS7
  • createPKCS10
  • createFilePKCS10
  • the following properties are blocked from being reset
  • ProviderType
  • KeySpec
  • ProviderFlags
  • ContainerName
  • ProviderName

unless the ICEnroll3::Reset method is called.

For information about individual properties and methods, see the reference topics for those properties and methods in the Certificate Enrollment Control Reference.

The following sections contain language-specific information for setting and retrieving the Certificate Enrollment Control properties:

  • Certificate Enrollment Control Properties in Visual Basic
  • Certificate Enrollment Control Properties in C++


Certificate Enrollment Control Properties in C++

When you set or retrieve a Certificate Enrollment Control property in C++, the method call returns an HRESULT. In this HRESULT, a value of S_OK indicates that the method was successfully executed.

Programs written in C++ can retrieve the Certificate Enrollment Control properties by method calls in the following form:

HRESULT get_propertyName( datatype * pPropValue);

where propertyName specifies the name of the property being accessed, and pPropValue is a pointer to a variable of the appropriate data type. Upon successful completion of this method call, pPropValue will point to the variable containing the value of the propertyName property.

For example, to retrieve the property value for the RootStoreType, you use the following code:

// Get the store type.
// hr is an HRESULT.
// bstrStoreType is a BSTR variable.
hr = pEnroll->get_RootStoreType( &bstrStoreType );

Programs written in C++ can set the Certificate Enrollment Control properties by calling methods in the form of

HRESULT put_propertyName( datatype PropValue);

where propertyName specifies the name of the property being accessed, and PropValue is a value of the appropriate data type. Upon successful completion of this method call, the new value of the propertyName property will be PropValue.

For example, to set the property value for the RootStoreType, the following code could be used:

// Set the storetype.
// bstrNewType previously set to a valid store type
hr = pEnroll->put_RootStoreType( bstrNewType );


Certificate Enrollment Control Properties in Visual Basic

Programs written in Visual Basic can directly access the Certificate Enrollment Control property values by using the property name. For example, to retrieve the property value for the RootStoreType, you can use the following code:

' Retrieve the RootStoreType.
strStoreType = objXen.RootStoreType

To set the property value for the RootStoreType, the following code can be used:

' Set the RootStoreType.
' (strNewType previously set to a valid store type.)
objXen.RootStoreType = strNewType


Creating the Certificate Request

The process of creating a certificate request involves collecting certain information from the requester. Usually, this is done through some sort of user interface (UI), although the information could be taken directly from a database without the need for a UI. The level of information required is set by the policy of the certification authority (CA). An example of the required information might be as follows:

Common Name
Unit Name
Company Name
City
State
Country/Region

Note The interface is designed to make a single request for each xenroll instance. A separate xenroll instance must be created to create each certificate request.

The following sections illustrate how to use the Certificate Enrollment Control to request a certificate in specific programming languages.

Request Sample in C++

Request Sample in Visual Basic

Request Sample in VBScript


Request Sample in C++

The following C++ sample program shows how the Certificate Enrollment Control can be used with the ICertRequest object to create and submit a certificate request.

// Example code for Certificate Enrollment Control
// used with ICertRequest in C++
//

#include <stdio.h>
#include <certsrv.h> // for ICertRequest object
#include <xenroll.h>

HRESULT __cdecl main()
{

    // pointer to interface objects
    ICEnroll2 * pEnroll = NULL;
    ICertRequest * pRequest = NULL;

    // BSTR variables
    BSTR    bstrDN = NULL;
    BSTR    bstrOID = NULL;
    BSTR    bstrCertAuth = NULL;
    BSTR    bstrReq = NULL;
    BSTR    bstrAttrib = NULL;

    // Request disposition variable
    long    nDisp;

    // variable for return value
    HRESULT    hr;

    // initialize COM
    hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );

    // check status
    if ( FAILED( hr ) )
    {
        printf("Failed CoInitializeEx - [%x]\n", hr);
        goto error;
    }

    // Create an instance of the Certificate Enrollment object.
    hr = CoCreateInstance( CLSID_CEnroll,
                           NULL,
                           CLSCTX_INPROC_SERVER,
                           IID_ICEnroll2,
                           (void **)&pEnroll);
    // check status
    if ( FAILED( hr ) )
    {
        printf("Failed CoCreateInstance - pEnroll [%x]\n", hr);
        goto error;
    }

    // Create an instance of the Certificate Request object.
    hr = CoCreateInstance( CLSID_CCertRequest,
                           NULL,
                           CLSCTX_INPROC_SERVER,
                           IID_ICertRequest,
                           (void **)&pRequest);
    // check status
    if ( FAILED( hr ) )
    {
        printf("Failed CoCreateInstance - pRequest [%x]\n", hr);
        goto error;
    }

    // Create the data for the request.
    // A user interface or database retrieval could
    // be used instead of this sample's hardcoded text.
    bstrDN = SysAllocString(L"CN=UserName"    // Common Name
                            L",OU=UserUnit"   // Org Unit
                            L",O=UserOrg"     // Org
                            L",L=UserCity"    // Locality
                            L",S=WA"          // State
                            L",C=US");        // Country/Region

    // Allocate the BSTR representing the certification authority.
    // Note the use of '\\' to produce a single '\' in C++.
    bstrCertAuth = SysAllocString(L"Server\\CertAuth");

    // Allocate the BSTR for the certificate usage.
    bstrOID = SysAllocString(L"1.3.6.1.4.1.311.2.1.21");

    // Allocate the BSTR for the attributes.
    // In this case, no attribute is specified.
    bstrAttrib = SysAllocString(L"");

    // Create the PKCS #10.
    hr = pEnroll->createPKCS10( bstrDN, bstrOID, &bstrReq );
    // check status
    if ( FAILED( hr ) )
    {
        printf("Failed createPKCS10 - [%x]\n", hr);
        goto error;
    }

    // Submit the certificate request.
    hr = pRequest->Submit( CR_IN_BASE64 | CR_IN_PKCS10,
                           bstrReq,
                           bstrAttrib,
                           bstrCertAuth,
                           &nDisp );
    // check status
    if ( FAILED( hr ) )
    {
        printf("Failed Request Submit - [%x]\n", hr);
        goto error;
    }
    else
        printf("Request submitted; disposition = %d\n", nDisp );

error:

    // done processing
    // clean up object resources
    if ( NULL != pEnroll )
        pEnroll->Release();
    if ( NULL != pRequest )
        pRequest->Release();

    // free BSTR variables
    if ( NULL != bstrDN )
        SysFreeString ( bstrDN );
    if ( NULL != bstrOID )
        SysFreeString ( bstrOID );
    if ( NULL != bstrCertAuth )
        SysFreeString ( bstrCertAuth );
    if ( NULL != bstrReq )
        SysFreeString ( bstrReq );
    if ( NULL != bstrAttrib )
        SysFreeString ( bstrAttrib );

    // free COM resources
    CoUninitialize();

    return hr;
}


Request Sample in Visual Basic

The following Visual Basic sample code shows how the Certificate Enrollment Control can be used with the CCertRequest object to create and submit a certificate request. The CCertRequest object is available in the Certcli Type Library.

Private Sub Command1_Click()

    ' Declare objects for Enrollment and Request controls.
    Dim objXen As Object
    Dim objRequest As CCertRequest ' from CertCli Type library

    ' string variables
    Dim strDN As String
    Dim strReq As String

    ' variable to retrieve request's Submit disposition
    Dim nDisp As Long

    ' consts used by CCertRequest
    Const CR_IN_BASE64 As Long = &H1
    Const CR_IN_PKCS10 As Long = &H100

    On Error GoTo Err_Handler

    ' Create an instance of the Certificate Enrollment object.
    Set objXen = CreateObject("CEnroll.CEnroll.1")

    ' Create an instance of the Certificate Request object.
    Set objRequest = New CCertRequest

    'Build the distinguished name string.
    strDN = "CN=UserName" _
             & ",OU=UserUnit" _
             & ",O=UserOrg" _
             & ",L=UserCity" _
             & ",S=WA" _
             & ",C=US"

    ' Create the PKCS #10 request.
    strReq = objXen.createPKCS10(strDN, "1.3.6.1.4.1.311.2.1.21")

    ' Submit the request.
    MsgBox ("Attempting request submit")
    nDisp = objRequest.Submit(CR_IN_BASE64 Or CR_IN_PKCS10, _
                               strReq, _
                               "", _
                               "Server\CertAuth")

    ' Free the objects.
    Set objXen = Nothing
    Set objRequest = Nothing

    Exit Sub

Err_Handler:

    ' Inform user there was an error.
    MsgBox ("Failed")
    ' Disable error handling.
    On Error GoTo 0

End Sub


Request Sample in VBScript

The following VBScript sample code shows how the Certificate Enrollment Control can be used with the CCertRequest object to create and submit a certificate request.

<HTML>
<HEAD>
<TITLE>VBScript Certificate Enrollment Control Sample
</TITLE>
<OBJECT classid="clsid:43F8F289-7A20-11D0-8F06-00C04FC295E1"
    codebase="xenroll.dll"
    id=Enroll >
</OBJECT>
<OBJECT classid="clsid:98AFF3F0-5524-11D0-8812-00A0C903B83C"
    codebase="certcli.dll"
    id=Request >
</OBJECT>
<BR>
Certificate Enrollment Control Request Sample
<BR>
<BR>

<SCRIPT language="VBScript">
<!--
' Declare the distinguished name variable.
Dim strDN

' Declare the request variable.
Dim strReq

' Declare a local variable for request disposition.
Dim nDisp

' Enable error handling.
On Error Resume Next

' Declare consts used by CertRequest object.
const CR_IN_BASE64 = &H1
const CR_IN_PKCS10 = &H100

' Build the DN.
strDN =  "CN=UserName" _
      & ",OU=UserUnit" _
      & ",O=UserOrg" _
      & ",L=UserCity" _
      & ",S=WA" _
      & ",C=US"

' Attempt to use the control, in this case, to create a PKCS #10.
MsgBox("Creating PKCS #10 " & strDN)
strReq = Enroll.createPKCS10( strDN, "1.3.6.1.4.1.311.2.1.21")
' If above line failed, Err.Number will not be 0.
if ( Err.Number <> 0 ) then
    MsgBox("Error in call to createPKCS10 " & Err.Number)
    err.clear
else
    MsgBox("Submitting request " & strReq)
    nDisp = Request.Submit( CR_IN_BASE64 OR CR_IN_PKCS10, _
                            strReq, _
                            "", _
                            "Machine\CertAuth")
    ' If the preceding line failed, Err.Number will not be 0.
    if ( Err.Number <> 0 ) then
        MsgBox("Error in Request Submit " & Err.Number)
        err.clear
    else
        MsgBox("Submitted certificate; disposition = " & nDisp)
    end if

end if
-->
</SCRIPT>
<BR>
</HEAD>
</HTML>


Receiving the Returned Certificate

When the certification authority (CA) has verified the information and is satisfied that the requester is the owner of the private key and that the data about that requester is accurate, the CA constructs an X.509 certificate, signs it, packages it with any other needed certificates (such as the CA's own certificate) in a PKCS # 7 message, and sends the message to the requester.

The receiving application passes the PKCS # 7 message to the Certificate Enrollment Control. The Certificate Enrollment Control then opens the message and extracts the certificates, putting any self-signed certificates in the "Root" store. The rest (except for the requester's certificate) is placed in the "CA" store. The Certificate Enrollment Control then places the requester's certificate in the certificate store specified by the requester in the MyStoreName property.

The following code is a simple example of how to use Visual Basic Script and HTML in a Web page to receive and store the returned certificates.

<HTML>
<TITLE>Certificate Enrollment Acceptance HTML Page</TITLE>
<BODY>

<OBJECT
    classid="clsid:43F8F289-7A20-11D0-8F06-00C04FC295E1"
    CODEBASE="xenroll.dll"
    id=IControl
    >
</OBJECT>

<FORM NAME="result" ENCTYPE=x-www-form-encoded METHOD=POST>
    <INPUT TYPE="HIDDEN" NAME="result">
    <TD ALIGN=center><INPUT TYPE="BUTTON" _
        NAME="Accept" value="Accept" onClick="AcceptCertSub"
        language="VBScript">
    <TD ALIGN=center><INPUT TYPE="BUTTON"
        NAME="No" value="No" onClick="NoAcceptCertSub"
        language="VBScript">

<SCRIPT LANGUAGE="VBSCRIPT">

    '-----------------------------------------------------------------
    'Accept the certificate subroutine.
    '-----------------------------------------------------------------
    Sub AcceptCertSub

    On Error Resume Next

    '--------------------------------------------------------------
    ' Get the issued certificate.
    ' The following value, "PKCS7", represents the received message.
    ' Actually, this value must be supplied through the design of
    ' the receiving application.
    ' A possible implementation is as follows: after using
    ' ICertRequest.Submit to submit the PKCS #10, call
    ' ICertRequest.GetLastStatus to confirm successful certificate
    ' creation, and then call ICertRequest.GetCertificate to retrieve
    ' the certificate.
    ' -------------------------------------------------------------
    document.result.result.value = "PKCS7"

    Call IControl.AcceptPKCS7(document.result.result.value)

    If err.Number = 0 Then
        navigate "..\done.htm"
    Else
        Alert "Error: " & Hex(err)
    End If

    End sub

    '-----------------------------------------------------------------
    ' Decline the certificate sub-routine.
    '-----------------------------------------------------------------
    Sub NoAcceptCertSub
    navigate "..\notdone.htm"
    End sub

</SCRIPT>
</BODY>
</HTML>


Method Return Values

For each interface method there are two prototypes shown, each of which has the [Visual Basic] or [C++] notation beside it. The method prototypes return different values depending on which language is used.

Return Values For Microsoft C++

The return value is always of type HRESULT; this value can be checked to determine success or failure. The use of "output" parameters allows values to be assigned to variables during the method or property call. The following example shows a C++ method call to enumerate providers:

UINT          ucEnumProvIndex = 0;
BSTR          bstrProvider = NULL;
HRESULT       hr;

// pEnroll is previously instantiated CEnroll interface pointer
hr       = pEnroll->enumProviders(ucEnumProvIndex, 0, &bstrProvider);

In the preceding code fragment, success or failure is returned to the "hr" variable. If the call was successful, hr will be set to S_OK and the variable bstrProvider will contain the name of the enumerated provider.

A C++ call to retrieve a property value would be as follows:

BSTR     bstrStoreName = NULL;
HRESULT  hr;

// pEnroll is previously instantiated CEnroll interface pointer

// get the storename
hr = pEnroll->get_CAStoreName( &bstrStoreName );

// (When done using bstrStoreName, free it by calling SysFreeString).

A C++ call to set a property value would be as follows:

// bstrNewName previously set to a valid store name
hr = pEnroll->put_CAStoreName( bstrNewName );

Return Values For Microsoft Visual Basic

The return value is of the type specified by the particular method or property. A call to retrieve a property value would be as follows:

' objXen is previously instantiated Certificate Enrollment object.

Dim strCAStoreName As String

' Retrieve the CAStoreName.
strCAStoreName = objXen.CAStoreName

A call to a method would be as follows:

' objXen is previously instantiated Certificate Enrollment object.
' strDN and strUsage are previously defined String variables.

Dim strPKCS10 As String

' Create the PKCS #10 request.
strPKCS10 = objXen.createPKCS10( strDN, strUsage )

An alternative to assigning method and property return values to a specific type is to assign them to Variant variables. For example:

Dim myPKCS10 As Variant

' Create the PKCS10 request.
myPKCS10 = objXen.createPKCS10( strDN, strUsage )


Error Checking

In the case of Microsoft® Visual Basic®, if an error occurs within the method, the method will throw an exception. The script or program must check for these exceptions separately from the return value.

For C++, the return value is always an HRESULT, and indicates whether the method call succeeded or failed. If the call failed then the return value indicates why it failed.


Certificate Enrollment Control Reference

This reference guide describes the methods and properties of the Certificate Enrollment Control object. The CEnroll Object provides the following interfaces:

  • ICEnroll
  • ICEnroll2
  • ICEnroll3
  • ICEnroll4 (New in Whistler)


CEnroll Object

Xenroll.dll contains the Certificate Enrollment Control (CEnroll) object.

[C++]

The Whistler release of the CEnroll object exposes the following interfaces.

Interface | Description
ICEnroll | Supplies the sole interface for Certificate Enrollment Control objects distributed with operating system releases earlier than Microsoft® Windows® 2000 Beta 2.
ICEnroll2 | Introduced in Windows 2000 Beta 2, this interface inherits the methods and properties of ICEnroll and defines additional methods and properties.
ICEnroll3 | Introduced in Windows 2000 Beta 3, this interface inherits the methods and properties of ICEnroll and ICEnroll2 and defines additional methods and properties.
ICEnroll4 | Introduced in the Whistler release of Windows 2000, this interface inherits the methods and properties of ICEnroll, ICEnroll2, and ICEnroll3 and defines additional methods and properties.

[Visual Basic]

The Whistler release of the CEnroll object has the following methods.

Method | Description
acceptFilePKCS7 | Accepts and processes a PKCS #7 message containing a certificate. The PKCS #7 message is stored in a file.
acceptFileResponse | Accepts and stores a response read from a file. New in Whistler.
acceptPKCS7 | Accepts and processes a PKCS #7 message containing a certificate. The PKCS #7 message is input as a parameter.
acceptResponse | Accepts and stores a response. New in Whistler.
addAttributeToRequest | Adds an attribute to the certificate request. New in Whistler.
addCertTypeToRequest | Adds a certificate template to a request. Valid with an enterprise certification authority (CA) only.
addExtensionToRequest | Adds an extension to the certificate request. New in Whistler.
addNameValuePairToRequest | Adds a name/value pair to the certificate request as an unauthenticated attribute. New in Whistler.
addNameValuePairToSignature | Adds a name/value pair of an attribute to the certificate request.
binaryToString | Converts a binary data BLOB to a string. New in Whistler.
createFilePFX | Saves the accepted certificate chain and private key in a file in Personal Information Exchange (PFX) format. New in Whistler.
createFilePKCS10 | Creates a PKCS #10 certificate request and saves it to a file.
createFileRequest | Builds a certificate request and stores it in a file in PFX format. New in Whistler.
createPFX | Saves the accepted certificate chain and private key in PFX format. New in Whistler.
createPKCS10 | Creates a PKCS #10 certificate request.
createRequest | Builds a certificate request. New in Whistler.
EnumAlgs | Enumerates IDs of algorithms supported by the cryptographic service provider (CSP).
enumContainers | Enumerates the containers for the provider specified in the ProviderName property.
enumPendingRequest | Enumerates the properties of pending certificate requests. New in Whistler.
enumProviders | Enumerates the providers available on the computer for the specified ProviderType property.
freeRequestInfo | Cleans up the stores if an error occurs. Currently not implemented.
GetAlgName | Retrieves the name corresponding to an algorithm ID.
getCertFromFileResponse | Retrieves a certificate from a response stored in a file. New in Whistler.
getCertFromPKCS7 | Retrieves (from a PKCS #7 message) the certificate issued in response to a PKCS #10 certificate request.
getCertFromResponse | Retrieves a certificate from a response. New in Whistler.
GetKeyLen | Retrieves minimum and maximum key lengths.
GetKeyLenEx | Retrieves key information. New in Whistler.
GetSupportedKeySpec | Retrieves information regarding the CSP's support for signature or exchange keys.
InstallPKCS7 | Accepts and processes a PKCS #7 message containing a certificate or chain of certificates.
removePendingRequest | Removes a pending certificate request. New in Whistler.
Reset | Places the object into its initial state.
resetAttributes | Removes all attributes for the certificate request. New in Whistler.
resetExtensions | Removes all extensions for the certificate request. New in Whistler.
setPendingRequestInfo | Specifies information for a pending certificate request. New in Whistler.
stringToBinary | Converts a string to a binary data BLOB. New in Whistler.

The Whistler release of the CEnroll object includes the following properties.

Property | Description
CAStoreFlags Access: Read/write Data type: Long | Passed to CertOpenStore. Specifies characteristics when opening the certification authority (CA) store.
CAStoreName Access: Read/write Data type: String | Specifies where all non-"ROOT" and non-"MY" certificates are kept.
CAStoreType Access: Read/write Data type: String | Contains the type of the store specified by the CAStoreName property.
ContainerName Access: Read/write Data type: String | Specifies the name of the key container to use.
DeleteRequestCert Access: Read/write Data type: Boolean | Controls whether dummy certificates in the request store are deleted.
EnableSMIMECapabilities Access: Read/write Data type: Boolean | Controls whether the certificate request contains a signed attribute for S/MIME capabilities.
EnableT61DNEncoding Access: Read/write Data type: Boolean | Controls whether the certificate's distinguished name is encoded as a T61 string instead of as a UNICODE string.
GenKeyFlags Access: Read/write Data type: Long | Passed to CryptGenKey. Specifies characteristics of the key being created.
HashAlgID Access: Read/write Data type: Long | Specifies the preferred hash algorithm for signing the certificate request.
HashAlgorithm Access: Read/write Data type: String | Specifies the preferred hash algorithm for signing the certificate request.
KeySpec Access: Read/write Data type: Long | Specifies the key type to be generated.
LimitExchangeKeyToEncipherment Access: Read/write Data type: Boolean | Controls whether the request will contain key usages for digital signature and non-repudiation (applies to AT_KEYEXCHANGE requests only).
MyStoreFlags Access: Read/write Data type: Long | Passed directly to CertOpenStore. Specifies characteristics when opening the MY store.
MyStoreName Access: Read/write Data type: String | Specifies where certificates with linked private keys are kept.
MyStoreType Access: Read/write Data type: String | Contains the type of the store specified by the MyStoreName property.
PrivateKeyArchiveCertificate Access: Read/write Data type: String | Specifies the certificate used to encrypt a private key when the private key is archived. New in Whistler.
ProviderFlags Access: Read/write Data type: Long | Use depends on the cryptographic service provider (CSP) in use.
ProviderName Access: Read/write Data type: String | Specifies the CSP to use.
ProviderType Access: Read/write Data type: Long | Use depends on the provider in use.
PVKFileName Access: Read/write Data type: String | Controls whether a private key is exportable. The private key is written to the file specified by the PVKFileName property.
RequestStoreFlags Access: Read/write Data type: Long | Passed to CertOpenStore. Specifies characteristics when opening the REQUEST store.
RequestStoreName Access: Read/write Data type: String | Specifies the certificate store used to store a dummy certificate.
RequestStoreType Access: Read/write Data type: String | Contains the type of the store specified by the RequestStoreName property.
ReuseHardwareKeyIfUnableToGenNew Access: Read/write Data type: Boolean | For hardware CSPs only (such as smart card), determines if an existing key is reused when it is not possible to create a new key.
RootStoreFlags Access: Read/write Data type: Long | Passed directly to CertOpenStore. Specifies characteristics when opening the ROOT store.
RootStoreName Access: Read/write Data type: String | Specifies where all intrinsically trusted, self-signed ROOT certificates are kept.
RootStoreType Access: Read/write Data type: String | Contains the type of the store specified by the RootStoreName property.
SPCFileName Access: Read/write Data type: String | Specifies a file to receive the PKCS #7 message (in BSTR form) returned from the certification authority.
ThumbPrint Access: Read/write Data type: String | Contains a hash of the certificate data. New in Whistler.
UseExistingKeySet Access: Read/write Data type: Boolean | Specifies that an existing key set be used, instead of generating a new one.
WriteCertToCSP Access: Read/write Data type: Boolean | Specifies whether a certificate should be written to the cryptographic service provider.
WriteCertToUserDS Access: Read/write Data type: Boolean | Specifies whether a certificate is written to the user's Directory Service.

Note For programming without Automation, the Whistler release of the CEnroll exposes four interfaces:

• ICEnroll
• ICEnroll2
• ICEnroll3
• ICEnroll4

The documentation for the individual methods and properties of CEnroll is organized by interface.


ICEnroll

[Visual Basic] The ICEnroll interface is an interface of the CEnroll object. This interface is primarily of interest if you are not using Automation. If, on the other hand, you are programming in Visual Basic or another Automation language, see the CEnroll object for a complete listing of the methods and properties available.

The ICEnroll interface is one of three interfaces currently exposed by the CEnroll object, which provides the entire functionality for the Certificate Enrollment Control. Previously, the CEnroll object exposed only the ICEnroll interface. However, beginning with Microsoft® Windows® 2000 Beta 2, the CEnroll object supports ICEnroll2, which inherits and extends the methods and properties of ICEnroll. Beginning with Microsoft® Windows® 2000 Beta 3, the CEnroll object supports ICEnroll3, which inherits and extends the methods and properties of both ICEnroll and ICEnroll2.

ICEnroll has the following methods.

Method | Description
acceptFilePKCS7 | Accepts and processes a PKCS #7 message containing a certificate. The PKCS #7 is stored in a file.
acceptPKCS7 | Accepts and processes a PKCS #7 message containing a certificate. The PKCS #7 message is input as a parameter.
createFilePKCS10 | Creates a PKCS #10 certificate request for the person or entity whose information is supplied in the PKCS #10. This PKCS #10 is saved to a file.
createPKCS10 | Creates a PKCS #10 certificate request and saves it to a file.
enumContainers | Enumerates the containers for the provider specified in the ProviderName property.
enumProviders | Enumerates the providers available on the computer for the specified ProviderType property.
freeRequestInfo | Cleans up the stores if an error occurs. Currently not implemented.
getCertFromPKCS7 | Retrieves from a PKCS #7 message the certificate issued in response to a PKCS #10 certificate request.

The following properties are provided for the ICEnroll interface. For information on using these properties, see Using the Certificate Enrollment Control Properties.

Property | Description
CAStoreFlags [C++] Access: Read/write Data type: DWORD [Visual Basic] Access: Read/write Data type: Long | Specifies characteristics when opening the certification authority (CA) store.
CAStoreName [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Specifies where all non-"ROOT" and non-"MY" certificates are kept.
CAStoreType [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Specifies a type value for the store specified by the CAStoreName property.
ContainerName [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Specifies the name of the key container to use.
DeleteRequestCert [C++] Access: Read/write Data type: BOOL [Visual Basic] Access: Read/write Data type: Boolean | Controls whether dummy certificates in the request store are deleted.
GenKeyFlags [C++] Access: Read\write Data type: DWORD [Visual Basic] Access: Read\write Data type: Long | Specifies characteristics of the key being created.
HashAlgorithm [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies the preferred hash algorithm for signing PKCS #10 certificate requests.
KeySpec [C++] Access: Read\write Data type: DWORD [Visual Basic] Access: Read\write Data type: Long | Specifies the CSP-specific key type.
MyStoreFlags [C++] Access: Read\write Data type: DWORD [Visual Basic] Access: Read\write Data type: Long | Specifies characteristics when opening the MY store.
MyStoreName [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies where certificates with linked private keys are kept.
MyStoreType [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies a type value for the store identified by the MyStoreName property.
ProviderFlags [C++] Access: Read\write Data type: DWORD [Visual Basic] Access: Read\write Data type: Long | Specifies CSP-specific flags.
ProviderName [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies the CSP to use.
ProviderType [C++] Access: Read\write Data type: DWORD [Visual Basic] Access: Read\write Data type: Long | Specifies CSP-specific information.
PVKFileName [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Controls exportable private keys; a non-null value indicates that private keys are exportable. The private keys are written to the file specified by this property.
RequestStoreFlags [C++] Access: Read\write Data type: DWORD [Visual Basic] Access: Read\write Data type: Long | Specifies characteristics when opening the REQUEST store.
RequestStoreName [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies the certificate store that holds dummy certificates created for pending requests.
RequestStoreType [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies the certificate store that holds dummy certificates created for pending requests.
RootStoreFlags [C++] Access: Read\write Data type: DWORD [Visual Basic] Access: Read\write Data type: Long | Specifies characteristics when opening the ROOT store.
RootStoreName [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies where all intrinsically trusted, self-signed ROOT certificates are kept.
RootStoreType [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies a type value for the store specified by the RootStoreName property.
SPCFileName [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies the name of a file where a PKCS #7 message returned from the CA is written.
UseExistingKeySet [C++] Access: Read\write Data type: BOOL [Visual Basic] Access: Read\write Data type: Boolean | Controls whether an existing key set is used or a new one is generated.
WriteCertToCSP [C++] Access: Read\write Data type: BOOL [Visual Basic] Access: Read\write Data type: Boolean | Controls whether a certificate is written to the CSP.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.

See Also

ICEnroll2


ICEnroll::acceptFilePKCS7

Platform SDK: Security

ICEnroll::acceptFilePKCS7 [C++]

CEnroll.acceptFilePKCS7 [Visual Basic]

The acceptFilePKCS7 method accepts and processes a PKCS #7 message containing a certificate. The message is input from a file.

[Visual Basic]
objEnroll.acceptFilePKCS7( _
  wszPKCS7FileName As String _
)
[C++]
HRESULT acceptFilePKCS7 (
  BSTR wszPKCS7FileName
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] wszPKCS7FileName
[in] Specifies the name of the file containing the PKCS #7.

Return Values

[Visual Basic] None.

[C++] The return value is an HRESULT. A value of S_OK indicates success. Upon successful completion of this function, the PKCS7 in the file will be accepted.

Remarks

By default, the system stores MY, CA, ROOT, and REQUEST are used to store the certificates. However, you can specify other stores by assigning the following properties before calling this method:

  • MyStoreName
  • CAStoreName
  • RootStoreName
  • RequestStoreName

The acceptFilePKCS7 method differs from acceptPKCS7 only in that a file supplies the certificate.

Example Code [C++]

HRESULT  hr;
BSTR     bstrFileName;

// Allocate a BSTR referencing an existing file.
bstrFileName = SysAllocString(TEXT("myPKCS7.fil"));
// pEnroll is a previously instantiated ICEnroll interface pointer.
hr = pEnroll->acceptFilePKCS7( bstrFileName );
if (FAILED(hr))
    printf("Failed acceptFilePKCS7 - %x\n", hr );
else
    printf("Accepted PKCS7 from file %ws successfully\n", bstrFileName );

// Free BSTR when done.
if ( NULL != bstrFileName )
    SysFreeString(bstrFileName);

Example Code [Visual Basic]

    Dim strFileName As String
    strFileName = "myPKCS7.fil"

    On Error GoTo Err_Accept
    objEnroll.acceptFilePKCS7 (strFileName)
    MsgBox ("Accepted PKCS7 from " & _
            strFileName & _
            " successfully")

    Exit Sub

Err_Accept:

    MsgBox ("Failed acceptFilePKCS7" & _
            " from file " & _
            strFileName)

    End Sub

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.

See Also

acceptPKCS7, CAStoreName, MyStoreName, RootStoreName, RequestStoreName


ICEnroll::acceptPKCS7

Platform SDK: Security

ICEnroll::acceptPKCS7 [C++]

CEnroll.acceptPKCS7 [Visual Basic]

The acceptPKCS7 method accepts and processes a PKCS #7 containing a certificate. The PKCS #7 is input as a parameter.

[Visual Basic]
objEnroll.acceptPKCS7( _
  PKCS7 As String _
)
[C++]
HRESULT acceptPKCS7 (
  BSTR PKCS7
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] PKCS7
[in] Represents the base64-encoded PKCS #7 containing the certificate and the chain of certificates identifying the issuer.

Return Values

[Visual Basic] None.

[C++] The return value is an HRESULT. A value of S_OK indicates success. Upon successful completion of this function, the PKCS7 will be accepted.

Remarks

The PKCS #7 input as a parameter for acceptPKCS7 contains the request certificate and the chain of certificates identifying the issuer of the certificate. Typically, but not always, the chain of certificates does not include the root. The PKCS #7 can be in base64-encoded, binary or X.509 certificate format (with or without the begin cert / end cert tags). The certificate and the associated keys generated for it are put in the MY store. A root certificate is placed in the ROOT store and the rest of the chain of certificates are placed in the certification authority (CA) store. If any ROOT certificates found in the PKCS #7 are accepted, Crypt32 will notify the user that a ROOT certificate is being added to his store. The user has the option of declining the ROOT certificate; this option is provided so that the user can decline to place an untrusted root in the ROOT store. Declining to place the ROOT in the ROOT store will not cause Certificate Enrollment Control to fail acceptance.

By default, the system stores MY, CA, ROOT, and REQUEST are used to store the certificates. However, you can specify other stores by assigning the following properties before calling this method:

  • MyStoreName
  • CAStoreName
  • RootStoreName
  • RequestStoreName

Example Code [C++]

HRESULT    hr;

// pEnroll is previously instantiated ICEnroll interface pointer
// bstrPKCS7 is previously created BSTR containing PCKS7
hr = pEnroll->acceptPKCS7( bstrPKCS7 );
if (FAILED(hr))
    printf("Failed acceptPKCS7 - %x\n", hr );
else
    printf("Accepted PKCS7 successfully\n");

Example Code [Visual Basic]

    On Error GoTo Err_Accept
    ' strPKCS7 is a String containing PKCS7
    objEnroll.acceptPKCS7 (strPKCS7)
    MsgBox ("Accepted PKCS7 successfully")

    Exit Sub

Err_Accept:

    MsgBox ("Failed acceptPKCS7")

    End Sub

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.

See Also

acceptFilePKCS7, CAStoreName, MyStoreName, RootStoreName, RequestStoreName


ICEnroll::createFilePKCS10

Platform SDK: Security

ICEnroll::createFilePKCS10 [C++]

CEnroll.createFilePKCS10 [Visual Basic]

The createFilePKCS10 method creates a base64-encoded PKCS #10 certificate request and saves it in a file.

This method differs from createPKCS10 only in saving the base64-encoded PKCS #10 (in BSTR form) to the file specified by wszPKCS10FileName.

[Visual Basic]
objEnroll.createFilePKCS10( _
  DNName As String , _
  Usage As String , _
  wszPKCS10FileName As String _
)
[C++]
HRESULT createFilePKCS10(
  BSTR DNName,
  BSTR Usage,
  BSTR wszPKCS10FileName
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] DNName
[in] The distinguished name (DN) of the entity for which the request is being made. DNName must follow the X.500 naming convention. For example "CN=User, O=Microsoft". If a two-letter prefix does not exist, an object identifier (OID) may be provided instead.
[Visual Basic,C++] Usage
[in] An OID that describes the purpose of the certificate being generated, for example, individual or commercial Authenticode certificate, or client authentication. You can also specify multiple OIDs separated by a comma.

The OID is passed through to the PKCS #10 request; the control does not examine the OID.

[Visual Basic,C++] wszPKCS10FileName
[in] The name of the file in which the base64-encoded PKCS #10 (in BSTR form) is saved. This contents of this file may be submitted to a certification authority for processing.

Return Values

[Visual Basic] None.

[C++] The return value is an HRESULT. A value of S_OK indicates success.

If the method fails, the return value is an HRESULT indicating the error. For a list of common error codes, see Common HRESULT Values.

Remarks

By default, the Microsoft Base Cryptographic Provider is used, and a unique signature key is created.

Example Code [C++]

BSTR       bstrDN = NULL;
BSTR       bstrOID = NULL;
BSTR       bstrFileName = NULL;
ICEnroll * pEnroll = NULL;
HRESULT    hr;

// Initialize COM.
hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );

if (FAILED(hr))
{
    printf("Failed CoInitializeEx - %x\n", hr);
    goto error;
}

hr = CoCreateInstance( CLSID_CEnroll,
                       NULL,
                       CLSCTX_INPROC_SERVER,
                       IID_ICEnroll,
                       (void **)&pEnroll);
if (FAILED(hr))
{
    printf("Failed CoCreateInstance - pEnroll [%x]\n", hr);
    goto error;
}
// Generate the DN for the cert request.
bstrDN = SysAllocString( TEXT("CN=Your Name")   // common name
                         TEXT(",OU=Your Unit")  // org unit
                         TEXT(",O=Your Org")    // organization
                         TEXT(",L=Redmond")     // locality
                         TEXT(",S=Washington")  // state
                         TEXT(",C=US") );       // country/region

// Generate the OID.
bstrOID = SysAllocString(TEXT("1.3.6.1.4.1.311.2.1.21"));

// Specify the file name.
bstrFileName = SysAllocString(TEXT("myPKCS10.req"));

// Create the PKCS10 (stored in a file).
hr = pEnroll->createFilePKCS10( bstrDN, bstrOID, bstrFileName );

if (FAILED(hr))
{
        printf("Failed createFilePKCS10 - %x\n", hr);
        goto error;
}
else
    // Success.
    printf("Successfully created file containing PKCS10\n");

error:
// Clean up resources etc.

if ( NULL != bstrFileName )
    SysFreeString( bstrFileName );

if ( NULL != bstrDN )
    SysFreeString( bstrDN );

if ( NULL != bstrOID )
    SysFreeString( bstrOID );

if ( NULL != pEnroll )
       pEnroll->Release();

CoUninitialize();

Example Code [Visual Basic]

' Generate the distinguished name string.
Dim strDN As String
strDN = "CN=Your Name"           ' common name
strDN = strDN & ",OU=Your Unit"  ' org unit
strDN = strDN & ",O=Your Org"    ' organization
strDN = strDN & ",L=Redmond"     ' locality
strDN = strDN & ",S=Washington"  ' state
strDN = strDN & ",C=US"          ' country/region

' The following variable is the file used to store the PKCS10.
Dim strFileName As String
strFileName = "myPKCS10.req"

' objEnroll is previously created CEnroll object.
' Generate the PKCS10 string, saved to file.
Dim strPKCS10 As String
strPKCS10 = objEnroll.createFilePKCS10(strDN, _
                                       "1.3.6.1.4.1.311.2.1.21", _
                                        strFileName)

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::createPKCS10

Platform SDK: Security

ICEnroll::createPKCS10 [C++]

CEnroll.createPKCS10 [Visual Basic]

The createPKCS10 method creates a base64-encoded PKCS #10 (in BSTR form) that can be submitted to a certification authority. This PKCS #10 requests that a certificate be issued to the person or entity whose information it contains.

[Visual Basic]
objEnroll.createPKCS10( _
  DNName As  String, _
  Usage As String ) As String
[C++]
HRESULT createPKCS10(
  BSTR DNName,
  BSTR Usage,
  BSTR *pPKCS10
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] DNName
[in] The distinguished name (DN) of the entity for which the request is being made. In this parameter, the DN name must follow the X.500 naming convention. For example "CN=User, O=Microsoft". If a two-letter prefix does not exist, an OID may be provided instead.
[Visual Basic,C++] Usage
[in] An OID that describes the purpose of the certificate being generated. For example, Individual or Commercial Authenticode certificate, or Client Authentication. You can also specify multiple OIDs separated by a comma.

The purpose OID is just passed through to the PKCS #10 request. For general extensibility and ease of understanding, the control does not attempt to understand specific-purpose OIDs. Therefore if you specify a Client Authentication OID, the generated key will still be a signature key, not an exchange key.

[C++] pPKCS10
[in] The returned Base64-encoded PKCS10 certificate request.

Return Values

[Visual Basic] None.

[C++] The return value is an HRESULT. A value of S_OK indicates success. Upon successful completion of this function, pPKCS10 will contain a base64-encoded PKCS #10 request (in BSTR form). The format is such that it can be directly posted to a Web server for processing.

Remarks

By default, the Microsoft Base Cryptographic Provider is used, PROV_RSA_FULL is the provider type, a signature key is created, and a unique new key set is created.

Example Code [C++]

BSTR       bstrDN = NULL;
BSTR       bstrReq = NULL;
BSTR       bstrOID = NULL;
ICEnroll * pEnroll = NULL;
HRESULT    hr;

// initialize COM
hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );

if (FAILED(hr))
{
    printf("Failed CoInitializeEx - %x\n", hr);
    goto error;
}

hr = CoCreateInstance( CLSID_CEnroll,
                       NULL,
                       CLSCTX_INPROC_SERVER,
                       IID_ICEnroll,
                       (void **)&pEnroll);
if (FAILED(hr))
{
    printf("Failed CoCreateInstance - pEnroll [%x]\n", hr);
    goto error;
}
// generate the DN for the cert request
bstrDN = SysAllocString( TEXT("CN=Your Name")   // common name
                         TEXT(",OU=Your Unit")  // org unit
                         TEXT(",O=Your Org")    // organization
                         TEXT(",L=Redmond")     // locality
                         TEXT(",S=Washington")  // state
                         TEXT(",C=US") );       // country/region

// generate the OID
bstrOID = SysAllocString(TEXT("1.3.6.1.4.1.311.2.1.21"));

// create the PKCS10
hr = pEnroll->createPKCS10( bstrDN, bstrOID, &bstrReq );

if (FAILED(hr))
{
        printf("Failed createPKCS10 - %x\n", hr);
        goto error;
}
else
    // do something with the PKCS10 (bstrReq);

error:

//clean up resources, etc.
if ( NULL != bstrDN )
    SysFreeString( bstrDN );
if ( NULL != bstrOID )
    SysFreeString( bstrOID );
if ( NULL != bstrReq )
    SysFreeString( bstrReq );
if ( NULL != pEnroll )
       pEnroll->Release();

CoUninitialize();

Example Code [Visual Basic]

' generate the distinguished name string
Dim strDN As String, strPKCS10 As String
strDN = "CN=Your Name"           ' common name
strDN = strDN & ",OU=Your Unit"  ' org unit
strDN = strDN & ",O=Your Org"    ' organization
strDN = strDN & ",L=Redmond"     ' locality
strDN = strDN & ",S=Washington"  ' state
strDN = strDN & ",C=US"          ' country/region

' objEnroll is previously created CEnroll object
' generate the PKCS10 string
strPKCS10 = objEnroll.createPKCS10(strDN, "1.3.6.1.4.1.311.2.1.21")

' do something with the PKCS10 string...
MsgBox (strPKCS10)

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::enumContainers

Platform SDK: Security

ICEnroll::enumContainers [C++]

CEnroll.enumContainers [Visual Basic]

The enumContainers method retrieves the names of containers for the cryptographic service provider (CSP) specified by the ProviderName property.

[Visual Basic]
objEnroll.enumContainers( _
  dwIndex As Long ) As String
[C++]
HRESULT enumContainers (
  DWORD dwIndex,
  BSTR *pbstrContainerName
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic ,C++] dwIndex
[in] Specifies the ordinal position of the container whose name will be retrieved. Specify zero for the first container.

Note In Windows Whistler, the C++ data type for this parameter has changed to LONG.

[C++] pbstrContainerName
[out] Pointer to BSTR variable that receives the name of the container. The caller must free this variable by calling the SysFreeString function.

Return Values

[Visual Basic] The return value is a String variable representing the name of the container. An exception is raised if an error is encountered or when there are no more items.

[C++] The return value is an HRESULT. A value of S_OK indicates success. The value ERROR_NO_MORE_ITEMS is returned when there are no more items.

Remarks

If the ProviderName property value has not been set, the default value (usually Microsoft Base Cryptographic Provider) of ProviderName as set in the registry, is used.

Example Code [C++]

BSTR       bstrProvName = NULL;
BSTR       bstrCon = NULL;
DWORD      nCon;
HRESULT    hr;

// Let the control know which provider to query.
bstrProvName = SysAllocString(TEXT("Microsoft Base")
                              TEXT(" Cryptographic Pr")
                              TEXT("ovider v1.0"));
hr = pEnroll->put_ProviderName( bstrProvName );
if (FAILED(hr))
{
    printf("Failed put_ProviderName - %x\n", hr);
    goto error;
}

// enumerate the containers for this provider
nCon = 0;
printf("Containers for %ws:\n", bstrProvName );
// pEnroll is previously instantiated ICEnroll interface pointer
while ( S_OK == pEnroll->enumContainers(nCon, &bstrCon) )
{
    printf("\t%d) %ws\n", nCon++, bstrCon );
    // Free this string, so it can be re-used.
    if ( NULL != bstrCon )
    {
        SysFreeString( bstrCon );
        bstrCon = NULL;
    }
}

error:

//clean up resources, etc.
if ( NULL != pEnroll )
       pEnroll->Release();

if ( NULL != bstrProvName )
    SysFreeString( bstrProvName );

if ( NULL != bstrCon )
    SysFreeString( bstrCon );

CoUninitialize();

Example Code [Visual Basic]

Dim strOut As String
Dim i As Integer
Dim NoMoreRecs As Boolean

    ' enumerate the containers
    i = 0
    NoMoreRecs = False

    On Error GoTo ErrorHandler
    Do
        strOut = objEnroll.enumContainers(i)
        If NoMoreRecs Then
            Exit Do
        End If
        ' display the index and Container value
        MsgBox (i & " " & strOut)
        i = i + 1
    Loop

    Exit Sub

ErrorHandler:

    NoMoreRecs = True
    Resume Next

    End Sub

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.

See Also

ProviderName


ICEnroll::enumProviders

Platform SDK: Security

ICEnroll::enumProviders [C++]

CEnroll.enumProviders [Visual Basic]

The enumProviders method retrieves the names of available cryptographic service providers (CSPs) that have the property type specified by the ProviderType property.

This method calls the CryptEnumProviders function.

[Visual Basic]
objEnroll.enumProviders( _
  dwIndex As Long, _
  dwFlags As Long ) As String
[C++]
HRESULT enumProviders (
  DWORD dwIndex,
  DWORD dwFlags,
  BSTR *pbstrProvName
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic, C++] dwIndex
[in] Specifies the ordinal position of the CSP whose name will be retrieved. Specify zero for the first CSP.

Note In Windows Whistler, the C++ data type for this parameter has changed to LONG.

[Visual Basic, C++] dwFlags
[in] Specifies flags that are passed through to the CryptEnumProviders function. Not currently used; specify zero.

Note In Windows Whistler, the C++ data type for this parameter has changed to LONG.

[C++] pbstrProvName
[out] Pointer to BSTR variable that receives the name of a CSP with the specified property type. The caller must free this variable by calling the SysFreeString function.

Return Values

[Visual Basic] The return value is a String variable containing the name of a CSP. An exception is raised if an error is encountered or when there are no more items.

[C++] The return value is an HRESULT. A value of S_OK indicates success. The value ERROR_NO_MORE_ITEMS is returned when there are no more CSPs with the property type indicated by the ProviderType property.

Remarks

If the ProviderType property value has not been set, the default value (usually PROV_RSA_FULL) of ProviderType as set in the registry, is used.

Example Code [C++]

BSTR       bstrProvName = NULL;
DWORD      dwType, nProv;
int        j;
HRESULT    hr;

// array of CSP provider types (see wincrypt.h)
DWORD      nProvType[] = { PROV_RSA_FULL,
                           PROV_RSA_SIG,
                           // list shortened for brevity
                           //...
                           PROV_STT_ISS };

// Loop, for each Prov Type.
for (j = 0; j < (sizeof(nProvType)/sizeof(DWORD)); j++)
{
    nProv = 0;

    // Check specific prov type.
    dwType = nProvType[j];
    // pEnroll is previously instantiated ICEnroll interface pointer
    hr = pEnroll->put_ProviderType( dwType );
    if ( FAILED(hr))
    {
        printf("Failed put_ProviderType - %x\n", hr);
        goto error;
    }
    // Enumerate the CSPs of this type.
    while ( S_OK == ( hr  = pEnroll->enumProviders(nProv,
                                                   0,
                                                   &bstrProvName)))
    {
        printf("Provider %ws (type %d )\n", bstrProvName, dwType );
        // Increment the index.
        nProv++;
        // Free this string, so it can be re-used.
        if ( NULL != bstrProvName )
        {
            SysFreeString( bstrProvName );
            bstrProvName = NULL;
        }
    }
    // Print message if provider type doesn't have any CSPs.
    if ( 0 == nProv )
       printf("There were no CSPs of type %d\n", dwType );
}

error:
// Clean up resources, etc.
if ( NULL != pEnroll )
       pEnroll->Release();
if ( NULL != bstrProvName )
    SysFreeString( bstrProvName );

CoUninitialize();

Example Code [Visual Basic]

Dim strOut As String
Dim i As Integer
Dim NoMoreRecs As Boolean

    ' Enumerate the providers.
    i = 0
    NoMoreRecs = False
    On Error GoTo ErrorHandler
    Do
        strOut = objEnroll.enumProviders(i, 0)
        If NoMoreRecs Then
            Exit Do
        End If
        ' Display the index and Provider value.
        MsgBox (i & " " & strOut)
        i = i + 1
    Loop

    Exit Sub

ErrorHandler:

    NoMoreRecs = True
    Resume Next

    End Sub

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.

See Also

ProviderType


ICEnroll::freeRequestInfo

Platform SDK: Security

ICEnroll::freeRequestInfo [C++]

CEnroll.freeRequestInfo [Visual Basic]

This method is not currently implemented.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::getCertFromPKCS7

Platform SDK: Security

ICEnroll::getCertFromPKCS7 [C++]

CEnroll.getCertFromPKCS7 [Visual Basic]

The getCertFromPKCS7 method retrieves from a PKCS #7 certification authority (CA) response, the single certificate that was issued. A PKCS #7 may contain many certificates specifying the certification chain of authority that issued the certificate.

[Visual Basic]
objEnroll.getCertFromPKCS7( _
  wszPKCS7 As String ) As String
[C++]
HRESULT getCertFromPKCS7(
  BSTR wszPKCS7,
  BSTR *pbstrCert
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] wszPKCS7
[in] Specifies the PKCS #7 from which the issued certificate is being retrieved.
[C++] pbstrCert
[out] Pointer to a BSTR variable which receives the issued certificate. The caller must free this variable by calling the SysFreeString function.

Return Values

[Visual Basic] None.

[C++] The return value is an HRESULT. A value of S_OK indicates success.

Example Code [C++]

BSTR    bstrCert = NULL;
HRESULT    hr;

// pEnroll is previously instantiated ICEnroll interface pointer
// bstrPKCS7 is previously created BSTR containing PCKS7
hr = pEnroll->getCertFromPKCS7( bstrPKCS7, &bstrCert );
if (FAILED(hr))
    printf("Failed getCertFromPKCS7 - %x\n", hr );
else
{
    printf("Successfully called getCertFromPKCS7\n");
    // do something with the certificate
}

// free BSTR when done
if ( NULL != bstrCert )
    SysFreeString( bstrCert );

Example Code [Visual Basic]

    On Error GoTo Err_GetCert

    ' strPKCS7 is a String variable containing PKCS7
    strCert = objEnroll.getCertFromPKCS7(strPKCS7)
    MsgBox ("Retrieved certificate: " & _
            strCert)
    Exit Sub

Err_GetCert:

    MsgBox ("Failed getCertFromPKCS7")

    End Sub

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::CAStoreFlags

Platform SDK: Security

ICEnroll::CAStoreFlags [C++]

CEnroll.CAStoreFlags [Visual Basic]

The CAStoreFlags property value is passed to the CryptoAPI CertOpenStore function when the certification authority (CA) store is opened. This value is passed as CertOpenStore's dwFlags parameter.

The default value for CAStoreFlags is CERT_SYSTEM_STORE_CURRENT_USER.

[Visual Basic]
objEnroll.CAStoreFlags [ = Flags ]
[C++]
HRESULT put_CAStoreFlags(DWORD Flags);
HRESULT get_CAStoreFlags(DWORD *pFlags);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Flags
Value assigned to the CAStoreFlags property. The data type is a DWORD in C++ and a Long in Visual Basic. It is one of the following values:
  • CERT_SYSTEM_STORE_CURRENT_USER
  • CERT_SYSTEM_STORE_LOCAL_MACHINE
  • CERT_SYSTEM_STORE_SERVICES
  • CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
  • CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY

Note In Windows Whistler, the C++ data type for this parameter has changed to LONG.

[C++] pFlags
Pointer that receives the current value for the CAStoreFlags property.

Note In Windows Whistler, the data type for this parameter has changed to LONG.

Remarks

CAStoreFlags affects the behavior of the following methods:

  • acceptPKCS7
  • acceptFilePKCS7

Example Code [C++]

DWORD    dwFlags;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll interface pointer

// retrieve the flag value
hr = pEnroll->get_CAStoreFlags( &dwFlags );
if ( FAILED ( hr ) )
    printf("Failed retrieving CAStoreFlags - %x\n", hr );
else
    printf("CAStoreFlags is %x\n", dwFlags );

// set the flag
hr = pEnroll->put_CAStoreFlags( CERT_SYSTEM_STORE_LOCAL_MACHINE );
if ( FAILED ( hr ) )
    printf("Failed updating CAStoreFlags - %x\n", hr );
else
    printf("Updated CAStoreFlags\n");

Example Code [Visual Basic]

Const CERT_SYSTEM_STORE_LOCAL_MACHINE As Long = &H20000

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim flags As Long

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' retrieve and display the CAStoreFlags value
flags = objXen.CAStoreFlags
MsgBox flags, vbOKOnly, "CAStoreFlags"

' set the CAStoreFlags value
objXen.CAStoreFlags = CERT_SYSTEM_STORE_LOCAL_MACHINE

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::CAStoreName

Platform SDK: Security

ICEnroll::CAStoreName [C++]

CEnroll.CAStoreName [Visual Basic]

The CAStoreName property specifies where all non-"ROOT" and non-"MY" certificates are kept. By default, this is set to the "CA" system store.

[Visual Basic]
objEnroll.CAStoreName [ = Name ]
[C++]
HRESULT put_CAStoreName(BSTR Name);
HRESULT get_CAStoreName(BSTR *pName);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Name
The string value assigned to the CAStoreName property. It can be any defined store name, such as one of the following:
  • "CA" (the default)
  • "MY"
  • "ROOT"
[C++] pName
Pointer to retrieved property value.

Remarks

CAStoreName Affects the behavior of the following methods:

  • acceptPKCS7
  • acceptFilePKCS7

Example Code [C++]

BSTR     bstrStoreName = NULL;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll interface pointer

// get the storename
hr = pEnroll->get_CAStoreName( &bstrStoreName );
if ( FAILED ( hr ) )
    printf("Failed getting CAStoreName - %x\n", hr );
else
    printf( "CAStoreName: %ws\n", bstrStoreName );
// free BSTR when done
if ( NULL != bstrStoreName )
    SysFreeString( bstrStoreName );

// set the storename
// bstrNewName previously set to a valid store name
hr = pEnroll->put_CAStoreName( bstrNewName );
if ( FAILED ( hr ) )
    printf("Failed setting CAStoreName - %x\n", hr );
else
    printf( "CAStoreName was set to : %ws\n", bstrNewName );

Example Code [Visual Basic]

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim strStoreName As String

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' retrieve and display the CAStoreName
strStoreName = objXen.CAStoreName
MsgBox strStoreName, vbOKOnly, "CAStoreName"

' set the CAStoreName
' (strOtherStoreName previously set to a valid store name)
objXen.CAStoreName = strOtherStoreName

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::CAStoreType

Platform SDK: Security

ICEnroll::CAStoreType [C++]

CEnroll.CAStoreType [Visual Basic]

The CAStoreType property specifies the type of store to use for the store specified by the CAStoreName property. CAStoreType's value is passed directly on to CertOpenStore. By default, this value is sz_CERT_STORE_PROV_SYSTEM.

Currently only system stores are supported.

[Visual Basic]
objEnroll.CAStoreType [ = Type ]
[C++]
HRESULT put_CAStoreType(BSTR Type);
HRESULT get_CAStoreType(BSTR *pType);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Type
The string value assigned to the CAStoreType property. It is one of the following currently supported store provider types:
Store Provider Type | Value
sz_CERT_STORE_PROV_SYSTEM_W | "System"
sz_CERT_STORE_PROV_SYSTEM | "System"

[C++] pType
Pointer to retrieved property value.

Remarks

CAStoreType affects the behavior of the following methods:

  • acceptPKCS7
  • acceptFilePKCS7

Example Code [C++]

BSTR     bstrStoreType = NULL;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll interface pointer

// get the storetype
hr = pEnroll->get_CAStoreType( &bstrStoreType );
if ( FAILED ( hr ) )
    printf("Failed getting CAStoreType - %x\n", hr );
else
    printf( "CAStoreType: %ws\n", bstrStoreType );
// free BSTR when done
if ( NULL != bstrStoreType )
    SysFreeString( bstrStoreType );

// set the storetype
// bstrNewType previously set to a valid store type
hr = pEnroll->put_CAStoreType( bstrNewType );
if ( FAILED ( hr ) )
    printf("Failed setting CAStoreType - %x\n", hr );
else
    printf( "CAStoreType was set to %ws\n", bstrNewType );

Example Code [Visual Basic]

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim strStoreType As String

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' retrieve and display the CAStoreType
strStoreType = objXen.CAStoreType
MsgBox strStoreType, vbOKOnly, "CAStoreType"

' set the CAStoreType
' (strNewType previously set to a valid store type)
objXen.CAStoreType = strNewType

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::ContainerName

Platform SDK: Security

ICEnroll::ContainerName [C++]

CEnroll.ContainerName [Visual Basic]

The ContainerName property specifies the name of the key container to use.

[Visual Basic]
objEnroll.ContainerName [ = Name ]
[C++]
HRESULT put_ContainerName(BSTR Name);
HRESULT get_ContainerName(BSTR *pName);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Name
The string value assigned to the ContainerName property. If the using application has not assigned a value to this property, by default a generated GUID is used for its value.
[C++] pName
Pointer to retrieved property value.

Remarks

The container specified may be an existing container or a new one. It may only be an existing container if the UseExistingKeySet property is set, as long as the key set has not been generated yet. For example, if only an exchange key set has been generated for a container, it is still possible to perform a certificate enrollment using the signature key set without setting UseExistingKeySet. The exchange key set could be used if UseExistingKeySet is set beforehand.

By default, a new container is selected each time the ICEnroll control is run. This ensures that a new key set is generated. If this property is not explicitly set, a generated GUID is used as the container name.

ContainerName affects the behavior of the following methods:

  • createPKCS10
  • createFilePKCS10

Example Code [C++]

BSTR     bstrContainerName = NULL;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll interface pointer

// get the container name
hr = pEnroll->get_ContainerName( &bstrContainerName );
if ( FAILED ( hr ) )
    printf("Failed getting ContainerName - %x\n", hr );
else
    printf( "ContainerName: %ws\n", bstrContainerName );
// free BSTR when done
if ( NULL != bstrContainerName )
    SysFreeString( bstrContainerName );

// set the container name
// bstrMyName previously set to a valid name
hr = pEnroll->put_ContainerName( bstrMyName );
if ( FAILED ( hr ) )
    printf("Failed setting ContainerName - %x\n", hr );
else
    printf( "ContainerName was set to %ws\n", bstrMyName );

Example Code [Visual Basic]

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim strContainerName As String

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' retrieve and display the ContainerName
strContainerName = objXen.ContainerName
MsgBox strContainerName, vbOKOnly, "ContainerName"

' set the ContainerName
' strMyName previously set to a valid name
objXen.ContainerName = strMyName

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::DeleteRequestCert

Platform SDK: Security

ICEnroll::DeleteRequestCert [C++]

CEnroll.DeleteRequestCert [Visual Basic]

The DeleteRequestCert property is used to control whether deletion occurs on a dummy certificate created for the purpose of persisting the keys generated for the PKCS #10 request during the enrollment process.

The store specified by the RequestStoreName property is where the dummy certificate is created. The newly generated keys are added as properties to the dummy certificate to persist them until a certification authority processes the request and responds with a PKCS #7. On acceptance of the PKCS #7, the dummy certificate is removed and the keys are added as properties of the issued certificate returned by the certification authority. For debugging and testing, it is often desirable to not delete the dummy certificate. Setting DeleteRequestCert to FALSE prevents its deletion. By default, this value is set to TRUE.

[Visual Basic]
objEnroll.DeleteRequestCert [ = bValue ]
[C++]
HRESULT put_DeleteRequestCert(BOOL bValue);
HRESULT get_DeleteRequestCert(BOOL *pbValue);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] bValue
A boolean value assigned to the DeleteRequestCert property. It is one of the following values:
  • TRUE (the default)
  • FALSE
[C++] pbValue
Pointer to retrieved property value.

Remarks

DeleteRequestCert affects the behavior of the following methods:

  • acceptPKCS7
  • acceptFilePKCS7

Example Code [C++]

BOOL     bDRC;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll interface pointer

// get the DeleteRequestCert boolean value
hr = pEnroll->get_DeleteRequestCert( &bDRC );
if ( FAILED ( hr ) )
    printf("Failed getting DeleteRequestCert - %x\n", hr );
else
    printf( "DeleteRequestCert: %s\n", ( bDRC ? "TRUE" : "FALSE" ) );

// set the DeleteRequestCert value
hr = pEnroll->put_DeleteRequestCert( FALSE );
if ( FAILED ( hr ) )
    printf("Failed Setting DeleteRequestCert - %x\n", hr );
else
    printf( "DeleteRequestCert was set to FALSE\n" );

Example Code [Visual Basic]

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim bDelReqCert As Boolean

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' retrieve and display the DeleteRequestCert value
bDelReqCert = objXen.DeleteRequestCert
MsgBox bDelReqCert, vbOKOnly, "DeleteRequestCert"

' set the DeleteRequestCert value
objXen.DeleteRequestCert = False

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::GenKeyFlags

Platform SDK: Security

ICEnroll::GenKeyFlags [C++]

CEnroll.GenKeyFlags [Visual Basic]

The GenKeyFlags property value controls whether a private key is exportable. By default, the value is zero; however, when a .PVK file is specified, the value of GenKeyFlags defaults to CRYPT_EXPORTABLE. See Remarks for additional details.

[Visual Basic]
objEnroll.GenKeyFlags [ = Flags ]
[C++]
HRESULT put_GenKeyFlags(DWORD Flags);
HRESULT get_GenKeyFlags(DWORD *pFlags);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Flags
Value assigned to the GenKeyFlags property. The data type is a DWORD in C++, and a Long in Visual Basic.

Note In Windows Whistler, the C++ data type for this parameter has changed to LONG.

[C++] pFlags
Pointer to retrieved property value.

Note In Windows Whistler, the data type for this parameter has changed to LONG.

Remarks

By default private keys are not exportable unless a .pvk file is requested. To make the private key exportable without specifying a .PVK file, set GenKeyFlags to CRYPT_EXPORTABLE.

Specify a .PVK file name using the PVKFileName property.

The GenKeyFlags property value is passed to the CryptGenKey CryptoAPI function via its dwFlags parameter.

If the cryptographic service provider does not support exportable private keys, an error occurs.

GenKeyFlags affects the behavior of the following methods:

  • createPKCS10
  • createFilePKCS10
  • createRequest

Warning The default value for the GenKeyFlags property is 0. If you need to change this value, you must do so before calling these methods. After calling any of these methods, you cannot change the GenKeyFlags property value.

Example Code [C++]

DWORD    dwGenKey;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll interface pointer

// get the GenKeyFlags value
hr = pEnroll->get_GenKeyFlags( &dwGenKey );
if (FAILED( hr ))
    printf("Failed get_GenKeyFlags - %x\n", hr );
else
    printf( "GenKeyFlags: %d\n", dwGenKey );

// set the GenKeyFlags value
hr = pEnroll->put_GenKeyFlags( CRYPT_EXPORTABLE );
if (FAILED( hr ))
    printf("Failed put_GenKeyFlags - %x\n", hr );
else
    printf( "GenKeyFlags set to %d\n", CRYPT_EXPORTABLE );

Example Code [Visual Basic]

Const CRYPT_EXPORTABLE As Long = 1

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim GKFlags As Long

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' retrieve and display the GenKeyFlags
GKFlags = objXen.GenKeyFlags
MsgBox GKFlags, vbOKOnly, "GenKeyFlags"

' set the GenKeyFlags
objXen.GenKeyFlags = CRYPT_EXPORTABLE

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::HashAlgorithm

Platform SDK: Security

ICEnroll::HashAlgorithm [C++]

CEnroll.HashAlgorithm [Visual Basic]

The HashAlgorithm property refers only to the signature hash algorithm used to sign the PKCS #10. It is not to be confused with the hash algorithm used to sign the certificate. The enrollment control currently supports any OID for hash algorithms, plus the following friendly name values: SHA1 (the default), MD2, and MD5. When retrieving this property, the retrieved value is in OID format (that is, SHA1 appears as 1.3.14.3.2.29); when setting this property, the corresponding OID format can be used as an alternative to the text shown for the defined friendly values.

The Certificate Enrollment Control considers the HashAlgorithm value as a hint to the hash algorithm to use for signing the PKCS #10. If the CSP supports the algorithm specified in the HashAlgorithm, it will be used; otherwise, the Certificate Enrollment Control will try to use SHA1. If SHA1 is not supported by the CSP, then MD5 will be tried. If neither SHA1 or MD5 is supported, the Certificate Enrollment Control will try to use the first hash algorithm returned from the CSP.

[Visual Basic]
objEnroll.HashAlgorithm [ = HashAlg ]
[C++]
HRESULT put_HashAlgorithm(BSTR HashAlg);
HRESULT get_HashAlgorithm(BSTR *pHashAlg);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] HashAlg
The string value assigned to the HashAlgorithm property. It can be one of the following values:
  • "SHA1" (the default)
  • "MD2"
  • "MD5"

Alternatively, it can be any OID for a hash algorithm.

[C++] pHashAlg
Pointer to retrieved property value.

Remarks

HashAlgorithm affects the behavior of the following methods:

  • createPKCS10
  • createFilePKCS10

If both the ICEnroll3::HashAlgID and HashAlgorithm properties are set, whichever is last updated will specify which hash algorithm will be used to sign the PKCS #10.

Example Code [C++]

BSTR     bstrHashAlg = NULL;
HRESULT  hr;

// get the hash algorithm
hr = pEnroll->get_HashAlgorithm( &bstrHashAlg );
if ( FAILED ( hr ) )
    printf("Failed get_HashAlgorithm - %x\n", hr );
else
    printf( "HashAlgorithm: %ws\n", bstrHashAlg );
// free BSTR
if ( NULL != bstrHashAlg )
    SysFreeString( bstrHashAlg);

BSTR    bstrMyHashAlg = SysAllocString(TEXT("MD5"));
// alternatively, ... = SysAllocString(TEXT("1.2.840.113549.1.1.4"));

// set the hash algorithm
hr = pEnroll->put_HashAlgorithm( bstrMyHashAlg );
if ( FAILED ( hr ) )
    printf("Failed put_HashAlgorithm - %x\n", hr );
else
    printf( "HashAlgorithm was set to %ws\n", bstrMyHashAlg );
// free BSTR
if ( NULL != bstrMyHashAlg )
    SysFreeString( bstrMyHashAlg);

Example Code [Visual Basic]

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim strHashAlg As String

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' retrieve and display the HashAlgorithm
strHashAlg = objXen.HashAlgorithm
MsgBox strHashAlg, vbOKOnly, "HashAlgorithm"

' set the HashAlgorithm
objXen.HashAlgorithm = "MD5"
' alternatively, objXen.HashAlgorithm = "1.2.840.113549.1.1.4"

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::KeySpec

Platform SDK: Security

ICEnroll::KeySpec [C++]

CEnroll.KeySpec [Visual Basic]

The KeySpec property is used to specify the type of key generated. Valid values are determined by the cryptographic service provider (CSP) in use.

[Visual Basic]
objEnroll.KeySpec [ = Spec ]
[C++]
HRESULT put_KeySpec(DWORD Spec);
HRESULT get_KeySpec(DWORD *pSpec);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Spec
Value assigned to the KeySpec property. The data type is a DWORD in C++, and a Long in Visual Basic. The value of this property depends on the CSP in use. See Remarks for details.

Note In Windows Whistler, the C++ data type for this parameter has changed to LONG.

[C++] pSpec
Pointer to retrieved property value.

Note In Windows Whistler, the data type for this parameter has changed to LONG*.

Remarks

For the Microsoft Base Cryptographic Provider, the KeySpec property has a value of AT_KEYEXCHANGE for exchange keys, or AT_SIGNATURE for signature keys. The default is AT_SIGNATURE.

For information on the other Microsoft CSPs, see Cryptographic Service Providers in the CryptoAPI 2.0 documentation.

For information on other CSPs, see the documentation provided with the CSP.

KeySpec affects the behavior of the following methods:

  • createPKCS10
  • createFilePKCS10

Example Code [C++]

DWORD    dwKeySpec;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll interface pointer

// get the KeySpec value
hr = pEnroll->get_KeySpec( &dwKeySpec );
if (FAILED( hr ))
    printf("Failed get_KeySpec - %x\n", hr );
else
    printf( "KeySpec: %d\n", dwKeySpec );

// set the KeySpec value
hr = pEnroll->put_KeySpec( AT_KEYEXCHANGE );
if (FAILED( hr ))
    printf("Failed put_KeySpec - %x\n", hr );
else
    printf( "KeySpec set to %d\n", AT_KEYEXCHANGE );

Example Code [Visual Basic]

Const AT_KEYEXCHANGE As Long = 1

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim nKeySpec As Long

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' retrieve and display the KeySpec
nKeySpec = objXen.KeySpec
MsgBox nKeySpec, vbOKOnly, "KeySpec"

' set the KeySpec
objXen.KeySpec = AT_KEYEXCHANGE

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::MyStoreFlags

Platform SDK: Security

ICEnroll::MyStoreFlags [C++]

CEnroll.MyStoreFlags [Visual Basic]

The MyStoreFlags property value sets the registry location used for the MY store. The default value for MyStoreFlags is CERT_SYSTEM_STORE_CURRENT_USER.

[Visual Basic]
objEnroll.MyStoreFlags [ = Flags ]
[C++]
HRESULT put_MyStoreFlags(DWORD Flags);
HRESULT get_MyStoreFlags(DWORD *pFlags);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Flags
Value assigned to the MyStoreFlags property. The data type is a DWORD in C++, and a Long in Visual Basic. The value indicates the relative path of the registry location used for the MY store, and is one of the following values:
  • CERT_SYSTEM_STORE_CURRENT_USER
  • CERT_SYSTEM_STORE_LOCAL_MACHINE
  • CERT_SYSTEM_STORE_SERVICES
  • CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
  • CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY

Note In Windows Whistler, the C++ data type for this parameter has changed to LONG.

[C++] pFlags
Pointer to retrieved property value.

Note In Windows Whistler, the data type for this parameter has changed to LONG*.

Remarks

The MyStoreFlags property value is passed to the CertOpenStore CryptoAPI function via its dwFlags parameter.

MyStoreFlags should be set before using the following methods:

  • acceptPKCS7
  • acceptFilePKCS7

Example Code [C++]

DWORD    dwFlags;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll interface pointer

// retrieve the flag value
hr = pEnroll->get_MyStoreFlags( &dwFlags );
if ( FAILED ( hr ) )
    printf("Failed retrieving MyStoreFlags - %x\n", hr );
else
    printf("MyStoreFlags is %x\n", dwFlags );

// set the flag
hr = pEnroll->put_MyStoreFlags( CERT_SYSTEM_STORE_LOCAL_MACHINE );
if ( FAILED ( hr ) )
    printf("Failed updating MyStoreFlags - %x\n", hr );
else
    printf("Updated MyStoreFlags\n");

Example Code [Visual Basic]

Const CERT_SYSTEM_STORE_LOCAL_MACHINE As Long = &H20000

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim flags As Long

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' retrieve and display the MyStoreFlags value
flags = objXen.MyStoreFlags
MsgBox flags, vbOKOnly, "MyStoreFlags"

' set the MyStoreFlags value
objXen.MyStoreFlags = CERT_SYSTEM_STORE_LOCAL_MACHINE

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::MyStoreName

Platform SDK: Security

ICEnroll::MyStoreName [C++]

CEnroll.MyStoreName [Visual Basic]

The MyStoreName property specifies where certificates with linked private keys are kept. The value of MyStoreName specifies the store in which to place the new certificate produced from acceptPKCS7 or acceptFilePKCS7. By default, this is set to the "MY" system store.

[Visual Basic]
objEnroll.MyStoreName [ = Name ]
[C++]
HRESULT put_MyStoreName(BSTR Name);
HRESULT get_MyStoreName(BSTR *pName);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Name
The string value assigned to the MyStoreName property. It can be any defined store name, such as one of the following:
  • "MY" (the default)
  • "CA"
  • "ROOT"
[C++] pName
Pointer to retrieved property value.

Remarks

MyStoreName affects the behavior of the following methods:

  • acceptPKCS7
  • acceptFilePKCS7

Example Code [C++]

BSTR     bstrStoreName = NULL;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll interface pointer

// get the storename
hr = pEnroll->get_MyStoreName( &bstrStoreName );
if ( FAILED ( hr ) )
    printf("Failed getting MyStoreName - %x\n", hr );
else
    printf( "MyStoreName: %ws\n", bstrStoreName );
// free BSTR when done
if ( NULL != bstrStoreName )
    SysFreeString( bstrStoreName );

// set the storename
// bstrNewName previously set to a valid store name
hr = pEnroll->put_MyStoreName( bstrNewName );
if ( FAILED ( hr ) )
    printf("Failed setting MyStoreName - %x\n", hr );
else
    printf( "MyStoreName was set to : %ws\n", bstrNewName );

Example Code [Visual Basic]

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim strStoreName As String

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' retrieve and display the MyStoreName
strStoreName = objXen.MyStoreName
MsgBox strStoreName, vbOKOnly, "MyStoreName"

' set the MyStoreName
' (strOtherStoreName previously set to a valid store name)
objXen.MyStoreName = strOtherStoreName

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::MyStoreType

Platform SDK: Security

ICEnroll::MyStoreType [C++]

CEnroll.MyStoreType [Visual Basic]

The MyStoreType property specifies the type of store to use for the store specified by the MyStoreName property. The value for MyStoreType is passed directly on to CertOpenStore. By default, this value is sz_CERT_STORE_PROV_SYSTEM.

Currently only system stores are supported.

[Visual Basic]
objEnroll.MyStoreType [ = Type ]
[C++]
HRESULT put_MyStoreType(BSTR Type);
HRESULT get_MyStoreType(BSTR *pType);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Type
The string value assigned to the MyStoreType property. It is one of the following currently supported store provider types:
Store Provider Type | Value
sz_CERT_STORE_PROV_SYSTEM_W | "System"
sz_CERT_STORE_PROV_SYSTEM | "System"

[C++] pType
Pointer to retrieved property value.

Remarks

MyStoreType affects the behavior of the following methods:

  • acceptPKCS7
  • acceptFilePKCS7

Example Code [C++]

BSTR     bstrStoreType = NULL;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll interface pointer

// get the storetype
hr = pEnroll->get_MyStoreType( &bstrStoreType );
if ( FAILED ( hr ) )
    printf("Failed getting MyStoreType - %x\n", hr );
else
    printf( "MyStoreType: %ws\n", bstrStoreType );
// free BSTR when done
if ( NULL != bstrStoreType )
    SysFreeString( bstrStoreType );

// set the storetype
// bstrNewType previously set to a valid store type
hr = pEnroll->put_MyStoreType( bstrNewType );
if ( FAILED ( hr ) )
    printf("Failed setting MyStoreType - %x\n", hr );
else
    printf( "MyStoreType was set to %ws\n", bstrNewType );

Example Code [Visual Basic]

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim strStoreType As String

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' retrieve and display the MyStoreType
strStoreType = objXen.MyStoreType
MsgBox strStoreType, vbOKOnly, "MyStoreType"

' set the MyStoreType
' (strNewType previously set to a valid store type)
objXen.MyStoreType = strNewType

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::ProviderFlags

Platform SDK: Security

ICEnroll::ProviderFlags [C++]

CEnroll.ProviderFlags [Visual Basic]

The ProviderFlags property is passed to the CryptAcquireContext CryptoAPI function. Valid values are determined by the cryptographic service provider (CSP) in use; the default value is zero.

[Visual Basic]
objEnroll.ProviderFlags [ = Flags ]
[C++]
HRESULT put_ProviderFlags(DWORD Flags);
HRESULT get_ProviderFlags(DWORD *pFlags);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Flags
Value assigned to the ProviderFlags property. The data type is a DWORD in C++, and a Long in Visual Basic. Valid values for this property are determined by the CSP in use.

Note In Windows Whistler, the C++ data type for this parameter has changed to LONG.

[C++] pFlags
Pointer to retrieved property value.

Note In Windows Whistler, the data type for this parameter has changed to LONG*.

Remarks

For details on the valid ProviderFlags values for the Microsoft Base Cryptographic Provider, see the CryptAcquireContext CryptoAPI function.

For information on other CSPs, see the documentation provided with the CSP.

The ProviderFlags property value is passed to CryptAcquireContext via its dwFlags parameter.

ProviderFlags affects the behavior of the following methods:

  • createPKCS10
  • createFilePKCS10

Example Code [C++]

DWORD    dwProvFlags;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll interface pointer
// get the ProviderFlags value
hr = pEnroll->get_ProviderFlags( &dwProvFlags );
if (FAILED( hr ))
    printf("Failed get_ProviderFlags - %x\n", hr );
else
    printf( "ProviderFlags: %d\n", dwProvFlags );

// Set the ProviderFlags value.
hr = pEnroll->put_ProviderFlags(CRYPT_MACHINE_KEYSET);
if (FAILED( hr ))
    printf("Failed put_ProviderFlags - %x\n", hr );
else
    printf( "ProviderFlags set to %d\n", CRYPT_MACHINE_KEYSET  );

Example Code [Visual Basic]

Const CRYPT_MACHINE_KEYSET As Long = &H20

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim ProvFlags As Long

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' Retrieve and display the ProviderFlags.
ProvFlags = objXen.ProviderFlags
MsgBox ProvFlags, vbOKOnly, "ProviderFlags"

' set the ProviderFlags
objXen.ProviderFlags = CRYPT_MACHINE_KEYSET

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::ProviderName

Platform SDK: Security

ICEnroll::ProviderName [C++]

CEnroll.ProviderName [Visual Basic]

The ProviderName property specifies the cryptographic service provider (CSP) to use. If one has not been specified, the default provider is Microsoft Base Cryptographic Provider, and the ProviderName will be an empty string.

[Visual Basic]
objEnroll.ProviderName [ = Name ]
[C++]
HRESULT put_ProviderName(BSTR Name);
HRESULT get_ProviderName(BSTR *pName);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Name
The string value assigned to the ProviderName property. Is any valid provider name.
[C++] pName
Pointer to retrieved property value.

Remarks

ProviderName affects the behavior of the following methods:

  • createPKCS10
  • createFilePKCS10
  • enumContainers

Example Code [C++]

BSTR     bstrProvName = NULL;
BSTR     bstrMyProvName = NULL;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll interface pointer

// get the ProviderName
hr = pEnroll->get_ProviderName( &bstrProvName );
if (FAILED( hr ))
    printf("Failed get_ProviderName - %x\n", hr );
else
    printf( "ProviderName: %ws\n", bstrProvName );
// free BSTR when done
if ( NULL != bstrProvName )
    SysFreeString( bstrProvName );

// set the ProviderName value
bstrMyProvName = SysAllocString(TEXT("Microsoft Base DSS")
                                TEXT(" Cryptographic Provider"));
hr = pEnroll->put_ProviderName( bstrMyProvName );
if (FAILED( hr ))
    printf("Failed put_ProviderName - %x\n", hr );
else
    printf( "ProviderName set to %ws\n", bstrMyProvName );
// free BSTR when done
if ( NULL != bstrMyProvName )
    SysFreeString( bstrMyProvName );

Example Code [Visual Basic]

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim strProvName As String

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' retrieve and display the ProviderName
strProvName = objXen.ProviderName
MsgBox strProvName, vbOKOnly, "ProviderName"

' set the ProviderName
objXen.ProviderName = "Microsoft Base DSS" _
                    & " and Diffie-Hellman" _
                    & " Cryptographic Provider"

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::ProviderType

Platform SDK: Security

ICEnroll::ProviderType [C++]

CEnroll.ProviderType [Visual Basic]

The ProviderType property specifies the type of provider. The value for this property is passed to the CryptAcquireContext CryptoAPI function. Valid values are determined by the cryptographic service provider (CSP) in use; the default value is one.

[Visual Basic]
objEnroll.ProviderType [ = Type ]
[C++]
HRESULT put_ProviderType(DWORD Type);
HRESULT get_ProviderType(DWORD *pType);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Type
The value assigned to the ProviderType property. Valid values for this property are determined by the CSP in use.

Note In Windows Whistler, the C++ data type for this parameter has changed to LONG.

[C++] pType
Pointer to retrieved property value.

Note In Windows Whistler, the data type for this parameter has changed to LONG*.

Remarks

For general information on provider types, see Cryptographic Provider Types.

For details on valid values for the Microsoft Base Cryptographic Provider, see the CryptAcquireContext CryptoAPI function.

For provider type information for other CSPs, see the documentation provided with the CSP.

The ProviderType property value is passed to CryptAcquireContext via its dwProvType parameter.

ProviderType affects the behavior of the following methods:

  • createPKCS10
  • createFilePKCS10
  • enumProviders

Example Code [C++]

DWORD    dwProvType;
HRESULT  hr;

// Get the ProviderType value.
// pEnroll is previously instantiated ICEnroll interface pointer
hr = pEnroll->get_ProviderType(&dwProvType);
if (FAILED( hr ))
    printf("Failed get_ProviderType - %x\n", hr);
else
    printf("ProviderType: %d\n", dwProvType);

// Set the ProviderType value.
hr = pEnroll->put_ProviderType(PROV_MS_EXCHANGE);
if (FAILED(hr))
    printf("Failed put_ProviderType - %x\n", hr);
else
    printf("ProviderType set to %d\n", PROV_MS_EXCHANGE);

Example Code [Visual Basic]

Const PROV_MS_EXCHANGE As Long = 5

' Declare Certificate Enrollment Control object
Dim objXen As Object

Dim ProvType As Long

' Create the object.
Set objXen = CreateObject("CEnroll.CEnroll.1")

' Retrieve and display the ProviderType.
ProvType = objXen.ProviderType
MsgBox ProvType, vbOKOnly, "ProviderType"

' Set the ProviderType.
objXen.ProviderType = PROV_MS_EXCHANGE

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::PVKFileName

Platform SDK: Security

ICEnroll::PVKFileName [C++]

CEnroll.PVKFileName [Visual Basic]

The PVKFileName property contains the name of the file that will contain exported keys.

[Visual Basic]
objEnroll.PVKFileName [ = FileName ]
[C++]
HRESULT put_PVKFileName(BSTR FileName);
HRESULT get_PVKFileName(BSTR *pFileName);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] FileName
The string value assigned to the PVKFileName property. It can be any valid filename supported by your operating system.
[C++] pFileName
Pointer to retrieved property value.

Remarks

PVKFileName affects the behavior of the following methods:

  • createPKCS10
  • createFilePKCS10

Exporting functionality may not be supported by your cryptographic service provider (CSP). Historically, Authenticode has exported the private key to a .pvk file on a disk and removed the keys from the registry. By default, private keys are not generated for exportation, and many cryptographic service providers do not support exporting keys. However, if the cryptographic service provider supports exporting private keys, specifying a non-NULL value for the PVKFileName property causes the private keys to be generated as exportable and the private and public key to be written to the file specified by the PVKFileName property. The private key is removed from the CSP. The filename specified by the property can be any accessible file. By default, no .pvk file is generated and the keys are not generated as exportable.

If the .pvk file already exists, the user is notified and prompted for permission to overwrite it.

The GenKeyFlags property also has a flag that controls whether the private key can be exported. Use care when utilizing the GenKeyFlags property and the PVKFileName property together. If the PVKFileName property is set first, the GenKeyFlags property is automatically set to CRYPT_EXPORTABLE. If the GenKeyFlags property is set (using the put_GenKeyFlags function) without including the CRYPT_EXPORTABLE flag, then the GenKeyFlags will not be set to CRYPT_EXPORTABLE and the generated keys will not be exportable. The following example demonstrates this:

  1. Call put_PVKFileName to set the filename for the file that will receive the exported keys. The GenKeyFlags property is automatically set to CRYPT_EXPORTABLE.
  2. Call put_GenKeyFlags with a value not set to CRYPT_EXPORTABLE; for example, zero.
  3. GenKeyFlags is no longer set to CRYPT_EXPORTABLE (the value that was automatically set in step one).

Any keys generated following the previous steps will be not exportable. Therefore, it is recommended that the user set the GenKeyFlags property before the PVKFileName property when they are used together.

Alternatively, the user could determine the current value of the CRYPT_EXPORTABLE bit in the GenKeyFlags property, and then OR this value into any changes that are made to the GenKeyFlags property to ensure that the bit is not wiped out. The user could also specifically set the CRYPT_EXPORTABLE bit when updating the GenKeyFlags property.

Example Code [C++]

BSTR     bstrPVKFile = NULL;
BSTR     bstrNewPVKFile = NULL;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll interface pointer

// get the PVKFileName
hr = pEnroll->get_PVKFileName( &bstrPVKFile );
if (FAILED( hr ))
    printf("Failed get_PVKFileName - %x\n", hr );
else
    printf( "PVKFileName: %ws\n", bstrPVKFile );
// free BSTR when done
if ( NULL != bstrPVKFile )
    SysFreeString( bstrPVKFile );

// set the PVKFileName
bstrNewPVKFile = SysAllocString(TEXT("MyKeys.pvk"));

hr = pEnroll->put_PVKFileName( bstrNewPVKFile );
if (FAILED( hr ))
    printf("Failed put_PVKFileName - %x\n", hr );
else
    printf( "PVKFileName set to %ws\n", bstrNewPVKFile );
// free BSTR when done
if ( NULL != bstrNewPVKFile )
    SysFreeString( bstrNewPVKFile );

Example Code [Visual Basic]

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim strPVKFile As String

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' retrieve and display the PVKFileName
strPVKFile = objXen.PVKFileName
MsgBox strPVKFile, vbOKOnly, "PVKFileName"

' set the PVKFileName
objXen.PVKFileName = "MyFile.PVK"

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::RequestStoreFlags

Platform SDK: Security

ICEnroll::RequestStoreFlags [C++]

CEnroll.RequestStoreFlags [Visual Basic]

The RequestStoreFlags property value sets the registry location used for the REQUEST store. The default value for RequestStoreFlags is CERT_SYSTEM_STORE_CURRENT_USER.

[Visual Basic]
objEnroll.RequestStoreFlags [ = Flags ]
[C++]
HRESULT put_RequestStoreFlags(DWORD Flags);
HRESULT get_RequestStoreFlags(DWORD *pFlags);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Flags
Value assigned to the RequestStoreFlags property. The data type is a DWORD in C++, and a Long in Visual Basic. The value indicates the relative path of the registry location used for the REQUEST store, and is one of the following values:
  • CERT_SYSTEM_STORE_CURRENT_USER
  • CERT_SYSTEM_STORE_LOCAL_MACHINE
  • CERT_SYSTEM_STORE_SERVICES
  • CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
  • CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY

Note In Windows Whistler, the C++ data type for this parameter has changed to LONG.

[C++] pFlags
Pointer to retrieved property value.

Note In Windows Whistler, the data type for this parameter has changed to LONG*.

Remarks

The RequestStoreFlags property value is passed to the CertOpenStore CryptoAPI function via its dwFlags parameter.

Typically, modification of the RequestStoreFlags property is only performed in advanced applications. RequestStoreFlags should be set before using the following methods:

  • acceptPKCS7
  • acceptFilePKCS7
  • createPKCS10
  • createFilePKCS10

Example Code [C++]

DWORD    dwFlags;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll interface pointer

// retrieve the flag value
hr = pEnroll->get_RequestStoreFlags( &dwFlags );
if ( FAILED ( hr ) )
    printf("Failed retrieving RequestStoreFlags - %x\n", hr );
else
    printf("RequestStoreFlags is %x\n", dwFlags );

// set the flag
hr = pEnroll->put_RequestStoreFlags( CERT_SYSTEM_STORE_LOCAL_MACHINE );
if ( FAILED ( hr ) )
    printf("Failed updating RequestStoreFlags - %x\n", hr );
else
    printf("Updated RequestStoreFlags\n");

Example Code [Visual Basic]

Const CERT_SYSTEM_STORE_LOCAL_MACHINE As Long = &H20000

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim flags As Long

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' retrieve and display the RequestStoreFlags value
flags = objXen.RequestStoreFlags
MsgBox flags, vbOKOnly, "RequestStoreFlags"

' set the RequestStoreFlags value
objXen.RequestStoreFlags = CERT_SYSTEM_STORE_LOCAL_MACHINE

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::RequestStoreName

Platform SDK: Security

ICEnroll::RequestStoreName [C++]

CEnroll.RequestStoreName [Visual Basic]

The RequestStoreName property specifies where to store the dummy certificate with the added private keys until a certification authority processes the request and responds with a PKCS #7. By default the "REQUEST" system store is used. If the default is not to be used, this property must be set to the store to be used before calls to createPKCS10 /createFilePKCS10 and again before calls to acceptPKCS7 /acceptFilePKCS7.

Typically, modification of the RequestStoreName property is only performed in advanced applications; changing this value is not recommended for most applications.

[Visual Basic]
objEnroll.RequestStoreName [ = Name ]
[C++]
HRESULT put_RequestStoreName(BSTR Name);
HRESULT get_RequestStoreName(BSTR *pName);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Name
The string value assigned to the RequestStoreName property. It can be any defined store name, such as one of the following:
  • "REQUEST" (the default)
  • "ROOT"
  • "CA"
  • "MY"
[C++] pName
Pointer to retrieved property value.

Remarks

RequestStoreName affects the behavior of the following methods:

  • acceptPKCS7
  • acceptFilePKCS7
  • createPKCS10
  • createFilePKCS10

Example Code [C++]

BSTR     bstrStoreName = NULL;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll interface pointer

// get the storename
hr = pEnroll->get_RequestStoreName( &bstrStoreName );
if ( FAILED ( hr ) )
    printf("Failed getting RequestStoreName - %x\n", hr );
else
    printf( "RequestStoreName: %ws\n", bstrStoreName );
// free BSTR when done
if ( NULL != bstrStoreName )
    SysFreeString( bstrStoreName );

// set the storename
// bstrNewName previously set to a valid store name
hr = pEnroll->put_RequestStoreName( bstrNewName );
if ( FAILED ( hr ) )
    printf("Failed setting RequestStoreName - %x\n", hr );
else
    printf( "RequestStoreName was set to : %ws\n", bstrNewName );

Example Code [Visual Basic]

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim strStoreName As String

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' retrieve and display the RequestStoreName
strStoreName = objXen.RequestStoreName
MsgBox strStoreName, vbOKOnly, "RequestStoreName"

' set the RequestStoreName
' (strOtherStoreName previously set to a valid store name)
objXen.RequestStoreName = strOtherStoreName

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::RequestStoreType

Platform SDK: Security

ICEnroll::RequestStoreType [C++]

CEnroll.RequestStoreType [Visual Basic]

The RequestStoreType property specifies the type of store to use for the store specified by the RequestStoreName property. The value for RequestStoreType is passed directly on to CertOpenStore. By default RequestStoreType's value is sz_CERT_STORE_PROV_SYSTEM. If the default is not to be used, this property must be set to the same value before calls to createPKCS10 /createFilePKCS10 and again before calls to acceptPKCS7 /acceptFilePKCS7.

Currently only system stores are supported.

Typically, modification of the RequestStoreType property is only performed in advanced applications.

[Visual Basic]
objEnroll.RequestStoreType [ = Type ]
[C++]
HRESULT put_RequestStoreType(BSTR Type);
HRESULT get_RequestStoreType(BSTR *pType);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Type
The string value assigned to the RequestStoreType property. It is one of the following currently supported store provider types:
Store Provider Type | Value
sz_CERT_STORE_PROV_SYSTEM_W | "System"
sz_CERT_STORE_PROV_SYSTEM | "System"

[C++] pType
Pointer to retrieved property value.

Remarks

RequestStoreType affects the behavior of the following methods:

  • acceptPKCS7
  • acceptFilePKCS7
  • createPKCS10
  • createFilePKCS10

Example Code [C++]

BSTR     bstrStoreType = NULL;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll interface pointer

// get the storetype
hr = pEnroll->get_RequestStoreType( &bstrStoreType );
if ( FAILED ( hr ) )
    printf("Failed getting RequestStoreType - %x\n", hr );
else
    printf( "RequestStoreType: %ws\n", bstrStoreType );
// free BSTR when done
if ( NULL != bstrStoreType )
    SysFreeString( bstrStoreType );

// set the storetype
// bstrNewType previously set to a valid store type
hr = pEnroll->put_RequestStoreType( bstrNewType );
if ( FAILED ( hr ) )
    printf("Failed setting RequestStoreType - %x\n", hr );
else
    printf( "RequestStoreType was set to %ws\n", bstrNewType );

Example Code [Visual Basic]

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim strStoreType As String

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' retrieve and display the RequestStoreType
strStoreType = objXen.RequestStoreType
MsgBox strStoreType, vbOKOnly, "RequestStoreType"

' set the RequestStoreType
' (strNewType previously set to a valid store type)
objXen.RequestStoreType = strNewType

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::RootStoreFlags

Platform SDK: Security

ICEnroll::RootStoreFlags [C++]

CEnroll.RootStoreFlags [Visual Basic]

The RootStoreFlags property value sets the registry location used for the ROOT store. The default value for MyStoreFlags is CERT_SYSTEM_STORE_CURRENT_USER.

[Visual Basic]
objEnroll.RootStoreFlags [ = Flags ]
[C++]
HRESULT put_RootStoreFlags(DWORD Flags);
HRESULT get_RootStoreFlags(DWORD *pFlags);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Flags
Value assigned to the RootStoreFlags property. The data type is a DWORD in C++, and a Long in Visual Basic. It is one of the following values:
  • CERT_SYSTEM_STORE_CURRENT_USER
  • CERT_SYSTEM_STORE_LOCAL_MACHINE
  • CERT_SYSTEM_STORE_SERVICES
  • CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
  • CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY

Note In Windows Whistler, the C++ data type for this parameter has changed to LONG.

[C++] pFlags
Pointer to retrieved property value.

Note In Windows Whistler, the data type for this parameter has changed to LONG*.

Remarks

The RootStoreFlags property value is passed to the CertOpenStore CryptoAPI function via its dwFlags parameter.

RootStoreFlags should be set before using the following methods:

  • acceptPKCS7
  • acceptFilePKCS7

Example Code [C++]

DWORD    dwFlags;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll interface pointer.

// Retrieve the flag value.
hr = pEnroll->get_RootStoreFlags( &dwFlags );
if ( FAILED ( hr ) )
    printf("Failed retrieving RootStoreFlags - %x\n", hr );
else
    printf("RootStoreFlags is %x\n", dwFlags );

// Set the flag.
hr = pEnroll->put_RootStoreFlags( CERT_SYSTEM_STORE_LOCAL_MACHINE );
if ( FAILED ( hr ) )
    printf("Failed updating RootStoreFlags - %x\n", hr );
else
    printf("Updated RootStoreFlags\n");

Example Code [Visual Basic]

Const CERT_SYSTEM_STORE_LOCAL_MACHINE As Long = &H20000

' Declare Certificate Enrollment Control object.
Dim objXen As Object

Dim flags As Long

' Instantiate the object.
Set objXen = CreateObject("CEnroll.CEnroll.1")

' Retrieve and display the RootStoreFlags value.
flags = objXen.RootStoreFlags
MsgBox flags, vbOKOnly, "RootStoreFlags"

' Set the RootStoreFlags value.
objXen.RootStoreFlags = CERT_SYSTEM_STORE_LOCAL_MACHINE

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::RootStoreName

Platform SDK: Security

ICEnroll::RootStoreName [C++]

CEnroll.RootStoreName [Visual Basic]

The RootStoreName property specifies where all intrinsically trusted self-signed ROOT certificates are kept. By default, this is set to the "ROOT" system store. Because of the level of trust associated with the ROOT store, the user may be prompted (by means of a user interface) to accept the certificate. Although this property need not be changed for many applications, to avoid the user interface associated with trusting ROOT certificates, a possiblity is to set RootStoreName to "CA".

[Visual Basic]
objEnroll.RootStoreName [ = Name ]
[C++]
HRESULT put_RootStoreName(BSTR Name);
HRESULT get_RootStoreName(BSTR *pName);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Name
The string value assigned to the RootStoreName property. It can be any defined store name, such as the following:
  • "ROOT" (the default)
  • "CA"
  • "MY"
[C++] pName
Pointer to retrieved property value.

Remarks

RootStoreName affects the behavior of the following methods:

  • acceptPKCS7
  • acceptFilePKCS7

Example Code [C++]

BSTR     bstrStoreName = NULL;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll interface pointer

// get the storename
hr = pEnroll->get_RootStoreName( &bstrStoreName );
if ( FAILED ( hr ) )
    printf("Failed getting RootStoreName - %x\n", hr );
else
    printf( "RootStoreName: %ws\n", bstrStoreName );
// free BSTR when done
if ( NULL != bstrStoreName )
    SysFreeString( bstrStoreName );

// set the storename
// bstrNewName previously set to a valid store name
hr = pEnroll->put_RootStoreName( bstrNewName );
if ( FAILED ( hr ) )
    printf("Failed setting RootStoreName - %x\n", hr );
else
    printf( "RootStoreName was set to : %ws\n", bstrNewName );

Example Code [Visual Basic]

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim strStoreName As String

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' retrieve and display the RootStoreName
strStoreName = objXen.RootStoreName
MsgBox strStoreName, vbOKOnly, "RootStoreName"

' set the RootStoreName
' (strOtherStoreName previously set to a valid store name)
objXen.RootStoreName = strOtherStoreName

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::RootStoreType

Platform SDK: Security

ICEnroll::RootStoreType [C++]

CEnroll.RootStoreType [Visual Basic]

The RootStoreType property specifies the type of store to use for the store specified by the RootStoreName property. The value for RootStoreType is passed directly on to CertOpenStore. By default, this value is sz_CERT_STORE_PROV_SYSTEM.

Currently only system stores are supported.

[Visual Basic]
objEnroll.RootStoreType [ = Type ]
[C++]
HRESULT put_RootStoreType(BSTR Type);
HRESULT get_RootStoreType(BSTR *pType);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Type
The string value assigned to the RootStoreType property. It is one of the following currently supported store provider types:
Store Provider Type | Value
sz_CERT_STORE_PROV_SYSTEM_W | "System"
sz_CERT_STORE_PROV_SYSTEM | "System"

[C++] pType
Pointer to retrieved property value.

Remarks

RootStoreType affects the behavior of the following methods:

  • acceptPKCS7
  • acceptFilePKCS7

Example Code [C++]

BSTR     bstrStoreType = NULL;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll interface pointer

// get the storetype
hr = pEnroll->get_RootStoreType( &bstrStoreType );
if ( FAILED ( hr ) )
    printf("Failed getting RootStoreType - %x\n", hr );
else
    printf( "RootStoreType: %ws\n", bstrStoreType );
// free BSTR when done
if ( NULL != bstrStoreType )
    SysFreeString( bstrStoreType );

// set the storetype
// bstrNewType previously set to a valid store type
hr = pEnroll->put_RootStoreType( bstrNewType );
if ( FAILED ( hr ) )
    printf("Failed setting RootStoreType - %x\n", hr );
else
    printf( "RootStoreType was set to %ws\n", bstrNewType );

Example Code [Visual Basic]

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim strStoreType As String

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' retrieve and display the RootStoreType
strStoreType = objXen.RootStoreType
MsgBox strStoreType, vbOKOnly, "RootStoreType"

' set the RootStoreType
' (strNewType previously set to a valid store type)
objXen.RootStoreType = strNewType

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::SPCFileName

Platform SDK: Security

ICEnroll::SPCFileName [C++]

CEnroll.SPCFileName [Visual Basic]

The SPCFileName property specifies a file to write the resulting base64-encoded PKCS #7 (in BSTR form) as returned from the certification authority. The file is written as a binary PKCS #7. Specifying this file does not affect the acceptance of the certificates into any of the user's stores.

If the file already exists, the user is notified, and prompted for permission to overwrite.

[Visual Basic]
objEnroll.SPCFileName [ = FileName ]
[C++]
HRESULT put_SPCFileName(BSTR FileName);
HRESULT get_SPCFileName(BSTR *pFileName);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] FileName
The string value assigned to the SPCFileName property. It can be any valid filename supported by your operating system.
[C++] pFileName
Pointer to retrieved property value.

Remarks

SPCFileName affects the behavior of the following methods:

  • acceptPKCS7
  • acceptFilePKCS7

Example Code [C++]

BSTR     bstrSPCFile = NULL;
BSTR     bstrNewSPCFile = NULL;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll interface pointer

// get the SPCFileName
hr = pEnroll->get_SPCFileName( &bstrSPCFile );
if (FAILED( hr ))
    printf("Failed get_SPCFileName - %x\n", hr );
else
    printf( "SPCFileName: %ws\n", bstrSPCFile );
// free BSTR when done
if ( NULL != bstrSPCFile )
    SysFreeString( bstrSPCFile );

// set the SPCFileName
bstrNewSPCFile = SysAllocString(TEXT("MyFile.SPC"));

hr = pEnroll->put_SPCFileName( bstrNewSPCFile );
if (FAILED( hr ))
    printf("Failed put_SPCFileName - %x\n", hr );
else
    printf( "SPCFileName set to %ws\n", bstrNewSPCFile );
// free BSTR when done
if ( NULL != bstrNewSPCFile )
    SysFreeString( bstrNewSPCFile );

Example Code [Visual Basic]

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim strSPCFile As String

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' retrieve and display the SPCFileName
strSPCFile = objXen.SPCFileName
MsgBox strSPCFile, vbOKOnly, "SPCFileName"

' set the SPCFileName
objXen.SPCFileName = "MyFile.SPC"

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::UseExistingKeySet

Platform SDK: Security

ICEnroll::UseExistingKeySet [C++]

CEnroll.UseExistingKeySet [Visual Basic]

The UseExistingKeySet property must be set to TRUE if an existing key set is used instead of generating a new one. By default, this property value is FALSE.

[Visual Basic]
objEnroll.UseExistingKeySet [ = bValue ]
[C++]
HRESULT put_UseExistingKeySet(BOOL bValue);
HRESULT get_UseExistingKeySet(BOOL *pbValue);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] bValue
A boolean value assigned to the UseExistingKeySet property. It is one of the following values:
  • TRUE
  • FALSE (the default)
[C++] pbValue
Pointer to retrieved property value.

Remarks

UseExistingKeySet affects the behavior of the following methods:

  • createPKCS10
  • createFilePKCS10

Example Code [C++]

BOOL     bUEKS;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll interface pointer

// get the UseExistingKeySet value
hr = pEnroll->get_UseExistingKeySet( &bUEKS );
if (FAILED( hr ))
    printf("Failed get_UseExistingKeySet - %x\n", hr );
else
    printf( "UseExistingKeySet: %d\n", bUEKS );

// set the UseExistingKeySet value
hr = pEnroll->put_UseExistingKeySet( TRUE );
if (FAILED( hr ))
    printf("Failed put_UseExistingKeySet - %x\n", hr );
else
    printf( "UseExistingKeySet set to TRUE\n" );

Example Code [Visual Basic]

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim bUseExistKS As Boolean

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' retrieve and display the UseExistingKeySet value
bUseExistKS = objXen.UseExistingKeySet
MsgBox bUseExistKS, vbOKOnly, "UseExistingKeySet"

' set the UseExistingKeySet value
objXen.UseExistingKeySet = True

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll::WriteCertToCSP

Platform SDK: Security

ICEnroll::WriteCertToCSP [C++]

CEnroll.WriteCertToCSP [Visual Basic]

The WriteCertToCSP property specifies whether a certificate should be written to the cryptographic service provider (CSP). This is typically used with smart cards, where the certificate is written to the smart card in addition to being written to the "MY" store.

The default value is TRUE, meaning that the Certificate Enrollment Control will try to write the certificate to the CSP; but will not fail unless a hardware token error is encountered. (If this value is TRUE, but no smart card or other hardware-dependent CSP is installed, then hardware token errors will be ignored).

To explicitly force that the Certificate Enrollment Control not attempt to write to the CSP, set this value to FALSE.

[Visual Basic]
objEnroll.WriteCertToCSP [ = bValue ]
[C++]
HRESULT put_WriteCertToCSP(BOOL bValue);
HRESULT get_WriteCertToCSP(BOOL *pbValue);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] bValue
A boolean value assigned to the WriteCertToCSP property. It is one of the following values:
  • TRUE (the default)
  • FALSE
[C++] pbValue
Pointer to retrieved property value.

Remarks

WriteCertToCSP affects the behavior of the following methods:

  • acceptPKCS7
  • acceptFilePKCS7

Example Code [C++]

BOOL     bWriteCSP;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll interface pointer

// get the WriteCertToCSP value
hr = pEnroll->get_WriteCertToCSP( &bWriteCSP );
if (FAILED( hr ))
    printf("Failed get_WriteCertToCSP - %x\n", hr );
else
    printf( "WriteCertToCSP: %d\n", bWriteCSP );

// set the WriteCertToCSP value
hr = pEnroll->put_WriteCertToCSP( TRUE );
if (FAILED( hr ))
    printf("Failed put_WriteCertToCSP - %x\n", hr );
else
    printf( "WriteCertToCSP set to TRUE\n" );

Example Code [Visual Basic]

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim bWriteCSP As Boolean

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' retrieve and display the WriteCertToCSP value
bWriteCSP = objXen.WriteCertToCSP
MsgBox bWriteCSP, vbOKOnly, "WriteCertToCSP"

' set the WriteCertToCSP value
objXen.WriteCertToCSP = True

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 with the Windows NT 4.0 Option Pack).
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll2

[Visual Basic] The ICEnroll2 interface is an interface of the CEnroll object. This interface is primarily of interest if you are not using Automation. If, on the other hand, you are programming in Visual Basic or another Automation language, see the CEnroll object for a complete listing of the methods and properties available.

The ICEnroll2 interface is one of three interfaces currently exposed by the CEnroll object, which provides the entire functionality for the Certificate Enrollment Control. Previously, the CEnroll object exposed a single interface, ICEnroll. However, beginning with Microsoft® Windows® 2000 Beta 2, the CEnroll object also supports ICEnroll2.

Because ICEnroll2 inherits all members of the earlier ICEnroll interface, the following tables include those members as well as the additional methods and properties that ICEnroll2 supports.

Additionally, beginning with Microsoft® Windows® 2000 Beta 3, the CEnroll object exposes the ICEnroll3 interface, which inherits and extends the methods and properties of both ICEnroll and ICEnroll2.

Method | Description
acceptFilePKCS7 | Accepts and processes a PKCS #7 containing a certificate. The PKCS #7 is stored in a file. Implemented as ICEnroll::acceptFilePKCS7.
acceptPKCS7 | Accepts and processes a PKCS #7 containing a certificate. The PKCS #7 is input as a parameter. Implemented as ICEnroll::acceptPKCS7.
addCertTypeToRequest | Adds a certificate template to a request (used to support the enterprise certification authority (CA)).
addNameValuePairToSignature | Adds a name/value pair to an attribute (the name/value pair is interpreted by the certification authority ).
createFilePKCS10 | Creates a PKCS #10 reqesting a certificate for the person or entity whose information is supplied in the PKCS #10. This PKCS #10 is saved to a file. Implemented as ICEnroll::createFilePKCS10.
createPKCS10 | Creates a PKCS #10 reqesting a certificate for the person or entity whose information is supplied in the PKCS #10. This PKCS #10 is a return or output parameter. Implemented as ICEnroll::createPKCS10.
enumContainers | Enumerates all the containers for the provider specified in the ProviderName property. Implemented as ICEnroll::enumContainers.
enumProviders | Enumerates all the providers available on the computer for the specified ProviderType property. Implemented as ICEnroll::enumProviders.
freeRequestInfo | Cleans up the stores if an error occurs or if a PKCS #7 is not to be accepted for some reason. Currently not implemented. Implemented as ICEnroll::freeRequestInfo.
getCertFromPKCS7 | Retrieves from a PKCS #7 the single certificate that was issued in response to a PKCS #10. Implemented as ICEnroll::getCertFromPKCS7.

The following properties are provided for the ICEnroll2 interface. For information on using these properties, see Using the Certificate Enrollment Control Properties.

Property | Description
CAStoreFlags [C++] Access: Read/write Data type: DWORD [Visual Basic] Access: Read/write Data type: Long | Passed directly to CertOpenStore, specifying characteristics when opening the certification authority (CA) store. Implemented as ICEnroll::CAStoreFlags.
CAStoreName [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Specifies where all non-"ROOT" and non-"MY" certificates are kept. Implemented as ICEnroll::CAStoreName.
CAStoreType [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Specifies the type of store to use for the store specified by the CAStoreName property. Implemented as ICEnroll::CAStoreType.
ContainerName [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Specifies the name of the key container to use. Implemented as ICEnroll::ContainerName.
DeleteRequestCert [C++] Access: Read/write Data type: BOOL [Visual Basic] Access: Read/write Data type: Boolean | Controls whether a dummy certificate is deleted — a dummy certificate created to persist the keys generated while the PKCS #10 certificate request is being issued. Implemented as ICEnroll::DeleteRequestCert.
EnableT61DNEncoding [C++] Access: Read/write Data type: BOOL [Visual Basic] Access: Read/write Data type: Boolean | Controls whether the certificate's distinguished name is encoded as a T61 string instead of as a UNICODE string.
GenKeyFlags [C++] Access: Read\write Data type: DWORD [Visual Basic] Access: Read\write Data type: Long | Passed directly to CryptGenKey, specifying characteristics of the key being created. Implemented as ICEnroll::GenKeyFlags.
HashAlgorithm [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies the the preferred hash algorithm for signing the PKCS #10. Implemented as ICEnroll::HashAlgorithm.
KeySpec [C++] Access: Read\write Data type: DWORD [Visual Basic] Access: Read\write Data type: Long | Specifies the key type to be generated. Implemented as ICEnroll::KeySpec.
MyStoreFlags [C++] Access: Read\write Data type: DWORD [Visual Basic] Access: Read\write Data type: Long | Passed directly to CertOpenStore, specifying characteristics when opening the MY store. Implemented as ICEnroll::MyStoreFlags.
MyStoreName [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies where certificates with linked private keys are kept. Implemented as ICEnroll::MyStoreName.
MyStoreType [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies the type of store to use for the store specified by the MyStoreName property. Implemented as ICEnroll::MyStoreType.
ProviderFlags [C++] Access: Read\write Data type: DWORD [Visual Basic] Access: Read\write Data type: Long | Use depends on the provider in use. Implemented as ICEnroll::ProviderFlags.
ProviderName [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies the cryptographic service provider (CSP) to use. Implemented as ICEnroll::ProviderName.
ProviderType [C++] Access: Read\write Data type: DWORD [Visual Basic] Access: Read\write Data type: Long | Use depends on the provider in use. Implemented as ICEnroll::ProviderType.
PVKFileName [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Secifies that the private keys be generated as exportable and written to the file specified by the PVKFileName property. Implemented as ICEnroll::PVKFileName.
RequestStoreFlags [C++] Access: Read\write Data type: DWORD [Visual Basic] Access: Read\write Data type: Long | Passed directly to CertOpenStore, specifying characteristics when opening the REQUEST store. Implemented as ICEnroll::RequestStoreFlags.
RequestStoreName [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies the certificate store used to store the dummy certificate to which the private keys have been added, until a certification authority processes the request and responds with a PKCS #7. Implemented as ICEnroll::RequestStoreName.
RequestStoreType [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies the type of store to use for the store specified by the RequestStoreName property. Implemented as ICEnroll::RequestStoreType.
RootStoreFlags [C++] Access: Read\write Data type: DWORD [Visual Basic] Access: Read\write Data type: Long | Passed directly to CertOpenStore, specifying characteristics when opening the ROOT store. Implemented as ICEnroll::RootStoreFlags.
RootStoreName [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies where all intrinsically trusted, self-signed ROOT certificates are kept. Implemented as ICEnroll::RootStoreName.
RootStoreType [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies the type of store to use for the store specified by the RootStoreName property. Implemented as ICEnroll::RootStoreName.
SPCFileName [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies a file to which to write the PKCS #7 (in BSTR form) returned from the certification authority. Implemented as ICEnroll::SPCFileName.
UseExistingKeySet [C++] Access: Read\write Data type: BOOL [Visual Basic] Access: Read\write Data type: Boolean | Specifies that an existing key set be used, instead of generating a new one (the default value is FALSE). Implemented as ICEnroll::UseExistingKeySet.
WriteCertToCSP [C++] Access: Read\write Data type: BOOL [Visual Basic] Access: Read\write Data type: Boolean | Specifies whether a certificate should be written to the cryptographic service provider. Implemented as ICEnroll::WriteCertToCSP.
WriteCertToUserDS [C++] Access: Read\write Data type: BOOL [Visual Basic] Access: Read\write Data type: Boolean | Specifies whether a certificate is written to the user's Directory Service.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.

See Also

ICEnroll


ICEnroll2::addCertTypeToRequest

Platform SDK: Security

ICEnroll2::addCertTypeToRequest [C++]

CEnroll.addCertTypeToRequest [Visual Basic]

This method is used to add a certificate template to a request. This method is associated with the Microsoft Certificate Services enterprise Policy Module. This method is an advanced topic and its use is not recommended for most applications.

The phrase 'certificate type' is synonymous with 'certificate template'.

[Visual Basic]
objEnroll.addCertTypeToRequest( _
  CertType As String _
)
[C++]
HRESULT addCertTypeToRequest(
  BSTR CertType
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] CertType
[in] The certificate template fully qualified name which is being added to the certificate request; this value is interpreted by the certification authority.

Return Values

[Visual Basic] None.

[C++] The return value is an HRESULT, with S_OK returned if the call is successful.

Remarks

This method can be called multiple times if more than one certificate template is desired for the request.

Example Code [C++]

BSTR    bstrCertType = NULL;
HRESULT hr;

// allocate BSTR for the certificate template
bstrCertType = SysAllocString(L"Machine");

// add the certificate template to the request
// pEnroll is previously instantiated ICEnroll2 interface pointer
hr = pEnroll->addCertTypeToRequest( bstrCertType );

if ( FAILED( hr ) )
    printf("Failed addCertTypeToRequest - %x\n", hr );
else
    printf("addCertTypeToRequest(%ws) succeeded\n", bstrCertType );

// free BSTR
if ( NULL != bstrCertType )
    SysFreeString( bstrCertType );

Example Code [Visual Basic]

' declare Certificate Enrollment Control object
Dim objXen As Object

' variable to contain Cert Template
Dim strCertType As String

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' add a cert type to the request
strCertType = "Machine"
objXen.addCertTypeToRequest strCertType

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll2::addNameValuePairToSignature

Platform SDK: Security

ICEnroll2::addNameValuePairToSignature [C++]

CEnroll.addNameValuePairToSignature [Visual Basic]

This method adds the name and value pair of an attribute to the request. It is up to the CA (CA) to interpret the meaning of the name/value pair.

[Visual Basic]
objEnroll.addNameValuePairToSignature( _
  Name As String, _
  Value As String _
)
[C++]
HRESULT addNameValuePairToSignature(
  BSTR Name,
  BSTR Value
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Name
[in] The name of the attribute, such as "2.5.4.6" for the country/region name.
[Visual Basic,C++] Value
[in] The value of the attribute, such as "US".

Return Values

[Visual Basic] None.

[C++] The return value is an HRESULT, with S_OK returned if the call is successful.

Remarks

Use this function to add attributes to the request.

Example Code [C++]

BSTR    bstrName = NULL;
BSTR    bstrValue = NULL;
HRESULT hr;

// allocate BSTR for the name
bstrName = SysAllocString(TEXT(szOID_COUNTRY_NAME));
// alternatively,bstrName = SysAllocString(L"2.5.4.6");
// allocate BSTR for the value
bstrValue = SysAllocString(L"US");

// add the Name/Value pair to the signature
// pEnroll is previously instantiated ICEnroll2 interface pointer
hr = pEnroll->addNameValuePairToSignature( bstrName, bstrValue );

if ( FAILED( hr ) )
    printf("Failed addNameValuePairToSignature - %x\n", hr );
else
    printf("addNameValuePairToSignature(%ws, %ws) succeeded\n",
            bstrName,
            bstrValue );

// free BSTRs
if ( NULL != bstrName )
    SysFreeString( bstrName );
if ( NULL != bstrValue )
    SysFreeString( bstrValue );

Example Code [Visual Basic]

' declare Certificate Enrollment Control object
Dim objXen As Object

' variables for Name and Value
Dim strName As String
Dim strValue As String

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' add the name/value pair to the signature
' in this case, for the Country/Region name
strName = "2.5.4.6"
strValue = "US"
objXen.addNameValuePairToSignature strName, strValue

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll2::EnableT61DNEncoding

Platform SDK: Security

ICEnroll2::EnableT61DNEncoding [C++]

CEnroll.EnableT61DNEncoding [Visual Basic]

The EnableT61DNEncoding property is used to control whether the distinguished name in the request is encoded as a T61 string instead of as a UNICODE string. A T61 character is 8 bits, hence all UNICODE characters to be encoded must be less than or equal to 0xFF.

[Visual Basic]
objEnroll.EnableT61DNEncoding [ = bValue ]
[C++]
HRESULT put_EnableT61DNEncoding(BOOL bValue);
HRESULT get_EnableT61DNEncoding(BOOL *pbValue);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] bValue
A boolean value assigned to the EnableT61DNEncoding property. It is one of the following values:
  • TRUE
  • FALSE (the default)
[C++] pbValue
Pointer to retrieved property value.

Remarks

EnableT61DNEncoding affects the behavior of the following methods:

  • createPKCS10
  • createFilePKCS10

Example Code [C++]

BOOL     bT61DN;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll2 interface pointer

// get the EnableT61DNEncoding boolean value
hr = pEnroll->get_EnableT61DNEncoding( &bT61DN );
if ( FAILED ( hr ) )
    printf("Failed get_EnableT61DNEncoding - %x\n", hr );
else
    printf( "T61DNEncoding: %s\n",
             ( bT61DN ? "Enabled" : "Disabled" ) );

// set the EnableT61DNEncoding value
hr = pEnroll->put_EnableT61DNEncoding( TRUE );
if ( FAILED ( hr ) )
    printf("Failed Setting EnableT61DNEncoding - %x\n", hr );
else
    printf( "EnableT61DNEncoding was set to TRUE\n" );

Example Code [Visual Basic]

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim bT61DN As Boolean

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' retrieve and display the EnableT61DNEncoding
bT61DN = objXen.EnableT61DNEncoding
MsgBox bT61DN, vbOKOnly, "EnableT61DNEncoding"

' set the EnableT61DNEncoding
objXen.EnableT61DNEncoding = True

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll2::WriteCertToUserDS

Platform SDK: Security

ICEnroll2::WriteCertToUserDS [C++]

CEnroll.WriteCertToUserDS [Visual Basic]

The WriteCertToUserDS property specifies whether the certificate is written to the user's Directory Service store. This property should not need to be modified by most applications.

[Visual Basic]
objEnroll.WriteCertToUserDS [ = bValue ]
[C++]
HRESULT put_WriteCertToUserDS(BOOL bValue);
HRESULT get_WriteCertToUserDS(BOOL *pbValue);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] bValue
A boolean value assigned to the WriteCertToUserDS property. It is one of the following values:
  • TRUE
  • FALSE (the default)
[C++] pbValue
Pointer to retrieved property value.

Remarks

WriteCertToUserDS affects the behavior of the following methods:

  • acceptPKCS7
  • acceptFilePKCS7

Example Code [C++]

BOOL     bWriteUserDS;
HRESULT  hr;

// pEnroll is previously instantiated ICEnroll2 interface pointer

// get the WriteCertToUserDS value
hr = pEnroll->get_WriteCertToUserDS( &bWriteUserDS );
if (FAILED( hr ))
    printf("Failed get_WriteCertToUserDS - %x\n", hr );
else
    printf( "WriteCertToUserDS: %d\n", bWriteUserDS );

// set the WriteCertToUserDS value
hr = pEnroll->put_WriteCertToUserDS( TRUE );
if (FAILED( hr ))
    printf("Failed put_WriteCertToUserDS - %x\n", hr );
else
    printf( "WriteCertToUserDS set to TRUE\n" );

Example Code [Visual Basic]

' declare Certificate Enrollment Control object
Dim objXen As Object

Dim bWriteUserDS As Boolean

' instantiate the object
Set objXen = CreateObject("CEnroll.CEnroll.1")

' retrieve and display the WriteCertToUserDS value
bWriteUserDS = objXen.WriteCertToUserDS
MsgBox bWriteUserDS, vbOKOnly, "WriteCertToUserDS"

' set the WriteCertToUserDS value
objXen.WriteCertToUserDS = True

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll3

[Visual Basic] The ICEnroll3 interface is an interface of the CEnroll object. This interface is primarily of interest if you are not using Automation. If, on the other hand, you are programming in Visual Basic or another Automation language, see the CEnroll object for a complete listing of the methods and properties available.

The ICEnroll3 interface is one of three interfaces currently exposed by the CEnroll object, which provides the entire functionality for the Certificate Enrollment Control. Before Microsoft® Windows® 2000 Beta 3, the CEnroll object exposed two interfaces, ICEnroll and ICEnroll2. However, beginning with Windows 2000 Beta 3, the CEnroll object also supports ICEnroll3.

Because ICEnroll3 inherits all members of the earlier ICEnroll and ICEnroll2 interfaces, the following tables include those members as well as the additional methods and properties that ICEnroll3 supports.

Method | Description
acceptFilePKCS7 | Accepts and processes a PKCS #7 containing a certificate. The PKCS #7 is stored in a file. Implemented as ICEnroll::acceptFilePKCS7.
acceptPKCS7 | Accepts and processes a PKCS #7 containing a certificate. The PKCS #7 is input as a parameter. Implemented as ICEnroll::acceptPKCS7.
addCertTypeToRequest | Adds a certificate template to a request (used to support the enterprise certification authority (CA)). Implemented as ICEnroll2::addCertTypeToRequest.
addNameValuePairToSignature | Adds a name/value pair to an attribute (the name/value pair is interpreted by the CA). Implemented as ICEnroll2::addNameValuePairToSignature.
createFilePKCS10 | Creates a PKCS #10 reqesting a certificate for the person or entity whose information is supplied in the PKCS #10. This PKCS #10 is saved to a file. Implemented as ICEnroll::createFilePKCS10.
createPKCS10 | Creates a PKCS #10 reqesting a certificate for the person or entity whose information is supplied in the PKCS #10. This PKCS #10 is a return or output parameter. Implemented as ICEnroll::createPKCS10.
EnumAlgs | Enumerates IDs of algorithms supported by the cryptographic service provider (CSP).
enumContainers | Enumerates all the containers for the provider specified in the ProviderName property. Implemented as ICEnroll::enumContainers.
enumProviders | Enumerates all the providers available on the computer for the specified ProviderType property. Implemented as ICEnroll::enumProviders.
freeRequestInfo | Cleans up the stores if an error occurs or if a PKCS #7 is not to be accepted for some reason. Currently not implemented. Implemented as ICEnroll::freeRequestInfo.
GetAlgName | Retrieves the name corresponding to an algorithm ID.
getCertFromPKCS7 | Retrieves from a PKCS #7 the single certificate that was issued in response to a PKCS #10. Implemented as ICEnroll::getCertFromPKCS7.
GetKeyLen | Retrieves minimum and maximum key lengths.
GetSupportedKeySpec | Retrieves information regarding the CSP's support for signature or exchange keys.
InstallPKCS7 | Accepts and processes a PKCS #7 containing a certificate or chain of certificates. The PKCS #7 is input as a parameter. This differs from acceptPKCS7 because InstallPKCS7 doesn't receive a request certificate.
Reset | Places the ICEnroll3 object into its initial state.

The following properties are provided for the ICEnroll3 interface. For information on using these properties, see Using the Certificate Enrollment Control Properties.

Property | Description
CAStoreFlags [C++] Access: Read/write Data type: DWORD [Visual Basic] Access: Read/write Data type: Long | Passed directly to CertOpenStore, specifying characteristics when opening the certification authority (CA) store. Implemented as ICEnroll::CAStoreFlags.
CAStoreName [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Specifies where all non-"ROOT" and non-"MY" certificates are kept. Implemented as ICEnroll::CAStoreName.
CAStoreType [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Specifies the type of store to use for the store specified by the CAStoreName property. Implemented as ICEnroll::CAStoreType.
ContainerName [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Specifies the name of the key container to use. Implemented as ICEnroll::ContainerName.
DeleteRequestCert [C++] Access: Read/write Data type: BOOL [Visual Basic] Access: Read/write Data type: Boolean | Controls whether a dummy certificate is deleted — a dummy certificate created to persist the keys generated while the PKCS #10 certificate request is being issued. Implemented as ICEnroll::DeleteRequestCert.
EnableT61DNEncoding [C++] Access: Read/write Data type: BOOL [Visual Basic] Access: Read/write Data type: Boolean | Controls whether the certificate's distinguished name is encoded as a T61 string instead of as a UNICODE string. Implemented as ICEnroll2::EnableT61DNEncoding.
EnableSMIMECapabilities [C++] Access: Read/write Data type: BOOL [Visual Basic] Access: Read/write Data type: Boolean | Controls whether the PKCS10 will contain a signed attribute for S/MIME capabilities.
GenKeyFlags [C++] Access: Read\write Data type: DWORD [Visual Basic] Access: Read\write Data type: Long | Passed directly to CryptGenKey, specifying characteristics of the key being created. Implemented as ICEnroll::GenKeyFlags.
HashAlgID [C++] Access: Read\write Data type: DWORD [Visual Basic] Access: Read\write Data type: Long | Specifies the preferred hash algorithm for signing the PKCS #10.
HashAlgorithm [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies the preferred hash algorithm for signing the PKCS #10. Implemented as ICEnroll::HashAlgorithm.
KeySpec [C++] Access: Read\write Data type: DWORD [Visual Basic] Access: Read\write Data type: Long | Specifies the key type to be generated. Implemented as ICEnroll::KeySpec.
LimitExchangeKeyToEncipherment [C++] Access: Read/write Data type: BOOL [Visual Basic] Access: Read/write Data type: Boolean | Controls whether the request will contain key usages for digital signature and non-repudiation (applies to AT_KEYEXCHANGE requests only).
MyStoreFlags [C++] Access: Read\write Data type: DWORD [Visual Basic] Access: Read\write Data type: Long | Passed directly to CertOpenStore, specifying characteristics when opening the MY store. Implemented as ICEnroll::MyStoreFlags.
MyStoreName [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies where certificates with linked private keys are kept. Implemented as ICEnroll::MyStoreName.
MyStoreType [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies the type of store to use for the store specified by the MyStoreName property. Implemented as ICEnroll::MyStoreType.
ProviderFlags [C++] Access: Read\write Data type: DWORD [Visual Basic] Access: Read\write Data type: Long | Use depends on the provider in use. Implemented as ICEnroll::ProviderFlags.
ProviderName [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies the cryptographic service provider (CSP) to use. Implemented as ICEnroll::ProviderName.
ProviderType [C++] Access: Read\write Data type: DWORD [Visual Basic] Access: Read\write Data type: Long | Use depends on the provider in use. Implemented as ICEnroll::ProviderType.
PVKFileName [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Secifies that the private keys be generated as exportable and written to the file specified by the PVKFileName property. Implemented as ICEnroll::PVKFileName.
RequestStoreFlags [C++] Access: Read\write Data type: DWORD [Visual Basic] Access: Read\write Data type: Long | Passed directly to CertOpenStore, specifying characteristics when opening the REQUEST store. Implemented as ICEnroll::RequestStoreFlags.
RequestStoreName [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies the certificate store used to store the dummy certificate to which the private keys have been added, until a certification authority processes the request and responds with a PKCS #7. Implemented as ICEnroll::RequestStoreName.
RequestStoreType [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies the type of store to use for the store specified by the RequestStoreName property. Implemented as ICEnroll::RequestStoreType.
ReuseHardwareKeyIfUnableToGenNew [C++] Access: Read\write Data type: BOOL [Visual Basic] Access: Read\write Data type: Boolean | For hardware CSPs only (such as smart card), determines if an existing key is reused when it is not possible to create a new key.
RootStoreFlags [C++] Access: Read\write Data type: DWORD [Visual Basic] Access: Read\write Data type: Long | Passed directly to CertOpenStore, specifying characteristics when opening the ROOT store. Implemented as ICEnroll::RootStoreFlags.
RootStoreName [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies where all intrinsically trusted, self-signed ROOT certificates are kept. Implemented as ICEnroll::RootStoreName.
RootStoreType [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies the type of store to use for the store specified by the RootStoreName property. Implemented as ICEnroll::RootStoreName.
SPCFileName [C++] Access: Read\write Data type: BSTR [Visual Basic] Access: Read\write Data type: String | Specifies a file to which to write the PKCS #7 (in BSTR form) returned from the certification authority. Implemented as ICEnroll::SPCFileName.
UseExistingKeySet [C++] Access: Read\write Data type: BOOL [Visual Basic] Access: Read\write Data type: Boolean | Specifies that an existing key set be used, instead of generating a new one (the default value is FALSE). Implemented as ICEnroll::UseExistingKeySet.
WriteCertToCSP [C++] Access: Read\write Data type: BOOL [Visual Basic] Access: Read\write Data type: Boolean | Specifies whether a certificate should be written to the cryptographic service provider. Implemented as ICEnroll::WriteCertToCSP.
WriteCertToUserDS [C++] Access: Read\write Data type: BOOL [Visual Basic] Access: Read\write Data type: Boolean | Specifies whether a certificate is written to the user's Directory Service. Implemented as ICEnroll2::WriteCertToUserDS.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.

See Also

ICEnroll, ICEnroll2


ICEnroll3::EnableSMIMECapabilities

Platform SDK: Security

ICEnroll3::EnableSMIMECapabilities [C++]

CEnroll.EnableSMIMECapabilities [Visual Basic]

The EnableSMIMECapabilities property controls whether the PKCS10 will contain a signed attribute for Secure/Multipurpose Internet Mail Extensions (S/MIME) capabilities. The default value is FALSE.

[Visual Basic]
objEnroll.EnableSMIMECapabilities [ = bValue ]
[C++]
HRESULT put_EnableSMIMECapabilities(BOOL bValue);
HRESULT get_EnableSMIMECapabilities(BOOL *pbValue);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] bValue
A Boolean value assigned to this property. It is one of the following values:
  • TRUE
  • FALSE (the default)
[C++] pbValue
Pointer to the retrieved property value.

Example Code [C++]

// Get the EnableSMIMECapabilities value.
BOOL       bSMIME;
HRESULT    hr;
// pEnroll is previously instantiated ICEnroll interface pointer.
hr = pEnroll->get_EnableSMIMECapabilities(&bSMIME);
if (FAILED(hr))
    printf("Failed get_EnableSMIMECapabilities - %x\n", hr );
else
    printf("EnableSMIMECapabilities: %s\n",
          ( bSMIME ? "TRUE" : "FALSE"));

// Set the EnableSMIMECapabilities value.
hr = pEnroll->put_EnableSMIMECapabilities(TRUE);
if ( FAILED ( hr ) )
    printf("Failed put_EnableSMIMECapabilities - %x\n", hr );
else
    printf( "EnableSMIMECapabilities was set to TRUE\n" );

Example Code [Visual Basic]

' Declare Certificate Enrollment Control object.
Dim objXen As Object

Dim bSMIME As Boolean

' Instantiate the object.
Set objXen = CreateObject("CEnroll.CEnroll.1")

' Retrieve the EnableSMIMECapabilities value.
bSMIME = objXen.EnableSMIMECapabilities
MsgBox bSMIME, vbOKOnly, "EnableSMIMECapabilities"

' Set the EnableSMIMECapabilities value.
objXen.EnableSMIMECapabilities = True

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.

See Also

ICEnroll3


ICEnroll3::EnumAlgs

Platform SDK: Security

ICEnroll3::EnumAlgs [C++]

CEnroll.EnumAlgs [Visual Basic]

The EnumAlgs method retrieves the IDs of cryptographic algorithms in a given algorithm class that are supported by the current cryptographic service provider (CSP).

[Visual Basic]
objEnroll.EnumAlgs( _
  dwIndex As Long, _
  algClass As Long ) As Long
[C++]
HRESULT EnumAlgs(
  DWORD dwIndex,
  DWORD algClass,
  DWORD *pdwAlgID
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++]dwIndex
[in] Specifies the ordinal position of the algorithm whose ID will be retrieved. Specify zero for the first algorithm.

Note In Windows Whistler, the C++ data type for this parameter has changed to LONG.

[Visual Basic,C++]algClass
A cryptographic algorithm class. The IDs returned by this method will be in the specified class. Specify one of the following:
  • ALG_CLASS_HASH
  • ALG_CLASS_KEY_EXCHANGE
  • ALG_CLASS_MSG_ENCRYPT
  • ALG_CLASS_DATA_ENCRYPT
  • ALG_CLASS_SIGNATURE.

Note In Windows Whistler, the C++ data type for this parameter has changed to LONG.

[C++] pdwAlgID
Pointer to variable which receives a cryptographic algorithm ID which is supported by the current CSP.

Note In Windows Whistler, the data type for this parameter has changed to LONG*.

Return Values

[Visual Basic] A cryptographic algorithm ID which is supported by the current CSP. When there are no more algorithms to enumerate, the value ERROR_NO_MORE_ITEMS is returned.

[C++] The return value is an HRESULT. A value of S_OK indicates success, When there are no more algorithms to enumerate, the value ERROR_NO_MORE_ITEMS is returned.

Remarks

For algorithm ID and class constants used by this method, see Wincrypt.h

Example Code [C++]

DWORD     dwAlgID;
DWORD     dwIndex;

BSTR      bstrAlgName = NULL;

HRESULT   hr, hr2;

// Loop through the AlgIDs.
dwIndex = 0;
while ( TRUE )
{
    // Enumerate the alg IDs for a specific class.
    hr = pEnroll->EnumAlgs(dwIndex, ALG_CLASS_SIGNATURE, &dwAlgID);
    if ( S_OK != hr )
    {
       break;
    }

    // Do something with the AlgID.
    // For example, retrieve the corresponding name.
    hr2 = pEnroll->GetAlgName( dwAlgID, &bstrAlgName);
    if ( FAILED( hr2 ) )
        printf("Failed GetAlgName [%x]\n", hr);
    else
        printf("AlgID: %d Name: %S\n", dwAlgID, bstrAlgName );

    // Reuse the BSTR variable in next iteration.
    if ( NULL != bstrAlgName )
    {
        SysFreeString( bstrAlgName );
        bstrAlgName = NULL;
    }

    // Increment the index.
    dwIndex++;
}

Example Code [Visual Basic]

    ' Constants representing algorithm classes.
    Const ALG_CLASS_SIGNATURE = &H2000    ' (1 << 13) in wincrypt.h
    Const ALG_CLASS_MSG_ENCRYPT = &H4000  ' (2 << 13) in wincrypt.h
    Const ALG_CLASS_DATA_ENCRYPT = &H6000 ' (3 << 13) in wincrypt.h
    Const ALG_CLASS_HASH = &H8000         ' (4 << 13) in wincrypt.h
    Const ALG_CLASS_KEY_EXCHANGE = &HA000 ' (5 << 13) in wincrypt.h

    ' Variables for algID and index
    Dim AlgID As Long, Index As Long

    ' Set the index to the first item.
    Index = 0

    On Error GoTo Err1
    ' Loop through the algorithm IDs for a specific class.
    Do
        ' objXen is a previously instantiated ICEnroll3 object.
        AlgID = objXen.EnumAlgs(Index, ALG_CLASS_DATA_ENCRYPT)
        ' Do something with the algID.
        MsgBox (objXen.GetAlgName(AlgID))
        ' Increment to next index.
        Index = Index + 1
    Loop

Err1:

    MsgBox ("Number of algorithm ID(s): " & Index)

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.

See Also

ICEnroll3


ICEnroll3::GetAlgName

Platform SDK: Security

ICEnroll3::GetAlgName [C++]

CEnroll.GetAlgName [Visual Basic]

The GetAlgName method retrieves the name of a cryptographic algorithm given its ID. The values retrieved by this method depend on the current cryptographic service provider (CSP).

[Visual Basic]
objEnroll.GetAlgName( _
  algID As Long ) As String
[C++]
HRESULT GetAlgName(
  DWORD algID,
  BSTR *pbstr
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] algID
Value representing a cryptographic algorithm, as defined in wincrypt.h. For example, CALG_MD2 is a defined algorithm identifier. For this method to be successful, the current CSP must support the algID algorithm.

Note In Windows Whistler, the C++ data type for this parameter has changed to LONG.

[C++] pbstr
Upon success, pointer to a BSTR representing the name of the algorithm specified by algID. It is the caller's responsibility to free the memory used by pbstr (by means of SysFreeString).

Return Values

[Visual Basic] The return value is a string representing the name of the algorithm specified by algID. If a CSP doesn't support this method, an error is returned.

[C++] The return value is an HRESULT. A value of S_OK indicates success. If a CSP does not support this method or does not support the algId cryptographic algorithm, an error is returned.

Remarks

This method may be used to display the names of algorithms whose IDs are retrieved by calling ICEnroll3::EnumAlgs.

Constants for the cryptographic algorithms are defined in wincrypt.h.

Example Code [C++]

BSTR      bstrAlgName = NULL;

HRESULT   hr;

// Retrieve the algorithm name.
// dwAlgID is a DWORD variable for an algorithm ID.
hr = pEnroll->GetAlgName( dwAlgID, &bstrAlgName);
if (FAILED(hr))
    printf("Failed GetAlgName [%x]\n", hr);
else
    printf("AlgID: %d Name: %S\n", dwAlgID, bstrAlgName );

// Free BSTR resource.
if ( NULL != bstrAlgName )
{
    SysFreeString( bstrAlgName );
    bstrAlgName = NULL;
}

Example Code [Visual Basic]

Dim strAlgName As String

' Retrieve the name.
' AlgID is a LONG value representing an algorithm ID.
strAlgName = objXen.GetAlgName(AlgID)

' Display the name.
MsgBox(strAlgName)

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.

See Also

ICEnroll3::EnumAlgs


ICEnroll3::GetKeyLen

Platform SDK: Security

ICEnroll3::GetKeyLen [C++]

CEnroll.GetKeyLen [Visual Basic]

The GetKeyLen method is used to retrieve the minimum and maximum key lengths for the signature and exchange keys. The values retrieved by this method are dependent upon the current cryptographic service provider.

[Visual Basic]
objEnroll.GetKeyLen( _
  fMin As Boolean, _
  fExchange As Boolean ) As Long
[C++]
HRESULT GetKeyLen(
  BOOL fMin,
  BOOL fExchange,
  DWORD *pdwKeySize
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] fMin
Boolean value indicating which key length (minimum or maximum) is retrieved. If fMin is TRUE, the minimum key length is retrieved; if it is FALSE, the maximum key length is retrieved.
[Visual Basic,C++] fExchange
Boolean value indicating the type of key. If fExchange is TRUE, the exchange key length is retrieved; if it is FALSE, the signature key length is retrieved.
[C++] pdwKeySize
Pointer that receives the key's minimum or maximum length, in bits.

Note In Windows Whistler, the data type for this parameter has changed to LONG*.

Return Values

[Visual Basic] Value representing the length (in bits) for the key's minimum or maximum length.

[C++] The return value is an HRESULT. A value of S_OK indicates success, and *pdwKeySize will be the value representing the length (in bits) for the key's minimum or maximum length.

Remarks

Call this method to determine the minimum and maximum key lengths. If a CSP doesn't support this method, an error is returned.

Example Code [C++]

DWORD dwExchMin, dwExchMax, dwSignMin, dwSignMax;

// Determine the minimum and maximum key length values.
// hr is HRESULT variable.
hr = pEnroll->GetKeyLen( TRUE, TRUE, &dwExchMin );
if ( FAILED( hr ) )
    printf("Failed GetKeyLen for Exchange Minimum [%x]\n", hr);
else
    printf("Exchange key Min: %d\n", dwExchMin);

hr = pEnroll->GetKeyLen( FALSE, TRUE, &dwExchMax );
if ( FAILED( hr ) )
    printf("Failed GetKeyLen for Exchange Maximum [%x]\n", hr);
else
    printf("Exchange key Max: %d\n", dwExchMax );

hr = pEnroll->GetKeyLen( TRUE, FALSE, &dwSignMin );
if ( FAILED( hr ) )
    printf("Failed GetKeyLen for Signature Minimum [%x]\n", hr);
else
    printf("Signature key Min: %d\n", dwSignMin );

hr = pEnroll->GetKeyLen( FALSE, FALSE, &dwSignMax );
if ( FAILED( hr ) )
    printf("Failed GetKeyLen for Signature Maximum [%x]\n", hr);
else
    printf("Signature key Max: %d\n", dwSignMax );

Example Code [Visual Basic]

' Variable for the CEnroll object.
Dim objXen As Object

' Instantiate the object.
Set objXen = CreateObject("CEnroll.CEnroll.1")

' Variables to contain key min/max values.
Dim nMinExch As Long
Dim nMaxExch As Long
Dim nMinSign As Long
Dim nMaxSign As Long

' Retrieve the minimum and maximum key lengths.
nMinExch = objXen.GetKeyLen(True, True)
nMaxExch = objXen.GetKeyLen(False, True)
nMinSign = objXen.GetKeyLen(True, False)
nMaxSign = objXen.GetKeyLen(False, False)

' Display the results.
Dim strText As String
strText = "Exchange key Min: " & nMinExch & " Max: " & nMaxExch
strText = strText & vbNewLine & _
          "Signature key Min: " & nMinSign & " Max: " & nMaxSign
MsgBox (strText)

' Free object resource.
Set objXen = Nothing

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.

See Also

ICEnroll3


ICEnroll3::GetSupportedKeySpec

Platform SDK: Security

ICEnroll3::GetSupportedKeySpec [C++]

CEnroll.GetSupportedKeySpec [Visual Basic]

The GetSupportedKeySpec method retrieves information regarding the current cryptographic service provider (CSP) support for signature and/or exchange operations. The values retrieved by this method are dependent upon the current CSP.

[Visual Basic]
objEnroll.GetSupportedKeySpec( void )
[C++]
HRESULT GetSupportedKeySpec(
  DWORD *pdwKeySpec
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[C++] pdwKeySpec
Pointer to a DWORD that receives a bit flag indicating whether the current CSP supports exchange and/or signature keys.

Note In Windows Whistler, the data type for this parameter has changed to LONG*.

Return Values

[Visual Basic] Returns a value indicating whether the current CSP supports exchange and/or signature keys. If the CSP doesn't support this method, an error is returned.

[C++] The return value is an HRESULT. A value of S_OK indicates success If a CSP doesn't support this method, an error is returned.

Remarks

Call this method to determine if the current CSP supports exchange keys, signature keys, or both. pdwKeySpec will contain one or more of the following constants (defined in in wincrypt.h):

  • AT_KEYEXCHANGE
  • AT_SIGNATURE.

Example Code [C++]

DWORD dwKeySpec;

// Determine the supported key specifications.
// hr is HRESULT variable.
hr = pEnroll->GetSupportedKeySpec( &dwKeySpec );
if ( FAILED( hr ) )
    printf("Failed GetSupportedKeySpec [%x]\n", hr);
else
{
    printf("Exchange keys are %s. Signature keys are %s.\n",
           dwKeySpec & AT_KEYEXCHANGE ? "supported" : "not supported",
           dwKeySpec & AT_SIGNATURE ? "supported" : "not supported" );
}

Example Code [Visual Basic]

' Constants (from wincrypt.h).
Const AT_KEYEXCHANGE = 1
Const AT_SIGNATURE = 2

' Variable for the CEnroll object.
Dim objXen As Object

' Instantiate the object.
Set objXen = CreateObject("CEnroll.CEnroll.1")

Dim KeySpec As Long

' Retrieve the value for key support
KeySpec = objXen.GetSupportedKeySpec()

' Create a string based on the result.
Dim strText As String

strText = "Exchange keys are"
If (KeySpec And AT_KEYEXCHANGE) Then
    strText = strText & " supported."
Else
    strText = strText & " unsupported."
End If
strText = strText & vbNewLine
strText = strText & "Signature keys are"
If (KeySpec And AT_SIGNATURE) Then
    strText = strText & " supported."
Else
    strText = strText & " unsupported."
End If

' Output the key support.
MsgBox (strText)

' Free object resource.
Set objXen = Nothing

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.

See Also

ICEnroll3


ICEnroll3::HashAlgID

Platform SDK: Security

ICEnroll3::HashAlgID [C++]

CEnroll.HashAlgID [Visual Basic]

The HashAlgID property specifies the hash algorithm to be used when signing a PKCS #10 certificate request.

[Visual Basic]
objEnroll.HashAlgID [ = hashAlgID]
[C++]
HRESULT put_HashAlgID( DWORD hashAlgID);
HRESULT get_HashAlgID( DWORD *hashAlgID);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] hashAlgID
The ID of a hash algorithm. The data type is a DWORD in C++ and a Long in Visual Basic.

Note In Windows Whistler, the C++ data type for this parameter has changed to LONG.

Remarks

The values for this property are hash algorithm IDs, such as those returned by the ICEnroll3::EnumAlgs method. If both the HashAlgID and HashAlgorithm properties are set, whichever has been updated most recently determines the hash algorithm used to sign the PKCS #10 request.

Example Code [C++]

// Code to set the hash algorithm ID.
// hr is HRESULT variable.
hr = pEnroll->put_HashAlgID( CALG_MD4 );
if ( FAILED( hr ) )
    printf("Failed put_HashAlgID [%x]\n", hr);

// Code to retrieve the hash algorithm ID.
DWORD dwHashID;

hr = pEnroll->get_HashAlgID( &dwHashID );
if ( FAILED( hr ) )
    printf("Failed get_HashAlgID [%x]\n", hr);
else
    printf("HashAlgID: %d\n", dwHashID);

Example Code [Visual Basic]

' Constant for CALG_MD4 (from wincrypt.h).
Const CALG_MD4 = 32770

' Set the hash algorithm ID.
objXen.HashAlgID = CALG_MD4

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.

See Also

ICEnroll::HashAlgorithm, ICEnroll3::EnumAlgs


ICEnroll3::InstallPKCS7

Platform SDK: Security

ICEnroll3::InstallPKCS7 [C++]

CEnroll.InstallPKCS7 [Visual Basic]

The InstallPKCS7 method processes a certificate or chain of certificates, placing them into the appropriate certificate stores.

[Visual Basic]
objEnroll.InstallPKCS7( _
  PKCS7 As String _
)
[C++]
HRESULT InstallPKCS7(
  BSTR PKCS7
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] PKCS7
String containing a certificate or chain of certificates.

Return Values

[Visual Basic] None.

[C++] The return value is an HRESULT. A value of S_OK indicates success.

Remarks

The InstallPKCS7 method is similar to the ICEnroll::acceptPKCS7 method, except the input parameter to InstallPKCS7 does not contain a request certificate.

Example Code [C++]

HRESULT    hr;

// Install the PKCS7.
// bstrPKCS7 is a BSTR variable previously set to a PKCS #7.
hr = pEnroll3->InstallPKCS7(bstrPKCS7);
if (FAILED(hr))
    printf("Failed InstallPKCS7 [%x]\n", hr);

Example Code [Visual Basic]

' Install the PKCS7.
' strPKCS7 is a String variable previously set to a PKCS #7.
objXen.InstallPKCS7(strPKCS7)

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.

See Also

ICEnroll::acceptPKCS7


ICEnroll3::LimitExchangeKeyToEncipherment

Platform SDK: Security

ICEnroll3::LimitExchangeKeyToEncipherment [C++]

CEnroll.LimitExchangeKeyToEncipherment [Visual Basic]

The LimitExchangeKeyToEncipherment property controls whether an AT_KEYEXCHANGE request contains digital signature and non-repudiation key usages. The default value is FALSE. This property has no effect on AT_SIGNATURE requests.

[Visual Basic]
objEnroll.LimitExchangeKeyToEncipherment [ = bValue ]
[C++]
HRESULT put_LimitExchangeKeyToEncipherment(BOOL bValue);
HRESULT get_LimitExchangeKeyToEncipherment(BOOL *pbValue);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] bValue
A Boolean value assigned to this property. It is one of the following values:
  • TRUE
  • FALSE (the default)
[C++] pbValue
Pointer to the retrieved property value.

Remarks

This property is a Boolean value and effects only AT_KEYEXCHANGE requests; it has no impact on AT_SIGNATURE requests.

If the value for this property is FALSE, an AT_KEYEXCHANGE request will contain the following key usages:

  • CERT_DATA_ENCIPHERMENT_KEY_USAGE
  • CERT_KEY_ENCIPHERMENT_KEY_USAGE
  • CERT_DIGITAL_SIGNATURE_KEY_USAGE
  • CERT_NON_REPUDIATION_KEY_USAGE

If the value for this property is TRUE, an AT_KEYEXCHANGE request will contain the following key usages:

  • CERT_DATA_ENCIPHERMENT_KEY_USAGE
  • CERT_KEY_ENCIPHERMENT_KEY_USAGE

Example Code [C++]

// Get the LimitExchangeKeyToEncipherment value.
BOOL       bLimitKey;
HRESULT    hr;
// pEnroll is previously instantiated ICEnroll interface pointer.
hr = pEnroll->get_LimitExchangeKeyToEncipherment(&bLimitKey);
if (FAILED(hr))
    printf("Failed get_LimitExchangeKeyToEncipherment - %x\n", hr );
else
    printf("LimitExchangeKeyToEncipherment: %s\n",
          ( bLimitKey ? "TRUE" : "FALSE"));

// Set the LimitExchangeKeyToEncipherment value.
hr = pEnroll->put_LimitExchangeKeyToEncipherment( TRUE );
if ( FAILED ( hr ) )
    printf("Failed put_LimitExchangeKeyToEncipherment - %x\n", hr );
else
    printf( "LimitExchangeKeyToEncipherment was set to TRUE\n" );

Example Code [Visual Basic]

' Declare Certificate Enrollment Control object.
Dim objXen As Object

Dim bLimitKey As Boolean

' Instantiate the object.
Set objXen = CreateObject("CEnroll.CEnroll.1")

' Retrieve the LimitExchangeKeyToEncipherment value.
bLimitKey = objXen.LimitExchangeKeyToEncipherment
MsgBox bLimitKey, vbOKOnly, "LimitExchangeKeyToEncipherment"

' Set the LimitExchangeKeyToEncipherment value.
objXen.LimitExchangeKeyToEncipherment = True

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.

See Also

ICEnroll3, ICEnroll::KeySpec


ICEnroll3::Reset

Platform SDK: Security

ICEnroll3::Reset [C++]

CEnroll.Reset [Visual Basic]

The Reset method returns the CEnroll3 object to its initial state.

[Visual Basic]
objEnroll.Reset( void )
[C++]
HRESULT Reset( void );

Parameters [Visual Basic]

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.

Return Values

[Visual Basic] None.

[C++] The return value is an HRESULT. A value of S_OK indicates success.

Remarks

The Reset method is provided to return the ICEnroll3 control to its initial state and thereby allow reuse of the control.

Example Code [C++]

HRESULT    hr;

// Reset the control.
hr = pEnroll3->Reset();
if (FAILED(hr))
    printf("Failed Reset [%x]\n", hr);

Example Code [Visual Basic]

'  Reset the control.
objXen.Reset

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.

See Also

ICEnroll3


ICEnroll3::ReuseHardwareKeyIfUnableToGenNew

Platform SDK: Security

ICEnroll3::ReuseHardwareKeyIfUnableToGenNew [C++]

CEnroll.ReuseHardwareKeyIfUnableToGenNew [Visual Basic]

The ReuseHardwareKeyIfUnableToGenNew property determines the action taken by the ICEnroll3 object if an error is encountered when generating a new key. This property is read-write. The default value is TRUE.

[Visual Basic]
objEnroll.ReuseHardwareKeyIfUnableToGenNew [ = bValue ]
[C++]
HRESULT put_ReuseHardwareKeyIfUnableToGenNew(BOOL bValue);
HRESULT get_ReuseHardwareKeyIfUnableToGenNew(BOOL *pbValue);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] bValue
A Boolean value assigned to this property. It is one of the following values:
  • TRUE (the default)
  • FALSE
[C++] pbValue
Pointer to retrieved property value.

Remarks

This property is a Boolean value. This property affects only cryptographic service providers that return NTE_TOKEN_KEYSET_STORAGE_FULL. These CSPs are typically hardware-based; an example is a smart card. If this property is TRUE and an error is encountered while generating a new key, the ICEnroll3 control will reuse the existing hardware key. If this property is FALSE and an error is encountered while generating a new key, the ICEnroll3 control will not reuse the existing hardware key but will instead pass an error to the caller.

Example Code [C++]

// Code to set the reuse H/W key status.
// hr is HRESULT variable.
hr = pEnroll->put_ReuseHardwareKeyIfUnableToGenNew( FALSE );
if ( FAILED( hr ) )
    printf("Failed put_ReuseHardwareKeyIfUnableToGenNew [%x]\n", hr);

// Code to retrieve the reuse H/W key status.
BOOL bReuse;

hr = pEnroll->get_ReuseHardwareKeyIfUnableToGenNew( &bReuse );
if ( FAILED( hr ) )
    printf("Failed get_ReuseHardwareKeyIfUnableToGenNew [%x]\n", hr);
else
    printf("Hardware key %s be reused if unable"
           " to generate a new key.\n", bReuse ? "will" : "will not");

Example Code [Visual Basic]

' Variable for the CEnroll object.
Dim objXen As Object

' Instantiate the object.
Set objXen = CreateObject("CEnroll.CEnroll.1")

Dim bReuse As Boolean

bReuse = objXen.ReuseHardwareKeyIfUnableToGenNew

If (True = bReuse) Then
    MsgBox ("H/W key will be re-used if a new one isn't creatable.")
Else
    MsgBox ("H/W key will not be re-used if a new one isn't creatable.")
End If

' Free object resource.
Set objXen = Nothing

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.

See Also

ICEnroll3


ICEnroll4

[This is preliminary documentation and subject to change.]

The ICEnroll4 interface inherits all of the methods and properties of ICEnroll3.

The following table lists all of the methods included in ICEnroll4.

Method | Description
acceptFilePKCS7 | Accepts and processes a PKCS #7 message containing a certificate. The PKCS #7 message is stored in a file.
acceptFileResponse | Accepts and stores a response read from a file. New in ICEnroll4.
acceptPKCS7 | Accepts and processes a PKCS #7 message containing a certificate. The PKCS #7 message is input as a parameter.
acceptResponse | Accepts and stores a response. New in ICEnroll4.
addAttributeToRequest | Adds an attribute to the certificate request. New in ICEnroll4.
addCertTypeToRequest | Adds a certificate template to a request. Valid with an enterprise certification authority (CA) only.
addCertTypeToRequestEx | Adds a certificate template to a request. Valid with an enterprise certification authority (CA) only. Can be used to add V@ template extension to a request.
addExtensionToRequest | Adds an extension to the certificate request. New in ICEnroll4.
addNameValuePairToRequest | Adds a name/value pair to the certificate request as an unauthenticated attribute. New in ICEnroll4.
addNameValuePairToSignature | Adds a name/value pair of an attribute to the certificate request.
binaryToString | Converts a binary data BLOB to a string. New in ICEnroll4.
createFilePFX | Saves the accepted certificate chain and private key in a file in Personal Information Exchange (PFX) format. New in ICEnroll4.
createFilePKCS10 | Creates a PKCS #10 certificate request and saves it to a file.
createFileRequest | Builds a certificate request and stores it in a file in PFX format. New in ICEnroll4.
createPFX | Saves the accepted certificate chain and private key in PFX format. New in ICEnroll4.
createPKCS10 | Creates a PKCS #10 certificate request.
createRequest | Builds a certificate request. New in ICEnroll4.
EnumAlgs | Enumerates IDs of algorithms supported by the cryptographic service provider (CSP).
enumContainers | Enumerates the containers for the provider specified in the ProviderName property.
enumPendingRequest | Enumerates the properties of pending certificate requests. New in ICEnroll4.
enumProviders | Enumerates the providers available on the computer for the specified ProviderType property.
freeRequestInfo | Cleans up the stores if an error occurs. Currently not implemented.
GetAlgName | Retrieves the name corresponding to an algorithm ID.
getCertFromFileResponse | Retrieves a certificate from a response stored in a file. New in ICEnroll4.
getCertFromPKCS7 | Retrieves (from a PKCS #7 message) the certificate issued in response to a PKCS #10 certificate request.
getCertFromResponse | Retrieves a certificate from a response. New in ICEnroll4.
GetKeyLen | Retrieves minimum and maximum key lengths.
GetKeyLenEx | Retrieves key information. New in ICEnroll4.
GetSupportedKeySpec | Retrieves information regarding the CSP's support for signature or exchange keys.
InstallPKCS7 | Accepts and processes a PKCS #7 message containing a certificate or chain of certificates.
InstallPKCS7Ex | The same as InstallPKCS7 but in addition returns the number of certificates installed into local stores.
removePendingRequest | Removes a pending certificate request. New in ICEnroll4.
Reset | Places the object into its initial state.
resetAttributes | Removes all attributes for the certificate request. New in ICEnroll4.
resetExtensions | Removes all extensions for the certificate request. New in ICEnroll4.
setPendingRequestInfo | Specifies information for a pending certificate request. New in ICEnroll4.
stringToBinary | Converts a string to a binary data BLOB. New in ICEnroll4.

The following properties are included in ICEnroll4.

Property | Description
CAStoreFlags [C++] Access: Read/write Data type: LONG [Visual Basic] Access: Read/write Data type: Long | Passed to CertOpenStore. Specifies characteristics when opening the certification authority (CA) store.
CAStoreName [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Specifies where all non-"ROOT" and non-"MY" certificates are kept.
CAStoreType [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Contains the type of the store specified by the CAStoreName property.
ContainerName [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Specifies the name of the key container to use.
DeleteRequestCert [C++] Access: Read/write Data type: BOOL [Visual Basic] Access: Read/write Data type: Boolean | Controls whether dummy certificates in the request store are deleted.
EnableSMIMECapabilities [C++] Access: Read/write Data type: BOOL [Visual Basic] Access: Read/write Data type: Boolean | Controls whether the certificate request contains a signed attribute for S/MIME capabilities.
EnableT61DNEncoding [C++] Access: Read/write Data type: BOOL [Visual Basic] Access: Read/write Data type: Boolean | Controls whether the certificate's distinguished name is encoded as a T61 string instead of as a UNICODE string.
GenKeyFlags [C++] Access: Read/write Data type: LONG [Visual Basic] Access: Read/write Data type: Long | Passed to CryptGenKey. Specifies characteristics of the key being created.
HashAlgID [C++] Access: Read/write Data type: LONG [Visual Basic] Access: Read/write Data type: Long | Specifies the preferred hash algorithm for signing the certificate request.
HashAlgorithm [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Specifies the preferred hash algorithm for signing the certificate request.
KeySpec [C++] Access: Read/write Data type: LONG [Visual Basic] Access: Read/write Data type: Long | Specifies the key type to be generated.
LimitExchangeKeyToEncipherment [C++] Access: Read/write Data type: BOOL [Visual Basic] Access: Read/write Data type: Boolean | Controls whether the request will contain key usages for digital signature and non-repudiation (applies to AT_KEYEXCHANGE requests only).
MyStoreFlags [C++] Access: Read/write Data type: LONG [Visual Basic] Access: Read/write Data type: Long | Passed directly to CertOpenStore. Specifies characteristics when opening the MY store.
MyStoreName [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Specifies where certificates with linked private keys are kept.
MyStoreType [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Contains the type of the store specified by the MyStoreName property.
PrivateKeyArchiveCertificate [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Specifies the certificate used to encrypt a private key when the private key is archived. New in ICEnroll4.
ProviderFlags [C++] Access: Read/write Data type: LONG [Visual Basic] Access: Read/write Data type: Long | Use depends on the cryptographic service provider (CSP) in use.
ProviderName [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Specifies the CSP to use.
ProviderType [C++] Access: Read/write Data type: LONG [Visual Basic] Access: Read/write Data type: Long | Use depends on the provider in use.
PVKFileName [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Controls whether a private key is exportable. The private key is written to the file specified by the PVKFileName property.
RequestStoreFlags [C++] Access: Read/write Data type: LONG [Visual Basic] Access: Read/write Data type: Long | Passed to CertOpenStore. Specifies characteristics when opening the REQUEST store.
RequestStoreName [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Specifies the certificate store used to store a dummy certificate.
RequestStoreType [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Contains the type of the store specified by the RequestStoreName property.
ReuseHardwareKeyIfUnableToGenNew [C++] Access: Read/write Data type: BOOL [Visual Basic] Access: Read/write Data type: Boolean | For hardware CSPs only (such as smart card), determines if an existing key is reused when it is not possible to create a new key.
RootStoreFlags [C++] Access: Read/write Data type: LONG [Visual Basic] Access: Read/write Data type: Long | Passed directly to CertOpenStore. Specifies characteristics when opening the ROOT store.
RootStoreName [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Specifies where all intrinsically trusted, self-signed ROOT certificates are kept.
RootStoreType [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Contains the type of the store specified by the RootStoreName property.
SPCFileName [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Specifies a file to receive the PKCS #7 message (in BSTR form) returned from the certification authority.
ThumbPrint [C++] Access: Read/write Data type: BSTR [Visual Basic] Access: Read/write Data type: String | Contains a hash of the certificate data. New in ICEnroll4.
UseExistingKeySet [C++] Access: Read/write Data type: BOOL [Visual Basic] Access: Read/write Data type: Boolean | Specifies that an existing key set be used, instead of generating a new one.
WriteCertToCSP [C++] Access: Read/write Data type: BOOL [Visual Basic] Access: Read/write Data type: Boolean | Specifies whether a certificate should be written to the cryptographic service provider.
WriteCertToUserDS [C++] Access: Read/write Data type: BOOL [Visual Basic] Access: Read/write Data type: Boolean | Specifies whether a certificate is written to the user's Directory Service.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll4::acceptFileResponse

Platform SDK: Security

ICEnroll4::acceptFileResponse[C++]

CEnroll.acceptFileResponse[Visual Basic]

[This is preliminary documentation and subject to change.]

The acceptFileResponse method accepts delivery of the credentials issued in response to an earlier call to createFileRequest, and it places the credentials in the appropriate store. The response may be a PKCS #7 message or a CMC response.

[Visual Basic]
objEnroll.acceptFileResponse ( _
  strResponseFileName As String _
)
[C++]
HRESULT acceptFileResponse (
  BSTR strResponseFileName
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] strResponseFileName
[in] Specifies the name of the file containing the base64-encoded response.

Return Values

[Visual Basic] None.

[C++]If the method is successful, the return value is S_OK.

If the method fails, the return value is an HRESULT indicating the error. For a list of common error codes, see Common HRESULT Values.

Remarks

The response named in the strResponseFileName parameter must contain exactly one certificate; a child certificate cannot be present.

The response may be either a PKCS #7 or a Full CMC response; however, to accept a Full CMC response, the cryptographic service provider must support ASN.1 encoding of CMC structures.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll4::acceptResponse

Platform SDK: Security

ICEnroll4::acceptResponse[C++]

CEnroll.acceptResponse[Visual Basic]

[This is preliminary documentation and subject to change.]

The acceptResponse method accepts delivery of the credentials issued in response to an earlier call to createRequest and places the credentials in the appropriate store. The response may be a PKCS #7 format or a Full CMC response.

[Visual Basic]
objEnroll.acceptResponse ( _
  strResponse As String _
)
[C++]
HRESULT acceptResponse(
  BSTR strResponse
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] strResponse
[in] String representing the base64-encoded response.

Return Values

[Visual Basic] None.

[C++] If the method is successful, the return value is S_OK.

If the method fails, the return value is an HRESULT indicating the error. For a list of common error codes, see Common HRESULT Values.

Remarks

The response must contain exactly one certificate; a child certificate cannot be present.

The response may be either a PKCS #7 or a Full CMC response; however, to accept a Full CMC response, the cryptographic service provider must support ASN.1 encoding of CMC structures.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll4::addAttributeToRequest

Platform SDK: Security

ICEnroll4::addAttributeToRequest [C++]

CEnroll.addAttributeToRequest [Visual Basic]

[This is preliminary documentation and subject to change.]

The addAttributeToRequest method adds an attribute to the certificate request.

[Visual Basic]
objEnroll.addAttributeToRequest( _
  Flags As Long, _
  strName As String, _
  strValue As String _
)
[C++]
HRESULT addAttributeToRequest(
  LONG Flags,
  BSTR strName,
  BSTR strValue
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Flags
[in] Reserved; must be zero.
[Visual Basic,C++] strName
[in] Object identifier (OID) representing the attribute name.
[Visual Basic,C++] strValue
[in] Base64-encoded or binary attribute value.

Return Values

[Visual Basic] None.

[C++] If the method is successful, the return value is S_OK.

If the method fails, the return value is an HRESULT indicating the error. For a list of common error codes, see Common HRESULT Values.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll4::addCertTypeToRequestEx

Platform SDK: Security

ICEnroll4::addCertTypeToRequestEx [C++]

CEnroll.addCertTypeToRequestEx [Visual Basic]

This method, like the addCertTypeToRequest method, adds a certificate template (or "certificate type") to a request. This method is associated with the Certificate Services enterprise policy module. This method is specialized, and its use is not recommended for most applications. This version can add a V@ template extension into a request.

[Visual Basic]
objEnroll.addCertTypeToRequestEx( _
  lFlag As LONG, _
  bstrOIDOrName As String _
  lMajorVersion As Long, _
  fMinorVersion As Boolean _
  lMinverVersion as Long _
)
[C++]
HRESULT addCertTypeToRequestEx(
  LONG lFlag,
  BSTR bstrOIDOrName,
  Long lMajorVersion,
  Bool fMinorVersion,
  long lMinorVersion
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] lFlag
[in] Indicates the version type of the template extention. Can be either of the following values:
Flag value | Meaning
XECT_EXTENSION_V1 | Uses a version 1 extension
XECT_EXTENSION_V2 | Uses a version 2 extension.

bstrOIDOrName
[in] The certificate template fully qualified name which is being added to the certificate request; this value is interpreted by the certification authority.
lMajorVersion
[in] Sets the major version of the template. This parameter is ignored if lFlag is XECT_EXTENSION_V!.
fMinorVersion
[in] Indicates whether a minor version of the template is used. This parameter is ignored if lFlag is XECT_EXTENSION_V!.
lMinorVersion
[in] Sets the minor version of the template. This parameter is ignored if lFlag is XECT_EXTENSION_V1 or if fMinorVersion is FALSE.

Return Values

[Visual Basic] None.

[C++] The return value is an HRESULT, with S_OK returned if the call is successful.

Remarks

This method supports only the new request method, createRequest. It does not support the createPKCS10 method.

This method can be called multiple times to establish multiple certificate templates for the request.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.

See Also

ICEnroll2::addCertTypeToRequest, ICEnroll::createPKCS10, ICEnroll4::createRequest


ICEnroll4::addExtensionToRequest

Platform SDK: Security

ICEnroll4::addExtensionToRequest[C++]

CEnroll.addExtensionToRequest[Visual Basic]

[This is preliminary documentation and subject to change.]

The addExtensionToRequest method adds an extension to the request.

[Visual Basic]
objEnroll.addExtensionToRequest( _
  Flags As Long, _
  strName As String, _
  strValue As String _
)
[C++]
HRESULT addExtensionToRequest(
  LONG Flags,
  BSTR strName,
  BSTR strValue
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Flags
[in] Reserved; must be zero.
[Visual Basic,C++] strName
[in] Object Identifier (OID) representing the extension name.
[Visual Basic,C++] strValue
[in] Base64-encoded or binary extension value.

Return Values

[Visual Basic] None.

[C++] If the method is successful, the return value is S_OK.

If the method fails, the return value is an HRESULT indicating the error. For a list of common error codes, see Common HRESULT Values.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll4::addNameValuePairToRequest

Platform SDK: Security

ICEnroll4::addNameValuePairToRequest[C++]

CEnroll.addNameValuePairToRequest[Visual Basic]

[This is preliminary documentation and subject to change.]

The addNameValuePairToRequest method adds a name/value string pair to the request.

[Visual Basic]
objEnroll.addNameValuePairToRequest ( _
  Flags As Long, _
  strName As String, _
  strValue As String _
)
[C++]
HRESULT addNameValuePairToRequest(
  LONG Flags,
  BSTR strName,
  BSTR strValue
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Flags
[in] Reserved; must be zero.
[Visual Basic,C++] strName
[in] The name portion of the name/value pair.
[Visual Basic,C++] strValue
[in] The value portion of the name/value pair.

Return Values

[Visual Basic] None.

[C++] If the method is successful, the return value is S_OK.

If the method fails, the return value is an HRESULT indicating the error. For a list of common error codes, see Common HRESULT Values.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll4::binaryToString

Platform SDK: Security

ICEnroll4::binaryToString[C++]

CEnroll.binaryToString[Visual Basic]

[This is preliminary documentation and subject to change.]

The binaryToString method converts a binary data BLOB to a string. This method uses the CryptBinaryToString function to do the conversion.

[Visual Basic]
objEnroll.binaryToString( _
  Flags As  LONG, _
  strBinary As String ) As String
[C++]
HRESULT binaryToString(
  LONG Flags,
  BSTR strBinary,
  BSTR *pstrEncoded
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Flags
[in] Value passed to the dwFlags parameter of the CryptBinaryToString function. See CryptBinaryToString for a description of possible values.
[Visual Basic,C++] strBinary
[in] Binary data BLOB to be converted to a string.
[C++] pstrEncoded
[out] Pointer to BSTR that receives the encoded data. The caller must free the BSTR by calling the SysFreeString function.

Return Values

[Visual Basic] The return value is a String representation of the binary data.

If the method is successful, the return value is S_OK.

If the method fails, the return value is an HRESULT indicating the error. For a list of common error codes, see Common HRESULT Values.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll4::createFilePFX

Platform SDK: Security

ICEnroll4::createFilePFX[C++]

CEnroll.createFilePFX[Visual Basic]

[This is preliminary documentation and subject to change.]

The createFilePFX method saves the accepted certificate chain and private key in a Personal Information Exchange (PFX) file.

[Visual Basic]
objEnroll.createFilePFX( _
  strPassword As String, _
  strPFXFileName As String _
)
[C++]
HRESULT createFilePFX(
  BSTR strPassword,
  BSTR strPFXFileName
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] strPassword
[in] Password for the PFX; this value may be empty (or NULL) to indicate that no password is used.
[Visual Basic,C++] strPFXFileName
[in] Name of the file that will receive the base64-encoded PFX data.

Return Values

[Visual Basic] None.

[C++] If the method is successful, the return value is S_OK.

If the method fails, the return value is an HRESULT indicating the error. For a list of common error codes, see Common HRESULT Values.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll4::createFileRequest

Platform SDK: Security

ICEnroll4::createFileRequest[C++]

CEnroll.createFileRequest[Visual Basic]

[This is preliminary documentation and subject to change.]

The createFileRequest method creates a PKCS #10 certificate request, a PKCS #7 request, or a Full CMC request and stores it in a file.

[Visual Basic]
objEnroll.createFileRequest( _
  Flags As Long, _
  strDNName As String, _
  strUsage As String, _
  strRequestFileName As String _
)
[C++]
HRESULT createFileRequest(
  LONG Flags,
  BSTR strDNName,
  BSTR strUsage,
  BSTR strRequestFileName
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Flags
[in] Value specifying the type of certificate to create. Specify one of the following values.
Value | Format
XECR_CMC | Full CMC
XECR_PKCS10_V1_5 | PKCS 10
XECR_PKCS10_V2_0 | PKCS 10 version 2
XECR_PKCS7 | PKCS 7

[Visual Basic,C++] strDNName
[in] May be NULL; otherwise, this parameter specifies the distinguished name (DN) of the entity for which the request is being made. The DN name must follow the X.500 naming convention, for example "CN=User, O=Microsoft". If a two-letter prefix does not exist, an OID may be provided instead.
[Visual Basic,C++] strUsage
[in] An OID that describes the purpose of the request being generated, for example, individual or commercial Authenticode certificate, or client authentication. You can also specify multiple OIDs separated by a comma.
[Visual Basic,C++] strRequestFileName
[in] Name of the file that will receive the request.

Return Values

[Visual Basic] None.

[C++] If the method is successful, the return value is S_OK.

If the method fails, the return value is an HRESULT indicating the error. For a list of common error codes, see Common HRESULT Values.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll4::createPFX

Platform SDK: Security

ICEnroll4::createPFX[C++]

CEnroll.createPFX[Visual Basic]

[This is preliminary documentation and subject to change.]

The createPFX method saves the accepted certificate chain and private key in a Personal Information Exchange (PFX) format string. The PFX format is also known as PKCS #12.

[Visual Basic]
objEnroll.createPFX( _
  strPassword As String ) As String
[C++]
HRESULT createPFX (
  BSTR strPassword,
  BSTR *pstrPFX
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] strPassword
[in] Password for the PFX-format message; this value may be empty or NULL to indicate that no password is used.
[C++] pstrPFX
[out] Pointer to BSTR that receives the base64 encoded PFX format certificate information. When the BSTR is no longer required, the caller must free it by calling SysFreeString.

Return Values

[Visual Basic] The return value is a String containing the PFX format certificate information.

[C++] If the method is successful, the return value is S_OK.

If the method fails, the return value is an HRESULT indicating the error. For a list of common error codes, see Common HRESULT Values.

Example Code [C++]

//assume you already have
//pEnroll4     - ICEnroll4 interface pointer
//bstrPassword - BSTR, password for creating pfx
//bstrResponse - BSTR, a response from CA
//hr           - HRESULT

BSTR        bstrPFX = NULL;

//make sure accept response or pkcs7 before creating pfx
hr = pEnroll4->acceptResponse( bstrResponse);
if (FAILED(hr))
{
    printf("Failed to accept response - pEnroll4 [%x]\n", hr);
    goto error;
}

// create the PFX
hr = pEnroll4->createPFX( bstrPassword,
                          &bstrPFX );
if (FAILED(hr))
{
        printf("Failed createPFX - pEnroll4 [%x]\n", hr);
        goto error;
}
else
    // do something with the PFX (bstrPFX);

error:

//clean up resources, etc.
if ( NULL != bstrPFX )
    SysFreeString( bstrPFX );

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll4::createRequest

Platform SDK: Security

ICEnroll4::createRequest[C++]

CEnroll.createRequest[Visual Basic]

[This is preliminary documentation and subject to change.]

The createRequest method creates a certificate request and stores it in a string. The request may be in PKCS #10, PKCS #7, or Full CMC format.

[Visual Basic]
objEnroll.createRequest( _
  Flags As Long, _
  strDNName As String, _
  Usage As String ) As String
[C++]
HRESULT createRequest(
  LONG Flags,
  BSTR strDNName,
  BSTR Usage,
  BSTR *pstrRequest
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Flags
[in] Value specifying the type of certificate request to create. Specify one of the following values.
Value | Format
XECR_CMC | Full CMC
XECR_PKCS10_V1_5 | PKCS 10
XECR_PKCS10_V2_0 | PKCS 10 version 2
XECR_PKCS7 | PKCS 7

[Visual Basic,C++] strDNName
[in] May be NULL; otherwise, this parameter specifies the distinguished name (DN) of the entity for which the request is being made. The DN name must follow the X.500 naming convention, for example "CN=User, O=Microsoft". If a two-letter prefix does not exist, an OID may be provided instead.
[Visual Basic,C++] Usage
[in] An OID that describes the purpose of the certificate being generated, for example, individual or commercial Authenticode certificate, or client authentication. You can also specify multiple OIDs separated by a comma.
[C++] pstrRequest
[out] Pointer to BSTR that receives the request. When the BSTR is no longer required, the caller must free it by calling SysFreeString.

Return Values

[Visual Basic] The return value is a String containing the request.

[C++]If the method is successful, the return value is S_OK.

If the method fails, the return value is an HRESULT indicating the error. For a list of common error codes, see Common HRESULT Values.

Example Code [C++]

BSTR        bstrDN = NULL;
BSTR        bstrReq = NULL;
ICEnroll4 * pEnroll4 = NULL;
HRESULT     hr;

// initialize COM
hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );

if (FAILED(hr))
{
    printf("Failed CoInitializeEx - %x\n", hr);
    goto error;
}

hr = CoCreateInstance( CLSID_CEnroll,
                       NULL,
                       CLSCTX_INPROC_SERVER,
                       IID_ICEnroll4,
                       (void **)&pEnroll4);
if (FAILED(hr))
{
    printf("Failed CoCreateInstance - pEnroll4 [%x]\n", hr);
    goto error;
}

//bstrExchCert is a certificate in binary or base64 format
//it can be obtained from certificate issuer
hr = pEnroll4->put_PrivateKeyArchiveCertificate(
                        bstrExchCert);
if (FAILED(hr))
{
    printf("Failed to set key archive certificate - pEnroll4 [%x]\n", hr);
    goto error;
}

// generate the DN for the cert request
bstrDN = SysAllocString( TEXT("CN=Your Name")   // common name
                         TEXT(",OU=Your Unit")  // org unit
                         TEXT(",O=Your Org")    // organization
                         TEXT(",L=Redmond")     // locality
                         TEXT(",S=Washington")  // state
                         TEXT(",C=US") );       // country/region

// create the CMC request
hr = pEnroll4->createRequest( XECR_CMC,
                              bstrDN,
                              NULL,
                              &bstrReq );

if (FAILED(hr))
{
        printf("Failed createRequest - pEnroll4 [%x]\n", hr);
        goto error;
}
else
    // do something with the CMC (bstrReq);

error:

//clean up resources, etc.
if ( NULL != bstrDN )
    SysFreeString( bstrDN );
if ( NULL != bstrReq )
    SysFreeString( bstrReq );
if ( NULL != pEnroll4 )
       pEnroll4->Release();

CoUninitialize();

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll4::enumPendingRequest

Platform SDK: Security

ICEnroll4::enumPendingRequest[C++]

CEnroll.enumPendingRequest[Visual Basic]

[This is preliminary documentation and subject to change.]

The enumPendingRequest method enumerates pending certificate requests and retrieves a specified property from each.

[Visual Basic]
objEnroll.enumPendingRequest( _
  lIndex As Long, _
  lDesiredProperty As Long ) As Variant
[C++]
HRESULT enumPendingRequest(
  LONG lIndex,
  LONG lDesiredProperty,
  VARIANT *pvarProperty
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] lIndex
[in] Specifies the ordinal position of the pending request whose property will be retrieved. Specify zero for the first request.
[Visual Basic,C++] lDesiredProperty
[in] Identifier for the property being retrieved. Specify one of the following values.
Value | Description
XEPR_CADNS | DNS name for the Certification Authority (CA).
XEPR_CAFRIENDLYNAME | Friendly name of the CA.
XEPR_CANAME | Name of the CA.
XEPR_HASH | Hash algorithm used in the request.
XEPR_REQUESTID | Certificate request ID.

[C++] pvarProperty
[out] Pointer to VARIANT that receives the value of the retrieved property.

When the VARIANT is no longer required, the caller must free it by calling the VariantClear function. See the example code for information on retrieving the property value from this VARIANT.

Return Values

[Visual Basic] Returns a Variant containing a property from a pending request.

[C++] If the method is successful, the return value is S_OK.

If the method fails, the return value is an HRESULT indicating the error. If the following values are specified for lDesiredProperty, this method returns E_NOTIMPL:

  • XEPR_DATE
  • XEPR_V1TEMPLATENAME
  • XEPR_V2TEMPLATEOID
  • XEPR_VERSION

If you specify any other value for lDesiredProperty this method returns E_INVALIDARG.

For a list of common error codes, see Common HRESULT Values.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll4::getCertFromFileResponse

Platform SDK: Security

ICEnroll4::getCertFromFileResponse[C++]

CEnroll.getCertFromFileResponse[Visual Basic]

[This is preliminary documentation and subject to change.]

The getCertFromFileResponse method retrieves the certificate from a file containing a response from a certification authority.

[Visual Basic]
objEnroll.getCertFromFileResponse ( _
  strResponseFileName As String ) As String
[C++]
HRESULT getCertFromFileResponse(
  BSTR strResponseFileName,
  BSTR *pstrCert
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] strResponseFileName
[in] Specify the name of the file containing the response.
[C++] pstrCert
[out] Pointer to BSTR that receives the certificate retrieved from the response. When the BSTR is no longer required, the caller must free it by calling the SysFreeString function.

Return Values

[Visual Basic] The return value is a String containing a certificate.

[C++] If the method is successful, the return value is S_OK.

If the method fails, the return value is an HRESULT indicating the error. For a list of common error codes, see Common HRESULT Values.

Remarks

The response contained in strResponseFileName must contain exactly one certificate; a child certificate cannot be present.

The response may be either a PKCS #7 or a Full CMC response; however, to accept a Full CMC response the cryptographic service provider must support ASN.1 encoding of CMC structures.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll4::getCertFromResponse

Platform SDK: Security

ICEnroll4::getCertFromResponse[C++]

CEnroll.getCertFromResponse[Visual Basic]

[This is preliminary documentation and subject to change.]

The getCertFromResponse method retrieves the certificate from a certification authority's response.

[Visual Basic]
objEnroll.getCertFromResponse( _
  strResponse As String ) As String
[C++]
HRESULT getCertFromResponse(
  BSTR strResponse,
  BSTR *pstrCert
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] strResponse
[in] The base64-encoded response.
[C++] pstrCert
[out] Pointer to a BSTR that receives the certificate retrieved from the response. When the BSTR is no longer required, the caller must free it by calling the SysFreeString function.

Return Values

[Visual Basic] The return value is a String containing a certificate.

[C++] If the method is successful, the return value is S_OK.

If the method fails, the return value is an HRESULT indicating the error. For a list of common error codes, see Common HRESULT Values.

Remarks

The response contained in strResponse must contain exactly one certificate; a child certificate cannot be present.

The response may be either a PKCS #7 or a Full CMC response; however, to accept a Full CMC response, the cryptographic service provider must support ASN.1 encoding of CMC structures.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll4::InstallPKCS7Ex

Platform SDK: Security

ICEnroll4::InstallPKCS7Ex [C++]

CEnroll.InstallPKCS7Ex [Visual Basic]

The InstallPKCS7Ex method is the same as InstallPKCS7 except that it returns the number of certificates actually installed in local stores. It processes a certificate or chain of certificates, placing them into the appropriate certificate stores.

[Visual Basic]
objEnroll.InstallPKCS7Ex( _
  PKCS7 As String, _
  plCertInstalled As LONG _
)
[C++]
HRESULT InstallPKCS7Ex(
  BSTR PKCS7,
  LONG * plCertInstalled
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] PKCS7
String containing a certificate or chain of certificates.
[Visual Basic,C++] plCertInstalled
Returns the number of certificates installed into local stores.

Return Values

[Visual Basic] None.

[C++] The return value is an HRESULT. A value of S_OK indicates success.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.

See Also

ICEnroll::acceptPKCS7, ICEnroll3::InstallPKCS7


ICEnroll4::removePendingRequest

Platform SDK: Security

ICEnroll4::removePendingRequest[C++]

CEnroll.removePendingRequest[Visual Basic]

[This is preliminary documentation and subject to change.]

The removePendingRequest method removes a pending request from the client's request store.

[Visual Basic]
objEnroll.removePendingRequest( _
  strThumbprint As String _
)
[C++]
HRESULT removePendingRequest(
  BSTR strThumbprint
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic, C++] strThumbprint
[in] The thumbprint, or hash of the certificate data.

Return Values

[Visual Basic] None.

[C++] If the method is successful, the return value is S_OK.

If the method fails, the return value is an HRESULT indicating the error. For a list of common error codes, see Common HRESULT Values.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll4::resetAttributes

Platform SDK: Security

ICEnroll4::resetAttributes[C++]

CEnroll.resetAttributes[Visual Basic]

[This is preliminary documentation and subject to change.]

The resetAttributes method removes all attributes from the request.

[Visual Basic]
objEnroll.resetAttributes( void )
[C++]
HRESULT resetAttributes( void );

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.

[C++] This method has no parameters.

Return Values

[Visual Basic] None.

[C++] If the method is successful, the return value is S_OK.

If the method fails, the return value is an HRESULT indicating the error. For a list of common error codes, see Common HRESULT Values.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll4::resetExtensions

Platform SDK: Security

ICEnroll4::resetExtensions[C++]

CEnroll.resetExtensions[Visual Basic]

[This is preliminary documentation and subject to change.]

The resetExtensions method removes all extensions from the request.

[Visual Basic]
objEnroll.resetExtensions( void )
[C++]
HRESULT resetExtensions( void );

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.

[C++] This method has no parameters.

Return Values

[Visual Basic] None.

[C++] If the method is successful, the return value is S_OK.

If the method fails, the return value is an HRESULT indicating the error. For a list of common error codes, see Common HRESULT Values.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll4::setPendingRequestInfo

Platform SDK: Security

ICEnroll4::setPendingRequestInfo[C++]

CEnroll.setPendingRequestInfo[Visual Basic]

[This is preliminary documentation and subject to change.]

The setPendingRequestInfo method sets properties for a pending request.

[Visual Basic]
objEnroll.setPendingRequestInfo( _
  lRequestID As Long, _
  strCADNS As String, _
  strCAName As String, _
  strFriendlyName As String _
)
[C++]
HRESULT setPendingRequestInfo(
  LONG lRequestID,
  BSTR strCADNS,
  BSTR strCAName,
  BSTR strFriendlyName
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] lRequestID
[in] Identifier for the request, as assigned by the certification authority (CA).
[Visual Basic,C++] strCADNS
[in] The CA's Domain Name System (DNS) name. strCADNS cannot be null.
[Visual Basic,C++] strCAName
[in] The CA's name. strCAName cannot be null.
[Visual Basic,C++] strFriendlyName
[in] The CA's friendly name. strFriendlyName may be null.

Return Values

[Visual Basic] None.

[C++] If the method is successful, the return value is S_OK.

If the method fails, the return value is an HRESULT indicating the error. For a list of common error codes, see Common HRESULT Values.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll4::stringToBinary

Platform SDK: Security

ICEnroll4::stringToBinary[C++]

CEnroll.stringToBinary[Visual Basic]

[This is preliminary documentation and subject to change.]

The stringToBinary method converts an encoded string to a binary data BLOB. This method calls the CryptStringToBinary function.

[Visual Basic]
objEnroll.stringToBinary( _
  Flags As Long, _
  strEncoded As String) As String
[C++]
HRESULT stringToBinary(
  LONG Flags,
  BSTR strEncoded,
  BSTR *pstrBinary
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] Flags
[in] Value passed to the dwFlags parameter of the CryptStringToBinary function. See CryptStringToBinary for valid values.
[Visual Basic,C++] strEncoded
[in] Encoded string to be converted to a binary data BLOB.
[C++] pstrBinary
[out] Pointer to BSTR that receives the binary data. When the BSTR is no longer required, the caller must free it by calling the SysFreeString function.

Return Values

[Visual Basic] The return value is a String containing the binary data.

[C++] If the method is successful, the return value is S_OK.

If the method fails, the return value is an HRESULT indicating the error. For a list of common error codes, see Common HRESULT Values.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll4::GetKeyLenEx

Platform SDK: Security

ICEnroll4::GetKeyLenEx [C++]

CEnroll.GetKeyLenEx [Visual Basic]

[This is preliminary documentation and subject to change.]

The GetKeyLenEx method retrieves size information for the signature and exchange keys. The values retrieved by this method are dependent upon the current cryptographic service provider.

[Visual Basic]
objEnroll.GetKeyLenEx( _
  lSizeSpec As Long, _
  lKeySpec As Long ) As Long
[C++]
HRESULT GetKeyLenEX(
  LONG lSizeSpec,
  LONG lKeySpec,
  LONG *pdwKeySize
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] lSizeSpec
Value indicating the type of size information to be retrieved. Specify one of the following values.
Value | Description
XEKL_KEYSIZE_MIN | Minimum key size.
XEKL_KEYSIZE_MAX | Maximum key size.
XEKL_KEYSIZE_INC | Size of key increment. For more information, see Remarks.

[Visual Basic,C++] lKeySpec
[in] Specifies the key for which size information is returned. Specify one of the following values.
Value | Meaning
XEKL_KEYSPEC_KEYX | Exchange key
XEKL_KEYSPEC_SIG | Signature key

[C++] pdwKeySize
[out] Pointer to a variable that receives the key size information, in bits.

Return Values

[Visual Basic] Value representing the key size information, in bits.

[C++] If the method is successful, the return value is S_OK.

If the method fails, the return value is an HRESULT indicating the error. For a list of common error codes, see Common HRESULT Values.

Remarks

If the cryptographic service provider does not support this method, an error is returned.

For additional details on the XEKL_KEYSIZE_INC value see PP_SIG_KEYSIZE_INC usage in the CryptGetProvParam reference page.

Example Code [C++]

DWORD dwExchMin, dwExchMax, dwSignDef, dwSignInc;

// Determine the minimum and maximum key length values.
// hr is HRESULT variable.
hr = pEnroll4->GetKeyLenEx( XEKL_KEYSIZE_MIN,
                            XEKL_KEYSPEC_KEYX,
                            &dwExchMin );
if ( FAILED( hr ) )
    printf("Failed GetKeyLenEx for Exchange Minimum [%x]\n", hr);
else
    printf("Exchange key Min: %d\n", dwExchMin);

hr = pEnroll4->GetKeyLenEx( XEKL_KEYSIZE_MAX,
                            XEKL_KEYSPEC_KEYX,
                            &dwExchMax );
if ( FAILED( hr ) )
    printf("Failed GetKeyLenEx for Exchange Maximum [%x]\n", hr);
else
    printf("Exchange key Max: %d\n", dwExchMax );

hr = pEnroll4->GetKeyLenEx( XEKL_KEYSIZE_DEFAULT,
                            XEKL_KEYSPEC_SIG,
                            &dwSignDef );
if ( FAILED( hr ) )
    printf("Failed GetKeyLenEx for Signature Default Key size [%x]\n", hr);
else
    printf("Signature key default size: %d\n", dwSignDef );

hr = pEnroll4->GetKeyLenEx( XEKL_KEYSIZE_INC,
                            XEKL_KEYSPEC_SIG,
                            &dwSignInc );
if ( FAILED( hr ) )
    printf("Failed GetKeyLenEx for Signature Key Size Increment [%x]\n", hr);
else
    printf("Signature key increment size: %d\n", dwSignInc );

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll4::PrivateKeyArchiveCertificate

Platform SDK: Security

ICEnroll4::PrivateKeyArchiveCertificate[C++]

CEnroll.PrivateKeyArchiveCertificate[Visual Basic]

[This is preliminary documentation and subject to change.]

The PrivateKeyArchiveCertificate property specifies the certificate that is used to archive a private key with a PKCS #7 or CMC request. If this property is not null, the private key is encrypted based on the specified certificate and added to the request as an unauthenticated attribute.

[Visual Basic]
objEnroll.PrivateKeyArchiveCertificate [ = bstrCert]
[C++]
HRESULT put_PrivateKeyArchiveCertificate(
  BSTR bstrCert
);
HRESULT get_PrivateKeyArchiveCertificate(
  BSTR *pbstrCert
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] bstrCert
A BSTR containing NULL or a binary or base64 encode X.509 certificate used to encrypt the private key.
[C++] pbstrCert
Pointer to a BSTR that receives the certificate used to encrypt the private key.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


ICEnroll4::ThumbPrint

Platform SDK: Security

ICEnroll4::ThumbPrint[C++]

CEnroll.ThumbPrint[Visual Basic]

[This is preliminary documentation and subject to change.]

The ThumbPrint property contains a hash of the certificate data.

[Visual Basic]
objEnroll.ThumbPrint [ = bstrThumbPrint ]
[C++]
HRESULT put_ThumbPrint (
  BSTR bstrThumbPrint
);
HRESULT get_ThumbPrint (
  BSTR *bstrThumbPrint
);

Parameters

[Visual Basic] objEnroll
Object expression that resolves to a CEnroll object.
[Visual Basic,C++] bstrThumbPrint
A BSTR containing a hash of the certificate data.
[C++] bstrThumbPrint
Pointer to a BSTR that receives a hash of the certificate data.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Xenroll.h.
Library: Use Uuid.lib.


Smart Card Enrollment Control

Purpose

Smart Card Enrollment Control enables Microsoft® Windows® 2000 administrators to obtain certificates for smart card users. This functionality is useful because an administrator can enroll and issue the smart card to each user instead of having each user take the steps of enrolling for smart card certificate.

About Smart Card Enrollment Control

General information about Smart Card Enrollment Control.

Using Smart Card Enrollment Control

Smart Card Enrollment Control usage scenario and sample HTML code.

Smart Card Enrollment Control Reference

Documentation of Smart Card Enrollment Control methods and properties.

Feedback

Make error reports and feature requests directly to Microsoft.


About Smart Card Enrollment Control

The Smart Card Enrollment Control is intended to be used by an administrator to enroll on behalf of smart card users. The enrollment process results in a certificate being issued on the user's smart card.

The Smart Card Enrollment Control is contained in scrdenrl.dll and consists of one object, SCrdEnr. No other objects are included in scrdenrl.dll. This Smart Card Enrollment object can be used with a script language, such as Microsoft® Visual Basic® Scripting Edition (VBScript).

A smart card reader must be installed on the machine running the Smart Card Enrollment Control.

Additionally, the smart card issuer must have obtained a signing certificate based on the "EnrollmentAgent" certificate template. This signing certificate will be used to sign the certificate request generated on behalf of the smart card recipient. By default, domain administrators are granted permission to request a certificate based on the "Enrollment Agent" template. Another user can be granted permission to enroll for an "EnrollmentAgent" certificate (by means of the Active Directory Sites and Services MMC snap-in); doing so, however, allows this user to self-issue a smart card with domain administrator privileges.


Using Smart Card Enrollment Control

The Smart Card Enrollment Control usage scenario and sample HTML code are documented in the following sections:

  • Smart Card Enrollment Control Usage Scenario
  • Smart Card Enrollment Control Example


Smart Card Enrollment Control Usage Scenario

The following scenario illustrates the use of the Smart Card Enrollment control by an administrator issuing smart cards for an organization. All methods and properties referenced are provided by the Smart Card Enrollment control.

  1. The administrator obtains an enrollment agent certificate (also known as a signing certificate). The private key associated with this enrollment agent certificate is used to sign a PKCS #7 request; the PKCS #7 request, in turn, contains the user's PKCS #10 request (which is signed with the user's private key).

    The administrator can use the Certificate Manager MMC snap-in to obtain an enrollment agent certificate. Note that although the administrator's enrollment agent certificate will be used to sign the certificate request, the certification authority (CA) will issue and sign the certificate that is stored on the smart card once enrollment has completed.

  2. The administrator uses a machine which is running the Smart Card Enrollment Control; the machine must contain one or more smart card readers. (If the administrator's enrollment agent certificate is stored on a smart card, the machine must contain two smart card readers: one for reading the administrator's enrollment agent smart card certificate, and one for generating the user's smart card certificate).
  3. The administrator sets the name of a certificate template to be used, by calling the setCertTemplateName method. An example of a certificate template name is "User". (If the administrator wishes to determine the available certificate templates, the getCertTemplateCount method retrieves the number of available certificate templates, and the enumCertTemplateName method can be used to enumerate their names).
  4. The administrator sets the name of a CA to be used to issue the certificate. This occurs by calling the setCAName method. (If the administrator wishes to determine the available CAs, the getCACount method returns the number of available CAs, and the enumCAName method can be used to enumerate their names).
  5. The administrator sets the name of a Cryptographic Service Provider (CSP) to be used. This occurs by setting the CSPName property. (If the administrator wishes to determine the available CSPs, the CSPCount property contains the number of available CSPs and the enumCSPName method can be used to enumerate their names).
  6. The administrator specifies a signing certificate to be used to sign the certificate request. This signing certificate is synonymous with the enrollment agent certificate obtained in Step 1. The selectSigningCertificate method invokes a user interface, allowing the administrator to choose the signing certificate. An alternative to using a user interface to select the signing certificate is to call setSigningCertificate. (Once a signing certificate has been specified, the getSigningCertificateName method can be called to retrieve the subject name of the certificate). If the administrator's signing certificate is on a smart card, the smart card must be placed in the smart card reader.
  7. The administrator places the user's smart card in the smart card reader. (Note that if the administrator's signing certificate is on a smart card, there would be at least two smart card readers on the machine; one reader would contain the smart card representing the administrator's enrollment agent certificate, and the other would contain the smart card which is to be issued the user certificate).
  8. The administrator specifies the name of the user to be issued the certificate. This can be done in one of two ways. The administrator can invoke the Select User interface by calling the selectUserName method and choosing the user name, or the administrator can call the setUserName method to specify the desired user name.
  9. The administrator requests a certificate on behalf of the user by calling the ISCrdEnr::enroll method. The CA receiving the request will verify the administrator's signature on the PKCS #7 (as well as verifying that the administrator's enrollment agent certificate was acceptable for enrolling on behalf of a user). The CA will also verify the user's signature on the PKCS #10. If the request is successful, the resulting certificate is automatically placed on the smart card.
  10. [Optional] The administrator can inspect the resulting certificate by calling the getEnrolledCertificateName method.
  11. The administrator removes the user's smart card and issues it to the user.
  12. The administrator calls the resetUser method, which clears the user's name and certificate from the Smart Card Enrollment control's memory, thereby preparing the control for the next user's certificate enrollment.
  13. The administrator repeats steps 7 through 12 for the remaining users on whose behalf the administrator is enrolling for certificates. Optionally, the administrator can change the certificate template, CA, CSP or signing certificate prior to each certificate enrollment.


Smart Card Enrollment Control Example

The following HTML script depicts a basic example using the Smart Card Enrollment Control. The example uses Microsoft Visual Basic Scripting Edition.

<HTML>
<TITLE>Microsoft Smart Card Enrollment Control Demonstration
</TITLE>

<OBJECT classid="clsid:80CB7887-20DE-11D2-8D5C-00C04FC29D45"
    CODEBASE="scrdenrl.dll"
    id=Senroll >
</OBJECT>

<B>Microsoft Smart Card Enrollment Control</B>

<SCRIPT language="VBScript">
<!--
' The following subroutines are contained in this script:
' ChangeCSP - called when the user specifies the CSP.
' ChangeCT - called when the user specifies the certificate template name.
' CTType_OnClick - called when the certificate template type changes.
' EnableEnroll - enables or disables the 'Enroll' button.
' Enroll_OnClick - enrolls for a certificate.
' GetSign_OnClick - selects a signing certificate.
' GetUser_OnClick - invokes the 'Select user' dialog.
' Initialize - executes when the script is downloaded to the client.
' RemoveItems - empties a list box.
' Reset_OnClick - resets the user name.
' UpdateCA - displays the certificate authorities in a list box.
' UpdateCSP - displays the crypto service providers in a list box.
' UpdateCT - displays the certificate templates in a list box.
' ViewCert_OnClick - displays the enrolled certificate.

Option Explicit
' Variables to determine if the necessary information
' has been provided by the admin user. These variables
' determine if the 'Enroll' button is enabled or disabled.
Dim CSP_OK      ' Cryptographic Service Provider specified.
Dim SignCert_OK ' Signing Certificate specified.
Dim CT_OK       ' Certificate template specified.
Dim CA_OK       ' Certification Authority specified.
Dim User_OK     ' User name specified.

' Consts
Const SCARD_ENROLL_USER_CERT_TEMPLATE = &H1
Const SCARD_ENROLL_MACHINE_CERT_TEMPLATE = &H2
Const SCARD_ENROLL_UPN_NAME = 1
Const SCARD_ENROLL_SAM_COMPATIBLE_NAME = 2
Const SCARD_ENROLL_CA_MACHINE_NAME = &H1
Const SCARD_ENROLL_NO_DISPLAY_CERT = &H1

sub ChangeCSP
    Senroll.CSPName = document.SCEnrForm.CSP.value
end sub

sub ChangeCT
    Senroll.setCertTemplateName 0, document.SCEnrForm.CT.value
    Call UpdateCA()
end sub

sub CTType_OnClick
    ' The certificate template type changed;
    ' update the list of certificate templates accordingly.
    Call UpdateCT()
end sub

sub EnableEnroll()
    ' This procedure enables the "Enroll" button if the necessary
    ' information has been entered. This gets called whenever a
    ' change occurs to the CSP, SigningCert, CT or User.
    ' This doesn't get called when the CA is changed because
    ' a change to the CT determines the availability of a CA.
    Dim Data_OK
    Data_OK = CSP_OK And SignCert_OK And CT_OK And CA_OK And User_OK
    document.SCEnrForm.Enroll.disabled = Not Data_OK
end sub

sub Enroll_OnClick
    Senroll.enroll(0)
    ' Allow the resulting cert to be viewed.
    SCEnrForm.ViewCert.disabled=False
end sub

sub GetSign_OnClick
    Dim strSignCert

    ' Select the EnrollmentAgent signing certificate.
    Senroll.selectSigningCertificate 0, "EnrollmentAgent"

    ' Retrieve the name of the signing certificate
    ' without displaying the cert user interface.
    strSignCert = Senroll.getSigningCertificateName(SCARD_ENROLL_NO_DISPLAY_CERT)

    If ( "" <> strSignCert ) Then
        document.SCEnrForm.SignCert.value = strSignCert
        SignCert_OK = True
    Else
        SignCert_OK = False
    End If

    ' Updated SignCert_OK flag.
    Call EnableEnroll()
end sub

sub GetUser_OnClick
    Dim strUser
    ' Clear user/certificate info.
    call Reset_OnClick()
    ' Invoke the 'Select user' dialog.
    Senroll.selectUserName(0)
    ' Retrieve the user name.
    strUser = Senroll.getUserName(0)
    If ( "" <> strUSer ) Then
        ' Display the user name in the form.
        document.SCEnrForm.User.Value = strUser
        ' Allow the administrator to clear this user info.
        document.SCEnrForm.Reset.disabled = False
        User_OK = True
        ' Because User_OK changed, call EnableEnroll().
        Call EnableEnroll()
    End If
end sub

sub Initialize
    ' Set the information variables to false.
    CSP_OK      = false
    SignCert_OK = false
    CT_OK       = false
    CA_OK       = false
    User_OK     = false

    ' Update the CSP listbox.
    Call UpdateCSP()

    ' Update the certificate template listbox.
    Call UpdateCT()

    ' Instruct the administrator to select a signing cert.
    document.SCEnrForm.SignCert.Value = "Select a signing certificate"
    ' Instruct the administrator to select a user.
    document.SCEnrForm.User.Value = "Select a user"
end sub

' Remove all elements of a list box.
sub RemoveItems( List1 )
   Dim nCount, nIndex, LB

   ' Determine which list box is being emptied.
   Select Case List1
       Case "CA"
           set LB = document.SCEnrForm.CA
       Case "CT"
           set LB = document.SCEnrForm.CT
       Case Else
           Exit Sub
   End Select

  ' Remove items in a loop.
  nCount = LB.length
  For nIndex = 0 to nCount - 1
      LB.Remove 0
  Next
end sub

sub Reset_OnClick
    Senroll.resetUser()
    document.SCEnrForm.User.Value = "Select a user"

    ' Disable this button (it will be enabled when a user is selected).
    document.SCEnrForm.Reset.disabled = True

    ' Disable the ViewCert button, because
    ' the resetUser() method removes the cert from memory.
    SCEnrForm.ViewCert.disabled=True

    User_OK = False
    ' Disable enroll button.
    Call EnableEnroll()
end sub

sub UpdateCA
    ' Update the list of CAs.
    ' This will be called every time a different Cert Template is selected.
    Dim nCount, nIndex, strCTName, Element

    ' Empty the list of CAs currently displayed.
    RemoveItems("CA")

    ' List the CAs for the current certificate template.
    strCTName = Senroll.getCertTemplateName( 0 )
    nCount = Senroll.getCACount(strCTName)
    If ( 0 = nCount ) Then
        CA_OK = False
        MsgBox("No Certification Authority is available for the specified certificate template.")
    Else
        ' At least one CA exists.
        CA_OK = True
        ' Populate the list of CAs.
        For nIndex = 0 To nCount - 1
            Set Element=document.createElement("OPTION")
            Element.text=Senroll.enumCAName( nIndex, 0, strCTName )
            Element.value=Element.text
            document.SCEnrForm.CA.Options.Add Element
        Next
        ' Select the top element in the list.
        document.SCEnrForm.CA.selectedIndex=0
    End If
end sub

sub UpdateCSP
    Dim nCount, nIndex, Element

    ' Display the CSPs in the list box.
    ' Determine the count of CSPs.
    nCount = Senroll.CSPCount
    If ( 0 = nCount ) Then
        MsgBox("No CSPs available.")
    Else
        ' At least one CSP exists.
        CSP_OK = True
        ' Add the CSP names to the CSP list
        For nIndex = 0 to nCount - 1
            Set Element=document.createElement("OPTION")
            Element.text=Senroll.enumCSPName( nIndex, 0 )
            Element.value=Element.text
            document.SCEnrForm.CSP.Options.Add Element
        Next
        ' Make the first item the selected item.
        ' This is for the user's viewing benefit.
        ' The Smart Card enrollment control upon initialization will
        ' have set the CSPName property to the value
        ' returned by enumCSPName(0, 0).
        document.SCEnrForm.CSP.selectedIndex=0
    End If
end sub

sub UpdateCT
    Dim nIndex, nCount, Element, CertTempType

    ' Determine the Type of certificate template.
    if ( document.SCenrForm.CTType(0).checked ) then
        CertTempType = SCARD_ENROLL_USER_CERT_TEMPLATE
    else
        CertTempType = SCARD_ENROLL_MACHINE_CERT_TEMPLATE
    end if

    ' Display the certificate templates in the list box.
    ' Empty the existing contents.
    RemoveItems("CT")

    ' Determine the count of Cert Templates.
    nCount = Senroll.getCertTemplateCount(CertTempType)

    If ( 0 = nCount ) Then
        CT_OK = False
        MsgBox("No certificate templates available.")
    Else
        ' At least one cert template exists.
        CT_OK = True
        ' Add the cert templates names to the CT list
        For nIndex = 0 to nCount - 1
            Set Element=document.createElement("OPTION")
            Element.text=Senroll.enumCertTemplateName( nIndex, CertTempType )
            Element.value=Element.text
            document.SCEnrForm.CT.Options.Add Element
        Next
        ' Make the first item the selected item.
        ' This is for the user's viewing benefit.
        ' The Smart Card enrollment control upon initialization will
        ' have set the CertTemplateName property to the value
        ' returned by enumCertTemplateName(0, 1).
        document.SCEnrForm.CT.selectedIndex=0
       ' Display the certification authorities in the list box.
       Call UpdateCA()
    End If
end sub

sub ViewCert_OnClick
    Dim strEnrolledCert

    ' Retrieve the name of the enrolled certificate and
    ' display the certificate viewer user interface.
    strEnrolledCert = Senroll.getEnrolledCertificateName(0)
end sub

-->
</SCRIPT>

<BODY LANGUAGE=VBScript OnLoad="Initialize">

<FORM NAME="SCEnrForm">
<P>
    Cryptographic Service Provider <SELECT NAME="CSP" SIZE=1 ID="CSP" onChange="ChangeCSP" LANGUAGE="VBScript">
                              </SELECT>
<P>
    Administrator Signing Certificate <INPUT NAME="SignCert" SIZE=40 READONLY><INPUT NAME="GetSign" TYPE="button" VALUE="Select Signing Certificate">
<P>
    Certificate Template <SELECT NAME="CertTemplate" SIZE=1 ID="CT" onChange="ChangeCT" LANGUAGE="VBScript">
                              </SELECT>  <INPUT NAME="CTType" onclick = "CTType_OnClick" ID="CTType" TYPE="radio" CHECKED VALUE=1>User <INPUT NAME="CTType" ID="CTType" onclick=CTType_OnClick TYPE="radio" VALUE=2>Machine
<P>
    Certification Authority <SELECT NAME="CertAuth" SIZE=1 ID="CA" onChange="ChangeCA" LANGUAGE="VBScript">
                              </SELECT>
<P>
    Enroll on behalf of <INPUT NAME="User" SIZE=40 READONLY><INPUT NAME="GetUser" TYPE="button" VALUE="Select User">
<P>
<INPUT NAME="Enroll" TYPE="button" VALUE="Enroll" DISABLED>
<INPUT NAME="Reset" TYPE="button" VALUE="Reset User" DISABLED>
<INPUT NAME="ViewCert" TYPE="button" VALUE="View Certificate" DISABLED>
</FORM></P>

</BODY>
</HTML>


Smart Card Enrollment Control Reference

This section describes the methods and properties available in the Smart Card Enrollment Control APIs. The information is categorized in the following sections:

  • Smart Card Enrollment Control Methods
  • Smart Card Enrollment Control Properties


Smart Card Enrollment Control Methods

The file scrdenrl.dll provides the functionality for the Smart Card Enrollment Control. The Smart Card Enrollment Control consists of one object, identified as SCrdEnr. The following methods are provided for the Smart Card Enrollment Control object.

Method | Description
enroll | Requests a smart card certificate.
enumCAName | Enumerates the certification authority (CA) names for a certificate template.
enumCertTemplateName | Enumerates the certificate template names.
enumCSPName | Enumerates the names of the cryptographic service providers.
getCACount | Retrieves the count of Windows 2000 Advanced Server CAs willing to issue a certificate based on the specified certificate template.
getCAName | Retrieves the specified Windows 2000 Enterprise CA name or machine name for the specified certificate template.
getCertTemplateCount | Retrieves the number of certificate templates.
getCertTemplateName | Retrieves the name of the certificate template for the certificate to be requested.
getCertTemplateSMIME | Used to determine whether e-mail protection is one of the key usages in the certificate template.
getEnrolledCertificateName | Retrieves the subject name of the enrolled certificate.
getSigningCertificateName | Retrieves the subject name of the certificate to use when signing the certificate request.
getUserName | Retrieves the name of the user to be issued the smart card.
resetUser | Resets the user name.
selectSigningCertificate | Chooses a signing certificate which will be used to sign the certificate request.
selectUserName | Selects a user name.
setCAName | Specifies the Windows 2000 Enterprise CA to use for the specified certificate template.
setCertTemplateName | Specifies the name of the certificate template for the certificate to be requested.
setSigningCertificate | Specifies a signing certificate which will be used to sign the certificate request.
setUserName | Specifies the name of the user to be issued the smart card.


ISCrdEnr::enroll

The enroll method is used to request a certificate on behalf of the user and store the resulting certificate on the user's smart card.

objSCEnroll.enroll(dwFlags As Long)

Parameters

objSCEnroll
Object expression that resolves to a SCrdEnr object.
dwFlags
Reserved for future use. Set this value to 0.

Return Values

This method has no return values.

Remarks

During the processing of this method, the resulting certificate will be available for storage on the smart card. Before the certificate is written to the smart card, the user will be prompted for the smart card PIN and, if necessary, for confirmation to overwrite the smart card's existing credentials. If the user doesn't enter the correct PIN number, or if the user declines to overwrite the smart card's existing credentials, this method will fail.

When re-issuing a smart card that previously contained a certificate, it may be necessary to run vendor-specific personalization software (prior to enrolling with the Smart Card Enrollment control) to ensure that a different public/private key pair is generated for the smart card. Consult your smart card vendor's documentation for instructions.

Valid names for the following items are mandatory for this method to be successful.

Names Required For… | Names Assigned By…
Certification authority (CA) | ISCrdEnr::setCAName method.
Certificate template | ISCrdEnr::setCertTemplateName method.
Cryptographic Service Provider | ISCrdEnr::CSPName property.
Signing certificate | ISCrdEnr::selectSigningCertificate method or ISCrdEnr::setSigningCertificate method.
User | ISCrdEnr::selectUserName method or ISCrdEnr::setUserName method.

The caller can retrieve the resulting certificate by means of ISCrdEnr::getEnrolledCertificateName.

Example Code in VBScript

' Senroll is a previously instantiated SCrdEnr object.
Senroll.enroll(0)

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Included as a resource in Scrdenrl.dll.

See Also

ISCrdEnr::getEnrolledCertificateName


ISCrdEnr::enumCAName

The enumCAName method enumerates the names of the certification authorities (CAs) for a given certificate template name.

objSCEnroll.enumCAName( _
    dwIndex As Long, _
    dwFlags As Long, _
    bstrCertTemplateName As String ) As String

Parameters

objSCEnroll
Object expression that resolves to a SCrdEnr object.
dwIndex
Zero-based index for the enumeration sequence.
dwFlags
Value that specifies whether the name refers to the CA name or the CA's machine name. If this value is SCARD_ENROLL_CA_MACHINE_NAME (defined as 0x01), the name refers to the CA's machine name. Otherwise the name refers to the CA name.
bstrCertTemplateName
Name of the certificate template.

Return Values

String representing the name of the CA.

Example Code in VBScript

' Define the constants.
Const SCARD_ENROLL_CA_MACHINE_NAME = 1

Dim  strCTName, strMachine, strFullCAName
Dim  nCount, nIndex

' Specify the certificate template name.
strCTName = "User"

' Retrieve the number of available CAs.
nCount = Senroll.getCACount( strCTName )
If ( 0 = nCount ) Then
    MsgBox("No CAs available for the specified certificate template.")
Else
    ' Display each CA name in a message box.
    For nIndex = 0 to nCount - 1
        strFullCAName = Senroll.enumCAName( nIndex, _
                        SCARD_ENROLL_CA_MACHINE_NAME, _
                        strCTName)
        strFullCAName = strFullCAName & "\"
        strFullCAName = strFullCAName & _
                        Senroll.enumCAName( nIndex, _
                        0, _
                        strCTName)
        MsgBox( strFullCAName )
    Next
End If

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Included as a resource in Scrdenrl.dll.

See Also

ISCrdEnr::getCACount, ISCrdEnr::getCAName, ISCrdEnr::setCAName


ISCrdEnr::enumCertTemplateName

The enumCertTemplateName method enumerates the certificate template names.

objSCEnroll.enumCertTemplateName( _
    dwIndex As Long, _
    dwFlags As Long) As String

Parameters

objSCEnroll
Object expression that resolves to a SCrdEnr object.
dwIndex
Zero-based index for the enumeration sequence.
dwFlags
Value which determines whether the enumerated certificate template applies to User or Machine certificates. If this value is SCARD_ENROLL_USER_CERT_TEMPLATE (defined as 1), the enumeration applies to user certificate templates. If this value is SCARD_ENROLL_MACHINE_CERT_TEMPLATE (defined as 2), the enumeration applies to machine certificate templates.

Return Values

String specifying the name of the enumerated certificate template.

Example Code in VBScript

' Define the constants.
Const SCARD_ENROLL_USER_CERT_TEMPLATE = 1
Const SCARD_ENROLL_MACHINE_CERT_TEMPLATE = 2

Dim nCount, nIndex, CertTempType

CertTempType = SCARD_ENROLL_USER_CERT_TEMPLATE

' Determine the count of certificate template names.
nCount = Senroll.getCertTemplateCount(CertTempType)
' Display the certificate template names.
For nIndex = 0 to nCount - 1
    MsgBox( Senroll.enumCertTemplateName( nIndex, CertTempType ) )
Next

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Included as a resource in Scrdenrl.dll.

See Also

ISCrdEnr::getCertTemplateCount, ISCrdEnr::getCertTemplateName, ISCrdEnr::setCertTemplateName


ISCrdEnr::enumCSPName

The enumCSPName method enumerates the name of the available cryptographic service providers (CSPs).

objSCEnroll.enumCSPName( _
    dwIndex As Long, _
    dwFlags As Long ) As String

Parameters

objSCEnroll
Object expression that resolves to a SCrdEnr object.
dwIndex
Zero-based index for the enumeration sequence.
dwFlags
Reserved for future use. Set this value to 0.

Return Values

String representing the name of the enumerated CSP.

Example Code in VBScript

Dim nCount, nIndex, Element

' Determine the count of CSPs.
nCount = Senroll.CSPCount
If ( 0 = nCount ) Then
    MsgBox("No CSPs available.")
Else
    ' Display the CSPs in the list box.
    For nIndex = 0 to nCount - 1
       ' Add each CSP name to the CSP list
        Set Element=document.createElement("OPTION")
        Element.text=Senroll.enumCSPName( nIndex, 0 )
        Element.value=Element.text
        ' document.SCEnrForm.CSP.Options is a SELECT control.
        document.SCEnrForm.CSP.Options.Add Element
    Next
End If

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Included as a resource in Scrdenrl.dll.

See Also

ISCrdEnr::CSPCount, ISCrdEnr::CSPName


ISCrdEnr::getCACount

The getCACount method returns the number of Windows 2000 Enterprise certification authorities (CAs) willing to issue a certificate based on the specified certificate template.

objSCEnroll.getCACount( _
    bstrCertTemplateName As String) As Long

Parameters

objSCEnroll
Object expression that resolves to a SCrdEnr object.
bstrCertTemplateName
String representing the name of the certificate template.

Return Values

Long value representing the number of available CAs that will issue a certificate for the certificate template specified in bstrCertTemplateName.

Example Code in VBScript

Dim nCount

' strCTName is the name of a certificate template.
nCount = Senroll.getCACount(strCTName)
If ( 0 = nCount ) Then
    MsgBox("No CA available for the specified certificate template.")
Else
    MsgBox("Number of CAs is " & nCount )
End If

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Included as a resource in Scrdenrl.dll.

See Also

ISCrdEnr::enumCAName, ISCrdEnr::getCAName


ISCrdEnr::getCAName

The getCAName method retrieves the name of the specified certification authority (CA) for a given certificate template.

objSCEnroll.getCAName( _
    dwFlags As Long, _
    bstrCertTemplateName As String) As String

Parameters

objSCEnroll
Object expression that resolves to a SCrdEnr object.
dwFlags
Value which specifies if the name refers to the CA name or the CA's machine name. If this value is SCARD_ENROLL_CA_MACHINE_NAME (defined as 0x01) then the name refers to the CA's machine name; otherwise the name refers to the CA name.
bstrCertTemplateName
Name of the certificate template.

Return Values

String representing the name of the CA.

Remarks

The default CA name is the first name in the available list of CAs.

Example Code in VBScript

' Define the constants.
Const SCARD_ENROLL_CA_MACHINE_NAME = 1

Dim strMachineName, strCAName, strCTName

strCTName = "User"

strMachineName = Senroll.getCAName( _
                 SCARD_ENROLL_CA_MACHINE_NAME, _
                 strCTName)

strCAName = Senroll.getCAName( _
            0, _
            strCTName)

MsgBox( strMachineName & "\" & strCAName )

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Included as a resource in Scrdenrl.dll.

See Also

ISCrdEnr::enumCAName, ISCrdEnr::getCACount, ISCrdEnr::setCAName


ISCrdEnr::getCertTemplateCount

The getCertTemplateCount method retrieves the number of certificate templates.

objSCEnroll.getCertTemplateCount (dwFlags As Long) As Long

Parameters

objSCEnroll
Object expression that resolves to a SCrdEnr object.
dwFlags
Value that determines if the template is for user or machine certificates. If this value is SCARD_ENROLL_USER_CERT_TEMPLATE (defined as 1) then the returned count will be for user certificate templates. If this value is SCARD_ENROLL_MACHINE_CERT_TEMPLATE (defined as 2) then the returned count will be for machine certificate templates.

Return Values

Long value representing the number of certificate templates.

Example Code in VBScript

' Define the constants.
Const SCARD_ENROLL_USER_CERT_TEMPLATE = 1
Const SCARD_ENROLL_MACHINE_CERT_TEMPLATE = 2

Dim nCount, CertTempType

' Specify the type of certificate template.
CertTempType = SCARD_ENROLL_USER_CERT_TEMPLATE

' Determine the count of Cert Templates.
nCount = Senroll.getCertTemplateCount(CertTempType)

If ( 0 = nCount ) Then
    MsgBox("No certificate templates available.")
Else
    MsgBox("Number of certificate templates: " & nCount )
End If

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Included as a resource in Scrdenrl.dll.

See Also

ISCrdEnr::enumCertTemplateName


ISCrdEnr::getCertTemplateName

The getCertTemplateName method retrieves the name of the certificate template.

objSCEnroll.getCertTemplateName( _
            dwFlags As Long ) As String

Parameters

objSCEnroll
Object expression that resolves to a SCrdEnr object.
dwFlags
Value which determines if the certificate template's real name or display name is returned. If dwFlags has the value SCARD_ENROLL_CERT_TEMPLATE_DISPLAY_NAME, the certificate template's display name is retrieved; otherwise, the real name of the certificate template is displayed.

Return Values

String representing the name of the certificate template which will be used in the certificate request.

Remarks

If you do not set the certificate template name by calling ISCrdEnr::setCertTemplateName, the name defaults to the first name in the list of available certificate templates.

Example Code in VBScript

Dim strCTName

' Retrieve the cert template name.
strCTName = Senroll.getCertTemplateName(0)

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Included as a resource in Scrdenrl.dll.

See Also

ISCrdEnr::setCertTemplateName


ISCrdEnr::getCertTemplateSMIME

The getCertTemplateSMIME method is used to determine if a certificate template contains the szOID_PKIX_KP_EMAIL_PROTECTION key usage. If this key usage is part of the certificate template, the certificate template supports S/MIME operations.

objSCEnroll.getCertTemplateSMIME( _
            bstrCertTemplateName As String ) As Long

Parameters

objSCEnroll
Object expression that resolves to a SCrdEnr object.
bstrCertTemplateName
Name of the certificate being queried for the S/MIME key usage.

Return Values

Long value of 1 if bstrCertTemplateName supports S/MIME; otherwise 0.

Remarks

The constant for szOID_PKIX_KP_EMAIL_PROTECTION is defined in wincrypt.h.

Example Code in VBScript

Dim lSMIME

' strCTName is a certificate template name, such as
' "ExchangeUser".
lSMIME = Senroll.getCertTemplateSMIME(strCTName)

' Use lSMIME as needed.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Included as a resource in Scrdenrl.dll.

See Also

ISCrdEnr::enroll


ISCrdEnr::getEnrolledCertificateName

The getEnrolledCertificateName method retrieves the name of the certificate resulting from an earlier successful call to ISCrdEnr::enroll. This method can also be used to display the certificate in a dialog box. This method calls the CryptoAPI function CertGetNameString.

objSCEnroll.getEnrolledCertificateName( _
            dwFlags As Long ) As String

Parameters

objSCEnroll
Object expression that resolves to a SCrdEnr object.
dwFlags
Value that determines whether the certificate is displayed in a dialog box. If this value is SCARD_ENROLL_NO_DISPLAY_CERT (defined as 0x01), the enrolled certificate is not displayed; any other values cause the enrolled certificate to be displayed in the Certificate dialog box.

Return Values

String representing the retrieved certificate name.

Remarks

Because this method operates on an existing certificate, you must have successfully called IScrdEnr::enroll before you can call getEnrolledCertificateName.

The getEnrolledCertificateName method calls the CertGetNameString function to retrieve the certificate name according to the sequence described for the CERT_NAME_SIMPLE_DISPLAY_TYPE value of CertGetNameString's dwType parameter.

Example Code in VBScript

' Define the constant.
Const SCARD_ENROLL_NO_DISPLAY_CERT = 1

Dim strEnrolledCert

' Retrieve the name of the enrolled certificate and
' display the certificate viewer dialog box.
strEnrolledCert = Senroll.getEnrolledCertificateName(0)

' Retrieve the name of the enrolled certificate
' without displaying the certificate viewer dialog box.
strEnrolledCert = Senroll.getEnrolledCertificateName(SCARD_ENROLL_NO_DISPLAY_CERT)

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Included as a resource in Scrdenrl.dll.

See Also

ISCrdEnr::enroll


ISCrdEnr::getSigningCertificateName

The getSigningCertificateName method retrieves the subject name from the signing certificate. This method can also be used to display the certificate in a dialog box. This method calls the CryptoAPI function CertGetNameString.

objSCEnroll.getSigningCertificateName( _
    dwFlags As Long ) As String

Parameters

objSCEnroll
Object expression that resolves to a SCrdEnr object.
dwFlags
Value that determines whether the certificate is displayed in a dialog box. If this value is SCARD_ENROLL_NO_DISPLAY_CERT (defined as 0x01), the signing certificate is not displayed; any other values result in the signing certificate being displayed in the Certificate dialog box.

Return Values

String representing the name of the signing certificate. The signing certificate will be used to sign the certificate request.

Remarks

The getSigningCertificateName method returns the subject name of the certificate you (or another administrator) have selected in a previous successful call to ISCrdEnr::selectSigningCertificate or ISCrdEnr::setSigningCertificate. This method calls the CertGetNameString function to retrieve the subject name according to the sequence described for the CERT_NAME_SIMPLE_DISPLAY_TYPE value of CertGetNameString's dwType parameter.

Example Code in VBScript

' Define the constant.
Const SCARD_ENROLL_NO_DISPLAY_CERT = 1

Dim strSignCert

' Retrieve the name of the signing certificate and
' display the Certificate dialog box.
strSignCert = Senroll.getSigningCertificateName(0)

' Retrieve the name of the signing certificate
' without displaying the certificate dialog box.
strSignCert = Senroll.getSigningCertificateName(SCARD_ENROLL_NO_DISPLAY_CERT)

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Included as a resource in Scrdenrl.dll.

See Also

ISCrdEnr::selectSigningCertificate


ISCrdEnr::getUserName

The getUserName method retrieves the name of the user on whose behalf the certificate enrollment is intended. Before calling this method, you must specify the user name in a call to ISCrdEnr::selectUserName or ISCrdEnr::setUserName.

objSCEnroll.getUserName (dwFlags As Long) As String

Parameters

objSCEnroll
Object expression that resolves to a SCrdEnr object.
dwFlags
This value must be either 0, SCARD_ENROLL_UPN_NAME or SCARD_ENROLL_SAM_COMPATIBLE_NAME.

If this value is SCARD_ENROLL_UPN_NAME, getUserName returns the user's Universal Principal Name, such as "someone@microsoft.com".

If this value is SCARD_ENROLL_SAM_COMPATIBLE_NAME, the method returns the user's security access manager (SAM) name in the format "DOMAIN\USER".

If this value is 0, the method returns the user's UPN name if it exists. If the user doesn't have a UPN name, the method returns the user's SAM name.

Remarks

You can specify the name of the user to whom the smart card is issued by calling either ISCrdEnr::setUserName or ISCrdEnr::selectUserName. Once a user name has been specified, its value can be retrieved by calling getUserName.

Example Code in VBScript

' Retrieve the user name.
Dim strUser
strUser = Senroll.getUserName(0)

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Included as a resource in Scrdenrl.dll.

See Also

ISCrdEnr::resetUser, ISCrdEnr::selectUserName, ISCrdEnr::setUserName


ISCrdEnr::resetUser

The resetUser method clears the user name from the smart card control.

objSCEnroll.resetUser()
objSCEnroll
Object expression that resolves to a SCrdEnr object.

Parameters

This method has no parameters.

Return Values

This method has no return values.

Remarks

This method clears any existing user name and previously enrolled certificate from memory. (The previously enrolled certificate is not removed from the smart card, however).

Example Code in VBScript

Senroll.resetUser()

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Included as a resource in Scrdenrl.dll.

See Also

ISCrdEnr::getUserName , ISCrdEnr::selectUserName, ISCrdEnr::setUserName


ISCrdEnr::selectSigningCertificate

The selectSigningCertificate method displays a Select Certificate dialog box, allowing a signing certificate (also known as the enrollment agent certificate) to be selected. Before enrolling on behalf of users, you must select a signing certificate. The private key associated with this signing certificate is used to sign a PKCS #7 request. The PKCS #7, in turn, contains the user's PKCS #10 request (which is signed with the user's private key).

objSCEnroll.selectSigningCertificate( _
    dwFlags As Long, _
    bstrCertTemplateName As String)

Parameters

objSCEnroll
Object expression that resolves to a SCrdEnr object.
dwFlags
Reserved for future use. Set this value to 0.
bstrCertTemplateName
String representing the name of the certificate template for the signing certificate. You can use the value "EnrollmentAgent" if you have obtained an EnrollmentAgent certificate.

Return Values

This method has no return values.

Remarks

Before enrolling on behalf of a user, you must first obtain a signing certificate. You can obtain a signing certificate by using the Certificate Manager MMC snap-in. The selectSigningCertificate method does not obtain the signing certificate but displays a dialog box of previously obtained signing certificates, allowing you to choose which certificate will be used to sign the enroll-on-behalf requests.

An alternative to selectSigningCertificate is ISCrdEnr::setSigningCertificate.

Once a signing certificate is selected, its name can be retrieved by calling ISCrdEnr::getSigningCertificateName.

Example Code in VBScript

' Select the EnrollmentAgent signing certificate.
Senroll.selectSigningCertificate 0, "EnrollmentAgent"

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Included as a resource in Scrdenrl.dll.

See Also

ISCrdEnr::getSigningCertificateName


ISCrdEnr::selectUserName

The selectUserName method displays a 'Select User' interface, allowing a user name to be selected. The user name applies to the user on whose behalf the certificate enrollment is intended.

objSCEnroll.selectUserName(dwFlags As Long)

Parameters

objSCEnroll
Object expression that resolves to a SCrdEnr object.
dwFlags
Reserved for future use. Set this value to 0.

Return Values

This method has no return values.

Remarks

Use this method to select the name of the user. Once a user name has been selected, its value can be retrieved by calling the ISCrdEnr::getUserName method.

An alternative to using the 'Select User' interface is to specify a user by calling the ISCrdEnr::setUserName method.

Example Code in VBScript

' Display the Select User dialog box
Senroll.selectUserName(0)

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Included as a resource in Scrdenrl.dll.

See Also

ISCrdEnr::getUserName, ISCrdEnr::resetUser, ISCrdEnr::setUserName


ISCrdEnr::setCAName

The setCAName method specifies the name of the certification authority (CA).

objSCEnroll.setCAName( _
    dwFlags As Long, _
    bstrCertTemplateName As String, _
    bstrCAName As String)

Parameters

objSCEnroll
Object expression that resolves to a SCrdEnr object.
dwFlags
Value that specifies whether the name refers to the CA name or the CA's machine name. If this value is SCARD_ENROLL_CA_MACHINE_NAME (defined as 0x01), the name refers to the CA's machine name. Otherwise, the name refers to the CA name.
bstrCertTemplateName
Name of the certificate template.
bstrCAName
CA name to be used with the certificate template specified by bstrCertTemplateName.

Return Values

This method has no return values.

Remarks

Use this method to specify a CA for a certificate template.

Example Code in VBScript

' Define the constant.
Const SCARD_ENROLL_CA_MACHINE_NAME = 1

' Specify the machine and CA name.
' In this sample, the certificate template is
' specified by strCertTemplateName.
' 1) Specify the machine name.
Senroll.setCAName SCARD_ENROLL_CA_MACHINE_NAME, _
                  strCertTemplateName, _
                  "MyServer"

' 2) Specify the CA name.
Senroll.setCAName 0, _
                  strCertTemplateName, _
                  "MyCA"

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Included as a resource in Scrdenrl.dll.

See Also

ISCrdEnr::enumCAName, ISCrdEnr::getCAName


ISCrdEnr::setCertTemplateName

The setCertTemplateName method specifies the name of the certificate template.

objSCEnroll.setCertTemplateName( _
            dwFlags As Long, _
            bstrCertTemplateName As String )

Parameters

objSCEnroll
Object expression that resolves to a SCrdEnr object.
dwFlags
Value which determines if the certificate template's real name or display name is being set. If dwFlags has the value SCARD_ENROLL_CERT_TEMPLATE_DISPLAY_NAME, the certificate template's display name is set; otherwise, the real name of the certificate template is set.
bstrCertTemplateName
Name of the certificate template which will be used in the certificate request.

Return Values

This method has no return values.

Remarks

If you do not set the certificate template name by calling ISCrdEnr::setCertTemplateName, the name defaults to the first name in the list of available certificate templates.

Example Code in VBScript

' Set the cert template name.
' strCTName was determined through an enumeration of the
' certificate templates (by means of enumCertTemplateName).
Senroll.setCertTemplateName 0, strCTName

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Included as a resource in Scrdenrl.dll.

See Also

ISCrdEnr::getCertTemplateName


ISCrdEnr::setSigningCertificate

The setSigningCertificate method specifies a signing certificate (also known as the enrollment agent certificate). Before enrolling on behalf of users, you must select or set a signing certificate. The private key associated with this signing certificate is used to sign a PKCS #7 request. The PKCS #7, in turn, contains the user's PKCS #10 request (which is signed with the user's private key).

objSCEnroll.setSigningCertificate( _
    dwFlags As Long, _
    bstrCertTemplateName As String)

Parameters

objSCEnroll
Object expression that resolves to a SCrdEnr object.
dwFlags
Reserved for future use. Set this value to 0.
bstrCertTemplateName
Name of the certificate template for the signing certificate. You can use the value "EnrollmentAgent" if you have obtained an EnrollmentAgent certificate.

Return Values

This method has no return values.

Remarks

Before enrolling on behalf of a user, you must first obtain a signing certificate. You can obtain a signing certificate by using the Certificate Manager MMC snap-in. The setSigningCertificate method does not obtain the signing certificate but informs the Smart Card Enrollment Control which previously obtained signing certificate to use. The setSigningCertificate method searches the caller's "My" store for the most recent signing certificate corresponding to the certificate template specified by bstrCertTemplateName.

An alternative to setSigningCertificate is ISCrdEnr::setSigningCertificate.

Once a signing certificate is set, its name can be retrieved by calling ISCrdEnr::getSigningCertificateName.

Example Code in VBScript

Senroll.setSigningCertificate 0, "EnrollmentAgent"

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Included as a resource in Scrdenrl.dll.

See Also

ISCrdEnr::getSigningCertificateName


ISCrdEnr::setUserName

The setUserName method specifies the name of the user on whose behalf the certificate enrollment is intended.

objSCEnroll.setUserName (dwFlags As Long, _
                         bstrUserName As String)

Parameters

objSCEnroll
Object expression that resolves to a SCrdEnr object.
dwFlags
This value must be either SCARD_ENROLL_UPN_NAME (defined as 1) or SCARD_ENROLL_SAM_COMPATIBLE_NAME (defined as 2).

Set this value to SCARD_ENROLL_UPN_NAME, if the name specified in bstrUserName is the user's Universal Principal Name, such as "someone@microsoft.com". The user's UPN name must correspond to an existing security access manager (SAM) name.

Set this value to SCARD_ENROLL_SAM_COMPATIBLE_NAME, if the name specified in bstrUserName is the user's SAM name in the format of "DOMAIN\USER".

bstrUserName
Name of the user.

Remarks

Call this method to specify the user name to be issued the smart card. An alternative to setUserName is ISCrdEnr::selectUserName.

Once a user name has been specified, its value can be retrieved by calling getUserName.

Example Code in VBScript

' Define the constants.

Const SCARD_ENROLL_UPN_NAME = 1
Const SCARD_ENROLL_SAM_COMPATIBLE_NAME = 2

' Specify the user name.
Senroll.setUserName SCARD_ENROLL_SAM_COMPATIBLE_NAME, _
                    "DOMAIN1\User1"

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Included as a resource in Scrdenrl.dll.

See Also

ISCrdEnr::getUserName, ISCrdEnr::resetUser, ISCrdEnr::selectUserName


Smart Card Enrollment Control Properties

The following properties are provided for the Smart Card Enrollment Control object.

Property | Description
CSPCount | Number of available Cryptographic Service Providers.
CSPName | Name of the CSP to use when processing the request.


ISCrdEnr::CSPCount

The CSPCount property specifies the number of cryptographic service providers. This property is read-only.

objSCEnroll.CSPCount As Long

Parameters

objSCEnroll
Object expression that resolves to a SCrdEnr object.

Example Code in VBScript

Dim nCount
nCount = Senroll.CSPCount

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Included as a resource in Scrdenrl.dll.

See Also

ISCrdEnr::CSPName, ISCrdEnr::enumCSPName


ISCrdEnr::CSPName

The CSPName property specifies the name of the cryptographic service provider (CSP). This property is read-write.

objSCEnroll.CSPName [ = newVal ]

Parameters

objSCEnroll
Object expression that resolves to a SCrdEnr object.
newVal
String representing the new value for the CSP name.

Remarks

Set this property to specify the name of the CSP to use with the Smart Card Enrollment Control; get this property to retrieve the name of the specified CSP.

If you do not specify a value for this property, the CSPName property defaults to the first name in the available list of CSPs.

Example Code in VBScript

' Retrieve the CSP name.
Dim strCSPName
strCSPName = Senroll.CSPName

' Set the CSP Name.
' document.SCEnrForm.CSP is a SELECT control.
Senroll.CSPName=document.SCEnrForm.CSP.value

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Included as a resource in Scrdenrl.dll.

See Also

ISCrdEnr::CSPCount, ISCrdEnr::enumCSPName


Cryptography

The cryptography technologies described in the following sections can be used to provide data security within applications.

Technology | Description
CryptoAPI | Functionality for encoding to and decoding from ASN.1, hashing, encrypting and decrypting data, for authentication using digital certificates, and for managing certificates in certificate stores.
CryptoAPI Tools | Utilities to digitally sign files to be used with Microsoft® Authenticode®, and view and manage certificates, certificate revocation lists (CRLs), and certificate trust lists (CTLs).
Cryptographic Service Providers | Information on how to create a custom CSP, an implementation that provides cryptographic algorithms.
WinTrust | Functionality to verify trust in files, catalogs, memory BLOBs, signatures, or certificates. This technology has been superseded by CryptoAPI.


CryptoAPI

Version 2.0

Purpose

CryptoAPI (an application programming interface) provides services that enable application developers to add security based on cryptography to applications. CryptoAPI includes functionality for encoding to and decoding from ASN.1, hashing, encrypting and decrypting data, for authentication using digital certificates, and for managing certificates in certificate stores. Encryption and decryption are provided both using both session keys and with public/private key pairs.

Developer Audience

This documentation is written for developers writing Microsoft® Win32®-based applications that will enable users to create and exchange documents and other data in a secure environment, especially over non-secure media such as the Internet. Developers should be familiar with C/C++ and the Microsoft Windows® programming environment. Although not required, an understanding of cryptography or security-related subjects is advised.

See Also

Cryptographic Service Providers, CryptoAPI Tools

About CryptoAPI

Provides key cryptography concepts and a high-level view of CryptoAPI technology.

Using CryptoAPI

Presents cryptography processes, procedures, and extended samples of C program and function code that use the CryptoAPI functions.

CryptoAPI Reference

Presents detailed descriptions of the CryptoAPI functions and structures.

Feedback

Make error reports and feature requests directly to Microsoft.


About CryptoAPI

CryptoAPI (an application programming interface) provides services that enable application developers to add security based on cryptography to applications. CryptoAPI includes functionality for encoding to and decoding from ASN.1, encrypting and decrypting data, and for authentication using digital certificates.

This section contains the following topics:

  • About This Documentation
  • Cryptography and CryptoAPI
  • Cryptographic Keys
  • Encoded and Decoded Data
  • Data Encryption and Decryption
  • Hashes and Digital Signatures
  • Digital Certificates
  • Digital Messages


About This Documentation

The following topics are included in this section:

  • What's New in CryptoAPI
  • Additional Documentation on Cryptography


What's New in CryptoAPI

CryptoAPI version 1.0 contained the functionality to handle essential cryptography. In this documentation, the original version 1.0 functionality is included in the base cryptography functions. These functions provide two of the three most important aspects of secure communications — privacy and integrity.

The other important aspect is authentication—the warranty that both the sender and recipient are who they say they are. One method being used to provide authentication in secure communications is the digital certificate (often shortened to just certificate). There is an evolving trend toward incorporating these certificates into secure communications. Functionality to manage and use certificates in secure communications has been added in CryptoAPI 2.0. In addition, version 2.0 also contains functions to encode and decode PKCS #7 (ASN.1) messages.

Added certificate management functions maintain and manage a persistent storage of certificates called a certificate store. The functions also incorporate certificates in outgoing messages and verify certificates that are being received in messages.

CryptoAPI 2.0 adds message management functions at two levels — low-level message functions and simplified message functions. The low-level message functions provide more flexibility than the simplified message functions, but require more function calls.


Additional Documentation on Cryptography

Additional documentation on cryptography and authentication, and the associated security issues includes:

  • Menezes, Alfred J., Paul C. Van Oorschot, Scott A. Vanstone. Handbook of Applied Cryptography. CRC Press Series on Discrete Mathematics and Its Applications. Boca Ratan: CRC Press, 1996.
  • Schneier, Bruce. Applied Cryptography: Protocols, Algorithms, and Source Code in C. New York: John Wiley & Sons, 1996.
  • Stinson, D. R. Cryptography: Theory and Practice (CRC Press Series on Discrete Mathematics and Its Applications). Boca Ratan: CRC Press, 1995.
  • Anderson, R. Why Cryptosystems Fail. Communications of the ACM, v. 37, n. 11, November 1994, pp. 32-40.
  • Cormen, Thomas H., Charles E. Leiserson, Ronald L. Rivest. Introduction to Algorithms. MIT Electrical Engineering and Computer Science Series. Cambridge: MIT Press, 1990.
  • Davies, D.W. and W.L. Price. Security for Computer Networks: An Introduction to Data Security in Teleprocessing and Electronic Funds Transfer. Wiley Series in Communication and Distributed Systems. New York: John Wiley & Sons, 1989.
  • Denning, Dorothy E. Cryptography and Data Security. Addison-Wesley, 1982.
  • International Standard ISO/IEC 9594-8: 1995, Second Edition, Information Technology—Open Systems Interconnection—The Directory: Authentication Framework.
  • RSA Laboratories, a division of RSA Data Security, Inc., RSA Data Security, Inc. Public-Key Cryptography Standards (PKCS), Copyright© 1991–1993.


Cryptography and CryptoAPI

CryptoAPI provides services that enable application developers to add encryption/decryption of data, authentication using digital certificates, and encoding to and decoding from ASN.1 to their Microsoft® Win32®-based applications. Application developers can use the functions in CryptoAPI without knowing details of the underlying implementation, in much the same way as they can use a graphics library without knowing anything about the particular graphics hardware configuration. CryptoAPI works with a number of Cryptographic Service Providers that perform the actual cryptographic functions.


Cryptography Concepts and Tasks

Secure communication over non-secure networks generally involves three major areas of concern: privacy , authentication , and integrity.

In addition to functionality for privacy, authentication, and integrity, CryptoAPI also provides for:

  • Encoding messages to ASN.1 form.
  • Decoding those messages.
  • Managing collections of certificates in certificate stores.
  • Working with trust lists and certificate chains for verification of the validity of certificates.


Privacy

To have privacy, users need to keep anyone except the intended recipient from reading a message. Ensuring privacy usually involves some form of cryptography. To provide privacy, cryptography encrypts (scrambles) messages such that the messages can be stored and transmitted securely.

Data encryption transforms a message written in plain text (called plaintext in the cryptography community) so that it appears as random gibberish. A good data encryption system makes it difficult to transform encrypted data back to plaintext without a secret key. The data to be encrypted can be ASCII text, a database file, or any other data you want to store or transmit securely. In this documentation, the term message is used to refer to any piece of data, plaintext refers to data that has not been encrypted, and ciphertext refers to data that has been encrypted.

Encrypted data can be stored on non-secure media or transmitted over a non-secure network and still remain private. Later, the data can be decrypted into its original form. This process is shown in the following illustration.

Data encryption and decryption are simple processes. When data is encrypted, an encryption key is used. This key is comparable to a physical key that is used to lock a padlock. To decrypt the data, a decryption key is be used. The decryption key is comparable to using a key to unlock a padlock. Encryption and decryption are often done using the same key, but unlike working with physical keys, sometimes encryption and decryption can use different keys from a public/private key pair.

Encryption keys must be kept secret and safe, and must be transmitted securely to other users. This is discussed further in Data Encryption and Decryption. The main challenge is properly restricting access to the decryption key because anyone who possesses it will be able to decrypt all messages that were encrypted with its corresponding encryption key.


Authentication

Secure communications require that the individuals communicating know the identity of those with whom they communicate. Authentication involves verifying the identity of a person or entity. To verify a person's identity, forms of physical documentation, often called credentials, are often used. When a check is cashed, the person cashing the check can ask to see a driver's license. The driver's license is a physical document that increases the merchant's confidence in the identity of the person cashing the check. In this case, the person cashing the check trusts that the state issuing the license adequately verified the license holder's identity.

Passports provide another example. A customs official looks at a passport and accepts it as proof that a person is who he says he is. The official trusts that the government did an adequate job of identifying the passport holder before issuing the passport. In both examples, a level of trust exists in the issuer of the physical document.

Authentication also involves making sure that the data received is the data that was sent. If A sends a message to B, B needs to be able to prove that the message received was the message that A sent and not a message that was substituted for that message. To provide this form of authentication, CryptoAPI provides functions for signing data and verifying signatures using public/private key pairs.

Since communications over a computer network take place with no physical contact between the communicators, verifying identity often depends upon a credential that can be sent and received over a network. Such a credential must be issued by a trusted issuer of credentials.

Digital certificates, commonly known as certificates, are just such a credential. They are a way to verify identity and achieve authentication on a computer network.

A digital certificate is a credential issued by a trusted organization or entity called a certification authority (CA). This credential contains a public key (see Public/Private-Key Pairs) and data that identifies the certificate's subject. A certificate is issued by a CA only after the CA has verified the certificate subject's identity and has confirmed that the public key included with the certificate belongs to that subject.

The communication between a CA and a certificate requester could be accomplished by the requester physically carrying the necessary information, perhaps stored on a floppy disk, to the CA. However, the communication is usually accomplished with a signed message sent over a network. The CA often uses a trusted application program called a certificate server to issues certificates.

For additional information on identity verification and authentication through the use of certificates, see Digital Certificates.


Integrity

Any data sent over a non-secure media can be changed either by accident or on purpose. In the real world, seals are used to provide and prove integrity. A bottle of aspirin, for example, can come in tamper-proof packaging that has an unbroken seal to prove that nothing was put into the package after the package left the manufacturer.

In the same manner, a receiver of data needs not only to be able to verify the identity of the sender of the data, but must also be sure that the data received is exactly the data that was sent; that it has not been tampered with. Establishing the integrity of data received is often done by sending not only the original data but also a verification message, called a hash, about that data. Both the data and the verification message can be sent with a digital signature that proves the origin of both.

Integrity is provided in CryptoAPI by means of using Digital Signatures and Data Hashes.


CryptoAPI

CryptoAPI provides privacy through the use of Base Cryptography Functions, Simplified Message Functions, and Low-Level Message Functions. These functions provide a way for applications to encrypt and digitally sign data in a flexible manner, while providing protection for the user's sensitive private-key data.

CryptoAPI supports authentication through the use of certificates with certificate encode/decode functions, and certificate store functions. A certificate is a data set that uniquely describes a particular entity and usually incorporates that entity's public key. A certificate is issued by a CA after the CA has determined the authenticity of the entity. More detailed information about public keys and certificates is provided in Public/Private Key Pairs and Certificates and Certification Authorities.


CSPs and the Cryptography Process

CryptoAPI functions use cryptographic service providers (CSPs) to perform encryption and decryption, and to provide key storage and security. These CSPs are independent modules. Ideally, CSPs are written to be independent of a particular application, so that any application will run with a variety of CSPs. In reality, however, some applications have specific requirements that require a customized CSP. This compares to the Windows GDI model. CSPs are analogous to graphics device drivers.

The quality of protection for keys within the system is a design parameter of the CSP and not of the system as a whole. This allows an application to run in a variety of security contexts without modification.

The access applications have to the cryptographic internals is carefully restricted. This facilitates secure and portable application development. The following three design rules apply:

  • Applications cannot directly access keying material. Because all keying material is generated within the CSP and used by the application through opaque handles, there is no risk of an application or its associated DLLs either divulging keying material or choosing keying material from poor random sources.
  • Applications cannot specify the details of cryptographic operations. The CSP interface allows an application to choose an encryption or signature algorithm, but the implementation of every cryptographic operation is done by the CSP.
  • Applications do not handle user credentials or other user authentication data. User authentication is done by the CSP; therefore, future CSPs with advanced authentication capabilities, such as biometric inputs, will function without needing to change the application authentication model.

At a minimum, a CSP consists of a dynamic-link library (DLL) and a signature file. The signature file is necessary to ensure that the CryptoAPI recognizes the CSP. CryptoAPI validates this signature periodically to ensure that any tampering with the CSP is detected.

Some CSPs can implement a fraction of their functionality in an address-separated service called through local RPC or in hardware called through a system device driver. Isolating global key-state and central cryptographic operations in an address-separated service or in hardware keeps keys and operations safe from tampering within an application data space.

It is unwise for an applications to take advantage of attributes particular to a specific CSP. For example, the Microsoft Base Cryptographic Provider (supplied with CryptoAPI) currently uses 40-bit session keys and 512-bit public keys. Applications manipulating these keys must avoid assumptions about the amount of memory needed to store these keys because the application is likely to fail if a different CSP is used. Well-written applications must work with a variety of CSPs.

For details about cryptographic provider types and predefined CSPs that can be used with CryptoAPI, see Cryptographic Provider Types and Microsoft Cryptographic Service Providers.


Cryptographic Service Provider Contexts

The first CryptoAPI function called by an application that uses any cryptographic APIs is the CryptAcquireContext function. This function returns a handle to a particular CSP which includes the specification of a particular key container within the CSP. This key container is either a specifically requested key container or it is the default key container for the currently logged-on user.

CryptAcquireContext can also create a new key container. See Example C Program: Creating a Key Container and Generating Keys and Example C Program: Using CryptAcquireContext.

A cryptographic service provider (CSP) has both a name and a type. For example, the name of one of the CSPs currently shipped with the operating system is Microsoft Base Cryptographic Provider. It is an PROV_RSA_FULL type provider. The name of each provider is unique; the provider type is not.

When an application calls CryptAcquireContext to obtain a CSP handle, it specifies a provider type and, optionally, a provider name. If both a type and a name are specified, the function loads the CSP with the matching provider type and provider name. The function returns the CSP's handle which provides access to both the CSP and to a key container within the CSP.

When an application calls CryptAcquireContext and specifies a provider type but no provider name, the function looks for a named provider, first checking a list of default named providers associated with the logged-on user and, if that fails, from a list of default named providers associated with the computer. After the provider name has been determined, the CryptAcquireContext function searches for the CSP for that provider, loads it, and returns its handle.


CryptoAPI System Architecture

The CryptoAPI system architecture is composed of five major functional areas:

  • Base cryptographic functions

    Context functions used to connect to a CSP. These functions enable applications to choose a specific CSP by name or to a specific CSP that can provide a needed class of functionality.

    Key generation functions used to generate and store cryptographic keys. Full support is included for changing chaining modes, initialization vectors, and other encryption features. See Key Generation and Exchange Functions.

    Key exchange functions are used to exchange or transmit keys. See Storage and Exchange of Cryptographic Keys, and Key Generation and Exchange Functions.

  • Certificate encode/decode functions

    Functions used to encrypt or decrypt data. Support is also included for hashing data. See Data Encryption/Decryption Functions and Data Encryption and Decryption.

  • Certificate store functions

    Functions used to manage collections of digital certificates. See Digital Certificates and Certificate Store Functions.

  • Simplified message functions

    Functions used to encrypt and decrypt messages and data.

    Functions used to sign messages and data.

    Functions used to verify the authenticity of signatures on received messages and related data.

    See Simplified Messages, and Simplified Message Functions.

  • Low-level message functions

    Function used to performs all of the tasks performed by the simplified message functions. The low-level message functions provide more flexibility than the simplified message functions but require more function calls. See Low-Level Messages, and Low-Level Message Functions.

Each of the functional areas has a key word in its function name indicating its functional area. Those key words are described as follows:

Functional area | Function name convention
Base cryptographic functions | Crypt
Encoding/decoding functions | Crypt
Certificate store functions | Store
Simplified message functions | Message
Low-level message functions | Msg

Applications use functions in all of these areas. These functions, taken together, make up CryptoAPI. The base cryptographic functions use the CSPs for the necessary cryptographic algorithms and for the generation of and the secure storage for cryptographic keys.

Two different kinds of cryptographic keys are used: session keys used for a single encryption/decryption, and public/private key pairs used on a more permanent basis.

Note Although an application can communicate directly with any of the five functional areas, it cannot communicate directly with a CSP. All application-to-CSP communications occur through the base cryptographic functions. Base cryptographic functions have a parameter that specifies which CSP to use. This parameter can be set to NULL to select a default CSP.


Cryptographic Keys

Cryptographic keys are central to cryptographic operations. They must be kept secret because whoever possesses a given key has access to any data that the key is associated with. For example, if a key is used to encrypt a file, anyone with a copy of that key can decrypt the file. Furthermore, anyone possessing a key used to sign messages can forge that message's signature.

There are two types of cryptographic keys: Session Keys and Public/Private Key Pairs.


Session Keys

Session keys, also called symmetric keys, are used with symmetric encryption algorithms. Symmetric algorithms are the most common type of encryption algorithm. They are called symmetric because they use the same key for both encryption and decryption. Session keys are frequently changed, usually using a different session key for each message encrypted.

Symmetric algorithms are faster than public-key algorithms. Thus, they are preferred when encrypting large amounts of data. Some of the more common symmetric algorithms are RC2, RC4, and the Data Encryption Standard (DES).

Session keys are created by applications using either the CryptGenKey or CryptDeriveKey function.

Since a good deal of the activity involving session keys relates to keeping them secret, it is important to keep the number of people who possess a particular session key as small as possible. (One or two people is recommended.) These keys are kept internal to the CSP for safekeeping.

Unlike public/private key pairs, session keys are volatile. Applications can save these keys for later use or for transmission to other users by using the CryptExportKey function to export them from the CSP into application space in the form of an encrypted "key BLOB." For more information, see Storage and Exchange of Cryptographic Keys.


Public/Private Key Pairs

Public/private key pairs are used for a more secure method of encryption called asymmetric encryption. Asymmetric encryption is used mainly to encrypt and decrypt session keys and digital signatures. Asymmetric encryption uses public-key encryption algorithms.

Public-key algorithms use two different keys: a public key and a private key. The private key member of the pair must be kept private and secure. The public key, however, can be distributed to anyone who requests it. The public key of a key pair is often distributed by means of a digital certificate. When one key of a key pair is used to encrypt a message, the other key from that pair is required to decrypt the message. Thus if user A's public key is used to encrypt data, only user A (or someone who has access to user A's private key) can decrypt the data. If user A's private key is used to encrypt a piece of data, only user A's public key will decrypt the data, thus indicating that user A (or someone with access to user A's private key) did the encryption.

If the private key is used to sign a message, the public key from that pair must be used to validate the signature. For example, if Alice wants to send someone a digitally signed message, she would sign the message with her private key, and the other person could verify her signature by using her public key. Since presumably only Alice has access to her private key, the fact that the signature can be verified with Alice's public key indicates that Alice created the signature.

Unfortunately, public-key algorithms are very slow, — roughly 1,000 times slower than symmetric algorithms. It is impractical to use them to encrypt large amounts of data. In practice, public-key algorithms are used to encrypt session keys. Symmetric algorithms are used for encryption/decryption of most data.

Similarly, because signing a message in effect encrypts the message, it is not practical to use public-key signature algorithms to sign large messages. Instead, a fixed-length hash is made of the message and the hash value is signed. For more details, see Hashes and Digital Signatures.

Each user generally has two public/private key pairs. One key pair is used to encrypt session keys and the other to create digital signatures. These are known as the key exchange key pair and the signature key pair, respectively.

Note that although key containers created by most cryptographic service providers (CSPs) contain two key pairs, this is not required. Some CSPs do not store any key pairs while other CSPs store more than two pairs.

All keys in CryptoAPI are stored within CSPs. CSPs are also responsible for creating the keys, destroying them, and using them to perform a variety of cryptographic operations. Exporting keys out of the CSP so that they can be sent to other users is discussed in Storage and Exchange of Cryptographic Keys.


Storage and Exchange of Cryptographic Keys

There are situations where keys must be exported from the secure environment of the cryptographic service provider (CSP) into an application's data space. Keys that have been exported are stored in encrypted key BLOB structures.

There are two specific situations where it is necessary to export keys:

  • To save a session key for later use by an application, if, for example, an application has just encrypted a database file to be decrypted at a later time. The application is responsible for storing the encryption key. This is necessary because CSPs do not preserve symmetric keys from session to session.
  • To send a key to someone else. This would be easier if the respective CSPs could communicate directly, but they cannot. Because CSPs can't communicate, the key has to be exported from one CSP, transmitted to the destination application, and then imported into the destination CSP. This process can become more complicated if the communication path is not trusted.

In either case, an application must store a session key outside of the CSP for a period of time. For more information, see Procedure for Storing a Session Key.


Key Databases

CryptoAPI uses a cryptographic service provider (CSP), an independent module that performs the real cryptographic work. Several CSPs are available and each CSP has a key database in which it stores cryptographic keys. Each key database contains one or more key containers, each of which contains all the key pairs belonging to a specific CryptoAPI client. Each key container has a unique name that applications provide to the CryptAcquireContext function to acquire access to the key container. The following is an illustration of the contents of a key database.

The CSP stores key containers, including all the public/private key pairs, in some form of permanent storage such as a disk file or under a key in the registry. Session keys are not automatically persisted to any permanent storage media.

Generally, a default key container is created for each user. This key container takes the user's logon name as its name, which is then used by any number of applications. It is also possible for an application to create its own key container and key pairs, which it usually names after itself.


Key BLOBs

Key BLOBs provide a way to store keys outside of the CSP in order to move them to different computers or otherwise transport them. Keys are kept inside the CSP for safekeeping, and applications are allowed access to the key only through a handle. Key BLOBs are the one exception to this rule.

Key BLOBs are created to securely transfer keys from one CSP to another. CryptExportKey creates a key BLOB and copies an existing key from the provider to that BLOB. The key BLOB can then be written out to a file or other storage media. Later, the key BLOB can be imported into a provider (often a different CSP on a different computer) by using CryptImportKey. CryptImportKey creates a duplicate of the exported key in the CSP.

Key BLOBs consist of a standard header, followed by data (a string of unintelligible bytes) that represents the key itself. If the key BLOB contains a session key, this data is always kept encrypted. Applications do not access the contents of key BLOBs. It was this characteristic of being an inaccessible, unintelligible string of bytes that led to the name "key BLOB."

Key BLOBs are personalized in that they are encrypted with the key exchange public key of the intended recipient. This makes them fairly secure. To make them tamper-proof, keys are sometimes signed with the key exchange private key of the originating user.

Four types of key BLOBs are defined:

  • Simple key BLOBs
  • Public key BLOBs
  • Private key BLOBs
  • Opaque key BLOBs


Simple Key BLOB

Platform SDK: Security

Simple Key BLOBs

A simple key BLOB (SIMPLEBLOB) is a session key encrypted with the key exchange public key of the destination user. This key BLOB type is used to store a session key or transmit a session key to another user.

The Microsoft Base Cryptographic Provider version 2.0 format of simple key BLOB is documented in Base Provider Key BLOBs.


Public Key BLOBs

A public key BLOB (PUBLICKEYBLOB) contains the public key portion of a public/private key pair. Unlike simple key BLOBs, public key BLOBs are not encrypted.

When communicating with someone who is not using CryptoAPI, an application might need to build a public key BLOB manually so that the other user's public keys can be imported into your CSP. See Manual Public Key Pair Exchanges for more information.

In addition, it is not uncommon for an application to display the value of a public key in plaintext form so the user can validate it by hand.

The Microsoft Base Cryptographic Provider version 2.0 format of public key BLOB is documented in Base Provider Key BLOBs.


Private Key BLOBs

A private key BLOB (PRIVATEKEYBLOB) contains one complete public/private key pair. Administrative programs use private key BLOBs to distribute or transport public/private key pairs (for example, between a network administrator's computer and a user's computer, or between the user's desktop computer and laptop computer). Private key BLOBs can also be used by advanced applications where the key pairs are stored within the application, rather than relying on the CSP's storage mechanism.

Because the private key portion of the key pair is extremely confidential, these BLOBs are typically kept encrypted with a symmetric cipher.

The Microsoft Base Cryptographic Service Provider format of private key BLOBs is documented in Private-Key BLOBs.


Opaque Key BLOBs

An opaque key BLOB (OPAQUEKEYBLOB) is a session key with all of the current state information. The opaque key BLOB is called "opaque" because its format is unpublished. The key BLOB type is used when storing a session key back into the same CSP from which it was originally exported.


Alternatives to Storing Session Keys

Instead of storing a random session key BLOB, a derived key can be used. Derived session keys are created with a password by using the CryptDeriveKey function. In this way, instead of storing a particular derived key, an application can create a derived key as needed by prompting the user for the password.

Stored key BLOBs depend on the stability of the public/private key pairs stored within the CSP. If these key pairs are somehow lost (for example, through a hardware or software incident), key BLOBs cannot be decrypted. This means that any data that has been encrypted by using these keys will also be lost. To prevent this kind of loss, use a backup authority when storing long-term archival data. A backup authority is a trusted application running on a secure computer that provides storage for the session keys of its clients. All session keys stored there are encrypted in the form of key BLOBs by using the backup authority's public key. See Procedure for Storing Session Keys Using a Backup Authority for more information.


Public Key Pair Exchanges

The first step that two users contemplating encrypted communication need to take is exchanging public keys. After doing this, the users can send encrypted and signed data to each other in a straightforward manner.

There are two fundamental ways to obtain each other's public keys:

  • Users can obtain each other's public keys in the form of certificates issued by a trusted certification authority (CA). Using certificates from a trusted CA is the most secure way to exchange public keys. This method of exchanging keys requires no direct user interaction. For more information, see Certificates and Certification Authorities.
  • Users can read their public keys to each other over the telephone, use certified mail to send them to each other, or use another method that is reasonably tamper-proof. Note that a user's public key is not secret, so that it doesn't matter if it is discovered by a third party. For more information, see Manual Public Key Pair Exchanges.

    This method can also be used to validate the public key values that have been exchanged in some other manner.


Certificates and Certification Authorities

A certificate is a packet of data that contains a user's public key and the data that identifies the user in the real world, such as the user's name. Every certificate is created and signed by a trusted entity known as a certification authority (CA).

Because certificates are signed by a CA, they can be transmitted over a non-secure network or stored on non-secure media. For better security, verify each certificate's signature as it is received using the CA's public key.

For more information on certificates, see Digital Certificates and Certificate Functions.

Warning If you use the Microsoft Base Cryptographic Provider to create a certification authority, your license to issue certificates is limited to certificates intended for use in the context of your particular application or service.


Manual Public Key Pair Exchanges

If a certification authority (CA) is not available, not considered trustworthy, or if users have not registered their public keys with a CA, users must exchange their public keys in some other manner. A direct exchange of public keys that does not involve exchanging certificates is called a manual exchange.

When transferring keys or messages from one user to another, one of the users is designated the sending user (or sender, who uses the sending application) and the other the destination user (or receiver, who uses the receiving application).

The first step is for the sender to export his public key from the CSP into a public key BLOB by using the CryptExportKey function. Next, the key BLOB is sent to the receiver in some secure manner (for example, the sender might hand-carry it on a floppy disk to the receiver). Although secrecy is not necessary, both users must be confident that the integrity of the key BLOB remains untarnished during the transfer. How this is done is completely independent of CryptoAPI.

Public key BLOBs are not encrypted; therefore, it would not be difficult for the sending application to convert the key BLOB to a readable format so that the sender could read the public key to the receiver over the telephone. Furthermore, it would not be difficult for the receiving application to reconstruct the public key BLOB.

After the receiving application has received the key BLOB data from the sending application, it imports the key BLOB into its own CSP using the CryptImportKey function.


Session Key Exchanges

To send another user an encrypted message, the session key used to perform the encryption must be sent to the user who will decrypt the message. There are two ways to approach this:

  • The sending user can create a random session key, encrypt it by using the receiver's public key, and send the encrypted key as a key BLOB to the receiver. See Manual Session Key Exchanges.
  • The sending and receiving users can mutually agree on a session key by exchanging several messages back and forth. The users can then use this session key to send and receive encrypted messages.


Encoded and Decoded Data

To send data over a communication medium such as a phone line, the data must be serialized — that is, converted into a string of ones and zeros that are transmitted serially over the line. Serialization must be done in such a way that the computer receiving the data can convert the data back into its original format. How serialization is accomplished is called a communication protocol, and is controlled by both software and data-transmission hardware. There are several levels at which the data is converted. The following illustration shows a greatly simplified view of communication protocol layers.

The preceding illustration shows the application layer on Computer #1 sending the data to be transmitted (which usually consists of some combination of textual characters and numbers) to the encode/decode layer. The encode/decode layer encodes the data into a stream of computer bytes. At the lowest level, the hardware layer, the hardware converts the bytes of data into a serial stream of ones and zeros that is transmitted over the line to Computer #2. The hardware layer of Computer #2 converts the ones and zeros back into computer bytes, and passes them up to the encode/decode layer for decoding. The encode/decode layer decodes the bytes back into their original format and passes the data up to the application layer.

An accepted software design principle is to use abstraction, that is, the process of describing a problem or object in terms of its general parameters rather than describing all the details necessary to solve the problem, or describing all the details of an object. Using abstraction, a designer can specify a software object that has specific qualities without concern for how the object is actually implemented in the software code. Such a practice leaves the implementation open. It also simplifies the specification and makes it possible to state axioms about the object that can be proved when the object is implemented. These axioms can then be assumed when the object is employed in another, higher-level object. Abstraction is the hallmark of most modern software specifications.

Most communication protocols involve a good deal of abstraction. Objects at higher layers are defined abstractly and are intended to be implemented by using objects at lower layers. For instance, a service at one layer might require transferring certain abstract objects between computers. A lower level layer can use encoding rules to transform the abstract objects into strings of ones and zeros.

One common method of specifying abstract objects intended to be serially transmitted is called Abstract Syntax Notation One (ASN.1). ASN.1 is defined in CCITT Recommendation X.208. One set of ASN.1 rules for representing such objects as strings of ones and zeros is called the Distinguished Encoding Rules (DER), and is defined in CCITT Recommendation X.509, Section 8.7. These are the encoding methods currently used by CryptoAPI. For more information, see Fundamentals of Abstract Syntax Notation One (ASN.1).

For more information on encode/decode functions, see CryptEncodeObject/CryptDecodeObject Functions.


Fundamentals of Abstract Syntax Notation One (ASN.1)

CryptoAPI does not require that the application programmer use ASN.1 notation (language) to encode and decode data. However, a programmer should become familiar with ASN.1 notation because the C structures used by CryptoAPI to encode and decode data mirror the appropriate ASN.1 data types.

A brief overview of ASN.1 is presented in this section. The article A Layman's Guide to a Subset of ASN.1, BER, and DER, by RSA Data Security, Inc., is recommended as additional reading on this subject, and can be found by searching http://www.rsa.com/rsalabs/PKCS.

ASN.1 is a flexible, abstraction notation that allows a variety of data types to be defined, from simple types such as integers and bit strings, to structured types such as collections of one or more other types.

The DER is a set of rules that define how the ASN.1 abstractions get serialized into streams of ones and zeros for transmission over the line. The DER describes how to represent or encode values of each ASN.1 data type as a string of eight-bit bytes. A string of bytes is also called a string of octets.


ASN.1 Simple Types

In ASN.1, a type is a set of values. For some types, there are a finite number of values, and for other types there are an infinite number. A value of a given ASN.1 type is an element of the type's set. ASN.1 has four kinds of types:

  • Simple types - base types that have no components.
  • Structured types - have components.
  • Tagged types - derived from other types.
  • Other types - include the CHOICE type and the ANY type.

Types and values can be given names with the ASN.1 assignment operator (::=), and those names can be used in defining other types and values. Only the first two types will be reviewed in this document. Information on the other types can be found in A Layman's Guide to a Subset of ASN.1, BER, and DER, by RSA Data Security, Inc., available by searching http://www.rsa.com/rsalabs/PKCS.

Simple types are the base types, and do not have components. ASN.1 defines several of these simple types. The types that are relevant to the Public Key Cryptography Standards (PKCS) are the following:

  • BIT STRING - an arbitrary string of bits (ones and zeros).
  • IA5String - an arbitrary string of IA5 (ASCII) characters.
  • INTEGER - an arbitrary integer.
  • NULL - a null value.
  • OBJECT IDENTIFIER - an object identifier, which is a sequence of integer components that identify an object such as an algorithm or attribute type.
  • OCTET STRING - an arbitrary string of octets (eight-bit values).
  • PrintableString - an arbitrary string of printable characters.
  • T61String - an arbitrary string of T.61 (eight-bit) characters.
  • UTCTime - a "coordinated universal time" or Greenwich Mean Time (GMT) value.


ASN.1 Structured Types

Structured types are those consisting of components. ASN.1 defines four structured types, all of which are relevant to PKCS:

  • SEQUENCE - an ordered collection of one or more types.
  • SEQUENCE OF - an ordered collection of zero or more occurrences of a given type.
  • SET - an unordered collection of one or more types.
  • SET OF - an unordered collection of zero or more occurrences of a given type.

The structured types can have optional components, possibly with default values.


Example ASN.1 Notation

The following example uses ASN.1 notation to define certificate request information:

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

In the preceding example, a CertificationRequestInfo object is created and defined as a SEQUENCE. This particular sequence includes the following set of values:

Identifier | Type reference
version | Version
subject | Name
subjectPublicKeyInfo | SubjectPublicKeyInfo
attributes [0] | IMPLICIT Attributes

Notice that the Version type is defined as an integer, and the Attributes type is defined as a SET OF Attribute types.

Additional information on certification request information can be found in the RSA Laboratories Technical Note, PKCS #10: Certification Request Syntax Standard, by RSA Data Security, Inc., which can be found at http://www.rsa.com.


CryptoAPI Encoding/Decoding Model

CryptoAPI is designed to relieve the programmer from performing ASN.1 encoding. Message functions encode and decode Public Key Cryptography Standards (PKCS) #7 messages. The actual encoding and decoding are handled by the function itself. For additional information on message functions, see Low-Level Messages, Simplified Messages, Low-Level Message Functions, and Simplified Message Functions.

For occasions when the message functions are not appropriate, such as when encoding certificate requests, the CryptoAPI provides the CryptEncodeObject and CryptDecodeObject functions to encode and decode data. These functions use C structures that mirror the appropriate ASN.1 SEQUENCE. The programmer works with familiar C structures rather than with the ASN.1 encoding language. For example, the C version of the ASN.1 abstraction for certificate request information presented in the previous section on example ASN.1 notation 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 | Structure Member ID | Structure Type
version | INTEGER | dwVersion | DWORD
subject | Name | Subject | CERT_NAME_BLOB
subjectPublicKeyInfo | SubjectPublicKeyInfo | SubjectPublicKeyInfo | CERT_PUBLIC_KEY_INFO
 |  | cAttribute | DWORD
attributes | IMPLICITAttributes | rgAttribute | PCRYPT_ATTRIBUTE

The structure ID passed into a 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 CryptoAPI.


Encoding and Decoding with CryptoAPI

The encoding process involves encoding nested C structures. First, the lowest level structure is encoded. This is depicted as structure 3 in the following illustration. To do this, the CryptEncodeObject function can be called with structure 3 as its input, and its output will be a BLOB with the input information encoded and provided as a member of structure 2. This process is repeated until the final encoded certificate BLOB is output from the function call.

The decoding process is the opposite of the encoding process. It involves taking an encoded certificate, usually in the form of a BLOB of bits, and decoding it into various predefined C structures. The following illustration depicts the decoding process.

The decoding process starts with the encoded portion of a certificate. A certificate includes both an encoded BLOB and a C structure that duplicates the encoded information. For the sake of clarity, the C structure is not shown here. When the CryptDecodeObject function is run on this BLOB, its output is a C structure that has both usable (non-encoded) members and encoded members that need further decoding. This is depicted as C structure 1 in the preceding illustration. If structure 1 is used as the input to the CryptDecodeObject function, the encoded members are decoded and output as structure 2. Structure 2 will most likely still have encoded members, and the process is repeated until all the members have been fully decoded (depicted as structure 3).

Among the items that the CryptEncodeObject and CryptDecodeObject functions can encode and decode are certificates, certificate extensions, certificate requests, certificate revocation lists, and certificate trust lists. For a complete list of structures that can be encoded and decoded, see CryptEncodeObject/CryptDecodeObject Functions.

For details on using CryptEncodeObject and CryptDecodeObject, see Encoding and Decoding a Certificate Context.

For details on how to use CryptEncodeObject to encode a certificate request, see Example C Program: Making a Certificate Request.


Data Encryption and Decryption

Encryption is the process of translating plain text data (plaintext) into something that appears to be random and meaningless (ciphertext). Decryption is the process of converting ciphertext back to plaintext.

To encrypt more than a small amount of data, symmetric encryption is used. The symmetric key or session key is used during both the encryption and decryption processes. To decrypt a particular piece of ciphertext, the key that was used to encrypt the data must be used. Essentially, a session key consists of a random number, from 40 to 2,000 bits in length. The longer the key, the more difficult it is to decrypt a piece of ciphertext without possessing the key.

The goal of every encryption algorithm is to make it as difficult as possible to decrypt the generated ciphertext without using the key. If a really good encryption algorithm is used, there is no technique significantly better than methodically trying every possible key. Even a key size of just 40 bits works out to just over one trillion possible keys.

It is difficult to determine the quality of an encryption algorithm. Algorithms that look promising sometimes turn out to be very easy to break, given the proper attack. When selecting an encryption algorithm, it is often a good idea to choose one that has been around for a while, and has successfully resisted all attacks.

For more information, see Data Encryption/Decryption Functions.


Encryption/Decryption Techniques and Algorithms

CryptoAPI functions can encrypt and decrypt messages and files. This section discusses various techniques and algorithms available for encrypting data. For C code demonstrating the encryption and decryption of a data file, see Example C Program: Encrypting a File and Example C Program: Decrypting a File. For C code showing the encryption of a message, see Example C Program: Using CryptEncryptMessage and CryptDecryptMessage.

The actual encryption algorithms used in the encryption/decryption process depend on the cryptographic service provider (CSP) in use. However, most CSPs share most of the attributes discussed here. A symmetric algorithm is used for all data encryption performed using the CryptoAPI functions, regardless of which CSP is installed. Applications that call CryptoAPI functions need not anticipate details of the actual algorithms used.

The following table lists performance benchmarks for some common encryption algorithms. These benchmark values were generated by an application using CryptoAPI on a 120-MHz, Pentium-based computer. These figures are for comparison purposes only.

Cipher | Cipher type | Key setup time (microseconds) | Encryption speed (bytes/second)
DES | 64-bit block | 460 | 1,138,519
RC2 | 64-bit block | 40 | 286,888
RC4 | stream | 151 | 2,377,723


Stream Ciphers

Stream cipher algorithms encrypt data one bit at a time. A stream of plaintext bits flows into the encryption process and a stream of encrypted ciphertext flows out. At least, this is the way it works mathematically; in practice, data is always encrypted in byte units.

Stream ciphers are not generally considered as secure as block ciphers, although their relative security will vary depending on the particular algorithm. On the other hand, stream ciphers tend to execute faster in software. Ciphertext encrypted with stream ciphers is always the same size as the original plaintext.

Error propagation is usually less when stream ciphers are used. If a bit of ciphertext gets garbled, many stream cipher algorithms will produce only a single bit of garbled plaintext. When a block cipher is used and a ciphertext bit is garbled, at minimum an entire block's worth of plaintext will be garbled.

RC4 Stream Cipher

The only stream cipher provided with the Microsoft Base Cryptographic Provider is the RC4 stream cipher. This stream cipher was developed by RSA Data Security, Inc.

RC4 is a variable-key-length cipher. When used with CryptoAPI and the Microsoft Base Cryptographic Provider, key lengths may be queried using CryptGetProvParam with the PP_ENUMALGS_EX parameter value. The key length can be set with the upper 16 bits of the dwFlags parameter in calls to CryptGenKey and CryptDeriveKey.


Block Ciphers

Block cipher algorithms encrypt data in block units, rather than a single bit at a time. The most common block size is 64 bits.

Because each block is heavily processed, block ciphers are considered more secure than stream ciphers. However, block cipher algorithms tend to execute more slowly than stream ciphers.

The basic block encryption algorithm only specifies how to get a block of ciphertext from a block of plaintext and vice versa. All other implementation details (for example, padding, initialization vectors, salt values, and cipher modes) are specified independently of the algorithm.

RC2 Block Cipher

The only block cipher provided with the Microsoft Base Cryptographic Provider is the RC2 block cipher. This algorithm has a block size of 64 bits. It was developed by RSA Data Security, Inc. The details of this algorithm have not been published.

RC2 is a variable-key-length cipher, but used with CryptoAPI and the Microsoft Base Cryptographic Provider, the key length is hard-coded to 40 bits. The block size is fixed at 64 bits.


Cipher Modes

When a block cipher is used, any one of the following cipher modes can be specified with the CryptSetKeyParam function.

  • Electronic Codebook (ECB) Mode
  • Cipher Block Chaining (CBC) Mode
  • Cipher Feedback Mode
  • Output Feedback Mode

If the application does not explicitly specify one of these modes, the cipher block chaining (CBC) cipher mode is used.


Electronic Codebook (ECB) Mode

The electronic codebook (ECB) cipher mode encrypts each block individually. This means that any blocks of plaintext that are identical and are either in the same message, or in a different message encrypted with the same key, will be transformed into identical ciphertext blocks.

If the plaintext to be encrypted contains substantial repetition, it is feasible for the ciphertext to be broken one block at a time. Furthermore, it is possible for an unscrupulous person to substitute and exchange individual blocks without detection.

Initialization vectors cannot be used with ECB mode.

If a single bit of the ciphertext block is garbled, the entire corresponding plaintext block will also be garbled.


Cipher Block Chaining (CBC) Mode

The cipher block chaining (CBC) cipher mode introduces feedback. Before each plaintext block is encrypted, it is combined with the ciphertext of the previous block by a bitwise-XOR operator. This ensures that even if the plaintext contains many identical blocks, they will each encrypt to a different plaintext block.

The initialization vector is combined with the first plaintext block by a bitwise-XOR operator before the block is encrypted.

As with the electronic codebook cipher mode, if a single bit of the ciphertext block is garbled, the corresponding plaintext block will also be garbled. In addition, a bit in the subsequent plaintext block (in the same position as the original garbled bit) will be garbled. Synchronization errors are fatal. If there are extra or missing bytes in the ciphertext, the plaintext will be garbled from that point on.

When the Microsoft Base Cryptographic Provider is used, CBC is the default cipher mode.


Cipher Feedback (CFB) Mode

The cipher feedback mode lets you process small increments of plaintext into ciphertext, instead of processing an entire block at a time. This is useful, for example, when encrypting a stream of data that originates at a keyboard. Each keystroke can be encrypted and transmitted without the need to wait for an entire block to be typed.

The CFB mode uses a shift register that is one block-size in length and divided up into sections. For example, if the block-size is 64 bits with eight bits processed at a time, the shift register is divided up into eight sections.

To use the cipher feedback mode

  1. Encrypt the block in the shift register by using typical procedures.
  2. Use a bitwise-XOR operator to combine the leftmost eight bits in the encrypted shift register with the next eight bits of plaintext and send them as eight bits of ciphertext.
  3. Shift the shift register eight bits to the left.
  4. Place the eight bits of ciphertext generated in step 2 in the rightmost 8 bits of the shift register.

In CryptoAPI, the number of bits processed at one time is specified by using the CryptSetKeyParam function to set the encryption key's KP_MODE_BITS value type. This parameter is typically set to eight bits by default.

Depending on the value of the KP_MODE_BITS value type, CFB cipher mode is substantially slower than the cipher block chaining mode. For example, if the block size is 64 bits and eight bits are processed at a time, the CFB cipher mode is 64/8 or eight times slower.

Before the encryption process begins, the shift register is filled with the initialization vector.

If a bit in the ciphertext is garbled, one plaintext bit is garbled and the shift register is corrupted. This results in the next several plaintext increments being garbled until the bad bit is shifted out of the shift register. In the preceding example, nine bytes of plaintext would be garbled. This is the same amount of error propagation as with the cipher block chaining mode. Synchronization errors are not fatal, provided that the slip is a multiple of KP_MODE_BITS. Thus, if KP_MODE_BITS is eight and there are extra or missing bytes from the ciphertext, 9 bytes of plaintext are garbled and the plaintext will have the same number of extra or missing bytes.


Output Feedback (OFB) Mode

The output feedback (OFB) cipher mode is similar to the cipher feedback mode. The only difference between the two modes is how the shift register is filled.

The OFB cipher mode uses the following procedure for each encryption cycle.

To use the output feedback mode

  1. Encrypt the block in the shift register by using typical procedures.
  2. Use a bitwise-XOR operator to combine the leftmost eight bits in the encrypted shift register with the next eight bits of plaintext and send them as eight bits of ciphertext.
  3. Shift the shift register eight bits to the left.
  4. Place the eight bits of ciphertext generated in step 2 in the rightmost eight bits of the shift register.

As with the cipher feedback mode, the shift register is filled with the initialization vector before the encryption process starts.

If a bit in the ciphertext is garbled, the corresponding bit of plaintext will also be garbled. This is much better than the cipher feedback mode. However, synchronization errors are fatal. If there are extra or missing bits from the ciphertext, the plaintext will be garbled from that point on.

Note According to Gait (see reference below), the OFB cipher mode has a weakness when the number of bits fed back is different than the block size. It is thus recommended that the KP_MODE_BITS value type be set to the block size when this cipher mode is used.

*Gait, J. "A New Nonlinear Pseudorandom Number Generator." IEEE Transactions on Software Engineering. v. SE-3, n. 5, September 1977, pp. 359-363.


Padding

Most plaintext messages do not consist of a number of bytes that completely fill blocks. Often, there are not enough bytes to fill the last block. When this happens, a padding string is added. For example, if the block length is 64 bits and the last block contains only 40 bits, 24 bits of padding is added.

This padding string can consist of all zeros, alternating zeros and ones, or some other pattern. Some encryption standards specify a particular padding scheme, such as the one described under Initialization Vectors.

Applications using CryptoAPI need not add padding to plaintext before it is encrypted, nor do they have to remove it after decrypting. CryptoAPI functions add and remove any padding.

The PKCS padding scheme is defined by RSA Data Security, Inc. and is documented in Public-Key Cryptography Standards (PKCS), PKCS #5, section 6.2.

The PKCS padding scheme adds padding strings even if all of the blocks are filled. The padding string consists of a sequence of bytes, each of which is equal to the total number of bytes in the padding string. If 24 bits of padding need to be added, the padding string is "03 03 03" (3 bytes times 8 bits equals 24 bits). Therefore, if 64 bits of padding needs to be added, the string is "08 08 08 08 08 08 08 08".


Initialization Vectors

An initialization vector is a random number, usually the same number of bits as the block size, that is used as a starting point to encrypt a set of data. Initialization vectors are used only with those cipher modes that use feedback (cipher feedback mode and output feedback mode). This ensures that the initialization vector's effect is propagated throughout the entire plaintext message being encrypted.

If initialization vectors are not used, two identical ciphertext messages are generated when two identical plaintext messages are encrypted with the same key. However, if each plaintext message is encrypted with a different initialization vector, the ciphertext messages generated are completely different.

For better security, encrypt each message with a different initialization vector, particularly when the messages contain a large amount of duplication. Applications using CryptoAPI are responsible for transmitting the initialization vector along with the encrypted message. There is no need to encrypt this vector.


Salt Values

Salt values, also called salt bits, make up a portion of many session keys.

The bits in a salt value consist of random data. The bits in the key must be kept secret, while the bits in the salt value are made public. When exchanging keys by using CryptoAPI, the key bits are transmitted inside of encrypted key BLOBs. The bits in the salt value, on the other hand, are transmitted in plaintext.

The size of the salt values depends on the CSP used. For example, the Microsoft Base Cryptographic Provider uses salt values of 88 bits and key values of 40 bits, for a total key size of 128 bits. Even though the bits in the salt value make up part of each encryption key, they are usually ignored when discussing keys and key sizes. That is, when talking about Microsoft Base Cryptographic Provider encryption keys, they are referred to as 40-bit keys.

Salt values are most useful for transmitting or storing large numbers of nearly identical packets using the same encryption key. Normally, two identical packets would encrypt into two identical ciphertext packets. However, this would indicate to an eavesdropper that the packets are identical and, thus, the packets could be attacked simultaneously. But, if the salt value is changed with every packet sent, a completely different ciphertext packet will always be generated, even if the plaintext packets are the same.

Because salt values need not be kept secret and can be transmitted in plaintext form bundled with each ciphertext packet, it is much easier to change salt values once per packet than it is to change the key value itself.

Applications that generate salt values with the CryptGenRandom function for each session key provide better security. This is most important when using stream ciphers.


RSA Public-Key Cipher

The RSA public-key cipher was developed by (and named after) Ron Rivest, Adi Shamir, and Leonard Adleman, in the late 1970s. Internal details about this well-known cipher can be found in many books on cryptography.

RSA is used by many CSPs to encrypt and decrypt keys and to generate and verify digital signatures. This algorithm is used when operations are performed by using either the key exchange or digital signature key pair. When using CryptoAPI, this algorithm cannot be used to encrypt bulk data.

RSA is a variable-key-length cipher. However, when using CryptoAPI with the Microsoft Base Cryptographic Provider, the key length is hard-coded to 512 bits.


File and Message Encryption Using CryptoAPI

To encrypt a file so that only the current user can access its data, the file is bulk-encrypted with a symmetric cipher. The key to this cipher is kept in an access block (key BLOB) that can be opened only with the user's private key. Note that this technique also works for encrypting messages for specific recipients.

There are a number of standard formats for encrypted files and messages. These are designed to make it easier for different applications to communicate. Explaining these formats falls outside the scope of this documentation. For a list of additional reading material, see Additional Documentation on Cryptography.

After a file or message has been encrypted, the following data must be stored by the application. These pieces are usually kept together:

  • The encrypted data. When a block cipher is used, the data is padded out to a multiple of the cipher's block size. Padding is often added even when the original message is already an even multiple. When a stream cipher is used, the encrypted data is generally the same size as the original plaintext.
  • One or more key BLOBs, each containing the session key used to encrypt the message. Each of these key BLOBs is encrypted with the key exchange public key of a user who will later decrypt the data. Note that these are not stored if the key was derived from a password. Instead, when it is time to decrypt the message, the session key is re-created from the password. The user must remember the password.
  • Any salt values that were specified as the data was being encrypted. When the data is decrypted, these values will have to be specified (by using the CryptSetKeyParam function) in the same manner as the data encryption process.
  • Any initialization vectors that were specified as the data was being encrypted. These values are handled in much the same way as the salt values.

All parameters that were specified with the CryptSetKeyParam function as the message was being encrypted must also be specified as the message is decrypted. These parameters can be stored with the encrypted message.


File and Message Decryption Using CryptoAPI

If a message was encrypted for a particular user, the CryptGenKey function was used to create a random session key before the encryption was performed. This means that before the message can be decrypted, the key BLOB containing the session key needs to be imported into the CSP with the CryptImportKey function. This function will use your key exchange private key to decrypt the key BLOB. This means that the key BLOB must have been originally created by using the matching key exchange public key.

If the message was encrypted so that any password holder can access the data, the CryptImportKey function is not used. Instead, you create the decryption session key with the CryptDeriveKey function. You will also need to supply the function with the password (or other access token).

The session key's parameters need to be configured in the same way they were during encryption. These parameters can be specified by using the CryptSetKeyParam function. For example, if the salt value was changed one or more times during the encryption process, it must also be changed during the decryption process in exactly the same manner.

The message is decrypted by using the CryptDecrypt function. If the message is too large to fit comfortably in memory, it can be decrypted in sections, through multiple calls to CryptDecrypt.

When the decryption is complete, be sure to destroy the session key by using the CryptDestroyKey function. In addition to destroying the key, this will free up CSP resources.


Simultaneous Encryption and Decryption Using CryptoAPI

Encrypting or decrypting two streams of data simultaneously with the same cryptographic key raises some issues. The same physical session key must not be used for both operations because every session key contains internal state information that will get mixed up if used for more than one operation at a time. A simple solution to this problem is to make a copy of the session key. In this way, the original key can be used for one operation and the copy used for the other.

Copying a session key is done by exporting the key with CryptExportKey and by using CryptImportKey to import it back in. When the key is imported, the CSP will give the new key its own section of internal memory, as if it were not related at all to the original key.

The following code fragment shows how a copy of a session key can be obtained.

HCRYPTPROV hProv;    // Handle to a CSP.
HCRYPTKEY hKey;      // Handle to a session key.

HCRYPTKEY hCopyKey = 0;
HCRYPTKEY hPubKey = 0;
BYTE pbBlob[256];
DWORD dwBlobLen;

// Get a handle to the current user's key exchange public key.
CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hPubKey);

// Export the session key into a key BLOB.
dwBlobLen = 256;
CryptExportKey(hKey, hPubKey, SIMPLEBLOB, 0, pbBlob, &dwBlobLen);

// Import the session key back into the CSP. This is stored separately
// from the original session key.
CryptImportKey(hProv, pbBlob, dwBlobLen, 0, 0, &hCopyKey);

// Use 'hKey' for one set of operations and 'hCopyKey' for the other.
...

Note To prevent a common crypto attack, do not use this technique with stream ciphers. Stream cipher keys should never be used more than once. Instead, use separate transmission and receiving keys.


Hashes and Digital Signatures

With hash and digital signature functions, a user can digitally sign data so that any other user can verify that the data has not been changed since it was signed. The identity of the user who signed the data can also be verified.

A digital signature consists of a small amount of binary data, typically less than 256 bytes. This signature can be bundled with the signed message or stored separately, depending on how a particular application has been implemented.

The Microsoft Base Cryptographic Provider creates digital signatures that conform to the RSA Public-Key Cryptography Standards (PKCS) #6.


Data Hashes

A hash of a text or other string of bytes is an associated, unique, fixed-length value. In some documents, a hash of a text is also called a digest; however, in this documentation the term hash will always be used. CryptoAPI functions provide a means to create a hash for any text or other string of bytes. That hash, then, can be used as a unique identifier of its associated data.

To ensure the integrity of a text, a hash of a text can be sent to accompany the text. The receiver can then compute a hash on the data received and compare the hash computed with the hash received. If the two match, the data received must be the same as the data from which the received hash was created.

To obtain a hash value, create a hash object using CryptCreateHash. This object will accumulate the data to be verified. The data is then added to the hash object with the CryptHashData function.

After the last block of data is added to the hash, the CryptGetHashParam function is used to obtain the hash value of the data.

Better security is provided by destroying the hash object with CryptDestroyHash as soon as the hash value has been obtained.


Digital Signatures

Digital signatures can be used to distribute a message in plaintext form when the recipients must identify and verify the message sender. Signing a message does not alter the message; it simply generates a digital signature string you can either bundle with the message or transmit separately. A digital signature is a short piece of data that is encrypted with the sender's private key. Decrypting the signature data using the sender's public key proves that the data was encrypted by the sender or by someone who had access to the sender's private key.

Digital signatures are generated by using public-key signature algorithms. A private key encrypts and generates the signature, and the corresponding public key must be used to decrypt and thus validate the signature. This process is shown in the following illustration.

There are two steps involved in creating a digital signature from a message. The first step involves creating a hash value (also known as a message digest) from the message. This hash value is then signed, using the signer's private key. The following is an illustration of the steps involved in creating a digital signature.

To verify a signature, both the message and the signature are required. First, a hash value must be created from the message in the same way the signature was created. This hash value is then verified against the signature by using the public key of the signer. If the hash value and the signature match, you can be confident that the message is indeed the one the signer originally signed and that it has not been tampered with. The following diagram illustrates the process involved in verifying a digital signature.

A hash value consists of a small amount of binary data, typically around 160 bits. This is produced by using a hashing algorithm. A number of these algorithms are listed later in this section.

All hash values share the following properties, regardless of the algorithm used:

  • The length of the hash value is determined by the type of algorithm used, and its length does not vary with the size of the message. The most common hash value lengths are either 128 or 160 bits.
  • Every pair of non-identical messages translates into a completely different hash value, even if the two messages differ only by a single bit. Using today's technology, it is not feasible to discover a pair of messages that translate to the same hash value without breaking the hashing algorithm.
  • Each time a particular message is hashed using the same algorithm, the same hash value is produced.
  • All hashing algorithms are one-way. Given a hash value, it is not possible to recover the original message. In fact, none of the properties of the original message can be determined given the hash value alone.


Message Signatures and Signature Verification

To apply a digital signature to a piece of data, a secure hash function is used to build a hash (message digest) of the data (for example, a 160-bit hash value). This hash is then encrypted with the private key of the signer. Other users can then check the authenticity of the signature by reconstructing the hash value, and checking it against the decryption of the digital signature data. CryptoAPI abstracts the actual method of doing the signature, so that application developers need not be aware of the details of the signature mechanics.


Signed Messages

To sign a message or any other data, create a hash object using CryptCreateHash. This hash object accumulates the data to be signed. Next, the data is added to the hash object with the CryptHashData function.

After the last block of data is added to the hash, the CryptSignHash function is used to sign the hash. A description of the data can also be added to the hash object at this point. To provide security, destroy the hash object with CryptDestroyHash after the digital signature data has been obtained.

Hashes can be signed with either the signature private key or the key exchange private key. The signature key is recommended when the user who owns the signature key is signing his or her own data. The key exchange key is recommended when signing data that does not directly belong to the user, such as when signing session keys during a key exchange protocol.

A single message can be signed by more that one signer. One or more signers can hash the original message and encrypt that hash, or a message signature itself can be signed by hashing and encrypting.


Verifying a Signature

To verify a signature, create a hash object using CryptCreateHash. This hash object accumulates the data to be verified. The data is then added to the hash object with the CryptHashData function.

After the last block of data is added to the hash, use CryptVerifySignature to verify the signature. The address of the signature data, a handle to the hash object, and the handle of the public keys are passed to CryptVerifySignature.

After the signature has been verified (or has failed the verification), destroy the hash object using the CryptDestroyHash function.


Hash and Signature Algorithms

The following algorithms compute hashes and digital signatures. Each of these algorithms is supported in the Microsoft Base Cryptographic Provider. However, the internal details of these algorithms are beyond the scope of this documentation. For a list of additional sources, refer to Additional Documentation on Cryptography.


MD2, MD4, and MD5

The MD2, MD4, and MD5 hashing algorithms were all developed by RSA Data Security, Inc. These algorithms were developed in sequential order, with the later algorithms more secure than the earlier ones. All three generate 128-bit hash values. Of the three algorithms, MD5 is recommended.

These algorithms are well known and can be reviewed in detail in any reference on cryptography.


Secure Hash Algorithm (SHA)

The SHA hashing algorithm was developed by the National Institute of Standards and Technology (NIST) and by the National Security Agency (NSA). This algorithm was developed for use with DSA (Digital Signature Algorithm) or DSS (Digital Signature Standard).

This algorithm generates a 160-bit hash value.


SSL3 Client Authorization Algorithm

The SSL3 Client Authorization algorithm is used for SSL3 client authentication. In the SSL3 protocol, a concatenation of an MD5 hash and an SHA hash is signed with an RSA private key. CryptoAPI 2.0 and the Microsoft Base and Enhanced Cryptographic Providers support this with the hash type CALG_SSL3_SHAMD5.

For details, see Creating a CALG_SSL3_SHAMD5 Hash.


Message Authorization Code (MAC)

Message Authentication Code (MAC) algorithms are similar to hash algorithms, but are computed by using a symmetric (session) key. The original session key is required to recompute the hash value. The recomputed hash value is used to verify that the base data was not changed. These algorithms are sometimes called keyed-hash algorithms. To see which Microsoft providers support MAC, see Microsoft Cryptographic Service Providers.


Cipher Block Chaining (CBC) MAC

One of the algorithms (CALG_MAC) implemented by Microsoft providers is a block cipher Message Authentication Code (MAC). This method encrypts the base data with a block cipher and then uses the last encrypted block as the hash value. The encryption algorithm used to build the MAC is the one that was specified when the session key was created. For more information, see Block Ciphers.


HMAC

An algorithm (CALG_HMAC) implemented by Microsoft providers. This algorithm also uses a symmetric key to create the hash, but is more complex than the simple CBC MAC algorithm. It can be used with any iterated cryptographic hash algorithm, such as MD5 or SHA-1.

The following expression is used to calculate an HMAC:

H( K XOR OuterString, H( K XOR InnerString, text ))

Where:

H is the cryptographic hash algorithm to be used. It must be of a type where data is hashed by iterating a basic compression function on blocks of data.

K is the symmetric key to be used.

InnerString is a fixed byte string.

OuterString is a fixed byte string.

text is the data that is to have the HMAC applied to it.

For details, see Creating an HMAC.


Digital Certificates

Authentication is crucial to secure communications. Users must be able to prove their identity to those with whom they communicate and must be able to verify the identity of others. Authentication of identity on a network is complex because the communicating parties do not physically meet as they communicate. This can allow an unethical person to intercept messages or to impersonate another person or entity. A method must be worked out to maintain the necessary level of trust within the communication process.

The digital certificate is a common credential that provides a means to verify identity. This section provides an overview of how certificates provide secure communications and how to use CryptoAPI to use and manage those certificates.

A certificate is a set of data that identifies an entity. A trusted organization assigns a certificate to an individual or an entity that associates a public key with the individual. The individual or entity to whom a certificate is issued is called the subject of that certificate. The trusted organization that issues the certificate is a Certification Authority (CA) and is known as the certificate's issuer. A trustworthy CA will only issue a certificate after verifying the identity of the certificate's subject.

Certificates use cryptographic techniques to address the problem of the lack of physical contact between those communicating. Using these techniques limits the possibility of an unethical person intercepting, altering, or counterfeiting messages. These cryptographic techniques make certificates difficult to modify. Thus, it is difficult for an entity to impersonate someone else.

The data in a certificate includes the public cryptographic key from the certificate subject's public/private key pair. A message signed with its sender's private key can only be retrieved by the message's recipient using the sender's public key. This key can be found on a copy of the sender's certificate. Retrieving a signature with a public key from a certificate proves that the signature was produced using the certificate subject's private key. If the sender has been vigilant and has kept the private key secret, the receiver can be confident in the identity of the message sender.

On a network, there is often a trusted application known as a certificate server. A CA running on a secure computer manages the certificate server. This application has access to the public key of all its clients. Certificate servers dispense messages known as certificates, each of which contains the public key of one of its client users. Each certificate is signed with the CA's private key. Thus the receiver of such a certificate can verify that a specified CA sent it.

Digital certificates also include extensions and extended properties that provide additional information about the certificate's subject such as the subject's e-mail address and the activities that the certificate's subject can perform.


X.509 Digital Certification

A primary task of a digital certificate is to provide access to the subject's public key. The certificate also confirms that the certificate's public key belongs to the certificate's subject. For example, a certification authority (CA) can digitally sign a special message (the certificate information) containing the name of some user, say "Alice," and her public key. This must be done in such a way that anyone can verify that the certificate was issued and signed by no one other than the CA. If the CA is trusted and it can be verified that Alice's certificate was issued by that CA, any receiver of Alice's certificate can trust Alice's public key from that certificate.

The typical implementation of digital certification involves a process for signing the certificate. The process goes something like this:

  1. Alice sends a signed certificate request containing her name, her public key, and perhaps some additional information to a CA.
  2. The CA creates a message, m, from Alice's request. The CA signs the message with its private key, creating a separate signature message, sig. The CA returns the message, m, and the signature, sig, to Alice. Together, m and sig form Alice's certificate.
  3. Alice sends both parts of her certificate to Bob to give him access to her public key.
  4. Bob verifies the signature, sig using the CA's public key. If the signature proves valid, he accepts the public key in the certificate as Alice's public key.

As with an ordinary digital signature, any receiver with access to the CA's public key can determine if a specific CA signed the certificate. This process requires no access to any secret information. The scenario just presented assumes that Bob has access to the CA's public key. Bob would have access to that key if he has a copy of the CA's certificate that contains that public key.

X.509 digital certificates include not only a user's name and public key, but also other information about the user. These certificates are more than stepping stones in a digital hierarchy of trust. They enable the CA to give a certificate's receiver a means of trusting not only the public key of the certificate's subject, but also that other information about the certificate's subject. That other information can include, among other things, an e-mail address, an authorization to sign documents of a given value, or the authorization to become a CA and sign other certificates.

X.509 certificates and many other certificates have a valid time duration. A certificate can expire and no longer be valid. A CA can revoke a certificate for a number of reasons. To handle revocations, a CA maintains and distributes a list of revoked certificates called a certificate revocation list (CRL). Network users access the CRL to determine the validity of a certificate.


Certificates and CryptoAPI

CryptoAPI supports using certificates as defined in the ITU-T recommendation X.509 (also, ISO/IEC 9594-8). This documentation assumes the use of an X.509 or comparable digital certificate.

An X.509 standard certificate contains the following information.

Field | Description
Version | Version number of the certificate.
Serial Number | Serial number of the certificate.
Algorithm Identifier | Signature algorithm used by the certificate signer.
Issuer Name | Name of the issuer of the certificate.
Validity: |
• Not Before (Date) | Date before which the certificate is not valid.
• Not After (Date) | Date after which the certificate is not valid.
Subject Name | Name of the person or entity to whom the certificate is being issued.
Subject Public Key Info: |
• Algorithm | Algorithm used for the public key.
• Subject Public Key | Actual public key (a bit string).
Optional Fields: |
• Issuer Unique ID | If present, version must be version 2.
• Subject Unique ID | If present, version must be version 2.
Extensions | Optional field. Represents additional data that an issuer can want to add to a certificate, such as e-mail address or authorization to issue certificates. If extensions are present, version must be version 3.


Encoding and Decoding a Certificate Context

CryptoAPI supports the encoding and decoding of certificates. CryptoAPI includes an extensive, flexible system of functions and C structures that allow encoding and decoding in various ways. CryptoAPI supports standard X.509 certificate structure and standard ASN.1 encoding to provide interoperability with other systems.

For an overview of encoded data, see Encoded and Decoded Data.

Certificate Contexts

A certificate context, CERT_CONTEXT, is a C structure that contains an encoded member, a handle to a certificate store, a pointer to the original encoded certificate BLOB, and a pointer to a CERT_INFO C structure.

The CERT_INFO structure is the heart of the certificate. It contains, in direct form and in encoded form, all the basic information in the certificate. The following illustration shows the CERT_INFO structure with all of its encoded members shown as shaded.

The IssuerUniqueID and SubjectUniqueID members are part of the X.509 version 2 certificate implementation but are seldom used. Certificate extensions in version 3 replace the functionality of these members.

If the information contained in the encoded (shaded) members Issuer and Subject is needed, those members must be decoded. Use CryptDecodeObject to decode these members. The following illustration depicts the process of decoding one of these members.

In the illustrated case, the CryptDecodeObject function creates a CERT_NAME_INFO structure, an array of CERT_RDN structures, a corresponding array of CERT_RDN_ATTR structures, and a string containing the name. Members of the CERT_RDN_ATTR structure determine the contents of the string. For example, if the pszObjId member is 2.5.4.3, the string contains a common name. If it is 2.5.4.10, the string would contain an organization name. For a list of these ObjIds, see CERT_RDN_ATTR.

The dwValueType member contains information about the type of string. If it is CERT_RDN_PRINTABLE_STRING, the value member contains a byte-width, zero-terminated character string. If it is CERT_RDN_UNICODE_STRING, the string is a double-width (word-sized) character string.

For a detailed process for encoding and decoding certificates, see Encoding a CERT_INFO Structure and Decoding a CERT_INFO Structure.


Operations with Certificates

CryptoAPI provides functions to work with certificates, certificate revocation lists (CRLs) and certificate trust lists (CTLs). These include functions for converting encoded types to context types, functions that duplicate objects, and functions that free these objects. These functions encode information into contexts but do not add this context to any store. These functions are CertCreateCertificateContext, CertCreateCRLContext, and CertCreateCTLContext. Use the appropriate CertFree function to free contexts created by one of these functions.

The CryptoAPI functions to duplicate certificates, CRLs, and CTLs increment the reference counter in the specified context and return a pointer to the context. The duplicating functions do not allocate additional space or copy the data from a context into a new memory location. These functions are CertDuplicateCertificateContext, CertDuplicateCRLContext, and CertDuplicateCTLContext. Contexts created with any of these functions must be freed using the appropriate CertFree function.

The CryptoAPI functions that free certificates, CRLs, and CTLs are CertFreeCertificateContext, CertFreeCRLContext, and CertFreeCTLContext. Each of these functions decreases the reference count in a context. If the reference count reaches zero, the memory allocated for the context is released.

For complete lists of functions for working with certificates, CRLs, and CTLs, see General Maintenance Functions, Certificate Functions, Certificate Revocation List Functions, and Certificate Trust List Functions.


Certificate Extended Properties

The data in a certificate, CRL, or CTL context, including any extensions, is read-only and cannot be changed. However, on Microsoft platforms, CryptoAPI certificates also have dynamic extended properties that can be added and changed.

Note Extended properties are associated with a certificate and are not part of a certificate as issued by a certification authority (CA). Extended properties are not available on a certificate when it is used on a non-Microsoft platform.

These properties include data that:

  • Pertains to the private key to be used with the certificate.
  • Indicates the type of hashes to be performed on the certificate.
  • Provides user-defined information associated with the certificate.

On Microsoft platforms, values for these properties are attached to and move with the certificate. Currently predefined properties identified with property IDs include:

  • CERT_KEY_PROV_HANDLE_PROP_ID,
    CERT_KEY_PROV_INFO_PROP_ID, and
    CERT_KEY_CONTEXT_PROP_ID

    These properties tie a certificate to a particular CSP and, within that CSP, to a particular private key.

  • CERT_SHA1_HASH_PROP_ID and
    CERT_MD5_HASH_PROP_ID

    These properties indicate the hashing algorithm to be used when a hashing operation is performed.

See CertGetCertificateContextProperty and CertSetCertificateContextProperty for complete lists of currently defined extended certificate properties and descriptions of the meaning and use of each property. Also see CertGetCRLContextProperty, CertSetCRLContextProperty, CertGetCTLContextProperty, and CertSetCTLContextProperty.


Certificates and Messages

The base cryptographic functions use certificates, and low-level message functions and simplified message functions also use them. To send or receive messages that incorporate certificates, use low-level message functions.

For examples of using certificates with the low-level message functions see Example C Program: Encoding and Decoding a Countersigned Message, Example C Program: Encoding and Decoding an Enveloped Message, Example C Program: Encoding and Decoding a Hashed Message.

For examples of using certificates with the simplified message functions see Example C Program: Using CryptEncryptMessage and CryptDecryptMessage.

For information on low-level message functions, see Low Level Messages.

For information on simplified message functions, see Simplified Messages.


Managing Certificates with Certificate Stores

Over a period of time, certificates will accumulate on a user's computer. Tools are required to manage these certificates. CryptoAPI provides those tools as API functions to store, retrieve, delete, list (enumerate), and verify certificates. CryptoAPI also provides the means to attach certificates to messages.

This section discuses using CryptoAPI functions to manage certificates. Two main categories of functions are available: functions that manage certificate stores, and those that work with the certificates, CRLs and CTLs within those stores. The functions that manage certificate stores include functions for working with logical or virtual stores, remote stores, external stores, and relocatable stores.

Certificates, CRLs, and CTLs can be kept and maintained in certificate stores. They can be retrieved from a store where they have been persisted for use in authentication processes. Throughout this section, references to certificates, unless otherwise noted, include certificates, CRLs, and CTLs.

The certificate store is central to all certificate functionality. The certificates are managed in the store using functions with a "Cert" prefix. A typical certificate store is a linked list of certificates as shown in the following diagram.

This illustration shows:

  • Each certificate store has a pointer to the first certificate block in that store.
  • A certificate block includes a pointer to that certificate's data and a "next" pointer to the next certificate block in the store.
  • The "next" pointer in the last certificate block is set to NULL.
  • The data block of a certificate contains the read-only certificate context and any extended properties of the certificate.
  • The data block of each certificate contains a reference count that keeps track of the number of pointers to the certificate that exist.

Certificates in a certificate store are normally kept in some kind of permanent storage such as a disk file or the system registry. Certificate stores can also be created and opened strictly in memory. A memory store provides temporary certificate storage for working with certificates that do not need to be kept.

Additional store locations allow stores to be kept and searched in various parts of a local computer's registry or, with proper permissions set, in the registry on a remote computer.

Each user has a personal MY store where that user's certificates are stored. The MY store can be at any one of many physical locations, including the registry on a local or remote computer, a disk file, a data base, directory service, a smart card, or another location. While any certificate can be stored in the MY store, this store should be reserved for a user's personal certificates, those certificates used for signing and decrypting that user's messages.

Using certificates for authentication depends on having certificates issued by some trusted certificate issuer. Certificates for trusted certificate issuers are typically kept in the ROOT store, which is currently persisted to a registry sub-key. In the CryptoAPI context, the ROOT store is protected and special user interface (UI) dialogues remind the user to place only trusted certificates into that store. In enterprise network situations, certificates might be pushed (copied) by a system administrator from the domain controller computer to the ROOT stores on client computers. This process provides all members of a domain with similar trust lists.

Other certificates can be stored in the CA system store or to user-created, file-based stores.

For lists of functions for using and maintaining certificate stores, see Certificate Store Functions.

For example code using some of these functions, see Example C Program: Certificate Store Operations.


Managing a Certificate Store's State

Several functions provide services for managing a certificate store's state.

To gain access to certificates, the certificate store in which they are stored must be opened through a call to CertOpenStore or CertOpenSystemStore.

Usually a certificate store is opened in cached memory. It can be a new store or its contents can be loaded from the local registry, the registry on a remote computer, a disk file, a PKCS #7 message, or some other source.

CryptoAPI certificate store functions also allow a store to maintain certificates outside cached memory in, for example, an external database of certificates such as the one provided by the Microsoft Certificate Server Database.

One of the parameters of the CertOpenStore function, lpszStoreProvider, determines the type of store opened and the provider used to open that store. See Example C Code for Opening Certificate Stores for examples of opening certificate stores using various providers.

CertCloseStore closes a certificate store. When a certificate store is closed, each of the certificate contexts in that store has its reference count reduced by one. Memory is freed for certificates whose reference count goes to zero.

Setting CERT_CLOSE_STORE_FORCE_FLAG with CertCloseStore closes the certificate store and frees memory for all of its certificate contexts regardless of their reference count. In some cases, such as in multithreaded programs, this cannot be desirable. If CERT_CLOSE_STORE_CHECK_FLAG is set, the store is closed, but a warning value is returned by the function if memory is still allocated for certificates whose reference counts have not been reduced to zero. If a certificate's reference count is greater than zero, a duplicate of that certificate context has not been freed. Use CertFreeCertificateContext, CertFreeCRLContext, and CertFreeCTLContext to free any certificates left open.

Note A certificate context is a structure of type CERT_CONTEXT that has, among other members, a pointer to the encoded certificate BLOB and a pointer to a CERT_INFO structure. The CERT_INFO structure contains the most significant certificate data. For more information about certificate, CRL and CTL context structures, see Encoding and Decoding a Certificate Context.

Each certificate context also contains a reference count indicating the number of copies of the context's address that have been assigned. Each time a certificate context is duplicated in any way, its reference count is incremented by one. Each time a pointer to a certificate context is freed, the reference count in the certificate context is decremented by one. When the reference count on a certificate context reaches zero, the memory holding the context is de-allocated. Memory allocated for a certificate context is also de-allocated when that context is in a store and the store is closed using CERT_CLOSE_STORE_FORCE_FLAG. If the memory for a context is de-allocated and pointers to that context are still in use, those pointers become invalid.

CertDuplicateStore increases the reference count on the store.

CertSaveStore saves the contents of a store to a disk file or a memory location, and

CertControlStore manages a store while it is open. An application with an open store can be notified when the persisted state of that store has changed by some other process. This could happen if new certificates were copied to the local computer store from a domain control computer.

When changes are discovered, the cached store can re-synchronize its cached store to match the persisted state of the store. CertControlStore also supports a process that copies cached store changes to permanent storage when these changes in the cached store are not automatically saved.

Certificate store-like certificate contexts can have extended properties. CertSetStoreProperty adds extended properties to a certificate store. CertGetStoreProperty retrieves any properties set on a certificate store. Currently, the only predefined certificate store property is a store's localized name.


Working with Certificates in Certificate Stores

Several functions add a certificate context or a link to a context to a store.

For certificates already in certificate context form:

  • CertAddCertificateContextToStore
  • CertAddCRLContextToStore
  • CertAddCTLContextToStore
  • CertAddCertificateLinkToStore
  • CertAddCRLLinkToStore
  • CertAddCTLLinkToStore

For certificates that are in encoded form but not full certificate contexts:

  • CertAddEncodedCertificateToStore
  • CertAddEncodedCRLToStore
  • CertAddEncodedCTLToStore

The following functions delete a certificate, CRL, or CTL from a store by decrementing its reference count is decremented by one. If this causes the reference count to become zero, the memory used to store the certificate, CRL, or CTL is freed.

  • CertDeleteCertificateFromStore
  • CertDeleteCRLFromStore
  • CertDeleteCTLFromStore


Certificate Links

The functions CertAddCertificateLinkToStore, CertAddCRLLinkToStore, and CertAddCTLLinkToStore add links to existing contexts into certificate stores rather than adding copies of those contexts. Adding links to stores makes the same physical certificate, CRL, or CTL available through several different stores. Changes made to the extended properties of a context from the store of the original context, or from a store where a link to that context is stored, are available in the store that holds the original context and in all other stores that have links to that context.

For a code example using CertAddCertificateLinkToStore, see Example C Program: Certificate Store Operations.

Assume that certificates A.1, A.2, A.3, and A.4 are originally in store A, and certificates B.1, B.2, B.3, and B.4 are originally in store B.

  • The diagram shows a link added in store B to certificate A.2 and a link added in store A to certificate B.2.
  • The original of certificate A.2 is still in store A. The original of B.2 is still in store B.
  • Any changes made to the extended properties of certificate A.2 or certificate B.2 from either store A or store B will be available to both stores.
  • If a copy of certificate A.3 were made and stored in store B, any changes to the extended properties of the original A.3 certificate made from store A would not be visible in the new copy in store B. If changes were made to the extended properties of the copy of certificate A.3 in store B, those changes would not affect the contents of the original A.3 certificate and would not be visible from store A.


Collection Stores

As the number of certificates, CRLs, and CTLs in a user's collection grows, the organization of those certificates becomes an issue. One possible solution is to create separate certificate stores to keep different kinds of certificates. This solution creates a new problem because an application might need to search several different stores to find a specific certificate. The use of logical or collection stores solves this problem.

A logical store and a collection certificate store are groups of physical stores that appears to an application as a single store. All member stores of a logical or collection store can be searched or enumerated with a single function call to either CertFindCertificateInStore or CertEnumCertificatesInStore.

The use of logical or collection stores also provides flexibility that is difficult to achieve with paper records. A certificate in a single physical store might need to be a member of several different logical groups. Therefore, an individual physical store can be a member of more than one logical or collection store as shown in the following illustration.

This illustration presents the following basic, logical certificate store concepts:

  • A collection certificate store has a pointer to the first pointer block for that collection store.
  • Each pointer block of a collection store has a pointer to a sibling store and a pointer to the next pointer block of the collection.
  • Each sibling store in a collection is a simple physical certificate store.
  • A simple certificate store can be a member sibling store in many different collection stores.
  • Certificates added to a collection store are physically added to one of the sibling stores in the collection.
  • Certificates in a sibling store can be accessed by any collection store in which the sibling store is a member.

Collection stores are built within an application by opening a collection store using CertOpenStore and then using CertAddStoreToCollection to add an open sibling store to the collection store. A sibling store can be deleted from a collection store by calling CertRemoveStoreFromCollection.


Logical and Physical Stores

With Microsoft® Windows® 2000, default system stores, including MY, CA, and ROOT, are implemented as logical collection stores with a number of predefined physical stores as their member stores. The member physical stores of a system store are opened automatically when the system store is opened. A user can add additional physical stores to any system store collection. The CryptoAPI function CertRegisterPhysicalStore adds a new physical store to a system store collection. CertUnregisterPhysicalStore disassociates a physical store from a logical system store. CertRegisterSystemStore creates a new system store under a registry hKey, while CertUnregisterSystemStore removes a system store from the registry.

In earlier CryptoAPI versions, a system store was a single, physical store and not a logical store consisting of a set of physical stores. In the CryptoAPI version initially supplied with Windows 2000, system stores have become logical stores with associated physical stores. All the certificates in an existing system store remain available, but the physical addition of new certificates will be made in the physical stores that make up the logical system store.

Users who prefer to continue to use physical system stores and not convert to logical stores can open system stores with the CERT_STORE_PROV_SYSTEM_REGISTRY provider. This provider will continue to use each system store as a single, physical store.

The functions CertEnumSystemStoreLocation, CertEnumSystemStore, and CertEnumPhysicalStore list system store locations, available system stores, and all physical stores that are members of a system store.

System stores are also relocatable. By default, a system store is opened relative to a registry subkey following a predefined pattern. (See System Store Locations for details.) Setting CERT_SYSTEM_STORE_RELOCATE_FLAG in the dwFlags parameter passed to CertOpenStore places a system store in the registry under a user-specified registry subkey instead of the predefined one.


System Store Locations

A system store is a collection consisting of one or more physical sibling stores. For each system store, there are predefined physical sibling stores. After opening a system store such as MY at CERT_SYSTEM_STORE_CURRENT_USER, the store provider calls CertOpenStore to open each of the physical stores in the system store collection. In the open process, each of these physical stores is added to the system store collection using CertAddStoreToCollection. All certificates in those physical stores are available through the logical system store collection.

For each system store location, the predefined systems stores are:

  • MY
  • Root
  • Trust
  • CA

In CERT_SYSTEM_STORE_CURRENT_USER, there is also a predefined UserDS store. A smart card store is planned for this location.

CERT_SYSTEM_STORE_CURRENT_USER system stores are at registry location HKEY_CURRENT_USER\Software\Microsoft\SystemCertificates.

The predefined physical stores associated with those system stores are as follows.

System Store | Physical Store
MY | .Default
Root | .Default .LocalMachine
Trust | .Default .GroupPolicy .LocalMachine
CA | .Default .GroupPolicy .LocalMachine
UserDS | .UserCertificate

CERT_SYSTEM_LOCAL_MACHINE system stores are at registry location HKEY_LOCAL_MACHINE\Software\Microsoft\SystemCertificates.

The predefined physical stores are associated with those system stores are as follows.

System Store | Physical Store
MY | .Default
Root | .Default .GroupPolicy
Trust | .Default .GroupPolicy
CA | .Default .GroupPolicy

CERT_SYSTEM_STORE_CURRENT_SERVICE are at registry location HKEY_LOCAL_MACHINE\Software\Microsoft\Crytography\Services\<ServiceName>\SystemCertificates.

The predefined physical stores associated with those system stores are as follows.

System Store | Physical Store
MY | .Default
Root | .Default .LocalMachine
Trust | .Default .LocalMachine
CA | .Default .LocalMachine

CERT_SYSTEM_STORE_SERVICES system stores are at registry location HKEY_LOCAL_MACHINE\Software\Microsoft\Cryptography\Services\<ServiceName>\SystemCertificates.

The predefined physical stores associated with those system stores are as follows.

System Store | Physical Store
ServiceName\MY | .Default
ServiceName\Root | .Default .LocalMachine
ServiceName\Trust | .Default .LocalMachine
ServiceName\CA | .Default .LocalMachine

CERT_SYSTEM_STORE_USERS system stores are at registry location HKEY_USERS\<UserName>\Software\Microsoft\SystemCertificates.

The predefined physical stores associated with those system stores are as follows.

System Store | Physical Store
userid\MY | .Default .LocalMachine
userid\Root | .Default .LocalMachine
userid\Trust | .Default .LocalMachine
userid\CA | .Default .LocalMachine

CERT_SYSTEM_CURRENT_USER_GROUP_POLICY system stores are at registry location HKEY_CURRENT_USER\Software\Policy\Microsoft\SystemCertificates.

CERT_SYSTEM_LOCAL_MACHINE_GROUP_POLICY system stores are at registry location HKEY_LOCAL_MACHINE\Software\Policy\Microsoft\SystemCertificates.

CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE contains certificates shared across domains in the enterprise and downloaded from the global enterprise directory. To synchronize the client's enterprise store, the enterprise directory is polled every eight hours and certificates are downloaded automatically in the background.

The predefined physical stores associated with these system stores are as follows.

System Store | Physical Store
MY | .Default
Root | .Default
Trust | .Default
CA | .Default

Additional physical stores can be associated with a system store using CertRegisterPhysicalStore.

CERT_SYSTEM_STORE_SERVICE and CERT_SYSTEM_STORE_USERS stores are opened by prefixing the name of the store in the string passed to pvPara with the service or user name such as ServiceName\Trust or .Default\MY. For Microsoft® Windows NT®/Windows 2000, the CERT_SYSTEM_STORE_SERVICES or CERT_SYSTEM_STORE_USERS location can open the same store in CERT_SYSTEM_CURRENT_SERVICE or CERT_SYSTEM_STORE_CURRENT_USER by using the textual SID of the current service or user. For Windows 95, the string returned by GetUserName is used.

Stores in CERT_SYSTEM_STORE_USER_GROUP_POLICY and CERT_SYSTEM_LOCAL_MACHINE_GROUP_POLICY in a network setting are downloaded to the client machine from the Group Policy Template (GPT) during machine startup or user logon. These stores can be updated on the client computer after startup or logon when the GPT is changed on the domain server by an administrator. The CertControlStore function allows an application to be notified when stores in either of these locations have changed.

The following system store locations can be opened remotely:

CERT_SYSTEM_STORE_LOCAL_MACHINE
CERT_SYSTEM_STORE_SERVICES
CERT_SYSTEM_STORE_USERS
CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY

System store locations are opened remotely by prefixing the store name in the string passed to pvPara with the computer name. Examples of remote system store names are:

ComputerName\CA
\\ComputerName\CA
ComputerName\ServiceName\Trust
\\ComputerName\ServiceName\Trust


Certificate Trust Verification

A trust must exist between the recipient of a signed message and the signer of the message. One method of establishing this trust is through a certificate, an electronic document verifying that entities or persons are who they claim to be. A certificate is issued to an entity by a third party that is trusted by both of the other parties. So, each recipient of a signed message decides if the issuer of the signer's certificate is trustworthy. CryptoAPI has implemented a methodology to allow application developers to create applications that automatically verify certificates against a predefined list of trusted certificates or roots. This list of trusted entities (called subjects) is called a certificate trust list (CTL).

The following example of using a CTL involves an intranet (intra-company network) administrator who wants to control just which outside sources are trusted. In this case, the administrator can create a list of trusted certificates or roots, sign it, and make the list available to all clients on the network in the form of a CTL. An application designed to use this CryptoAPI functionality would then only accept signed messages or downloaded software that was signed by entities on the list.

For a list of these functions, see Certificate Verification Functions.


Hierarchy of Trust

For digital certificates to be effective, users of certificates must have a high level of trust in them. There are cases where a user does not trust the issuer of a certificate. This could happen if the certificate user has never heard of the certification authority (CA) and therefore is uncomfortable with accepting a certificate from that issuer at face value. This problem is addressed in the certifying process by a hierarchy of trust.

The concept of hierarchy of trust is that the trust process must begin with at least one certifying authority accepted as trustworthy . Perhaps this could be some agency of the federal government, such as the postal service, or some company that everyone agrees is trustworthy. Such an ultimate authority, whatever it is, is called the root authority. The root authority can then certify other CAs, called first-tier CAs, who can then issue certificates and also certify additional or second tier CAs. This situation is shown in the following illustration.

The identity of the CA issuing a certificate is part of a certificate. That CA is called the certificate's issuer. When a certificate's issuer is a tier 1 or tier 2 CA, the receiver of that certificate can determine whether the certificate's issuer is certified as a valid CA by a CA at a level above it, and that the higher level CA is certified as a valid CA by still a higher level CA until it is determined that a chain of trust exists between the lowest level CA and the root CA.

For example, in the preceding diagram, it can be verified that CA #4 was certified as a CA by CA #1, and that CA #1 was certified as a CA by the root CA. Thus when a certificate from a lower-level CA is passed along with the encrypted message, information about all of the certificates in its chain of trust up to the root is passed along with it.

The diagram and description just presented is conceptual. In the real world, the certification authority situation is evolving and no single root authority has been established or accepted. In the short term, islands of authority will develop as shown in the following illustration.

In time, the root islands, Root 1 and Root 2 in the illustration, could become Tier 1 CAs to a single root CA. At that point, the situation would again have a single root authority. It remains to be seen just how the actual picture will evolve.


Certificate Chains

To use certificates for security, the authenticity and validity of each certificate received must be verified. This verification depends upon the concept of trust and the delegation of trust (see Hierarchy of Trust).

Every certificate has a subject, that is, the individual or group that is identified by that certificate. Each certificate also lists an issuer. The issuer of a certificate is its Certification Authority (CA), the individual or group empowered to issue certificates that certify the identity of the certificate's subject.

The issuer of a certificate must also be the subject of a certificate. That certificate, issued by still another CA, verifies the issuer's identity and authority to issue certificates. Furthermore, the CA that issues a certificate to the CA that issues the end certificate must also be certified. Thus, each valid certificate received is backed by a chain of certificates that leads to a universally acknowledged, trusted CA. This most trusted CA issues not only certificates for others, but also issues a certificate for itself.

The process of verifying the authenticity and validity of a newly received certificate involves checking all of the certificates in the chain of certificates from the original, universally trusted CA, through any intermediate CAs, down to the certificate just received which is called the end certificate. A new certificate can only be trusted if each certificate in that certificate's chain is properly issued and valid.

Tracking all of the certificates that back a new end certificate can become cumbersome. Therefore, CryptoAPI 2.0 technology provides functions that automate creating the chain of certificates that back any given end certificate. These functions also check and report on the validity of each certificate in a chain.

The chain-building and checking functions of CryptoAPI 2.0 use a chain engine to create and verify chains of certificates. A chain engine defines a store namespace and cache partitioning for the Certificate Chaining Infrastructure. CryptoAPI 2.0 provides a default chain engine for any application process that only uses default system stores (e.g. MY, Root, CA, and Trust) for chain building and caching. An application can define its own store namespace or have its own partitioned cache by creating its own chain engine. To achieve optimal caching behavior, it is advisable to create a single chain engine at application startup and use that chain engine throughout the lifetime of the application.

For a list of functions, see Certificate Chain Verification Functions. See Example C Program: Creating a Certificate Chain for a program that builds certificate chains and verifies certificates.


Certificate Trust List Overview

In addition to certificates and certificate revocation lists (CRL), the CryptoAPI certificate store supports the certificate trust list (CTL). A CTL is a predefined list of items signed by a trusted entity. A CTL is a list of hashes of certificates or a list of file names. All the items in the list are authenticated and approved by a trusted signing entity. A CTL_CONTEXT structure is similar to certificate and CRL context structures. A CTL context can be persisted to the certificate store.

A CryptoAPI CTL is a list of items that has been signed by a trusted entity. The list of items could be anything, such as a list of hashes of certificates, or a list of file names. In most cases, a CTL is a list of hashed certificate contexts. All the items in the list are authenticated and approved by the signing entity. The primary use of CTLs is to verify signed Messages, using the CTL as a source of trusted root certificates.

The CTL_CONTEXT structure is similar to the certificate and CRL context structures; however, unlike the certificate and CRL context structures, the CTL_CONTEXT structure contains a hCryptMsg member. This handle is opened by a call to any of the functions that return a CTL_CONTEXT structure, making it possible to use the message functions to verify the CTL's signature. This verification is necessary to ensure that a CTL is not a bogus CTL planted by a rogue entity.

For procedures to create a signed CTL and save it to a certificate store, see Creating, Signing, and Storing a CTL. Also see Verifying a CTL and Verifying Signed Messages By Using CTLs for step by step verification procedures.


Digital Messages

A message will be defined as any data that has been encoded. Messages are data encoded for transmission to another person or entity or encoded data received from another person or entity. In the crypto environment, messages are usually signed, encrypted, or both. The term messages often includes certificates.

In CryptoAPI version 2.0, message handling functions are divided into low-level message functions and simplified message functions.


PKCS 7 Concepts

The CryptoAPI message functions adhere to RSA PKCS #7 Cryptographic Message Syntax (CMS) Standard published by RSA Laboratories, a division of RSA Data Security, Inc. Details on this specification are available on their Web site, http://www.rsa.com. Developers need to be familiar with this specification to most effectively use the low-level message functions. A few of its definitions are highlighted here.

The PKCS #7 standard describes a general syntax for data that may have cryptography applied to it, such as digital signatures and digital envelopes. The syntax admits recursion, so that, for example, one envelope can be nested inside another, or one party can sign digital data that has already been put into an envelope. It also allows arbitrary attributes, such as signing time, to be authenticated along with the content of a message. Further, it provides for other attributes, such as countersignatures, to be associated with a signature.

The type of data contained in a PKCS #7 message is called its content type. There are two classes of content types—Base and Enhanced.

  • Base content types contain only data with no cryptographic enhancements. Presently there is only one content type in this class, the data content type.
  • Enhanced content types contain data of some type (possibly encrypted), and other cryptographic enhancements (such as hashes or signatures).

The content in the Enhanced class employs encapsulation, giving rise to the terms outer content (the one containing the enhancements) and inner content (the one being enhanced). For example, an Enhanced class might contain the data content type (Base class) that has a signature included with it. In this case, the data content type is the inner content and the combination of the data content type and the signature forms the outer content.

The content types defined in PKCS #7 standard are as follows.

Data type | Description
Data | An octet (BYTE) string.
Signed Data | Content of any type and encrypted message hashes (digests) of the content for zero or more signers.
Enveloped Data | Encrypted content of any type and encrypted content-encryption keys for one or more recipients. The combination of encrypted content and encrypted content-encryption key for a recipient is a digital envelope for that recipient.
Signed-and-Enveloped Data | Encrypted content of any type, encrypted content-encryption keys for one or more recipients, and doubly-encrypted message digests for one or more signers. The double encryption consists of an encryption with a signer's private key followed by an encryption with the content-encryption key.
Digested Data | Content of any type and a message hash (digest) of the content.
Encrypted Data | Encrypted content of any type. Unlike the enveloped-data content type, the encrypted-data content type has neither recipients nor encrypted content-encryption keys. Keys are assumed to be managed by other means.

Note Throughout the PKCS #7 specification, the terms "digest" and "digested" refer to the value produced from applying a hashing algorithm to data. This documentation uses the terms "hash" and "hashed" for the same purpose. For example, the data type used with the low-level message functions is called hashed rather than digested. For the purposes of this documentation, the two sets of terms may be used interchangeably.


Low-level Messages

The low-level message functions encode data for transmission and decode data that has been received. Low-level message functions also decrypt and verify the signatures of received messages.

When a message is opened using a low level message open function, it remains open and available (maintains its state) until it is closed. This allows a message to be constructed piecemeal using multiple calls to the CryptMsgUpdate function.

Using low-level message functions requires more function calls than using simplified message functions (see Simplified Messages). If the simplified message functions are used, more of the work is done inside the API functions.

Using low-level message functions involves the additional work of making calls to other certificate or cryptographic functions. For example, data from calls to certificate functions may be needed to initialize structures used by these low-level message functions. Simplified message functions initialize many of these structures internally.

The following table lists sections with procedure descriptions and C code examples of using the low level message functions.

Section | Contents
Low-Level Message Functions | Lists the low level message functions.
Example C Program: Encoding and Decoding a Hashed Message | Sample C code working with hashed messages.
Signing Data | Details the tasks needed to sign data.
Encoding Enveloped Data | Details the tasks needed to encode enveloped data.
Decoding Enveloped Data | Details the tasks needed to decode enveloped data.
Example C Program: Encoding and Decoding an Enveloped Message | Provides a sample program that encodes and decodes an enveloped message.


Simplified Messages

A group of high-level functions has been provided to simplify and shorten the amount of code necessary to accomplish the usual message manipulation tasks. These functions are called "simplified message functions." The names of all simplified message functions contain the word "Message."

Simplified message functions are at a higher level than the base cryptographic functions or the low-level message functions. They wrap several of the base cryptographic, low-level message, and certificate functions into a single function that performs a specific task in a specific manner, such as encrypting a PKCS #7 message or signing a message. Simplified message functions provide a quick way to get started using CryptoAPI by reducing the number of function calls needed to accomplish a task.

The following table list sections that contain detailed procedure descriptions or C program examples of using the simplified message functions.

Section | Contents
Simplified Message Functions | Lists the simplified message functions.
Creating a Signed Message | Details the process of creating a signed message.
Procedure for Signing Data | Provides a procedure for using the simplified message functions to create a signed message.
Verifying A Signed Message | Details a process for verifying the signature on a signed message.
Encrypting a Message | Details the tasks needed to encrypt and decrypt a message.
Decrypting a Message | Details the tasks needed to decrypt a message.
Example C Program: Using CryptEncryptMessage and CryptDecryptMessage | Provides a procedure and sample code for encrypting and decrypting a message.


Message Countersignatures

Sometimes a signed message requires a countersignature. For example, user A may send a signed-data message to user B, expecting B to confirm agreement with the terms contained in the document. User B decodes the message, reads the terms and, if in agreement, countersigns the message. The countersigned message is then sent back to user A. User A now knows, and can prove, that user B agreed to the terms.

The following table lists sections that contain procedure descriptions or C program examples of message countersigning.

Section | Contents
Message Functions | Lists the counter signature functions.
Countersigning a Message | Details the process of counter signing a message.
Verifying a Countersignature | Details the procedure for verifying a counter signature.
Verifying a Signed Message | Details a process for verifying the signature on a signed message.
Example C Program: Encoding and Decoding a CounterSigned Message | Sample C program that encodes and decodes a countersigned message.


CMS Additions for Windows 2000

Cryptographic Message Syntax (CMS) derived from PKCS #7 version 15 is the syntax used to hash, digitally sign, authenticate, and encrypt arbitrary messages. Where possible, backward compatibility is preserved; however, changes were necessary to accommodate attribute certificate transfer and key agreement techniques for key management. CMS allows multiple encapsulation so that one encapsulation envelope can be nested inside another. Also, one party can digitally sign previously-encapsulated data, arbitrary attributes, such as signing time, can be signed along with the message content, and attributes such as countersignatures can be associated with a signature. CMS can support a variety of architectures for certificate-based key management.

To support additional CMS capabilities, Windows 2000 includes no new APIs; however, underlying data structures were changed by adding new fields. New flags and parameter values were also added. All data structures and all APIs using CMS are 100% backward compatible with PKCS #7 version 1.5.

Additions include Enveloped Data Additions and Signed Data Additions.


Enveloped Data Additions

The following changes have been made to enveloped data capabilities:

  • Recipient identification can be done not only by Issuer and Serial Number (PKCS #7 1.5), but also by Key Identifier.
  • Three recipient key exchange choices are provided:
    • Key Transport using RSA keys.
    • Key Agreement using Ephemeral-Static Diffie-Hellman algorithm keys wrapped with 3DES or RC2.
    • Key Encryption Key or Mail List key transfer where the key used to encrypt the content encryption key has already been distributed to the recipients. RC2 and 3DES are allowed as key-wrapping algorithms.
  • Unprotected attributes can be included in the message.
  • An OriginatorInfo field containing information about the originator has been added that can contain certificates and CRLs.


Signed Data Additions

The following changes have been made to signed data capabilities:

  • Non-data inner content is encapsulated in an OCTET STRING.
  • Provision is made for different message versions.
  • Signers can be identified either by Issuer and Serial Number, as in PKCS #7 1.5, or by Subject key identifier.
  • Multiple signers are allowed.
  • Both RSA and DSA signatures are allowed.


Using CryptoAPI

These procedures and example code demonstrate the CryptoAPI functions and tasks. The code uses cryptographic function calls described in About CryptoAPI and CryptoAPI Reference. The procedures and code examples have been separated into the following sections:

  • Sample Program Conventions
  • Acquiring a Cryptographic Context and Generating Keys
  • Encoding and Decoding
  • Hashing
  • Signing Data
  • Enveloped Data
  • Countersigning
  • Encrypting and Decrypting
  • Working with Certificate Stores
  • Using Certificates
  • Other Extended C Code Examples
  • Extending CryptoAPI Functionality
  • Extending CertOpenStore Functionality


Sample Program Conventions

The example programs in this section except where noted include all of the code necessary to compile and link the programs. The necessary #include and #define statements are included as is the code for any general-purpose example functions used.

This section documents the following areas:

  • Example Program Limitations
  • Compile and Link Considerations
  • Necessary Key Containers, Keys, and Certificates
  • Retrieving Data of Unknown Length
  • General Purpose Functions


Example Program Limitations

Principles of good programming practice are not always followed in these sample programs in order to provide more concise, more readable code. In particular:

  • Only limited error responses are shown. Working programs should always check returned error codes and perform appropriate actions when an error is encountered.
  • Only limited memory and resource management is done. In working programs, all keys and hashes should be destroyed, all allocated memory should be freed, all files should be closed, and all handles should be released. These example programs provide only limited demonstrations of the use of functions that perform these tasks. These example programs perform no memory or resource management tasks in the case of program termination due to errors.


Compile and Link Considerations

Compiling and linking the sample programs in this section involves consideration in the following areas:

  • Required Libraries
  • Certificate and Message Encoding Types
  • #includes and #defines
  • Error Handling


Required Libraries

Linking CryptoAPI functions requires the availability of crypt32.lib. Programs using some of the functions may also require advapi32.lib. When using the Microsoft® Visual C++® compiler, these files should be listed among the object/library modules.


Certificate and Message Encoding Types

Many of the functions require certificate or message encoding types. This encoding type is a DWORD, possibly containing both the certificate and message encoding types. The certificate encoding type is stored in the low-order word. The message encoding type is stored in the high-order word. Some functions or structure fields require only one of the encoding types, but it is always acceptable to specify both encoding types. For example code specifying both encoding types, see #includes and #defines.

The following parameter naming convention is used to indicate the encoding types required.

Name | Comments
dwMsgAndCertEncodingType | Both encoding types are required.
dwMsgEncodingType | Only the message encoding type is required.
dwCertEncodingType | Only the certificate encoding type is required.
dwEncodingType | Either a message or certificate encoding type is required. If the low-order word containing the certificate encoding type is nonzero, then it is used. Otherwise, the high-order word containing the message encoding type is used. If both are specified, the certificate encoding type in the low-order word is used.

Currently defined encoding types are shown in the following table.

Encoding type | Value
CRYPT_ASN_ENCODING | 0x00000001
X509_ASN_ENCODING | 0x00000001
PKCS_7_ASN_ENCODING | 0x00010000


#includes and #defines

All of the program and code examples in this documentation are assumed to have the following #include and #define statements:

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)


Error Handling

In all of the C example code fragments that accompany each function's documentation, the example function HandleError is used to print an error message and exit a procedure. In real situations, more extensive error handling procedures may be required. For more information, see Example Program Limitations.


Necessary Key Containers, Keys, and Certificates

Example programs in the following sections perform operations that require public/private key pairs to be available for encrypting and decrypting files, messages, and signatures. Many of these programs will compile, link, and run but fail at run time without the existence of proper key containers, keys, certificate stores, and certificates in those stores.

In addition, some of the certificates in the MY store must have some of their extended properties set.

Creating the needed default key container can be done by running the program in Example C Program: Creating a Key Container and Generating Keys. Note that the creation of a key container does not automatically generate public/private key pairs. The example program, however, both creates the key container and generates both the public/private key pairs.

Once both sets of public/private key pairs have been generated, test certificates using those keys can be obtained from a certification authority (CA).

Several of the programs assume that certificates with specific subject names exist in the MY system store. In particular, several programs look for certificates with the subject names "Full Test Cert" and "Hortense." The subject names for the certificates may be changed in the code to match the subject names of certificates that exist in the MY certificate store.

Running the example program in Example C Program: Listing the Certificates in a Store will display all of the certificates in a store and all of the extended properties that are set on those certificates.


Retrieving Data of Unknown Length

Many functions return a potentially large amount of data to an address provided as one of the parameters by the application program. In all these cases, the operation is performed in a similar, if not identical, fashion. The parameter that points to the location of the returned data will use the notation convention where "pb" or "pv" are the first two characters of the parameter name. Another parameter will have "pcb" as the first three characters of the parameter name. This parameter represents the size, in bytes, of the data that will be returned to the "pb" or "pv" location. For example, consider the following function specification:

BOOL WINAPI SomeFunction(
  PCCRL_CONTEXT pCrlContext,  // in
  DWORD dwPropId,             // in
  BYTE *pbData,               // out
  DWORD *pcbData              // in/out
);

In this example pbData is a pointer to the location where the data will be returned, and pcbData is the size, in bytes, of the returned data.

Note The companion parameter to the "pcb" parameter may sometimes carry a slightly different prefix, such as "p" or "pv". Also, for companion parameters using the combination of prefixes "pwsz" and "pcch", the "pcch" parameter is the count in characters (Unicode or ASCII, as applicable), of the returned data.

If the buffer specified by pbData parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code (which can be seen by calling GetLastError), and stores the required buffer size, in *bytes, into the variable pointed to by pcbData.

If NULL is input for pbData and pcbData is non-NULL, no error is returned and the function returns the size of the needed memory buffer, in bytes, in the variable pointed to by pcbData. This lets an application determine the size of, and the best way to allocate, a buffer for the returned data.

Note When NULL is input for pbData to determine the size needed to ensure that the returned data fits in the specified buffer, the second call to the function (which populates the buffer with the desired data) may not use the whole buffer. After the second call, the actual size of the data returned is contained in pcbData. Use this size when processing the data.

The following example code demonstrates how input and output parameters might be implemented for this purpose:

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

void HandleError(char *s);

void main()
{
//--------------------------------------------------------------------
// Set up SomeFunction variables.

PCCRL_CONTEXT pCrlContext; // Initialized elsewhere.
DWORD dwPropId;            // Initialized elsewhere.
DWORD cbData;
BYTE  *pbData;

//--------------------------------------------------------------------
// Call SomeFunction to set cbData, the size of
// the buffer needed for pbData.

if(SomeFunction(
     pCrlContext,
     dwPropId,
     NULL,
     &cbData))
{
       printf("The function succeeded.\n");
}
else
{
// The function call failed. Handle the error.
       HandleError("Function call failed.");
}

//--------------------------------------------------------------------
// The call succeeded; the size for the needed buffer, in bytes,
// now resides in cbData.

//--------------------------------------------------------------------
// Malloc memory for the size of the message.

if(pbData = (BYTE*)malloc(cbData))
{
   printf("Memory has been allocated.\n");
}
else
{
   // The allocation failed. Write an error message and exit.
   HandleError("Malloc operation failed. ");
}

//--------------------------------------------------------------------
// The space for the buffer has been allocated.
// Call SomeFunction to fill the buffer with the data.

if(SomeFunction(
      pCrlContext,
      dwPropId,
      pbData,
      &cbData))
{
       printf("The function succeeded.\n");
}
else
{
   // The second function call failed. Handle the error.
   HandleError("The second call to the function failed.");
}
//*******************************************************************
// The function succeeded; the data is now in the buffer
// pointed to by pbData. Note that cbData is
// updated with the actual size of the data returned. Use this size
// to process bytes of pbData.
} // End of main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program.\n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr,"Error number %x.\n",GetLastError());
    fprintf(stderr,"Program terminating.\n");
    exit(1);
}

An Alternate Procedure

A performance gain may be realized in dealing with in/out parameters by preallocating a buffer for the returned "pb" data without querying the function involved for the exact size "cb" needed. When the preallocated buffer is at least as big as the "cb" required, a performance savings is realized because the function is only called once, producing the returned data placed in the "pb" specified buffer. If the preallocated buffer is not large enough to hold the data, then the function fails and there is no performance gain.

The following example code demonstrates how a preallocated buffer can be used to provide a performance gain:

//--------------------------------------------------------------------
// Assume SomeFunction (from the previous example) is called
// repetitively by an application, and that a buffer size of
// 50 bytes will handle the output for all but a few cases.

//--------------------------------------------------------------------
// Set up SomeFunction variables.

PCCRL_CONTEXT pCrlContext; // Initialized elsewhere.
DWORD dwPropId;            // Initialized elsewhere.

//--------------------------------------------------------------------
// Preallocate a 50 byte buffer, and
// use that buffer in a call to SomeFunction that produces the
// desired output data most of the time.
// However, the case where more than 50 bytes are required for the
// output data must be handled as well. For that case, use the cb
// returned by the failed call to SomeFunction to allocate a bigger
// buffer.
// After the allocation of additional bytes for the buffer, a second
// call to SomeFunction using the larger buffer is then made.

//--------------------------------------------------------------------
//   Assume variables pCrlContext and dwPropId have been declared and
//   initialized elsewhere.

DWORD dwTries = 0; // the number of times the function has been tried
BOOL fMore=TRUE;   // flag indicating the function needs to be tried
DWORD cbData = 50;
BYTE  *pbData;

//--------------------------------------------------------------------
//  Begin processing. This loop is executed at most twice.

while (fMore)
{
    if (pbData = (BYTE *)malloc(cbData))
    {
        printf("Memory has been allocated.\n");
    }
    else
    {
        HandleError("Memory allocation error.");
    }
//--------------------------------------------------------------------
//  Memory has been allocated. Try the function.
   if (SomeFunction(pCrlContext, dwPropId, pbData, &cbData))
       // The function succeeded. Exit the loop.
   {
            printf("The function succeeded. Exit the loop.\n");
            fMore=FALSE;
   }
   else
   {
         // The function failed. Free the space allocated.
          free(pbData);  // Free the buffer on failure.

        // If the error was not that the buffer was not big enough,
        // exit the loop having failed.

         if(GetLastError() != ERROR_MORE_DATA )
         {
              HandleError("General function failure.");
         }
         // If the error was that there was that there was not enough
         // space in the buffer, try a second but not a third time.
         if( ++dwtries > 1 )
          {
              HandleError("Function call failed twice ");
          }
}  // ends loop

//--------------------------------------------------------------------
//  If the loop runs to completion, the function succeeded either the
//  the first or the second time through. In either case, cbData is
//  updated with the actual size of the data returned.
//  Use this size when processing pbData.

//--------------------------------------------------------------------
//  Process pbData here as needed.

//--------------------------------------------------------------------
//  Clean up after processing.

free(pbData); // Free the data buffer
              // after the data has been processed.

Performance gains may also be made by using alloca to allocate memory from the stack instead of malloc to allocate memory from the heap. Because the buffer is on the stack, free does not need to be called when finished using the buffer. When using alloca, the data buffer must be used locally to the calling function because, upon function return, the buffer is automatically deallocated by the stack pop. Also, each call to alloca from the same function uses more stack. Excessive use may cause a stack overflow in repetitive cases.


General Purpose Functions

The following general-purpose example functions perform a number of auxiliary tasks in the example programs:

Function | Description
ByteToStr | Converts an array of bytes into a string of characters.
GetSignerCert | Retrieves a certificate from a store that has a key signature extension.
HandleError | Writes an error message and exits a program.


ByteToStr

The ByteToStr function converts an array of BYTEs to a hexadecimal char string.

//--------------------------------------------------------------------
//

void ByteToStr(
     DWORD cb,
     void* pv,
     LPSTR sz)
//--------------------------------------------------------------------
// Parameters passed are:
//    pv is the array of BYTES to be converted.
//    cb is the number of BYTEs in the array.
//    sz is a pointer to the string to be returned.

{
//--------------------------------------------------------------------
//  Declare and initialize local variables.

BYTE* pb = (BYTE*) pv; // local pointer to a BYTE in the BYTE array
DWORD i;               // local loop counter
int b;                 // local variable

//--------------------------------------------------------------------
//  Begin processing loop.

for (i = 0; i<cb; i++)
{
   b = (*pb & 0xF0) >> 4;
   *sz++ = (b <= 9) ? b + '0' : (b - 10) + 'A';
   b = *pb & 0x0F;
   *sz++ = (b <= 9) ? b + '0' : (b - 10) + 'A';
   pb++;
}
*sz++ = 0;
}


GetSignerCert

The GetSignertCert function goes through (enumerates) the certificates in a certificate store until a certificate with a signature key is found. If a certificate is found, a pointer to the certificate is returned. This code demonstrates:

  • Finding a certificate with a certificate property.
  • Checking that property.
  • Returning a pointer to the CERT_CONTEXT where the attribute was found.
PCCERT_CONTEXT GetSignerCert(
        HCERTSTORE hCertStore)
//--------------------------------------------------------------------
//   Parameter passed in:
//      hCertStore, the handle of the store to be searched.

{
//--------------------------------------------------------------------
//   Declare and initialize local variables.

PCCERT_CONTEXT       pCertContext = NULL;
BOOL                 fMore = TRUE;
DWORD                dwSize = NULL;
CRYPT_KEY_PROV_INFO* pKeyInfo = NULL;
DWORD                PropId = CERT_KEY_PROV_INFO_PROP_ID;

//--------------------------------------------------------------------
//  Find certificates in the store until the end of the store
//  is reached or a certificate with an AT_SIGNATURE key is found.

while(fMore &&
  (pCertContext= CertFindCertificateInStore(
     hCertStore,           // Handle of the store to be searched.
     0,                    // Encoding type. Not used for this search.
     0,                    // dwFindFlags. Special find criteria.
                           // Not used in this search.
     CERT_FIND_PROPERTY,   // Find type that determines the kind of
                           // search to do. In this case, search for
                           // certificates that have a specific
                           // extended property.
     &PropId,              // pvFindPara. Gives the specific
                           // value searched for, here the identifier
                           // of an extended property.
     pCertContext)))       // pCertContext is NULL for the
                           // first call to the function.
                           // If the function is called
                           // in a loop, after the first call
                           // pCertContext is the certificate
                           // returned by the previous call.
{
//-------------------------------------------------------------
// For simplicity, this code only searches
// for the first occurrence of an AT_SIGNATURE key.
// In many situations, a search would also look for a
// specific subject name as well as the key type.

//-------------------------------------------------------------
// Call CertGetCertificateContextProperty once to get the
// returned structure size.

   if(!(CertGetCertificateContextProperty(
                 pCertContext,
                 CERT_KEY_PROV_INFO_PROP_ID,
                 NULL,
                 &dwSize)))
   {
      HandleError("Error Getting Key Property");
   }

//--------------------------------------------------------------
// Allocate memory for the returned structure.

   if(pKeyInfo)
        free(pKeyInfo);
   if(!(pKeyInfo = (CRYPT_KEY_PROV_INFO*)malloc(dwSize)))
   {
       HandleError("Error Allocating Memory for pKeyInfo");
   }

   //--------------------------------------------------------------
   // Get the key information structure.

   if(!(CertGetCertificateContextProperty(
       pCertContext,
       CERT_KEY_PROV_INFO_PROP_ID,
       pKeyInfo,
       &dwSize)))
   {
       HandleError("The second call to the function failed.");
   }

   //-------------------------------------------
   // Check the dwKeySpec member for a signature key.
   if(pKeyInfo->dwKeySpec == AT_SIGNATURE)
   {
        fMore  = FALSE;
    }
}  // End of while loop

if(pKeyInfo)
   free(pKeyInfo);
return (pCertContext);
}  // End of GetSignerCert


HandleError

The HandleError function is used to print an error message and exit a program. The example code fragments for several CryptoAPI functions in CryptoAPI Reference and the more extended code in Using CryptoAPI call this function. Real applications may require more complex error handling capability.

void HandleError(char *s)
{
    printf("An error occurred in running the program.\n");
    printf("%s\n",s);
    printf("Error number %x.\n",GetLastError());
    printf("Program terminating.\n");
    exit(1);
}


Acquiring a Cryptographic Context and Generating Keys

This section includes:

  • Example C Program: Creating a Key Container and Generating Keys.
  • Example C Program: Using CryptAcquireContext.
  • Example C Program: Enumerating CSP Providers and Provider Types.
  • Example C Program: Deriving a Session Key from a Password.
  • Example C Program: Duplicating a Session Key.
  • Example C Program: Setting and Getting Session Key Parameters.
  • Working with Keys from Various CSPs.
  • Procedure for Storing a Session Key.
  • Procedure for Storing Session Keys Using a Backup Authority.
  • Example C Program: Exporting a Session Key.


Example C Program: Creating a Key Container and Generating Keys

This program sets up the default cryptographic user. This includes the creation of a default key container and sets of public/private cryptographic keys. Many of the example programs require such a default key container and key pairs. Run this program once for a user before attempting to run any programs that require a key container and key pairs. It can be run without problem even if a default key container and cryptographic keys already exist.

Note An application should not use the default key container to store private keys. When multiple applications use the same container, one application may change or destroy the keys that another application needs to have available. It is recommended that applications use key containers that are linked to the application. Doing so reduces the risk of other applications tampering with keys that are necessary for an application to function properly.

This example program illustrates the following tasks and CryptoAPI functions:

  1. It creates a default key container if one does not already exist.
  2. If a signature key pair does not exist in the key container, it creates such a signature key pair within the key container.
  3. If an exchange key pair does not exist in the key container, it creates such an exchange key pair within the key container.

These operations only need to be done once for each user on each computer. If the default key container and key pairs have already been created, this sample performs no operations.

This program uses the following CryptoAPI functions:

  • CryptAcquireContext
  • CryptDestroyKey
  • CryptGenKey
  • CryptGetProvParam
  • CryptGetUserKey
  • CryptReleaseContext

This example code uses the function HandleError. The C code for this function is included with the sample. Code for this and other auxiliary functions is also listed under General Purpose Functions.

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);

void main(void)
{
//--------------------------------------------------------------------
// Declare and initialize variables.

HCRYPTPROV hCryptProv;        // Handle for the
                              // cryptographic provider context.
HCRYPTKEY hKey;               // Public/private key handle.
CHAR szUserName[100];         // Buffer to hold the name
                              // of the key container.
DWORD dwUserNameLen = 100;    // Length of the buffer.
LPCSTR UserName= NULL;        // Optionally enter the user's name here
                              // to be used as the key container
                              // name (limited to 100 characters).
//--------------------------------------------------------------------
// Begin processing. Attempt to acquire a context with a default key
// container.

//  To create a new key container, substitute a string for the
//  NULL second parameter here and in the next call to
//  CryptAcquireContext.

if(CryptAcquireContext(
   &hCryptProv,               // Handle to the CSP
   UserName,                  // Container name
   NULL,                      // Use the default provider
   PROV_RSA_FULL,             // Provider type
   0))                        // Flag values
{
    printf("A crypto context with the %s key container \n", UserName);
    printf("has been acquired.\n\n");
}
else
{
//--------------------------------------------------------------------
// Some sort of error occurred in acquiring the context.
// Create a new default key container.

   if(CryptAcquireContext(
      &hCryptProv,
      UserName,
      NULL,
      PROV_RSA_FULL,
      CRYPT_NEWKEYSET))
   {
      printf("A new key container has been created.\n");
   }
   else
   {
      HandleError("Could not create a new key container.\n");
    }
} // End of else
//--------------------------------------------------------------------
// A cryptographic context and a key container is available. Get the
// name of the key container.
if(CryptGetProvParam(
    hCryptProv,               // Handle to the CSP
    PP_CONTAINER,             // Get the key container name
    (BYTE *)szUserName,       // Pointer to the key container name
    &dwUserNameLen,           // Length of name, preset to 100
    0))
{
    printf("A crypto context has been acquired and \n");
    printf("The name on the key container is %s\n\n",szUserName);
}
else
{
    // Error getting key container name
    HandleError("A context was acquired or created, but\
      an error occurred getting the key container name.\n");
}

//--------------------------------------------------------------------
// A context with a key container is available,
// Attempt to get the handle to key exchange key.

if(CryptGetUserKey(
   hCryptProv,                     // Handle to the CSP
   AT_SIGNATURE,                   // Key specification
   &hKey))                         // Handle to the key
{
    printf("A signature key is available.\n");
}
else
{
    printf("No signature key is available.\n");
    if(GetLastError() == NTE_NO_KEY)
    {
    //----------------------------------------------------------------
    // The error was that there is a container but no key.

    // Create a signature key pair.
       printf("The signature key does not exist.\n");
       printf("Create a signature key pair.\n");
       if(CryptGenKey(
          hCryptProv,
          AT_SIGNATURE,
          0,
          &hKey))
       {
          printf("Created a signature key pair.\n");
       }
       else
       {
          HandleError("Error occurred creating a signature key.\n");
       }
    }
    else
    {
        HandleError("An error other than NTE_NO_KEY getting signature\
            key.\n");
    }
} // End of if

printf("A signature key pair existed, or one was created.\n\n");
CryptDestroyKey(hKey);

// Next, check the exchange key.
if(CryptGetUserKey(
   hCryptProv,
   AT_KEYEXCHANGE,
   &hKey))
{
   printf("An exchange key exists. \n");
}
else
{
     printf("No exchange key is available.\n");
     // Check to see if one needs to be created.
     if(GetLastError()==NTE_NO_KEY)
     {
       // Create an key exchange key pair.
       printf("The exchange key does not exist.\n");
       printf("Attempting to create an exchange key pair.\n");
       if(CryptGenKey(
           hCryptProv,
           AT_KEYEXCHANGE,
           0,
           &hKey))
       {
           printf("Exchange key pair created.\n");
       }
       else
       {
          HandleError("Error occurred attempting to create \
             an exchange key.\n");
       }
    }
    else
    {
       HandleError("An error other than NTE_NO_KEY occurred.\n");
     }
}

printf("An exchange key pair existed, or one was created.\n\n");
CryptDestroyKey(hKey);
CryptReleaseContext(hCryptProv,0);
printf("Everything is okay. A signature key\n");
printf("pair and an exchange key exist in\n");
printf("the %s key container.\n",UserName);
} // End of main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message and exit
//  the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    printf("An error occurred in running the program.\n");
    printf("%s\n",s);
    printf("Error number %x\n.",GetLastError());
    printf("Program terminating.\n");
    exit(1);
}


Example C Program: Using CryptAcquireContext

The following program is example code working with a cryptographic service provider (CSP) using CryptAcquireContext and related CryptoAPI functions.

Note This program will fail with error number 0x80090016 if a default key container does not exist for the current user. Run the program in Example C Program: Creating a Key Container and Generating Keys to create a default key container and generate the needed. keys before running this program.

This example program illustrates the following tasks and CryptoAPI functions:

  • Using CryptAcquireContext to acquire a handle for the default CSP and the default key container.
  • Using CryptGetProvParam to retrieve information on the CSP and the key container being used.
  • Increasing the reference count on the provider using CryptContextAddRef.
  • Releasing a CSP using CryptReleaseContext.
  • Creating a new key container.
  • Acquiring a handle for a CSP using the newly created key container.

When this code runs the first time, it creates the key container KC1. To run the program again, a new name must be provided for the key container to be created.

This example code uses the function HandleError. The C code for this function is included with the sample. Code for this and other auxiliary functions is also listed under General Purpose Functions.

//--------------------------------------------------------------------
//  Example code using CryptAcquireContext.

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);

void main(void)
{
//--------------------------------------------------------------------
// Declare and initialize variables.
HCRYPTPROV hCryptProv;
BYTE pbData[1000];       // 1000 will hold the longest
                         // key container name.
DWORD cbData;

//--------------------------------------------------------------------
// Get a handle to the default PROV_RSA_FULL provider.

if(CryptAcquireContext(
    &hCryptProv,
    NULL,
    NULL,
    PROV_RSA_FULL,
    0))
{
    printf("CryptAcquireContext succeeded.\n");
}
else
{
        if (GetLastError() == 0x80090016 )
     {
       printf(" The default key container does not exist.\n");
       printf(" Create a default container and generate keys \n");
       printf(" Using the code in \n");
       printf("  Example C Program: Creating a Key Container and Generating Keys \n");
       printf("  Before running this program. \n");
       exit(0);
     }
     else
     {
          HandleError("A genral error runing CryptAcquireContext.");
     }
}

//--------------------------------------------------------------------
// Read the name of the default CSP.

cbData = 1000;
if(CryptGetProvParam(
    hCryptProv,
    PP_NAME,
    pbData,
    &cbData,
    0))
{
    printf("CryptGetProvParam succeeded.\n");
    printf("Provider name: %s\n", pbData);
}
else
{
    HandleError("Error reading CSP name. \n");
}
//--------------------------------------------------------------------
// Read the name of the default key container.

cbData = 1000;
if(CryptGetProvParam(
    hCryptProv,
    PP_CONTAINER,
    pbData,
    &cbData,
    0))
{
    printf("CryptGetProvParam succeeded. \n");
    printf("Key Container name: %s\n", pbData);
}
else
{
    HandleError("Error reading key container name. \n");
}
//--------------------------------------------------------------------
// Perform cryptographic operations.
//...

//--------------------------------------------------------------------
//  Add to the reference count on the provider. When the reference
//  count on a provider is greater than 1, CryptReleaseContext reduces
//  the reference count but does not free the provider.
//  This function works with Windows 2000 and
//  later. When running this sample code on an earlier version, remove
//  this function call and the subsequent CryptReleaseContext.

if(CryptContextAddRef(
       hCryptProv,
       NULL,
       0))
{
    printf("CryptcontextAddRef succeeded. \n");
}
else
{
   HandleError("Error during CryptContextAddRef!\n");
}
//--------------------------------------------------------------------
//  The reference count on hCryptProv is now greater than one. The
//  first call to CryptReleaseContext will not release the provider
//  handle.

//--------------------------------------------------------------------
//  Release the context once.

if (CryptReleaseContext(hCryptProv, 0))
{
    printf("The first call to CryptReleaseContext succeeded. \n");
}
else
{
    HandleError("Error during CryptReleaseContext! #1 \n");
}
//--------------------------------------------------------------------
// Release the provider handle again.

if (CryptReleaseContext(hCryptProv, 0))
{
    printf("The second call to CryptReleaseContext succeeded. \n");
}
else
{
   HandleError("Error during CryptReleaseContext #2 !\n");
}
//--------------------------------------------------------------------
// Get a handle to the Microsoft Base Cryptographic Provider and
// create a "KC1" key container.

if(CryptAcquireContext(
   &hCryptProv,
   "KC1",
   NULL,
   PROV_RSA_FULL,
   CRYPT_NEWKEYSET))
{
    printf("CryptAcquireContext succeeded. \n");
    printf("New key set created. \n");
}
else
{
    HandleError("Error during CryptAcquireContext for a new key\
    \ncontainer. A container with this name probably \
    \nalready exists. \n");
}
//--------------------------------------------------------------------
// Perform cryptographic operations.
// ...

//--------------------------------------------------------------------
// Release the provider handle and KC1 key container.

if(CryptReleaseContext(hCryptProv, 0))
{
    printf("CryptReleaseContext succeeded. \n");
}
else
{
    HandleError("Error during CryptReleaseContext!\n");
}
//--------------------------------------------------------------------
// Get a handle to the default provider using the new key container.
// Note: This key container will be empty until keys
// are explicitly created with the CryptGenKey function.

if(CryptAcquireContext(
   &hCryptProv,
   "KC1",
   NULL,
   PROV_RSA_FULL,
   0))
{
     printf("Acquired the key set just created. \n");
}
else
{
    HandleError("Error during CryptAcquireContext!\n");
}
//--------------------------------------------------------------------
// Perform cryptographic operations.

//--------------------------------------------------------------------
// Release the provider handle.
if(CryptReleaseContext(
   hCryptProv,
   0))
{
    printf("CryptReleaseContext succeeded. \n");
}
else
{
    HandleError("Error during CryptReleaseContext!\n");
}
} // End of main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message and exit
//  the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    printf("An error occurred in running the program.\n");
    printf("%s\n",s);
    printf("Error number %x\n.",GetLastError());
    printf("Program terminating.\n");
    exit(1);
}


Example C Program: Enumerating CSP Providers and Provider Types

This example program lists the CSPs available on a computer.

This program uses the following CryptoAPI functions:

  • CryptEnumProviderTypes
  • CryptEnumProviders
  • CryptGetDefaultProvider
  • CryptGetProvParam

CryptGetDefaultProvider requires Windows 98, Windows 2000 or later. CryptEnumProviderTypes and CryptEnumProviders require Windows 2000 or later.

This example code uses the function HandleError. The C code for this function is included with the sample. Code for this and other auxiliary functions is also listed under General Purpose Functions.

//--------------------------------------------------------------------
//  Example code using CryptEnumProviderTypes, CryptEnumProviders,
//  CryptGetDefaultProvider, and CryptGetProvParam.
//  Most of these functions are available only with Windows 2000
//  and later.
//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
void HandleError(char *s);
void Wait(char *s);

void main()
{

//--------------------------------------------------------------------
//  Declare and initialize variables.

HCRYPTPROV hProv;         // Handle to a CSP
LPTSTR      pszName;
DWORD       dwType;
DWORD       cbName;
DWORD       dwIndex=0;
BYTE        *ptr;
ALG_ID      aiAlgid;
DWORD       dwBits;
DWORD       dwNameLen;
CHAR        szName[100]; // Often allocated dynamically
BYTE        pbData[1024];// Often allocated dynamically
DWORD       cbData=1024;
DWORD       dwIncrement = sizeof(DWORD);
DWORD       dwFlags=CRYPT_FIRST;
DWORD       dwParam = PP_CLIENT_HWND;
CHAR        *pszAlgType = NULL;
BOOL        fMore=TRUE;
LPTSTR      pbProvName;
DWORD       cbProvName;

//--------------------------------------------------------------
//   Print header lines for provider types.

printf("\n          Listing Available Provider Types.\n");
printf("Provider type      Provider Type Name\n");
printf("_____________    _____________________________________\n");

// Loop through enumerating provider types.
dwIndex = 0;
while(CryptEnumProviderTypes(
       dwIndex,     // in -- dwIndex
       NULL,        // in -- pdwReserved- set to NULL
       0,           // in -- dwFlags -- set to zero
       &dwType,     // out -- pdwProvType
       NULL,        // out -- pszProvName -- NULL on the first call
       &cbName      // in, out -- pcbProvName
       ))
{

//--------------------------------------------------------------------
//  cbName is the length of the name of the next provider type.
//  Allocate memory in a buffer to retrieve that name.

if (!(pszName = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, cbName)))
{
   HandleError("ERROR - LocalAlloc failed!");
}
//--------------------------------------------------------------------
//  Get the provider type name.

if (CryptEnumProviderTypes(
       dwIndex++,
       NULL,
       NULL,
       &dwType,
       pszName,
       &cbName))
{
    printf ("     %4.0d        %s\n",dwType, pszName);
}
else
{
    HandleError("ERROR - CryptEnumProviders");
}
LocalFree(pszName);
}

//--------------------------------------------------------------
//   Print header lines for providers.

printf("\n\n          Listing Available Providers.\n");
printf("Provider type      Provider Name\n");
printf("_____________    _____________________________________\n");
//----------------------------------------------------------------
// Loop through enumerating providers.
dwIndex = 0;
while(CryptEnumProviders(
       dwIndex,     // in -- dwIndex
       NULL,        // in -- pdwReserved- set to NULL
       0,           // in -- dwFlags -- set to zero
       &dwType,     // out -- pdwProvType
       NULL,        // out -- pszProvName -- NULL on the first call
       &cbName      // in, out -- pcbProvName
       ))
{

//--------------------------------------------------------------------
//  cbName is the length of the name of the next provider.
//  Allocate memory in a buffer to retrieve that name.

if (!(pszName = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, cbName)))
{
   HandleError("ERROR - LocalAlloc failed!");
}
//--------------------------------------------------------------------
//  Get the provider name.

if (CryptEnumProviders(
       dwIndex++,
       NULL,
       0,
       &dwType,
       pszName,
       &cbName     // pcbProvName -- size of pszName
       ))
{
    printf ("     %4.0d        %s\n",dwType, pszName);
}
else
{
    HandleError("ERROR - CryptEnumProviders");
}
LocalFree(pszName);

} // End of while loop

printf("\n\nProvider types and provider names have been listed.\n");
Wait("Press any key to continue.");

//-----------------------------------------------------------------
// Get the name of the default CSP specified for the PROV_RSA_FULL
// type for the computer.
//

//---------------------------------------------------------------
// Get the length of the RSA_FULL default provider name.

if (!(CryptGetDefaultProvider(
     PROV_RSA_FULL,
     NULL,
     CRYPT_MACHINE_DEFAULT,
     NULL,
     &cbProvName)))
{
   HandleError("Error getting the length of the default provider name.");
}

//---------------------------------------------------------------
// Allocate local memory for the name of the default provider.

if (!(pbProvName = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, cbProvName)))
{
    HandleError("Error during memory allocation for provider name.");
}

//---------------------------------------------------------------
// Get the default provider name.

if (CryptGetDefaultProvider(
    PROV_RSA_FULL,
    NULL,
    CRYPT_MACHINE_DEFAULT,
    pbProvName,
    &cbProvName))
{
    printf("The default provider name is %s\n\n",pbProvName);
}
else
{
    HandleError("Getting the name of the provider failed.");
}

//-----------------------------------------------------
//  Acquire a cryptographic context.

if(!CryptAcquireContext(
   &hProv,
   "OUR Container",
   NULL,
   PROV_RSA_FULL,
   NULL            // Use CRYPT_NEWKEYSET if the Key Container
                   // is new.
   ))
{
    HandleError("Error during CryptAcquireContext!");
}

//------------------------------------------------------
// Enumerate the supported algorithms.

//------------------------------------------------------
// Print header for algorithm infomation table
printf("\n               Enumerating the supported algorithms\n\n");
printf("     Algid      Bits      Type        Name         Algorithm\n");
printf("                                     Length          Name\n");
printf("    ________________________________________________________\n");
while(fMore)
{
//------------------------------------------------------
// Retrieve information about an algorithm.

    if(CryptGetProvParam(hProv, PP_ENUMALGS, pbData, &cbData, dwFlags))
    {
    //-----------------------------------------------------------
    // Extract algorithm information from the 'pbData' buffer.

       dwFlags=0;
       ptr = pbData;
       aiAlgid = *(ALG_ID *)ptr;
       ptr += sizeof(ALG_ID);
       dwBits = *(DWORD *)ptr;
       ptr += dwIncrement;
       dwNameLen = *(DWORD *)ptr;
       ptr += dwIncrement;
       strncpy(szName,(char *) ptr, dwNameLen);

     //--------------------------------------------------------
     // Determine the algorithm type.

   switch(GET_ALG_CLASS(aiAlgid)) {
        case ALG_CLASS_DATA_ENCRYPT: pszAlgType = "Encrypt  ";
                                     break;
        case ALG_CLASS_HASH:         pszAlgType = "Hash     ";
                                     break;
        case ALG_CLASS_KEY_EXCHANGE: pszAlgType = "Exchange ";
                                     break;
        case ALG_CLASS_SIGNATURE:    pszAlgType = "Signature";
                                     break;
        default:                     pszAlgType = "Unknown  ";
    }

    //------------------------------------------------------------
    // Print information about the algorithm.

     printf("    %8.8xh    %-4d    %s     %-2d          %s\n",
        aiAlgid, dwBits, pszAlgType, dwNameLen, szName
    );
}
else
   fMore=FALSE;
}

if(GetLastError() == ERROR_NO_MORE_ITEMS)
{
   printf("\nThe program completed without error.\n");
}
else
{
   HandleError("Error reading algorithm!");
}

} // End of main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message and exit
//  the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    printf("An error occurred in running the program.\n");
    printf("%s\n",s);
    printf("Error number %x\n.",GetLastError());
    printf("Program terminating.\n");
    exit(1);
}

void Wait(char *s)
{
char x;
printf("%s",s);
scanf("%c",&x);
printf("\n\n\n\n\n\n\n\n\n");
}


Example C Program: Deriving a Session Key from a Password

The following program demonstrates creating a session cryptographic key from the hash of a password. The program illustrates the use of the function CryptDeriveKey and related functions.

This example program illustrates the following tasks and CryptoAPI functions:

  • Calling CryptAcquireContext to acquiring a handle for the default CSP and the default key container.
  • Using CryptCreateHash to create an empty hash object.
  • Hashing the text of a password using CryptHashData.
  • Deriving a session key from the hashed password using CryptDeriveKey.
  • Destroying the hash and the password.
  • Using CryptReleaseContext to release the CSP.

This example code uses the function HandleError. C code for this function is included with the sample.

Code for this and other auxiliary functions is also listed under General Purpose Functions.

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);

void main()
{

//--------------------------------------------------------------------
//  Declare and initialize variables.

HCRYPTPROV hCryptProv;
HCRYPTKEY hKey;
HCRYPTHASH hHash;
CHAR szPassword[512];
DWORD dwLength;

//--------------------------------------------------------------------
//  Get the password from the user.

fprintf(stderr,"Enter a password to be used to create a key:");
scanf("%s",szPassword);
fprintf(stderr,"The password is %s .\n", szPassword);
dwLength = strlen(szPassword);

//--------------------------------------------------------------------
// Acquire a CSP.

if(CryptAcquireContext(
   &hCryptProv,
   NULL,
   NULL,
   PROV_RSA_FULL,
   0))
{
    printf("A CSP has been acquired. \n");
}
else
{
     HandleError("Error during CryptAcquireContext!");
}
//--------------------------------------------------------------------
// Create an empty hash object.
if(CryptCreateHash(
   hCryptProv,
   CALG_MD5,
   0,
   0,
   &hHash))
{
    printf("An empty hash object has been created. \n");
}
else
{
    HandleError("Error during CryptCreateHash!");
}
//--------------------------------------------------------------------
// Hash the password string.

if(CryptHashData(
   hHash,
   (BYTE *)szPassword,
   dwLength,
   0))
{
     printf("The password has been hashed. \n");
}
else
{
     HandleError("Error during CryptHashData!");
}
//--------------------------------------------------------------------
// Create a session key based on the hash of the password.

if(CryptDeriveKey(
   hCryptProv,
   CALG_RC2,
   hHash,
   CRYPT_EXPORTABLE,
   &hKey))
{
    printf("The key has been derived. \n");
}
else
{
    HandleError("Error during CryptDeriveKey!");
}
//--------------------------------------------------------------------
// Use hKey as appropriate to encrypt or decrypt a message.

//--------------------------------------------------------------------
// Clean up.

// Destroy the hash object.

if(hHash)
   CryptDestroyHash(hHash);

// Destroy the session key.
if(hKey)
    CryptDestroyKey(hKey);

// Release the provider handle.
if(hCryptProv)
   CryptReleaseContext(hCryptProv, 0);
printf("The program to derive a key completed without error. \n");
} // End of main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message and exit
//  the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    printf("An error occurred in running the program.\n");
    printf("%s\n",s);
    printf("Error number %x\n.",GetLastError());
    printf("Program terminating.\n");
    exit(1);
}


Example C Program: Duplicating a Session Key

This example program creates a random session key, duplicates the key, sets some additional parameters on the original key, and destroys both the original and the duplicate keys. The program illustrates the use of CryptDuplicateKey and related functions. CryptDuplicateKey was added with Windows 2000. This example program will only run on systems running Windows 2000 or later.

This example program illustrates the following tasks and CryptoAPI functions:

  • Accessing a CSP using CryptAcquireContext.
  • Creating a session key using CryptGenKey.
  • Duplicating the key created using CryptDuplicateKey.
  • Using CryptSetKeyParam to alter the key generation process in two different ways.
  • Filing a buffer with random bytes using CryptGenRandom.
  • Destroying the keys using CryptDestroyKey.
  • Releasing the CSP with CryptReleaseContext.

This example code uses the function HandleError. The C code for this function is included with the sample. Code for this and other auxiliary functions is also listed under General Purpose Functions.

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);

//--------------------------------------------------------------------
//   Begin main.

void main()
{
//--------------------------------------------------------------------
// Declare and initialize variables.

HCRYPTPROV   hCryptProv;
HCRYPTKEY    hOriginalKey;
HCRYPTKEY    hDuplicateKey;
DWORD        dwMode;
BYTE         pbData[16];

//--------------------------------------------------------------------
//  Begin processing.

printf("This program creates a session key and duplicates \n");
printf("that key. Next, parameters are added to the original \n");
printf("key. Finally, both keys are destroyed. \n\n");

//--------------------------------------------------------------------
//  Acquire a CSP context.

if(CryptAcquireContext(
   &hCryptProv,
   NULL,
   NULL,
   PROV_RSA_FULL,
   0))
{
    printf("CryptAcquireContext succeeded. \n");
}
else
{
    HandleError("Error during CryptAcquireContext!\n");
}
//--------------------------------------------------------------------
// Generate a key.
if (CryptGenKey(
     hCryptProv,
     CALG_RC4,
     0,
     &hOriginalKey))
{
   printf("Original session key is created. \n");
}
else
{
   HandleError("ERROR - CryptGenKey.");
}
//--------------------------------------------------------------------
// Duplicate the key.

if (CryptDuplicateKey(
     hOriginalKey,
     NULL,
     0,
     &hDuplicateKey))
{
   printf("The session key has been duplicated. \n");
}
else
{
   HandleError("ERROR - CryptDuplicateKey");
}
//--------------------------------------------------------------------
//  Set additional parameters on the original key.
//  First, set the cipher mode.

dwMode = CRYPT_MODE_ECB;
if(CryptSetKeyParam(
   hOriginalKey,
   KP_MODE,
   (BYTE*)&dwMode,
   0))
{
     printf("Key Parameters set. \n");
}
else
{
     HandleError("Error during CryptSetKeyParam.");
}
// Generate a random initialization vector.
if(CryptGenRandom(
   hCryptProv,
   8,
   pbData))
{
     printf("Random sequence generated. \n");
}
else
{
     HandleError("Error during CryptGenRandom.");
}
//--------------------------------------------------------------------
// Set the initialization vector.
if(CryptSetKeyParam(
   hOriginalKey,
   KP_IV,
   pbData,
   0))
{
     printf("Parameter set with random sequence as initialization vector. \n");
}
else
{
     HandleError("Error during CryptSetKeyParam.");
}
//--------------------------------------------------------------------
// Clean up.

if (hOriginalKey)
    CryptDestroyKey(hOriginalKey)

if (hDuplicateKey)
    CryptDestroyKey(hDuplicateKey)

if(hCryptProv)
    CryptReleaseContext(hCryptProv, 0)

printf("\nThe program ran to completion without error. \n");

} //  End of main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message and exit
//  the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    printf("An error occurred in running the program.\n");
    printf("%s\n",s);
    printf("Error number %x\n.",GetLastError());
    printf("Program terminating.\n");
    exit(1);
}


Example C Program: Setting and Getting Session Key Parameters

This example program creates a random session key, gets and prints some default parameters of that key, sets a new parameters on the original key, the gets and prints the value of that new parameter. It cleans up by destroying the session key and releasing the cryptographic context.

This program illustrates the use of the following tasks and functions:

  • Accessing a CSP using CryptAcquireContext.
  • Filing a buffer with random bytes using CryptGenRandom.
  • Creating a session key using CryptGenKey.
  • Getting the value of key parameters using CryptGetKeyParam.
  • Using CryptSetKeyParam to alter the key generation process.
  • Destroying the keys using CryptDestroyKey.
  • Releasing the CSP with CryptReleaseContext.

This example code uses the function HandleError. The C code for this function is included with the sample. Code for this and other auxiliary functions is also listed under General Purpose Functions.

#include "windows.h"
#include "stdio.h"
#include "wincrypt.h"

void HandleError(char *s);

void main()
{
HCRYPTPROV hProv;
HCRYPTKEY hKey;
BYTE dwMode;
BYTE pbData[16];
BYTE pbRandomData[8];
DWORD dwCount;
DWORD i;
//----------------------------------------------------
// Get a handle to user default provider.
if(!CryptAcquireContext(
    &hProv,
    NULL,
    NULL,
    PROV_RSA_FULL,
    0))
{
    HandleError("Error during CryptAcquireContext.");
}

//--------------------------------------------------------------
//  Generate eight bytes of random data into pbRandomData

if( CryptGenRandom(
   hProv,
   8,
   pbRandomData))
{
     printf("Eight bytes of random data have been generated.\n");
}
else
{
     HandleError("Random bytes were not correctly generated.");
}
// Create a random block cipher session key.

if(!CryptGenKey(
     hProv,
     CALG_RC4,
     CRYPT_EXPORTABLE,
     &hKey))
{
    HandleError("Error during CryptGenKey.");
}

//--------------------------------------------------------------------
// Read the cipher mode.

dwCount = sizeof(DWORD);
if(CryptGetKeyParam(
     hKey,
     KP_MODE,
     &dwMode,
     &dwCount,
     0))
{
//---------------------------------------------------------------
// Print out the cipher mode.

     printf("Default cipher mode: %d\n", dwMode);

}
else
{
     HandleError("Error during CryptGetKeyParam.");
}

//---------------------------------------------------------------
// Read the initialization vector.

//-------------------------------------------------------------
//  Get the length of the initialization vector.

if(!CryptGetKeyParam(
    hKey,
    KP_IV,
    NULL,
    &dwCount,
    0))
{
    HandleError("Error getting the IV length");
}

//--------------------------------------------------------------
// Get the IV, itself

if(CryptGetKeyParam(
    hKey,
    KP_IV,
    pbData,
    &dwCount,
    0))
{
     //---------------------------------------------------------
     // Print out the initialization vector.
     printf("Default IV:");
     for(i=0;i<dwCount;i++)
          printf("%2.2x ",pbData[i]);
     printf("\n");
}
else
{
    HandleError("Error getting the IV.");
}

//-------------------------------------------------------------
//  Reset the Initialization Vector.

if(CryptSetKeyParam(
   hKey,
   KP_IV,
   pbRandomData,
   0))
{
     printf("New intialization vector is set.\n");
}
else
{
     HandleError("The new IV was not set.");
}
//---------------------------------------------------------------
// Read the New initialization vector.

//-------------------------------------------------------------
//  Get the length of the new initialization vector.

if(!CryptGetKeyParam(
    hKey,
    KP_IV,
    NULL,
    &dwCount,
    0))
{
    HandleError("Error getting the IV length");
}

//--------------------------------------------------------------
// Get the IV, itself

if(CryptGetKeyParam(
    hKey,
    KP_IV,
    pbData,
    &dwCount,
    0))
{
     //---------------------------------------------------------
     // Print out the initialization vector.
     printf("RE-set IV:");
     for(i=0;i<dwCount;i++)
          printf("%2.2x ",pbData[i]);
     printf("\n");
}
else
{
    HandleError("Error getting the IV.");
}

//-------------------------------------------------------------
//  Clean up.

//-------------------------------------------------------------
//  Destroy the session key.

if(hKey)
{
    CryptDestroyKey(hKey);
}
else
{
     printf("A session key does not exist.\n");
}

//--------------------------------------------------------------
// Release the provider handle.

if(hProv)
{
    CryptReleaseContext(hProv, 0);
}
else
{
     printf("No context was aquired.\n");
}

printf("\nProgram completing without error.\n\n");

} // end of main

void HandleError(char *s)
{
     printf("%s\n",s);
     exit(1);
}  // end of HandleError


Working with Keys from Various CSPs

The following sections give procedures for generating, retrieving, exporting, and importing keys using the various CSPs.

  • RSA/Schannel Keys
  • Diffie-Hellman Keys
  • Diffie-Hellman/Schannel Keys
  • DSS Keys


RSA/Schannel Keys

Generating And Retrieving RSA/Schannel Keys

RSA/Schannel Keys can be generated by calling CryptGenKey. The call to CryptGenKey requires an AT_KEYEXCHANGE algorithm identifier passed in the Algid argument.

To generate a RSA/Schannel public/private key pair

  1. Call CryptAcquireContext to get a handle to the Microsoft RSA/Schannel Cryptographic Provider.
  2. Call CryptGenKey to generate the keys. AT_KEYEXCHANGE must be passed in for the Algid argument and the upper 16 bits of the dwFlags argument must be set to the desired key size (512 bits). A HCRYPTKEY handle is returned in the hKey argument.

To retrieve a pointer to previously generated RSA/Schannel user keys

  1. Call CryptAcquireContext to get a handle to the Microsoft RSA/Schannel Cryptographic Provider.
  2. Call CryptGetUserKey, with the dwKeySpec argument set to AT_KEYEXCHANGE.

Exporting RSA/Schannel Keys

Master keys can be exported into SIMPLEBLOBs. This should be implemented the same way as the export of normal RC4 or DES bulk encryption keys. The aiKeyAlg field of the PUBLICKEYSTRUC structure is set to the algorithm identifier of the master key (CALG_PCT1_MASTER, CALG_SSL2_MASTER, CALG_SSL3_MASTER, or CALG_TLS1_MASTER).

If the CPExportKey function is exporting an SSL2 master key and the CRYPT_SSL2_SLUMMING flag is set. To help prevent version rollback attacks, set the first eight bytes of the encryption block padding to 0x03 rather than to random data.

If the CRYPT_DESTROYKEY flag is specified with the CPExportKey function, the CSP destroys the key or key handle after exporting the key. This flag is intended for use only with opaque BLOBs.


Diffie-Hellman Keys

Generating Diffie-Hellman Keys

The steps necessary for this are shown in the following procedure.

To generate a Diffie-Hellman public key

  1. Call CryptAcquireContext to get a handle to the Microsoft Diffie-Hellman Cryptographic Provider.
  2. Generate the new key. There are two ways to accomplish this — by having CryptoAPI generate all new values for G, P, and X or by using existing values for G and P, and generating a new value for X.

    To generate the key by generating all new values:

    Call CryptGenKey passing either CALG_DH_SF (store and forward) or CALG_DH_EPHEM (ephemeral) in the Algid parameter. The key will be generated, using new, random values for G and P, a newly calculated value for X, and its handle will be returned in the phKey parameter.

    The new key is now ready for use. Note that the values of G and P must be sent along with the key (or sent by some other method), when doing a key exchange.

    To generate the key by using predefined values for G and P:

    1. Initialize a CRYPT_DATA_BLOB structure with the pbData member set to the G value. The BLOB contains no header information and the pbData member is in little-endian format.
    2. Initialize a CRYPT_DATA_BLOB structure with the pbData member set to the P value. The BLOB contains no header information and the pbData member is in little-endian format.
    3. Call CryptGenKey passing either CALG_DH_SF (store and forward) or CALG_DH_EPHEM (ephemeral) in the Algid parameter, and CRYPT_PREGEN for the dwFlags parameter. A key handle will be generated and returned in the phKey parameter.
    4. The value of G id set by calling CryptSetKeyParam, passing the key handle (retrieved in step c) in the hKey parameter, the KP_G flag in the dwParam parameter, and a pointer to the structure containing the value of G in the pbData parameter.
    5. The value of P is set by calling CryptSetKeyParam, passing the key handle (retrieved in step c) in the hKey parameter, the KP_P flag in the dwParam parameter, and a pointer to the structure containing the value of P in the pbData parameter.
    6. The value of X is generated by calling CryptSetKeyParam, passing the key handle (retrieved in step c) in the hKey parameter, the KP_X flag in the dwParam parameter, and NULL in the pbData parameter.

      If all the function calls succeeded, the DIFFIE-HELLMAN public key is ready for use.

  3. When the key is no longer needed, call CryptDestroyKey to destroy the key handle (HCRYPTKEY).

If CALG_DH_SF was specified in the previous procedures, the key values are persisted to storage with each call to CryptSetKeyParam. The G and P values can then be retrieved using CryptGetKeyParam. Some CSPs may have hard-coded G and P values. In this case a NTE_FIXEDPARAMETERS error will be returned if CryptSetKeyParam is called with KP_G or KP_P specified in the dwParam parameter. If CryptDestroyKey is called, the handle to the key is destroyed, but the key values are retained in the CSP. However, if CALG_DH_EPHEM was specified, the handle to the key is destroyed and all values are purged from the CSP.

Exchanging Diffie-Hellman Keys

The purpose of the Diffie-Hellman algorithm is to make it possible for two or more hosts to create and share an identical, secret encryption key by simply sharing information over an insecure network. The information that gets shared over the network is in the form of a couple of constant values, and a DIFFIE-HELLMAN public key. The process used by two key-exchange participants is as follows:

  • Both participants agree to the "Diffie-Hellman parameters," a prime number (P), and a base number (G).
  • Participant 1 sends its DIFFIE-HELLMAN public key to participant 2.
  • Participant 2 computes the secret encryption key by using the information contained in participant 1's public key.
  • Participant 2 sends participant 1 its DIFFIE-HELLMAN public key.
  • Participant 1 computes the secret encryption key by using the information contained in participant 2's public key.
  • Both participants now have the same encryption key, which can be used for encrypting and decrypting data. The steps necessary for this are shown in the following procedure.

To prepare a Diffie-Hellman public key for transmission

  1. Call CryptAcquireContext to get a handle to the Microsoft Diffie-Hellman Cryptographic Provider.
  2. Get a handle to a DIFFIE-HELLMAN key by calling CryptGenKey to create a new key, or by calling CryptGetUserKey to retrieve an existing one.
  3. Get the memory byte length needed to hold a DIFFIE-HELLMAN key by calling CryptExportKey, passing NULL for the pbData parameter. The key length will be returned in pdwDataLen.
  4. Allocate memory for the key.
  5. Create a DIFFIE-HELLMAN public-key BLOB by calling CryptExportKey, passing PUBLICKEYBLOB in the dwBlobType parameter and the handle to the DIFFIE-HELLMAN key in the hKey parameter. This function call causes the calculation of the public key value, (G^X) mod P. If all the preceding function calls were successful, the DIFFIE-HELLMAN public key is now ready to be encoded and transmitted.

To import a DIFFIE-HELLMAN public key and calculate the private (secret) key

  1. Call CryptAcquireContext to get a handle to the Microsoft Diffie-Hellman Cryptographic Provider.
  2. Get a handle to a DIFFIE-HELLMAN key by calling CryptGenKey to create a new key, or by calling CryptGetUserKey to retrieve an existing one.
  3. To import the key into the CSP, call CryptImportKey, passing a pointer to the public key BLOB in the pbData parameter, the length of the BLOB in the dwDataLen parameter, and the handle to the DIFFIE-HELLMAN key in the hPubKey parameter. This call to CryptImportKey causes the calculation, (Y^X) mod P, to be performed thus creating the shared, secret key and completing the key exchange. This function call returns a handle to the new, secret, bulk-encryption key in the hKey parameter.
  4. Convert the shared, secret key to the CALG_CYLINK_MEK, bulk-encryption key type, by calling CryptSetKeyParam with dwParam set to KP_ALGID, and with pbData set to a pointer to CALG_CYLINK_MEK. This step must be done before using the shared key in CryptEncrypt or CryptDecrypt. Calls made to either of these functions prior to calling CryptSetKeyParam will fail.

    If a call to CryptGetKeyParam is made on the key handle returned from the call to CryptImportKey and prior to calling CryptSetKeyParam (as described in this step), the ALG_ID returned by the call to CryptGetKeyParam will be CALG_AGREEDKEY_ANY. If all the preceding function calls were successful, the secret key is now ready to be used for encryption or decryption.

  5. When the key is no longer needed, call CryptDestroyKey to destroy the key handle (HCRYPTKEY). .

Exporting a Diffie-Hellman Private (secret) Key

The steps necessary are shown in the following procedure.

To export a DIFFIE-HELLMAN private key

  1. Call CryptAcquireContext to get a handle to the Microsoft Diffie-Hellman Cryptographic Provider.
  2. Get a handle to a DIFFIE-HELLMAN key by calling CryptGenKey to create a new key, or by calling CryptGetUserKey to retrieve an existing one.
  3. Create a Diffie-Hellman public-key BLOB by calling CryptExportKey, passing PRIVATEKEYBLOB in the dwBlobType parameter and the handle to the DIFFIE-HELLMAN key in the hKey parameter.
  4. When the key is no longer needed, call CryptDestroyKey to destroy the key handle (HCRYPTKEY).


Diffie-Hellman/Schannel Keys

Generating Diffie-Hellman/Schannel keys

To generate a Diffie-Hellman public key

  1. Call CryptAcquireContext to get a handle to the Microsoft Diffie-Hellman/Schannel Cryptographic Provider.
  2. Generate the new key. There are two ways to accomplish this, by having CryptoAPI generate new values for G, P, and X, or by using existing values for G and P, and generating a new value for X.

    To generate the key by generating all new values:

    Call CryptGenKey passing either CALG_DH_SF (store and forward) or CALG_DH_EPHEM (ephemeral) in the Algid parameter. The key will be generated, using new, random values for G and P, a newly calculated value for X, and its handle will be returned in the phKey parameter.

    The new key is now ready for use. Note that the values of G and P must be sent along with the key (or sent by some other method), when doing a key exchange.

    To generate the key by using predefined values for G and P:

    1. Initialize a CRYPT_DATA_BLOB structure with the pbData member set to the G value. The BLOB contains no header information and the pbData member is in little-endian format.
    2. Initialize a CRYPT_DATA_BLOB structure with the pbData member set to the P value.The BLOB contains no header information and the pbData member is in little-endian format.
    3. Call CryptGenKey passing either CALG_DH_SF (store and forward) or CALG_DH_EPHEM (ephemeral) in the Algid parameter, and CRYPT_PREGEN for the dwFlags parameter. A key handle will be generated and returned in the phKey parameter.
    4. The value of G may be set by calling CryptSetKeyParam, passing the key handle (retrieved in step c) in the hKey parameter, the KP_G flag in the dwParam parameter, and a pointer to the structure containing the value of G in the pbData parameter.
    5. The value of P can be set by calling CryptSetKeyParam, passing the key handle (retrieved in step c) in the hKey parameter, the KP_P flag in the dwParam parameter, and a pointer to the structure containing the value of P in the pbData parameter.
    6. The value of X must be generated by calling CryptSetKeyParam, passing the key handle (retrieved in step c) in the hKey parameter, the KP_X flag in the dwParam parameter, and NULL in the pbData parameter.

      If all the function calls succeeded, the DIFFIE-HELLMAN public key is ready for use.

  3. When the key is no longer needed, call CryptDestroyKey to destroy the key handle (HCRYPTKEY).

If CALG_DH_SF was specified in the previous procedures, the key values are persisted to storage with each call to CryptSetKeyParam. The G and P values can then be retrieved using CryptGetKeyParam. Some CSPs may have hard coded G and P values. In this case a NTE_FIXEDPARAMETERS error will be returned if CryptSetKeyParam is called with KP_G or KP_P specified in the dwParam parameter. If CryptDestroyKey is called, the handle to the key is destroyed, but the key values are retained in the CSP. However, if CALG_DH_EPHEM was specified, the handle to the key is destroyed and all values are purged from the CSP.

Exchanging Diffie-Hellman/Schannel Keys

The Diffie-Hellman algorithm makes it possible for two or more hosts to create and share an identical, secret encryption key by simply sharing information over an insecure network. The information shared over the network is in the form of two constant values and a DIFFIE-HELLMAN public key. The process used by two key-exchange participants is as follows:

  • Both participants agree to the "Diffie-Hellman parameters"; a prime number, P and a base number, G.
  • Participant 1 sends its DIFFIE-HELLMAN public key to participant 2.
  • Participant 2 computes the secret encryption key by using the information contained in Participant 1's public key.
  • Participant 2 sends Participant 1 its DIFFIE-HELLMAN public key.
  • Participant 1 computes the secret encryption key by using the information contained in Participant 2's public key.
  • Both participants now have the same encryption key, which can be used for encrypting and decrypting data.

To prepare a Diffie-Hellman/Schannel public key for transmission

  1. Call CryptAcquireContext to get a handle to the Microsoft Diffie-Hellman Schannel Cryptographic Provider.
  2. Get a handle to a Diffie-Hellman key by calling CryptGenKey to create a new key, or by calling CryptGetUserKey to retrieve an existing one.
  3. Get the memory byte length needed to hold a DIFFIE-HELLMAN key by calling CryptExportKey, passing NULL for the pbData parameter. The key length will be returned in pcbData.
  4. Allocate memory for the key.
  5. Create a Diffie-Hellman public-key BLOB by calling CryptExportKey, passing PUBLICKEYBLOB in the dwBlobType parameter and the handle to the DIFFIE-HELLMAN key in the hKey parameter. This function call calculates the public key value, (G^X) mod P. If all the preceding function calls were successful, the DIFFIE-HELLMAN public key is now ready to be encoded and transmitted.

To import a Diffie-Hellman/Schannel public key and calculate the agreed (secret) key

  1. Call CryptAcquireContext to get a handle to the Microsoft Diffie-Hellman/Schannel Cryptographic Provider.
  2. Get a handle to a DIFFIE-HELLMAN key by calling CryptGenKey to create a new key, or by calling CryptGetUserKey to retrieve an existing one.
  3. To import the key into the CSP, call CryptImportKey, passing a pointer to the public key BLOB in the pbData parameter, the length of the BLOB in the dwDataLen parameter, and the handle to the DIFFIE-HELLMAN key in the hImpKey parameter. This call to CryptImportKey causes the calculation, (Y^X) mod P, to be performed thus creating the shared, secret key and completing the key exchange. This function call returns a handle to the new, secret, bulk-encryption key in the hKey parameter.
  4. Convert the shared, secret key to the appropriate ALG_ID, bulk-encryption key type, by calling CryptSetKeyParam with dwParam set to KP_ALGID, and with pbData set to a pointer to CALG_CYLINK_MEK. This step must be done before using the shared key in CryptEncrypt or CryptDecrypt. Calls made to either of these functions prior to calling CryptSetKeyParam will fail.

    If a call to CryptGetKeyParam is made on the key handle returned from the call to CryptImportKey and prior to calling CryptSetKeyParam (as described in this step), the ALG_ID returned by the call to CryptGetKeyParam will be CALG_AGREEDKEY_ANY. If all the preceding function calls were successful, the agreed key is now ready to be used for encryption or decryption.

    The SSL 3.0 or TLS 1.0 key length is 48 bytes. To obtain the required length, take the 384 Least Significant Bits of the returned HCRYPTKEY for this agreed key.

  5. When the key is no longer needed, call CryptDestroyKey to destroy the key handle (HCRYPTKEY).

Exporting Diffie-Hellman/Schannel keys

To export a Diffie-Hellman/Schannel agreed key

  1. Call CryptAcquireContext to get a handle to the Microsoft Diffie-Hellman/Schannel Cryptographic Provider.
  2. Get a handle to a Diffie-Hellman key. Do this by calling CryptGenKey to create a new key, or by calling CryptGetUserKey to retrieve an existing one.
  3. Create a Diffie-Hellman public-key BLOB by calling CryptExportKey, passing PRIVATEKEYBLOB in the dwBlobType parameter and the handle to the DIFFIE-HELLMAN key in the hKey parameter.
  4. When the key is no longer needed, call CryptDestroyKey to destroy the key handle (HCRYPTKEY).


DSS Keys

Generating and retrieving DSS keys

DSS Keys can be generated with a call to CryptGenKey. The call to CryptGenKey requires either AT_SIGNATURE or CALG_DSS_SIGN be passed in the Algid argument. This call will generate the P (prime modulus), Q (prime), G (generator), X (secret exponent) and Y (public key) values from scratch and persist them in a key BLOB to local storage. The steps necessary for this are shown in the following procedure.

To generate a DSS signature key pair

  1. Call CryptAcquireContext to get a handle to the Microsoft DSS Cryptographic Provider.
  2. Call CryptGenKey to generate the keys. Either AT_SIGNATURE or CALG_DSS_SIGN must be passed in for the Algid argument and the upper 16 bits of the dwFlags argument must be set to the desired key size. If the upper 16 bits are zero, then the default key size of 1,024 bits will be used. A HCRYPTKEY handle is returned in the hKey argument.

To retrieve a pointer to previously generated signature keys

  1. Call CryptAcquireContext to get a handle to the Microsoft DSS Cryptographic Provider.
  2. Call CryptGetUserKey, with the dwKeySpec argument set to either AT_SIGNATURE or CALG_DSS_SIGN.

To retrieve the P,Q, and G values

  1. Call CryptAcquireContext to get a handle to the Microsoft DSS Cryptographic Provider.
  2. Call CryptGetUserKey, with the dwKeySpec argument set to either AT_SIGNATURE or CALG_DSS_SIGN.
  3. Call CryptGetKeyParam with the hKey argument set to the pointer retrieved in the previous step. The dwParam argument must be set to the desired flag; KP_P, KP_Q, or KP_G. The value is returned in the pbData argument and the length of the data is returned in the pcbData argument. The value is returned with no header information and in little-endian format.

Generating DSS Signatures

Data to be signed must first be hashed using the SHA algorithm. After that data is hashed, a DSS signature is generated by calling CryptSignHash. The steps necessary for this are shown in the following procedure.

To generate a DSS signature

  1. Call CryptAcquireContext to get a handle to the Microsoft DSS Cryptographic Provider.
  2. Call CryptCreateHash with the Algid argument set to CALG_SHA to get a handle to an SHA hash object.
  3. Call CryptHashData with the hHash argument set to the handle retrieved in the previous step. This creates a hash of the data and returns a handle to the hash in the phHash argument of the CryptCreateHash function call.
  4. Call CryptSignHash with the hHash argument set to the handle retrieved in the previous step. Either AT_SIGNATURE or CALG_DSS_SIGN may be passed in the dwKeySpec parameter. The signature is returned to the address provided in the pbSignature argument and the length of the signature is returned to the address provided in the pcbSignature argument. A NULL pointer may be passed in the pbSignature argument, and in this case the signature is not generated, but the length of the signature is returned to the address provided in the pcbSignature parameter.

Verifying a DSS Signature

To verify a DSS signature, the DSS public key of the signer must be imported, the signed data must be hashed, and then the signature can be verified. The steps necessary for this are shown in the following procedure.

To verify a DSS Signature

  1. Call CryptAcquireContext to get a handle to the Microsoft DSS Cryptographic Provider.
  2. Call CryptImportKey to import the signer's DSS public key.
  3. Call CryptCreateHash with the Algid argument set to CALG_SHA to get a handle to an SHA hash object.
  4. Call CryptHashData with the hHash argument set to the handle retrieved in the previous step, and with pbData pointing to the signed data. This creates a hash of the data and returns a handle to the hash in the phHash argument of the CryptCreateHash function call.
  5. Call CryptVerifySignature with the following settings:

    hHash. set to the handle to the hash performed in the previous step.

    pbSignature. points to the signature to be verified.

    dwSigLen. set to the length of the signature.

    hPubKey. set to the handle of the public key imported in step 2.

    dwFlags. set to zero.

Exporting DSS Keys

When sending signed data to someone where the signature will need to be verified by the recipient, the signer's public key must be provided to the recipient; and is usually sent along with the signed data. Therefore, it is necessary to be able to export the DSS keys in a key BLOB format.

To export the DSS public key

  1. Call CryptAcquireContext to get a handle to the Microsoft DSS Cryptographic Provider.
  2. Call CryptGetUserKey, with the dwKeySpec argument set to either AT_SIGNATURE or CALG_DSS_SIGN.
  3. Call CryptExportKey with hKey set to the handle retrieved in the previous step, dwBlobType set to PUBLICKEYBLOB, and dwFlags set to zero. The DSS public-key BLOB is returned in pbData and the length of the key BLOB is returned in pdwDataLen. A NULL pointer may be passed in pbData, and in this case just the length of the DSS key BLOB will be returned. The BLOB returned when making the call to CryptExportKey is in the format described in DSS Provider Key Blobs.

To export the DSS private key

  1. Follow the same procedure as for exporting a DSS public key, except that when making the call to CryptExportKey, dwBlobType is set to PRIVATEKEYBLOB. The BLOB returned when making the call to CryptExportKey is in the format described in DSS Provider Key Blobs.


Procedure for Storing a Session Key

Note This section assumes that users possess a set of public/private key pairs. Instructions and example code for creating key pairs can be found in Example C Program: Creating a Key Container and Generating Keys.

To store a session key

  1. Create a simple key BLOB by using the CryptExportKey function. This will transfer the session key from the CSP to an application's memory space. Specify that an exchange public key be used to sign the key BLOB.
  2. Store the signed key BLOB to disk. It is assumed that all disks are nonsecure.
  3. When the key is needed, read the key BLOB from disk.
  4. Import the key BLOB back into the CSP by using the CryptImportKey function.

For the code needed to create a session key and export that key to a simple key BLOB that can be written to a disk file, see Example C Program: Exporting a Session Key.

This procedure provides only minimal security. If the stored session key will be used to encrypt data at a later date, the preceding procedure does not provide adequate security.

To provide greater security, sign the key BLOB with an exchange private key before it is stored to disk. When the key BLOB is later read from disk, its signature can be validated to ensure that the key BLOB is intact.

If the key BLOB is not signed, anyone with access to the disk or other media where the key is stored can create a new session key.

The new session key can be encrypted with the original user's public key exchange key, and this new key can be substituted for the original. If the user unknowingly used the substituted session key to encrypt files and messages, the individual who created the substitute key could easily decrypt them.

Digital signatures are discussed in detail in Hashes and Digital Signatures.


Procedure for Storing Session Keys Using a Backup Authority

An application using a backup authority to store session keys typically follows these steps.

To use a backup authority

  1. Encrypt the file as usual.
  2. Export the session key used to encrypt the file into a simple key BLOB, specifying that your own key exchange public key be used to encrypt the key BLOB. Store this key BLOB with the encrypted file.
  3. Export the session key again, this time specifying that the backup authority's public key be used to encrypt the key BLOB. Send this key BLOB to the backup authority, along with the key's description, serial number, and so on.

If a key pair is lost, the keys can be retrieved from the backup authority if the identity of the keys' owner can be established. The procedure for establishing identity is determined by the policy of the particular backup authority and does not involve the CryptoAPI.

For the code needed to create a session key and export that key to a simple key BLOB that can be written to a disk file, see Example C Program: Exporting a Session Key.


Example C Program: Exporting a Session Key

This example program creates a random session key and creates an exportable key BLOB. The program illustrates the use of CryptGetUserKey, CryptExportKey, and related functions.

This example program illustrates the following tasks and CryptoAPI functions:

  • Acquiring a CSP context using CryptAcquireContext.
  • Gaining access to two different pairs of public/private keys using CryptGetUserKey.
  • Generating an exportable session key using CryptGenKey.
  • Creating a simple key BLOB containing a session key using CryptExportKey.
  • Destroying a session key and access to the two pairs of public/private keys using CryptDestroyKey.
  • Releasing the CSP context using CryptReleaseContext.

This example code uses the function HandleError. The C code for this function is included with the sample. Code for this and other auxiliary functions is also listed under General Purpose Functions.

//--------------------------------------------------------------------
// This example program creates a session key and a simple key
// BLOB holding that session key. The key BLOB can be written to disk
// and later read from a disk file.

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);

void main(void)
{
//--------------------------------------------------------------------
//  Declare and initialize variables.

HCRYPTPROV hProv;       // CSP handle
HCRYPTKEY hSignKey;     // Signature key pair handle
HCRYPTKEY hXchgKey;     // Exchange key pair handle
HCRYPTKEY hKey;         // Session key handle
BYTE *pbKeyBlob;        // Pointer to a simple key BLOB
DWORD dwBlobLen;        // The length of the key BLOB

//--------------------------------------------------------------------
// Get a handle to the user default provider.

if(CryptAcquireContext(
   &hProv,
   NULL,
   NULL,
   PROV_RSA_FULL,
   0))
{
    printf("The CSP has been acquired. \n");
}
else
{
    HandleError("Error during CryptAcquireContext.");
}
//--------------------------------------------------------------------
// Get a handle to the signature key.

if(CryptGetUserKey(
   hProv,
   AT_SIGNATURE,
   &hSignKey))
{
    printf("The signature key has been acquired. \n");
}
else
{
    HandleError("Error during CryptGetUserKey for signkey.");
}
//--------------------------------------------------------------------
// Get a handle to the key exchange key.

if(CryptGetUserKey(
   hProv,
   AT_KEYEXCHANGE,
   &hXchgKey))
{
    printf("The key exchange key has been acquired. \n");
}
else
{
    printf("Error during CryptGetUserKey exchange key.");
}
// hSignKey may be used to verify a signature. hXchgKey will be used
// to export a session key.

//--------------------------------------------------------------------
// Generate a session key.

if (CryptGenKey(
    hProv,
    CALG_RC4,
    CRYPT_EXPORTABLE,
    &hKey))
{
    printf("Original session key is created. \n");
}
else
{
   HandleError("ERROR -- CryptGenKey.");
}
// Determine the size of the key BLOB and allocate memory.

if(CryptExportKey(
   hKey,
   hXchgKey,
   SIMPLEBLOB,
   0,
   NULL,
   &dwBlobLen))
{
     printf("Size of the BLOB for the session key determined. \n");
}
else
{
     HandleError("Error computing BLOB length.");
}

if(pbKeyBlob = (BYTE*)malloc(dwBlobLen))
{
    printf("Memory has been allocated for the BLOB. \n");
}
else
{
    HandleError("Out of memory. \n");
}
//--------------------------------------------------------------------
// Export the key into a simple key BLOB.

if(CryptExportKey(
   hKey,
   hXchgKey,
   SIMPLEBLOB,
   0,
   pbKeyBlob,
   &dwBlobLen))
{
     printf("Contents have been written to the BLOB. \n");
}
else
{
    HandleError("Error during CryptExportKey.");
}
//--------------------------------------------------------------------
//   At this point, other processing such as writing the key BLOB to
//   a file could be done.

//--------------------------------------------------------------------
// After all processing, clean up.

//--------------------------------------------------------------------
//  Free the memory used by the key BLOB.

free(pbKeyBlob);

// Destroy the session key.
if(hkey)
    CryptDestroyKey(hKey);

// Destroy the signature key handle.
if(hSignKey)
    CryptDestroyKey(hSignKey);

// Destroy the key exchange key handle.
if(hXchgKey)
     CryptDestroyKey(hXchgKey);

// Release the provider handle.
if(hProv)
   CryptReleaseContext(hProv, 0);
printf("The program ran to completion without error. \n");

}// End of main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message and exit
//  the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    printf("An error occurred in running the program.\n");
    printf("%s\n",s);
    printf("Error number %x\n.",GetLastError());
    printf("Program terminating.\n");
    exit(1);
}


Encoding and Decoding

The following procedure and code example deal with the general encoding and decoding process:

  • Procedure for Encoding and Decoding Messages
  • Example C Program: Encoding and Decoding Data


Procedure for Encoding and Decoding Messages

The procedure for encoding a general message is as follows.

To encode a message

  1. Initialize the appropriate data structures for the desired data type.
  2. Call CryptMsgOpenToEncode, passing the necessary arguments. When calling CryptMsgOpenToEncode, if the data that is to be provided to CryptMsgUpdate has already been message-encoded, pass the appropriate object identifier in pszInnerContentObjID (for example, "1.2.840.113549.1.7.2" for szOID_RSA_signedData). If pszInnerContentObjID is NULL, the inner content type is assumed not to have been previously encoded and is processed appropriately.
  3. Call CryptMsgUpdate as many times as necessary to complete the message. On the last call, set the fFinal parameter to TRUE. (For details, see CryptMsgUpdate).
  4. Call CryptMsgGetParam to get a pointer to the desired parameters, such as the content. For encoding simple, general data, use CMSG_CONTENT_PARAM for the dwParamtype.
  5. Close the message by calling CryptMsgClose.

This procedure results in an encoded message of a type specified in the function calls.

The procedure for decoding a general message is as follows.

To decode a message

  1. Determine the length needed for the buffer to hold the encoded data using CryptMsgCalculateEncodedLength.
  2. Call CryptMsgOpenToDecode, passing the necessary arguments. To maintain compatibility with Microsoft® Internet Explorer version 3.0, the dwMsgType parameter is provided. Signed data created in Internet Explorer 3.0 does not contain header information. Therefore, if such a message is extracted from file signatures, the message type must be passed into the function. If zero is passed into the dwMsgType parameter, the function will read the message type from the header on the message. If the header is missing, the function call will fail. If successful, a handle to the opened message is returned.
  3. Call CryptMsgUpdate once. This causes the appropriate actions to be taken on the message, depending on the message type.
  4. For additional processing of the message, such as additional decryption or signature verification, call CryptMsgControl, passing the desired action in dwCtrlType.
  5. Call CryptMsgGetParam to get a pointer to the desired parameters, such as the content. To decode simple general data, use CMSG_CONTENT_PARAM for the dwParamType parameter.
  6. Call CryptMsgClose to close the message.

For code that implements these steps, see Example C Program: Encoding and Decoding Data. For procedures and example code demonstrating the process of encoding, decoding, and verifying the signature of a signed message, see Example C Program: Signing, Encoding, Decoding, and Verifying a Message.


Example C Program: Encoding and Decoding Data

This program encodes and decodes simple, general data.

This example program illustrates the following tasks and CryptoAPI functions:

  • Determining the length needed for the buffer to hold the encoded data using CryptMsgCalculateEncodedLength.
  • Opening a message for encoding using CryptMsgOpenToEncode.
  • Adding content to the encoded message using CryptMsgUpdate.
  • Copying the encoded message into a buffer using CryptMsgGetParam.
  • Closing the encoded message using CryptMsgClose.
  • Opening a message to decode using CryptMsgOpenToDecode.
  • Using CryptMsgUpdate and CryptMsgGetParam to get the decoded data.

This example code uses the function HandleError. The C code for this function is included with the sample. Code for this and other auxiliary functions is also listed under General Purpose Functions.

//--------------------------------------------------------------------
// Example code for encoding and decoding a message.

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);

void main(void)
{
//-------------------------------------------------------------
// Declare and initialize variables. This includes getting a pointer
// to the message content. This sample program creates the message
// content and gets a pointer to it. In most situations,
// the content will exist somewhere and a pointer to it
// will get passed to the application.

HCRYPTMSG hMsg;
BYTE* pbContent;     // A byte pointer to the message
DWORD cbContent;     // The size of message
DWORD cbEncodedBlob;
BYTE *pbEncodedBlob;

//--------------------------------------------------------------------
//  The following variables are used only in the decoding phase.

DWORD cbData = sizeof(DWORD);
DWORD cbDecoded;
BYTE *pbDecoded;

//--------------------------------------------------------------------
//  Begin processing. Display the original message.

pbContent = (BYTE*) "Security is our only business";
cbContent = strlen((char *) pbContent)+1;

printf("The original message => %s\n",pbContent);

//--------------------------------------------------------------------
// Get the size of the encoded message BLOB.

if(cbEncodedBlob = CryptMsgCalculateEncodedLength(
             MY_ENCODING_TYPE,       // Message encoding type
             0,                      // Flags
             CMSG_DATA,              // Message type
             NULL,                   // Pointer to structure
             NULL,                   // Inner content object ID
             cbContent))             // Size of content
{
    printf("The length of the data has been calculated. \n");
}
else
{
    HandleError("Getting cbEncodedBlob length failed");
}
//--------------------------------------------------------------------
// Allocate memory for the encoded BLOB.

if(pbEncodedBlob = (BYTE *) malloc(cbEncodedBlob))
{
   printf("Memory has been allocated for the signed message. \n");
}
else
{
   HandleError("Memory allocation failed");
}
//--------------------------------------------------------------------
// Open a message to encode.

if(hMsg = CryptMsgOpenToEncode(
          MY_ENCODING_TYPE,        // Encoding type
          0,                       // Flags
          CMSG_DATA,               // Message type
          NULL,                    // Pointer to structure
          NULL,                    // Inner content object ID
          NULL))                   // Stream information (not used)
{
    printf("The message to be encoded has been opened. \n");
}
else
{
     HandleError("OpenToEncode failed");
}
//--------------------------------------------------------------------
// Update the message with the data.

if(CryptMsgUpdate(
        hMsg,         // Handle to the message
        pbContent,    // Pointer to the content
        cbContent,    // Size of the content
        TRUE))        // Last call
{
     printf("Content has been added to the encoded message. \n");
}
else
{
      HandleError("MsgUpdate failed");
}
//--------------------------------------------------------------------
// Get the resulting message.

if(CryptMsgGetParam(
               hMsg,                      // Handle to the message
               CMSG_BARE_CONTENT_PARAM,   // Parameter type
               0,                         // Index
               pbEncodedBlob,             // Pointer to the BLOB
               &cbEncodedBlob))           // Size of the BLOB
{
    printf("Message encoded successfully. \n");
}
else
{
      HandleError("MsgGetParam failed");
}
//--------------------------------------------------------------------
// pbEncodedBlob now points to the encoded, signed content.

//--------------------------------------------------------------------
// Close the message.

if(hMsg)
    CryptMsgClose(hMsg);

//--------------------------------------------------------------------
// The following code decodes a message.
// This code may be included here or could be used
// in a stand-alone program if the message
// to be decoded and its size were input.
// The encoded message BLOB and its length could be read
// from a disk file or could be extracted from an e-mail message
// or other input source.

//--------------------------------------------------------------------
// Open a message for decoding.

if(hMsg = CryptMsgOpenToDecode(
               MY_ENCODING_TYPE,      // Encoding type.
               0,                     // Flags.
               CMSG_DATA,             // Look for a data message.
               NULL,                  // Cryptographic provider.
               NULL,                  // Recipient information.
               NULL))                 // Stream information.
{
     printf("The message to decode is open. \n");
}
else
{
    HandleError("OpenToDecode failed");
}
//--------------------------------------------------------------------
// Update the message with an encoded BLOB.
// Both pbEncodedBlob, the encoded data,
// and cbEncodedBlob, the length of the encoded data,
// must be available.

printf("\nThe length of the encoded message is %d.\n\n",cbEncodedBlob);

if(CryptMsgUpdate(
    hMsg,                 // Handle to the message
    pbEncodedBlob,        // Pointer to the encoded BLOB
    cbEncodedBlob,        // Size of the encoded BLOB
    TRUE))                // Last call
{
      printf("The encoded BLOB has been added to the message. \n");
}
else
{
    HandleError("Decode MsgUpdate failed");
}
//--------------------------------------------------------------------
// Get the size of the content.

if(CryptMsgGetParam(
                  hMsg,                  // Handle to the message
                  CMSG_CONTENT_PARAM,    // Parameter type
                  0,                     // Index
                  NULL,                  // Address for returned
                                         // information
                  &cbDecoded))           // Size of the returned
                                         // information
{
    printf("The decoded message size is %d. \n", cbDecoded);
}
else
{
    HandleError("Decode CMSG_CONTENT_PARAM failed");
}
//--------------------------------------------------------------------
// Allocate memory.

if(pbDecoded = (BYTE *) malloc(cbDecoded))
{
     printf("Memory has been allocated for the decoded message.\n");
}
else
{
    HandleError("Decoding memory allocation failed.");
}
//--------------------------------------------------------------------
// Get a pointer to the content.

if(CryptMsgGetParam(
                  hMsg,                  // Handle to the message
                  CMSG_CONTENT_PARAM,    // Parameter type
                  0,                     // Index
                  pbDecoded,             // Address for returned
                                         // information
                  &cbDecoded))           // Size of the returned
                                         // information
{
     printf("The message is %s.\n",(LPSTR)pbDecoded);
}
else
{
     HandleError("Decode CMSG_CONTENT_PARAM #2 failed");
}
//--------------------------------------------------------------------
// Clean up.

if(pbEncodedBlob)
   free(pbEncodedBlob);
if(pbDecoded)
   free(pbDecoded);
if(hMsg)
    CryptMsgClose(hMsg);

printf("This program ran to completion without error. \n");

} //  End of main
//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message and exit
//  the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    printf("An error occurred in running the program.\n");
    printf("%s\n",s);
    printf("Error number %x\n.",GetLastError());
    printf("Program terminating.\n");
    exit(1);
}


Hashing

The following procedures and code examples deal with the creation, encoding, decoding and signing of hashes:

  • Creating a CALG_SSL3_SHAMD5 Hash
  • Creating an HMAC
  • Example C Program: Creating and Hashing a Session Key
  • Example C Program: Duplicating a Hash
  • Encoding and Decoding a Hashed Message
  • Example C Program: Encoding and Decoding a Hashed Message
  • Example C Program: Signing a Hash and Verifying the Hash Signature


Creating a CALG_SSL3_SHAMD5 Hash

To create a CALG_SSL3_SHAMD5 hash

  1. Using standard CryptoAPI methodology, create both a MD5 and a SHA hash of the target data.
  2. Concatenate the two hashes, with the MD5 value leftmost and the SHA value rightmost. This results in a 36-byte value (16 bytes + 20 bytes).
  3. Get a handle to a hash object by calling CryptCreateHash with CALG_SSL3_SHAMD5 passed in the Algid parameter.
  4. Set the hash value with a call to CryptSetHashParam. The concatenated hash values are passed as a BYTE* in the pbData parameter, and the HP_HASHVAL value must be passed in the dwParam parameter. Calling CryptHashData using the handle returned by CryptCreateHash in step 3 will fail.
  5. Call CryptSignHash to generate the signature.
  6. Call CryptDestroyHash to destroy the hash object.


Creating an HMAC

To compute an HMAC

  1. Get a pointer to the Microsoft Cryptographic Service Provider (CSP) by calling CryptAcquireContext.
  2. Create a handle to an HMAC hash object by calling CryptCreateHash. Pass CALG_HMAC in the Algid parameter. Pass the handle of a symmetric key in the hKey parameter. This symmetric key is the key used to compute the HMAC.
  3. Specify the type of hash to be used by calling CryptSetHashParam with the dwParam parameter set to the value HP_HMAC_INFO. The pbData parameter must point to an initialized HMAC_INFO structure.
  4. Call CryptHashData to begin computing the HMAC of the data. The first call to CryptHashData causes the key value to be combined using the XOR operator with the inner string and the data. The result of the XOR operation is hashed, and then the target data for the HMAC (pointed to by the pbData parameter passed in the call to CryptHashData) is hashed. If necessary, subsequent calls to CryptHashData may then be made to finish the hashing of the target data.
  5. Call CryptGetHashParam with the dwParam parameter set to HP_HASHVAL. This call causes the inner hash to be finished and the outer string to be combined using XOR with the key. The result of the XOR operation is hashed, and then the result of the inner hash (completed in the previous step) is hashed. The outer hash is then finished and returned in the pbData parameter and the length in the dwDataLen parameter.

Warning Do not use the same symmetric (session) key for both message encryption and MAC generation. Using the same key for both greatly increases the risk of messages being decoded by attackers.


Example C Program: Creating and Hashing a Session Key

This program creates and hashes a session key that can be used to encrypt a message, text, or file.

This example program illustrates using the following CryptoAPI functions:

  • CryptAcquireContext to acquire a CSP.
  • CryptCreateHash to create an empty hash object.
  • CryptGenKey to create a random session key.
  • CryptHashSessionKey to hash the session key created.
  • CryptDestroyHash to destroy the hash.
  • CryptDestroyKey to destroy the key created.
  • CryptReleaseContext to release the CSP.

This example code uses the function HandleError. The C code for this function is included with the sample. Code for this and other auxiliary functions is also listed under General Purpose Functions.

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);

void main()
{

//--------------------------------------------------------------------
//  Declare variables.

HCRYPTPROV hCryptProv;
HCRYPTHASH hHash;
HCRYPTKEY hKey;

//--------------------------------------------------------------------
//   Begin processing.

printf("Process beginning. Creating a session key. \n");

//--------------------------------------------------------------------
// Get a handle to the default provider.

if(CryptAcquireContext(
   &hCryptProv,
   NULL,
   NULL,
   PROV_RSA_FULL,
   0))
{
    printf("CryptAcquireContext complete. \n");
}
else
{
     HandleError("Acquisition of context failed.");
}
//--------------------------------------------------------------------
// Create a hash object.

if(CryptCreateHash(
   hCryptProv,
   CALG_MD5,
   0,
   0,
   &hHash))
{
    printf("An empty hash object has been created. \n");
}
else
{
    HandleError("Error during CryptBeginHash!\n");
}
//--------------------------------------------------------------------
// Create a random session key.

if(CryptGenKey(
   hCryptProv,
   CALG_RC2,
   CRYPT_EXPORTABLE,
   &hKey))
{
     printf("A random session key has been created. \n");
}
else
{
    HandleError("Error during CryptGenKey!\n");
}
//--------------------------------------------------------------------
// Compute the cryptographic hash on the key object.

if(CryptHashSessionKey(
   hHash,
   hKey,
   0))
{
     printf("The session key has been hashed. \n");
}
else
{
    HandleError("Error during CryptHashSessionKey!\n");
}
// Use the hash of the key object. For instance, additional
// data could be hashed and sent in a message to several recipients.
// The recipients will be able to verify who the message originator
// is if the key used is also exported to them.

//--------------------------------------------------------------------
// Clean up.

// Destroy the hash object.

if(hHash)
   CryptDestroyHash(hHash);

// Destroy the session key.

if(hKey)
   CryptDestroyKey(hKey);

// Release the CSP.

if(hCryptProv)
   CryptReleaseContext(hCryptProv,0);

printf("Create random session key completed without error. \n");
} // End of main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message and exit
//  the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    printf("An error occurred in running the program.\n");
    printf("%s\n",s);
    printf("Error number %x\n.",GetLastError());
    printf("Program terminating.\n");
    exit(1);
}


Example C Program: Duplicating a Hash

This program creates and duplicates a hash of some text. It then adds additional text to the original hash and different text to the duplicate.

CryptDuplicateHash is a CryptoAPI function added for Windows NT/Windows 2000 5.0. This sample program will only compile and link with Windows 2000 or later.

This example program illustrates the following CryptoAPI functions:

  • CryptAcquireContext.
  • CryptCreateHash.
  • CryptHashData.
  • CryptDuplicateHash.
  • CryptSetHashParam.
  • CryptGetHashParam.
  • CryptDestroyHash.
  • CryptReleaseContext.

This example code uses the function HandleError. C code for this function is included with the sample.

Code for this and other auxiliary functions is also listed under General Purpose Functions

//--------------------------------------------------------------------
// Example of program hashing and duplicating a hash.

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.
#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);
void Get_And_Print_Hash(HCRYPTHASH hHash);

void main(void)
{
//--------------------------------------------------------------------
//  Declare and initialize variables.

HCRYPTPROV   hCryptProv = NULL;
HCRYPTHASH   hOriginalHash;
HCRYPTHASH   hDuplicateHash;
BYTE         pbData[20];
DWORD        i;

//-------------------------------------------------------------------
//  Initialize the pbData buffer.

for(i=0;i<20;i++)
   pbData[i]=(unsigned char)i*7;
//-------------------------------------------------------------------
// Acquire a CSP context.

if(CryptAcquireContext(
   &hCryptProv,
   NULL,
   NULL,
   PROV_RSA_FULL,
   0))
{
    printf("CryptAcquireContext succeeded. \n");
}
else
{
    HandleError("Error during CryptAcquireContext!");
}
//--------------------------------------------------------------------
// Create a hash.

if (CryptCreateHash(
    hCryptProv,
    CALG_SHA1,
    0,
    0,
    &hOriginalHash))
{
   printf("An empty hash object has been created. \n");
}
else
{
   HandleError("Error during CryptCreateHash.");
}
//--------------------------------------------------------------------
// Hash a BYTE string.

if (CryptHashData(
    hOriginalHash,
    (BYTE*)"Some Common Data",
    sizeof("Some Common Data"), 0))
{
   printf("An original hash has been created. \n");
}
else
{
   HandleError("Error during CryptHashData.");
}
//--------------------------------------------------------------------
// Duplicate the hash.
// This function only works in Windows 2000 and later.

if (CryptDuplicateHash(
   hOriginalHash,
   NULL,
   0,
   &hDuplicateHash))
{
   printf("The hash has been duplicated. \n");
}
else
{
   HandleError("Error during CryptDuplicateHash.");
}

printf("The original hash -- phase 1.\n");
Get_And_Print_Hash(hOriginalHash);

printf("The duplicate hash -- phase 1.\n");
Get_And_Print_Hash(hDuplicateHash);

//--------------------------------------------------------------------
// Hash some data with the original hash.

if (CryptHashData(
     hOriginalHash,
     (BYTE*)"Some Data",
     sizeof("Some Data"),
     0))
{
    printf("Additional data has been hashed with the original. \n");
}
else
{
    HandleError("Error during CryptHashData.");
}
//--------------------------------------------------------------------
// Hash other data with the duplicate hash.

if (CryptHashData(
     hDuplicateHash,
     (BYTE*)"Other Data",
     sizeof("Other Data"),
     0))
{
   printf("More data has been hashed with the duplicate. \n");
}
else
{
   HandleError("Error during CryptHashData.");
}

printf("The original hash -- phase 1.\n");
Get_And_Print_Hash(hOriginalHash);

printf("The duplicate hash -- phase 1.\n");
Get_And_Print_Hash(hDuplicateHash);

//--------------------------------------------------------------------
//  Set a hash parameter on the original hash.

if(CryptSetHashParam(
   hOriginalHash,
   HP_HASHVAL,
   pbData,
   0))
{
     printf("A hash parameter has been set. \n");
}
else
{
     HandleError("Could not set a hash parameter.");
}

//--------------------------------------------------------------------
//  Get and print the actual hash value of the original hash.

printf("The hash after the parameter was set.\n");
Get_And_Print_Hash(hOriginalHash);

//--------------------------------------------------------------------
// Destroy the original hash.

if(CryptDestroyHash(hOriginalHash))
{
   printf("The original hash has been destroyed. \n");
}
else
{
   HandleError("ERROR during CryptDestroyHash");
}
//--------------------------------------------------------------------
// Destroy the duplicate hash.

if (CryptDestroyHash(hDuplicateHash))
{
   printf("The duplicate hash has been destroyed. \n");
}
else
{
   HandleError("Error -- CryptDestroyHash");
}

//--------------------------------------------------------------------
// Release the CSP.

if(hCryptProv)
   CryptReleaseContext(hCryptProv,0);

printf("The program ran to completion without error. \n");
} // End of main

//--------------------------------------------------------------------
//   Define the function Get_And_Print_Hash

void Get_And_Print_Hash(HCRYPTHASH hOHash)
{
//--------------------------------------------------------------------
//  Declare and initialize local variables.

HCRYPTHASH   hHash;
BYTE         *pbHash;
BYTE         *pbHashSize;
DWORD        dwHashLen = sizeof(DWORD);
DWORD        i;

//--------------------------------------------------------------------
// Duplicate the hash passed in.
// This function only works in Windows 2000 and later.
// The hash is duplicated in order to leave the original hash intact.

if (CryptDuplicateHash(
   hOHash,
   NULL,
   0,
   &hHash))
{
// It worked. Do nothing.
}
else
{
   HandleError("Error during CryptDuplicateHash.");
}
if(!(pbHashSize =(BYTE *) malloc(dwHashLen)))
HandleError("Memory allocation failed.");
if(CryptGetHashParam(
   hHash,
   HP_HASHSIZE,
   pbHashSize,
   &dwHashLen,
   0))
{
// It worked. Do nothing.
}
else
{
    HandleError("CryptGetHashParam failed to get size.");
}

if(CryptGetHashParam(
   hHash,
   HP_HASHVAL,
   NULL,
   &dwHashLen,
   0))
{
// It worked. Do nothing.
}
else
{
    HandleError("CryptGetHashParam failed to get length.");
}

if(pbHash = (BYTE*)malloc(dwHashLen))
{
// It worked. Do nothing.
}
else
{
     HandleError("Allocation failed.");
}
if(CryptGetHashParam(
   hHash,
   HP_HASHVAL,
   pbHash,
   &dwHashLen,
   0))
{
// Print the hash value.
printf("The hash is:  ");
   for(i = 0 ; i < dwHashLen ; i++)
   {
       printf("%2.2x ",pbHash[i]);
   }
printf("\n");
}
else
{
    HandleError("Error during reading hash value.");
}
free(pbHash);
if (CryptDestroyHash(hHash))
{
// It worked. Do nothing.
}
else
{
   HandleError("ERROR - CryptDestroyHash");
}
} // End of Get_And_Print_Hash

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError


Encoding and Decoding a Hashed Message

Hashed data consists of content of any type and a hash of the content. It can be used when it is only necessary to confirm that the message content has not been modified since the hash was created.

When creating a hashed message, there can be multiple hash algorithms and multiple hashes. The following illustration depicts the tasks required to encode a hashed message. The procedure is described in the text that follows the illustration.

To create a hashed message

  1. Get a pointer to the data to be hashed.
  2. Determine the hash algorithm to be used.
  3. Put the data through a hashing function using the hash algorithm.
  4. Include the original data to be hashed, the hashing algorithms, and the hashes in the encoded message.

To use low-level message functions to accomplish the tasks just outlined, use the following procedure.

To hash and encode a message using low-level message functions

  1. Create or retrieve the content to be hashed.
  2. Get a cryptographic provider.
  3. Initialize the CMSG_HASHED_ENCODE_INFO structure.
  4. Call CryptMsgCalculateEncodedLength to get the size of the encoded message BLOB. Allocate memory for it.
  5. Call CryptMsgOpenToEncode, passing in CMSG_HASHED for the dwMsgType parameter and a pointer to CMSG_HASHED_ENCODE_INFO for the pvMsgEncodeInfo parameter. As a result of this call, you get a handle to the opened message.
  6. Call CryptMsgUpdate, passing in the handle retrieved in step 5 and a pointer to the data that is to be hashed and encoded. This function can be called as many times as necessary to complete the encoding process.
  7. Call CryptMsgGetParam, passing in the handle retrieved in step 5 and the appropriate parameter types to access the desired, encoded data. For example, pass in CMSG_CONTENT_PARAM to get a pointer to the entire PKCS #7 message.

    If the result of this encoding is to be used as the inner data for another encoded message, such as an enveloped message, CMSG_BARE_CONTENT_PARAM must be passed. For example code showing this, see Alternate Code for Encoding an Enveloped Message.

  8. Close the message by calling CryptMsgClose.

The result of this procedure is an encoded message that contains the original data, the hashing algorithms, and the hash of that data. A pointer to the encoded message BLOB is obtained in step 7.

The following two procedures decode and then verify hashed data.

To decode hashed data

  1. Get a pointer to the encoded BLOB.
  2. Call CryptMsgOpenToDecode, passing the necessary arguments.
  3. Call CryptMsgUpdate once, passing in the handle retrieved in step 2 and a pointer to the data that is to be decoded. This causes the appropriate actions to be taken on the message, depending on the message type.
  4. Call CryptMsgGetParam, passing in the handle retrieved in step 2, and the appropriate parameter types to access the desired, decoded data. For example, pass in CMSG_CONTENT_PARAM to get a pointer to the decoded content.

To verify the hash

  1. Call CryptMsgControl, passing in CMSG_CTRL_VERIFY_HASH to verify the hashes.
  2. Call CryptMsgClose to close the message.

For an example program, see Example C Program: Encoding and Decoding a Hashed Message.


Example C Program: Encoding and Decoding a Hashed Message

The following is an example program that hashes and encodes a text message and then decodes and verifies the message. Although for simplicity the two different functions have been combined in this program, in a more realistic setting the two parts would be used separately.

This example program illustrates the following tasks and CryptoAPI functions:

  • Calling CryptAcquireContext to acquire a CSP provider.
  • Using CryptMsgCalculateEncodedLength to calculate the length of the an encoded message.
  • Allocating memory for a buffer to hold the encoded data.
  • Opening a message to encode using CryptMsgOpenToEncode.
  • Adding content to the message to encode using CryptMsgUpdate.
  • Using CryptMsgGetParam to copy the encoded message to the allocated buffer.
  • Opening a message to decode using CryptMsgOpenToDecode.
  • Adding the encoded message to the message to decode using CryptMsgUpdate.
  • Creating a duplicate pointer to the message using CryptMsgDuplicate.
  • Checking the message type with CryptMsgGetParam.
  • Using CryptMsgGetParam to decode the message.
  • Verifying the hash using CryptMsgControl.
  • Using CryptMsgClose to release the message handle.
  • Using CryptReleaseContext to release the CSP.

This example code uses the function HandleError. C code for this function is included with the sample.

Code for this and other auxiliary functions is also listed under General Purpose Functions.

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the following #define and #include statements These
//   are listed under the #includes and #defines section.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);

void main(void)
{
//--------------------------------------------------------------------
//  Declare and initialize variables. This includes creating a
//  pointer to the message content. In real situations,
//  the message content will usually exist somewhere and a pointer
//  to it will get passed to the application.

BYTE* pbContent = (BYTE*) "A razzle-dazzle hashed message \n"
       "Hashing is better than trashing. \n";    // The message
DWORD cbContent = strlen((char *)pbContent)+1;  // Size of message
                                                // including the final
                                                // NULL.
HCRYPTPROV hCryptProv;                          // CSP handle
DWORD HashAlgSize;
CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
CMSG_HASHED_ENCODE_INFO HashedEncodeInfo;
DWORD cbEncodedBlob;
BYTE *pbEncodedBlob;
HCRYPTMSG hMsg;
HCRYPTMSG hDupMsg;
//-------------------------------------------------------------------
//  Variables to be used in decoding.
DWORD cbData = sizeof(DWORD);
DWORD dwMsgType;
DWORD cbDecoded;
BYTE  *pbDecoded;

//--------------------------------------------------------------------
//  Begin processing.

printf("Begin processing. \n");
printf("The message to be hashed and encoded is: \n");
printf("%s\n",pbContent);    // Display original message.
printf("The starting message length is %d\n",cbContent);

//--------------------------------------------------------------------
// Acquire a cryptographic provider handle.

if(CryptAcquireContext(
               &hCryptProv,     // Address for the handle.
               NULL,            // Use the current user's logon name.
               NULL,            // Use the default provider.
               PROV_RSA_FULL,   // Provider type.
               0))              // Zero allows access to private keys.
{
    printf("A CSP context has been acquired. \n");
}
else
{
    HandleError("CryptAcquireContext failed.");
}
//--------------------------------------------------------------------
// The function succeeded; hCryptProv is the CSP handle.

//--------------------------------------------------------------------
// Initialize the algorithm identifier structure.

HashAlgSize = sizeof(HashAlgorithm);
memset(&HashAlgorithm, 0, HashAlgSize);   // Initialize to zero.
HashAlgorithm.pszObjId = szOID_RSA_MD5;   // Then set the
                                          //   necessary member.

//--------------------------------------------------------------------
// Initialize the CMSG_HASHED_ENCODE_INFO structure.

memset(&HashedEncodeInfo, 0, sizeof(CMSG_HASHED_ENCODE_INFO));
HashedEncodeInfo.cbSize = sizeof(CMSG_HASHED_ENCODE_INFO);
HashedEncodeInfo.hCryptProv = hCryptProv;
HashedEncodeInfo.HashAlgorithm = HashAlgorithm;
HashedEncodeInfo.pvHashAuxInfo = NULL;

//--------------------------------------------------------------------
// Get the size of the encoded message BLOB.

if(cbEncodedBlob = CryptMsgCalculateEncodedLength(
                     MY_ENCODING_TYPE,     // Message encoding type
                     0,                    // Flags
                     CMSG_HASHED,          // Message type
                     &HashedEncodeInfo,    // Pointer to structure
                     NULL,                 // Inner content object ID
                     cbContent))           // Size of content
{
    printf("The length to be allocated is %d bytes.\n",cbEncodedBlob);
}
else
{
    HandleError("Getting cbEncodedBlob length failed");
}
//--------------------------------------------------------------------
// Allocate memory for the encoded BLOB.
if(pbEncodedBlob = (BYTE *) malloc(cbEncodedBlob))
{
    printf("%d bytes of memory have been allocated.\n",cbEncodedBlob);
}
else
{
    HandleError("Malloc operation failed.");
}
//--------------------------------------------------------------------
// Open a message to encode.

if(hMsg = CryptMsgOpenToEncode(
            MY_ENCODING_TYPE,        // Encoding type
            0,                       // Flags
            CMSG_HASHED,             // Message type
            &HashedEncodeInfo,       // Pointer to structure
            NULL,                    // Inner content object ID
            NULL))                   // Stream information (not used)
{
    printf("The message to encode has been opened. \n");
}
else
{
    HandleError("OpenToEncode failed");
}
//--------------------------------------------------------------------
// Update the message with the data.

if(CryptMsgUpdate(
            hMsg,          // Handle to the message
            pbContent,     // Pointer to the content
            cbContent,     // Size of the content
            TRUE))         // Last call
{
    printf("Data has been added to the message to encode. \n");
}
else
{
    HandleError("MsgUpdate failed");
}
//--------------------------------------------------------------------
// Create a duplicate of the message.

if(hDupMsg = CryptMsgDuplicate(hMsg))
{
     printf("The message has been duplicated.\n");
}
else
{
     HandleError("Duplication of the message failed.");
}

//--------------------------------------------------------------------
// Get the resulting message from the duplicate of the message.

if(CryptMsgGetParam(
               hDupMsg,                  // Handle to the message
               CMSG_CONTENT_PARAM,       // Parameter type
               0,                        // Index
               pbEncodedBlob,            // Pointer to the BLOB
               &cbEncodedBlob))          // Size of the BLOB
{
     printf("Message encoded successfully. \n");
}
else
{
    HandleError("MsgGetParam failed");
}
//--------------------------------------------------------------------
// Close both messages to prepare for decoding.

CryptMsgClose(hMsg);
CryptMsgClose(hDupMsg);

// The following code decodes the hashed message.
// Usually, this would be in a separate program and the encoded,
// hashed data would be input from a file, from an e-mail message,
// or from some other source.
//
// The variables used in this code have already been
// declared and initialized.

//--------------------------------------------------------------------
// Open the  message for decoding.

if(hMsg = CryptMsgOpenToDecode(
            MY_ENCODING_TYPE,       // Encoding type
            0,                      // Flags
            0,                      // Message type (get from message)
            hCryptProv,             // Cryptographic provider
            NULL,                   // Recipient information
            NULL))                  // Stream information
{
     printf("The message has been opened for decoding. \n");
}
else
{
     HandleError("OpenToDecode failed");
}
//--------------------------------------------------------------------
// Update the message with the encoded BLOB.

if(CryptMsgUpdate(
            hMsg,             // Handle to the message
            pbEncodedBlob,    // Pointer to the encoded BLOB
            cbEncodedBlob,    // Size of the encoded BLOB
            TRUE))            // Last call
{
     printf("The encoded data is added to the message to decode. \n");
}
else
{
    HandleError("Decode MsgUpdate failed");
}
//--------------------------------------------------------------------
// Get the message type.

if(CryptMsgGetParam(
       hMsg,               // Handle to the message
       CMSG_TYPE_PARAM,    // Parameter type
       0,                  // Index
       &dwMsgType,         // Address for returned information
       &cbData))           // Size of the returned information
{
    printf("The message type has been obtained. \n");
}
else
{
    HandleError("Decode CMSG_TYPE_PARAM failed");
}
//--------------------------------------------------------------------
// Some applications may need to use a switch statement here
// and process the message differently, depending on the
// message type.

if(dwMsgType == CMSG_HASHED)
{
     printf("The message is a hashed message. Proceed. \n");
}
else
{
    HandleError("Wrong message type");
}
//--------------------------------------------------------------------
// Get the size of the content.

if(CryptMsgGetParam(
               hMsg,                   // Handle to the message
               CMSG_CONTENT_PARAM,     // Parameter type
               0,                      // Index
               NULL,                   // Address for returned
                                       // information
               &cbDecoded))            // Size of the returned
                                       // information
{
    printf("The length %d of the message obtained. \n", cbDecoded);
}
else
{
    HandleError("Decode CMSG_CONTENT_PARAM failed");
}
//--------------------------------------------------------------------
// Allocate memory.

if(pbDecoded = (BYTE *) malloc(cbDecoded))
{
     printf("Memory for the decoded message has been allocated.\n");
}
else
{
    HandleError("Decoding memory allocation failed");
}
//--------------------------------------------------------------------
// Copy the decoded message into the buffer just allocated.

if(CryptMsgGetParam(
            hMsg,                    // Handle to the message
            CMSG_CONTENT_PARAM,      // Parameter type
            0,                       // Index
            pbDecoded,               // Address for returned
                                     // information
            &cbDecoded))             // Size of the returned
                                     // information
{
    printf("Message decoded successfully \n");
    printf("The decoded message is \n%s\n", (LPSTR)pbDecoded);
}
else
{
    HandleError("Decoding CMSG_CONTENT_PARAM #2 failed");
}
//--------------------------------------------------------------------
// Verify the hash.

if(CryptMsgControl(
              hMsg,                        // Handle to the message
              0,                           // Flags
              CMSG_CTRL_VERIFY_HASH,       // Control type
              NULL))                       // Pointer not used
{
    printf("Verification of hash succeeded. \n");
    printf("The data has not been tampered with.\n");
}
else
{
     printf("Verification of hash failed. Something changed this message .\n");
}

printf("Test program completed without error. \n");

//--------------------------------------------------------------------
// Clean up

if(pbEncodedBlob)
    free(pbEncodedBlob);
if(pbDecoded)
    free(pbDecoded);

CryptMsgClose(hMsg);

// Release the CSP.

if(hCryptProv)
   CryptReleaseContext(hCryptProv,0);
} // End of main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError


Example C Program: Signing a Hash and Verifying the Hash Signature

The program hashes some data and signs that hash. In a second phase, the hash and its signature are verified. The hash is signed with the user's private key, and the signer's public key is exported so that the signature can be verified.

This example program illustrates the following tasks and CryptoAPI functions:

  • Acquiring a CSP using CryptAcquireContext.
  • Getting the user's AT_SIGNATURE key pair using CryptGetUserKey.
  • Creating a PUBLICKEYBLOB with the signer's public key to be used in the signature verification process using CryptExportKey.
  • Creating a hash object using CryptCreateHash.
  • Hashing the data using CryptHashData.
  • Signing the hash using CryptSignHash.
  • Destroying the original hash object using CryptDestroyHash.
  • Making the public key needed to verify the hash available using CryptImportKey.
  • Re-creating the hash object using CryptCreateHash and CryptHashData.
  • Verifying the signature on the hash using CryptVerifySignature.
  • Performing normal cleanup.
//--------------------------------------------------------------------
// Example code for signing a hash and
// verifying the hash signature.

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);

void main(void)
{
//-------------------------------------------------------------
// Declare and initialize variables.

HCRYPTPROV hProv;
BYTE *pbBuffer= (BYTE *)"The data that is to be hashed and signed.";
DWORD dwBufferLen = strlen((char *)pbBuffer)+1;
HCRYPTHASH hHash;
HCRYPTKEY hKey;
HCRYPTKEY hPubKey;
BYTE *pbKeyBlob;
BYTE *pbSignature;
DWORD dwSigLen;
DWORD dwBlobLen;
LPTSTR szDescription = "Test Data Description";

//--------------------------------------------------------------------
// Acquire a CSP.

if(CryptAcquireContext(
   &hProv,
   NULL,
   NULL,
   PROV_RSA_FULL,
   0))
{
     printf("CSP context acquired.\n");
}
else
{
     HandleError("Error during CryptAcquireContext.");
}
//--------------------------------------------------------------------
// Get the public at signature key. This is the public key
// that will be used by the receiver of the hash to verify
// the signature. In situations where the receiver could obtain the
// sender's public key from a certificate, this step would not be
// needed.

if(CryptGetUserKey(
   hProv,
   AT_SIGNATURE,
   &hKey))
{
    printf("The signature key has been acquired. \n");
}
else
{
    HandleError("Error during CryptGetUserKey for signkey.");
}
//--------------------------------------------------------------------
// Export the public key. Here the public key is exported to a
// PUBLICKEYBOLB so that the receiver of the signed hash can
// verify the signature. This BLOB could be written to a file and
// sent to another user.

if(CryptExportKey(
   hKey,
   NULL,
   PUBLICKEYBLOB,
   0,
   NULL,
   &dwBlobLen))
{
     printf("Size of the BLOB for the public key determined. \n");
}
else
{
     HandleError("Error computing BLOB length.");
}
//--------------------------------------------------------------------
// Allocate memory for the pbKeyBlob.

if(pbKeyBlob = (BYTE*)malloc(dwBlobLen))
{
    printf("Memory has been allocated for the BLOB. \n");
}
else
{
    HandleError("Out of memory. \n");
}
//--------------------------------------------------------------------
// Do the actual exporting into the key BLOB.

if(CryptExportKey(
   hKey,
   NULL,
   PUBLICKEYBLOB,
   0,
   pbKeyBlob,
   &dwBlobLen))
{
     printf("Contents have been written to the BLOB. \n");
}
else
{
    HandleError("Error during CryptExportKey.");
}
//--------------------------------------------------------------------
// Create the hash object.

if(CryptCreateHash(
   hProv,
   CALG_MD5,
   0,
   0,
   &hHash))
{
     printf("Hash object created. \n");
}
else
{
    HandleError("Error during CryptCreateHash.");
}
//--------------------------------------------------------------------
// Compute the cryptographic hash of the buffer.

if(CryptHashData(
   hHash,
   pbBuffer,
   dwBufferLen,
   0))
{
     printf("The data buffer has been hashed.\n");
}
else
{
     HandleError("Error during CryptHashData.");
}
//--------------------------------------------------------------------
// Determine the size of the signature and allocate memory.

dwSigLen= 0;
if(CryptSignHash(
   hHash,
   AT_SIGNATURE,
   szDescription,
   0,
   NULL,
   &dwSigLen))
{
     printf("Signature length %d found.\n",dwSigLen);
}
else
{
     HandleError("Error during CryptSignHash.");
}
//--------------------------------------------------------------------
// Allocate memory for the signature buffer.

if(pbSignature = (BYTE *)malloc(dwSigLen))
{
     printf("Memory allocated for the signature.\n");
}
else
{
     HandleError("Out of memory.");
}
//--------------------------------------------------------------------
// Sign the hash object.

if(CryptSignHash(
   hHash,
   AT_SIGNATURE,
   szDescription,
   0,
   pbSignature,
   &dwSigLen))
{
     printf("pbSignature is the hash signature.\n");
}
else
{
     HandleError("Error during CryptSignHash.");
}
//--------------------------------------------------------------------
// Destroy the hash object.

if(hHash)
  CryptDestroyHash(hHash);

printf("The hash object has been destroyed.\n");
printf("The signing phase of this program is completed.\n\n");

//--------------------------------------------------------------------
// In the second phase, the hash signature is verified.
// This would most often be done by a different user in a
// separate program. The hash, signature, and the PUBLICKEYBLOB
// would be read from a file, an e-mail message, or some other source.

// Here the original pbBuffer, pbSignature, szDescription.
// pbKeyBlob, and their lengths are used.

// The contents of the pbBuffer must be the same data
// that was originally signed.

// Point szDescription at the text describing the data being
// signed. This is the same description text that was originally
// passed to CryptSignHash.

//--------------------------------------------------------------------
// Get the public key of the user who created the digital signature
// and import it into the CSP by using CryptImportKey. This returns
// a handle to the public key in hPubKey.

if(CryptImportKey(
   hProv,
   pbKeyBlob,
   dwBlobLen,
   0,
   0,
   &hPubKey))
{
     printf("The key has been imported.\n");
}
else
{
     HandleError("Public key import failed.");
}
//--------------------------------------------------------------------
// Create a new hash object.

if(CryptCreateHash(
   hProv,
   CALG_MD5,
   0,
   0,
   &hHash))
{
     printf("The hash object has been recreated. \n");
}
else
{
     HandleError("Error during CryptCreateHash.");
}
//--------------------------------------------------------------------
// Compute the cryptographic hash of the buffer.

if(CryptHashData(
   hHash,
   pbBuffer,
   dwBufferLen,
   0))
{
     printf("The new has been created.\n");
}
else
{
     HandleError("Error during CryptHashData.");
}
//--------------------------------------------------------------------
// Validate the digital signature.

if(CryptVerifySignature(
   hHash,
   pbSignature,
   dwSigLen,
   hPubKey,
   szDescription,
   0))
{
     printf("The signature has been verified.\n");
}
else
{
     printf("Signature not validated!\n");
}
//--------------------------------------------------------------------
// Free memory to be used to store signature.

if(pbSignature)
  free(pbSignature);

//--------------------------------------------------------------------
// Destroy the hash object.

if(hHash)
  CryptDestroyHash(hHash);

//--------------------------------------------------------------------
// Release the provider handle.

if(hProv)
   CryptReleaseContext(hProv, 0);
} //  End of main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError


Signing Data

The following sections deal with encoding and decoding signed data, including messages, certificates, certificate revocation lists (CRLs), and certificate trust lists (CTLs):

  • Creating a Signed Message
  • Procedure for Signing Data
  • Verifying a Signed Message
  • Encoding Signed Data
  • Decoding Signed Data
  • Example C Program: Signing a Message and Verifying a Message Signature
  • Example C Program: Signing, Encoding, Decoding, and Verifying a Message
  • Example C Program: Sending and Receiving a Signed and Encrypted Message
  • Example C Program: Receiving a Signed and Encrypted Message


Creating a Signed Message

The following illustration depicts the tasks that must be accomplished to create a signed message. The steps are listed following the illustration.

To create a signed message

  1. Create the data (if necessary) and get a pointer to it.
  2. Open a certificate store that contains the signer's certificate.
  3. Get the private key for the certificate. There are two properties that must be set on the certificate before using it — one is used to tie a certificate to a particular CSP, and within that CSP, to a particular private key, and the other is used to indicate which hashing algorithm is to be used when a digest operation is called for. These need only be set once.
  4. From the certificate property, determine the hash algorithm.
  5. Send the data through the hashing function by using the hashing algorithm, thus creating a hash (digest) of the data.
  6. Using the private key obtained through the property on the certificate, encrypt the digest, creating the signature.
  7. Include the following in the signed message:
    • The signed data
    • The hash algorithm
    • The signature
    • The signer identifier (certificate issuer and serial number)
    • The signer's certificate (optional)

For a detailed procedure and code example, see Procedure for Signing Data and Example C Program: Signing a Message and Verifying a Message Signature.


Procedure for Signing Data

A single function, CryptSignMessage, performs all of the tasks listed in Creating a Signed Message. However, initialization of structures and other data is still necessary. The following illustration shows the relationship between those function parameters that point to structures or arrays and their initialized data. The illustration shows only the function parameters and structure members that are derived from other structures or functions. The rest of the parameters are straightforward initializations.

To sign data using CryptSignMessage

  1. Get a pointer to the data that is to be signed.
  2. Assign the pointer to the data to index zero of a "data to be signed" array.
  3. Get a handle to the cryptographic provider.
  4. Open a certificate store that contains the signer's certificate.
  5. Get an address to the signer's certificate.
  6. Assign the address of the certificate to the zero index of the MsgCert array.
  7. Assign the addresses of any other certificates to be included with the message to the MsgCert array.
  8. Initialize the CRYPT_ALGORITHM_IDENTIFIER structure, initializing the pszObjId member to the desired hash algorithm and the other members as appropriate.
  9. Initialize the CRYPT_SIGN_MESSAGE_PARA structure, initializing the pSigningCert member to the address of the signer's certificate, the MsgCert array member to the address of the signer's and other's certificates, the HashAlgorithm member to the address of the CRYPT_ALGORITHM_IDENTIFIER structure, and the other members as appropriate.
  10. Call the CryptSignMessage function, passing the CRYPT_SIGN_MESSAGE_PARA structure for the pSignPara parameter, the address of the "data to be signed" array for the rgpbToBeSigned parameter, an address for the pbSignedBlob output parameter, and values for the other parameters as appropriate.


Verifying a Signed Message

These steps verify the signature of signed data. The following illustration depicts the individual tasks that must be accomplished, as shown in the list that follows it.

To verify the signature of a signed message

  1. Get a pointer to the signed message.
  2. Open a certificate store.
  3. Using the signer ID contained in the message, get the sender's certificate and get a handle to its public key.

    As an alternative to steps 2 and 3, you can use the certificate contained in the message to retrieve the signer's public key.

  4. Using the signer's public key, decrypt the digital signature, producing the original digest of the data in the message.
  5. Using the hash algorithm contained in the message, hash the data contained in the message, yielding a new digest.
  6. Compare the digest retrieved from the message with the new digest just created.
  7. If the two digests match, the signature is verified. This means that the private key that was used to sign the data matches the public key just used to decrypt the signature, and that the data has not changed since the data was signed.

    If the two digests do not match, the signature is not verified, and either the private/public keys do not match, or the data has been changed since the data was signed, or both.

A single function, CryptVerifyMessageSignature, can be used to verify a signature, as shown in the following procedure.

To verify a signed message

  1. Get a pointer to the signed message.
  2. Get the size of the signed message.
  3. Get a handle on a cryptographic provider.
  4. Initialize the CRYPT_VERIFY_MESSAGE_PARA structure.
  5. Call CryptVerifyMessageSignature to verify the signature.

Code that implements this procedure is included in Example C Program: Signing a Message and Verifying a Message Signature.


Encoding Signed Data

Signed data consists of content of any type and encrypted message hashes of the content by zero or more signers. The resulting hash can confirm that the original message has not been modified since signing and that particular persons or entities signed the data.

The following illustration depicts the procedure for encoding a signed message. The list following the illustration describes the steps.

A message may have multiple signers, hashing algorithms, and certificates. While the illustration shows only certificates, CRLs, and CTLs can use the same process. They would fit into the illustration wherever certificates are shown.

The general process for encoding signed data is as follows:

  1. The data is created (if necessary), and a pointer to it is retrieved.
  2. A certificate store is opened that contains the signer's certificate.
  3. The private key for the certificate is retrieved. There are two properties that must be set on the certificate before using it. One is used to tie a certificate to a particular CSP and, within that CSP, to a particular private key container. The other is used to indicate which hashing algorithm is to be used when a hash operation is called. These need only be set once.
  4. A certificate's property determines the hash algorithm.
  5. A hash of the data is created by sending the data through the hashing function.
  6. The signature is created by encrypting the hash using the private key, obtained through a property on the certificate.
  7. The following data is included in the finished, signed message:
    • The original data to be signed
    • The hash algorithms
    • The signatures
    • The signer info structures, which includes the signer identifier (certificate issuer and serial number)
    • The signer's certificates (optional)

This procedure illustrates a simple case. More complex cases involve authenticated attributes included in the message. When the content type is anything but a BYTE string, or there is at least one authenticated attribute along with any data type, there are two standard authenticated attributes required: the content (data) type, and the hash of the content. Under these circumstances, the CryptoAPI automatically provides these two required attributes. The low-level message functions hash the authenticated attributes, encrypt the hash with the private key, and provide this as the signature.

Use the low-level message functions to accomplish the tasks just listed, by using the following procedure.

To encode a signed message

  1. Create or retrieve the content.
  2. Get a cryptographic provider.
  3. Get the signer certificates.
  4. Initialize the CMSG_SIGNER_ENCODE_INFO structure.
  5. Initialize the CMSG_SIGNED_ENCODE_INFO structure.
  6. Call CryptMsgCalculateEncodedLength to get the size of the encoded message BLOB. Allocate memory for it.
  7. Call CryptMsgOpenToEncode, passing in CMSG_SIGNED for dwMsgType and a pointer to CMSG_SIGNED_ENCODE_INFO for pvMsgEncodeInfo to get a handle to the opened message.
  8. Call CryptMsgUpdate, passing in the handle retrieved in step 7, and a pointer to the data that is to be signed and encoded. This function can be called as many times as necessary to complete the encoding process.
  9. Call CryptMsgGetParam, passing in the handle retrieved in step 7 and the appropriate parameter types to access the desired, encoded data. For example, pass in CMSG_CONTENT_PARAM to get a pointer to the entire PKCS #7 message.

    If the result of this encoding is to be used as the inner data for another encoded message, such as an enveloped message, the CMSG_BARE_CONTENT_PARAM parameter must be passed. For example code showing this, see Alternate Code for Encoding an Enveloped Message.

  10. Close the message by calling CryptMsgClose.

The result of this procedure is an encoded message that contains the original data, the encrypted hash of that data (signature), and the signer information. There is also a pointer to the desired, encoded BLOB.

For C coding details, see Example C Program: Signing, Encoding, Decoding, and Verifying a Message.


Decoding Signed Data

The following general process decodes a signed data type.

To decode a signed message

  1. Get a pointer to the encoded BLOB.
  2. Call CryptMsgOpenToDecode, passing the necessary arguments.
  3. Call CryptMsgUpdate once, passing in the handle retrieved in step 2 and a pointer to the data that is to be decoded. This causes the appropriate actions to be taken on the message, depending on the message type.
  4. Call CryptMsgGetParam, passing in the handle retrieved in step 2 and the appropriate parameter types to access the decoded data. For example, pass in CMSG_CONTENT_PARAM to get a pointer to the decoded content.

The following general process verifies the signature of a decoded, signed message.

To verify the signature of a decoded, signed message

  1. Call CryptMsgGetParam, passing in the message handle and CMSG_SIGNER_CERT_INFO_PARAM to get the signer's CERT_INFO from the message.
  2. Call CertOpenStore to open a temporary store that is initialized with the certificates from the message.
  3. Call CertGetSubjectCertificateFromStore to get the signer's CERT_INFO from the certificates included in the message.
  4. Call CryptMsgControl, passing in CMSG_CTRL_VERIFY_SIGNATURE to verify the signatures.
  5. Call CryptMsgClose to close the message.

The result of these procedures is that the signature is verified and a pointer is retrieved to the decoded message content obtained in step 4 of the procedure for decoding a signed message.

For C coding details, see Example C Program: Signing, Encoding, Decoding, and Verifying a Message.


Example C Program: Signing a Message and Verifying a Message Signature

The following example code implements the procedure described in Procedure for Signing Data. For general information, see Simplified Messages. Details about the functions and structures can be found in Base Cryptography Functions, Simplified Message Functions, and CryptoAPI Structures.

The example program also includes code to verify the message signature created. This code would usually be in a separate program but is included here for completeness and clarity.

This example program illustrates the following CryptoAPI functions:

  • CertOpenStore
  • CryptSignMessage
  • CryptVerifyMessageSignature
  • CertFreeCertificateContext
  • CertCloseStore

Signing the message can only be done with access to a certificate that has an available private key. Verification of the message can only be done with access to the public key related to the private key used to sign the certificate. The user can change the #define statement to the subject name from one of the user's personal certificates.

This example program also demonstrates the initialization of the CRYPT_SIGN_MESSAGE_PARA and CRYPT_VERIFY_MESSAGE_PARA structures needed for calls to CryptSignMessage and CryptVerifyMessageSignature.

This example code also uses the function HandleError. Code for this function is included with the example program and also can be seen in General Purpose Functions.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

//--------------------------------------------------------------------
//   Define the name of a certificate subject.
//   To use this program, the definition of SIGNER_NAME
//   must be changed to the name of the subject of
//   a certificate that has access to a private key.
//   That certificate must have either the CERT_KEY_PROV_INFO_PROP_ID,
//   or CERT_KEY_CONTEXT_PROP_ID property set for the context to
//   provide access to the private signature key.

#define SIGNER_NAME  L"Zeke"

//--------------------------------------------------------------------
//    Define the name of the store where the needed certificate
//    can be found.

#define CERT_STORE_NAME  L"MY"

//--------------------------------------------------------------------
//   Declare local functions.
//   Local function definitions follow main.

void HandleError(char *s);

void main(void)
{
//--------------------------------------------------------------------
// Declare and initialize local variables.
// This includes initializing a pointer to the message.
// Usually, the message will exist somewhere and a pointer will
// be passed to the application.

//--------------------------------------------------------------------
// System store handle

HCERTSTORE hStoreHandle;

//--------------------------------------------------------------------
// The message to be signed

BYTE* pbMessage =
    (BYTE*)"CryptoAPI is a good way to handle security";

//--------------------------------------------------------------------
// Size of message. Note that the length set is one more than the
// length returned by the strlen function in order to include
// the NULL string termination character.

DWORD cbMessage = strlen((char*) pbMessage)+1;

//--------------------------------------------------------------------
// Pointer to a signer certificate

PCCERT_CONTEXT pSignerCert;

CRYPT_SIGN_MESSAGE_PARA  SigParams;
DWORD cbSignedMessageBlob;
BYTE  *pbSignedMessageBlob;
DWORD cbDecodedMessageBlob;
BYTE  *pbDecodedMessageBlob;
CRYPT_VERIFY_MESSAGE_PARA VerifyParams;

//--------------------------------------------------------------------
// Create the MessageArray and the MessageSizeArray.

const BYTE* MessageArray[] = {pbMessage};
DWORD MessageSizeArray[1];
MessageSizeArray[0] = cbMessage;

//--------------------------------------------------------------------
//  Begin processing. Display the original message.

printf("Begin processing. \n");

printf(" The message to be signed is\n-> %s.\n",pbMessage);

//--------------------------------------------------------------------
// Open a certificate store.

if ( !( hStoreHandle = CertOpenStore(
   CERT_STORE_PROV_SYSTEM,
   0,
   NULL,
   CERT_SYSTEM_STORE_CURRENT_USER,
   CERT_STORE_NAME)))
{
     HandleError("The MY store could not be opened.");
}

//--------------------------------------------------------------------
// Get a pointer to the signer's certificate.
// This certificate must have access to the signer's private key.

if(pSignerCert = CertFindCertificateInStore(
   hStoreHandle,
   MY_TYPE,
   0,
   CERT_FIND_SUBJECT_STR,
   SIGNER_NAME,
   NULL))
{
   printf("The signer's certificate was found.\n");
}
else
{
    HandleError( "Signer certificate not found.");
}

//--------------------------------------------------------------------
// Initialize the signature structure.

SigParams.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
SigParams.dwMsgEncodingType = MY_TYPE;
SigParams.pSigningCert = pSignerCert;
SigParams.HashAlgorithm.pszObjId = szOID_RSA_MD5;
SigParams.HashAlgorithm.Parameters.cbData = NULL;
SigParams.cMsgCert = 1;
SigParams.rgpMsgCert = &pSignerCert;
SigParams.cAuthAttr = 0;
SigParams.dwInnerContentType = 0;
SigParams.cMsgCrl = 0;
SigParams.cUnauthAttr = 0;
SigParams.dwFlags = 0;
SigParams.pvHashAuxInfo = NULL;
SigParams.rgAuthAttr = NULL;

//--------------------------------------------------------------------
// With two calls to CryptSignMessage, sign the message.
// First, get the size of the output signed BLOB.

if(CryptSignMessage(
    &SigParams,            // Signature parameters
    FALSE,                 // Not detached
    1,                     // Number of messages
    MessageArray,          // Messages to be signed
    MessageSizeArray,      // Size of messages
    NULL,                  // Buffer for signed message
    &cbSignedMessageBlob)) // Size of buffer
{
    printf("The size of the BLOB is %d.\n",cbSignedMessageBlob);
}
else
{
    HandleError("Getting signed BLOB size failed");
}

//--------------------------------------------------------------------
// Allocate memory for the signed BLOB.

if(!(pbSignedMessageBlob =
   (BYTE*)malloc(cbSignedMessageBlob)))
{
    HandleError("Memory allocation error while signing.");
}

//--------------------------------------------------------------------
// Get the SignedMessageBlob.

if(CryptSignMessage(
      &SigParams,            // Signature parameters
      FALSE,                 // Not detached
      1,                     // Number of messages
      MessageArray,          // Messages to be signed
      MessageSizeArray,      // Size of messages
      pbSignedMessageBlob,   // Buffer for signed message
      &cbSignedMessageBlob)) // Size of buffer
{
    printf("The message was signed successfully. \n");
}
else
{
    HandleError("Error getting signed BLOB");
}

//--------------------------------------------------------------------
// pbSignedMessageBlob points to the signed BLOB.

//--------------------------------------------------------------------
//  Verify the message signature. Usually, this
//  would be done in a separate program.

//--------------------------------------------------------------------
//  Initialize the VerifyParams data structure.

VerifyParams.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);
VerifyParams.dwMsgAndCertEncodingType = MY_TYPE;
VerifyParams.hCryptProv = 0;
VerifyParams.pfnGetSignerCertificate = NULL;
VerifyParams.pvGetArg = NULL;

//--------------------------------------------------------------------
//   With two calls to CryptVerifyMessageSignature, verify and decode
//   the signed message.
//   First, call CryptVerifyMessageSignature to get the length of the
//   buffer needed to hold the decoded message.

if(CryptVerifyMessageSignature(
    &VerifyParams,           // Verify parameters.
    0,                       // Signer index.
    pbSignedMessageBlob,     // Pointer to signed BLOB.
    cbSignedMessageBlob,     // Size of signed BLOB.
    NULL,                    // Buffer for decoded message.
    &cbDecodedMessageBlob,                    // Size of buffer.
    NULL))                   // Pointer to signer certificate.
{
    printf("%d bytes need for the buffer.\n",cbDecodedMessageBlob);
}
else
{
    printf("Verification message failed. \n");
}

//--------------------------------------------------------------------
//   Allocate memory for the buffer.

if(!(pbDecodedMessageBlob =
   (BYTE*)malloc(cbDecodedMessageBlob)))
{
    HandleError("Memory allocation error allocating decode BLOB.");
}

//--------------------------------------------------------------------
//  Call CryptVerifyMessageSignature again to copy the message into
//  the buffer.

if(CryptVerifyMessageSignature(
    &VerifyParams,           // Verify parameters.
    0,                       // Signer index.
    pbSignedMessageBlob,     // Pointer to signed BLOB.
    cbSignedMessageBlob,     // Size of signed BLOB.
    pbDecodedMessageBlob,    // Buffer for decoded message.
    &cbDecodedMessageBlob,   // Size of buffer.
    NULL))                   // Pointer to signer certificate.
{
    printf("The verified message is \n-> %s \n",pbDecodedMessageBlob);
}
else
{
    printf("Verification message failed. \n");
}

//--------------------------------------------------------------------
// Clean up and free memory.

if(pbSignedMessageBlob)
     free(pbSignedMessageBlob);
if(pbDecodedMessageBlob)
     free(pbDecodedMessageBlob);
if(pSignerCert)
     CertFreeCertificateContext(pSignerCert);
if(CertCloseStore(
      hStoreHandle,
      CERT_CLOSE_STORE_CHECK_FLAG))
{
    printf("The store closed and all certificates are freed. \n");
}
else
{
    printf("Store closed after signing -- \n"
          "not all certificates, CRLs or CTLs were freed");
}
} // End of main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError


Example C Program: Signing, Encoding, Decoding, and Verifying a Message

This program combines signing and encoding a message and decoding a signed message and verifying the signature. Usually, the two operations would be in separate programs. The encoding program would create the encoded message, save it to a disk file or in some other way send it to another user. The decoding program would receive the encoded message, decode it, and verify the signature. The two processes have been combined here in order to show both procedures working.

Signing and encoding a message does not ensure privacy for that message. Rather it ensures the authenticity of the message. Since the message is signed with the sender's private key, when the receiver of the message decrypts the signature with the sender's public key (available from the certificate that is sent along with the message) the receiver can be sure that the message was sent by the person or entity associated with the certificate and that the message was not changed after it was signed.

This example program illustrates the following tasks and CryptoAPI functions:

  • Opening a certificate store using CertOpenStore.
  • Retrieving a certificate with a specific subject name using CertfindCertificateInStore.
  • Getting and printing a certificate's subject name using CertGetNameString.
  • Initializing a CRYPT_SIGN_MESSAGE_PARA structure to be used in a call to CryptSignMessage.
  • Signing and encoding a message with CryptSignMessage.
  • Opening a message for decoding with CryptMsgOpenToDecode.
  • Adding the encoded BLOB to the message to be decoded using CryptMsgUpdate.
  • Decoding the message using CryptMsgGetParam.
  • Opening a certificate store in memory with CertOpenStore using the message received and decoded.
  • Using CertGetSubjectCertificateFromStore to get the certificate of the message's signer.
  • Verifying a message's signature using CryptMsgControl.
  • Freeing memory, closing certificate stores, and freeing certificate context.

This example code uses the function HandleError. C code for this function is included with the sample.

Code for this and other auxiliary functions is also listed under General_Purpose_Functions.

//--------------------------------------------------------------------
// Example code for encoding and decoding a signed message.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
#define MAX_NAME 256

//--------------------------------------------------------------------
//   Define the name of a certificate subject.
//   To use this program, the definition of SIGNER_NAME
//   must be changed to the name of the subject of
//   a certificate that has access to a private key.
//   That certificate must have either the CERT_KEY_PROV_INFO_PROP_ID,
//   or CERT_KEY_CONTEXT_PROP_ID property set for the context to
//   provide access to the private signature key.

#define CERT_SUBJECT_NAME  L"Zeke"

#define CERTIFICATE_STORE_NAME L"MY"

//--------------------------------------------------------------------
//    Declare local functions.

void HandleError(char *s);

void ReportFailure();

void main(void)
{
//--------------------------------------------------------------------
// Declare and initialize variables. This includes getting a pointer
// to the message content. This sample program creates the message
// content and gets a pointer to it. In most situations,
// the content will exist somewhere and a pointer to it
// will get passed to the application.

HCERTSTORE hSystemStoreHandle;     // System Certificate store handle.
CRYPT_SIGN_MESSAGE_PARA   SignMessagePara;

//--------------------------------------------------------------------
//   The message to be signed and encoded.

BYTE* pbContent = (BYTE*) "In the room, the women come and go.";

//--------------------------------------------------------------------
//   The length of the message. This must be one more than the value
//   returned by strlen() to include the terminal NULL character.

DWORD cbContent = strlen((char *) pbContent)+1;

//--------------------------------------------------------------------
//    Arrays to hold the message to be signed and its length.

const BYTE *rgpbToBeSigned[1] ;
DWORD       rgcbToBeSigned[1];

//--------------------------------------------------------------------
//    The signer's certificate.

PCCERT_CONTEXT pSignerCert;

//--------------------------------------------------------------------
//   The length of the signed and encoded message.

DWORD cbEncodedBlob;

//--------------------------------------------------------------------
//    Pointer that will hold the address of the buffer holding the
//    signed and encoded message.

BYTE *pbEncodedBlob;

//--------------------------------------------------------------------
//    Buffer to hold the name of the subject of a certificate.

char pszNameString[MAX_NAME];

//--------------------------------------------------------------------
//  The following variables are used only in the decoding phase.

HCRYPTMSG hMsg;
HCERTSTORE hStoreHandle;           // Certificate store handle.
DWORD cbData = sizeof(DWORD);
DWORD cbDecoded;
BYTE *pbDecoded;
DWORD cbSignerCertInfo;
PCERT_INFO pSignerCertInfo;
PCCERT_CONTEXT pSignerCertContext;
PCERT_INFO pSignerCertificateInfo;

//--------------------------------------------------------------------
//  Begin processing. Display the original message.

rgpbToBeSigned[0] = pbContent;
rgcbToBeSigned[0] = cbContent;

printf("       The original message  => \n%s\n\n",rgpbToBeSigned[0]);

//--------------------------------------------------------------------
// Open a certificate store.

if(hSystemStoreHandle = CertOpenStore(
       CERT_STORE_PROV_SYSTEM,
       0,
       NULL,
       CERT_SYSTEM_STORE_CURRENT_USER,
       CERTIFICATE_STORE_NAME))
{
     printf("The cerrtificate store is open. \n");
}
else
{
    HandleError( "Error Getting Store Handle");
}

//--------------------------------------------------------------------
//  Find a certificate in the store. This certificate will
//  be used to sign the message. The certificate must have a private //  key accessible in order to sign the message.

if(pSignerCert = CertFindCertificateInStore(
   hSystemStoreHandle,
   MY_ENCODING_TYPE,
   0,
   CERT_FIND_SUBJECT_STR,
   CERT_SUBJECT_NAME,
   NULL))
{
//--------------------------------------------------------------------
//   Get and print the name of the subject of the certificate.

   if(CertGetNameString(
     pSignerCert,
     CERT_NAME_SIMPLE_DISPLAY_TYPE,
     0,
     NULL,
     pszNameString,
     MAX_NAME) > 1)
   {
      printf("The message signer is  %s \n",pszNameString);
   }
   else
   {
     HandleError("Getting the name of the signer failed.\n");
   }
}
else
{
    HandleError("Signer certificate not found.");
}

//--------------------------------------------------------------------
// Initialize the CRYPT_SIGN_MESSAGE_PARA structure.
// First, use memset to set all members to zero or NULL.
// Then set the values of all members that must be non-zero.

memset(&SignMessagePara, 0, sizeof(CRYPT_SIGN_MESSAGE_PARA));
SignMessagePara.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
SignMessagePara.HashAlgorithm.pszObjId = szOID_RSA_MD2;
SignMessagePara.pSigningCert = pSignerCert;
SignMessagePara.dwMsgEncodingType = MY_ENCODING_TYPE;
SignMessagePara.cMsgCert = 1;
SignMessagePara.rgpMsgCert = &pSignerCert;

//--------------------------------------------------------------------
//  In two steps, sign and encode the message.
//  First, get the number of bytes requred for the buffer
//  to hold the signed and encoded message.

if( CryptSignMessage(
     &SignMessagePara,
     FALSE,
     1,
     rgpbToBeSigned,
     rgcbToBeSigned,
     NULL,
     &cbEncodedBlob))
{
     printf("The needed length is %d \n",cbEncodedBlob);
}
else
{
     HandleError("Getting the length failed.\n");
}

//--------------------------------------------------------------------
//   Allocate memory for the required buffer.

if(!(pbEncodedBlob = (BYTE *)malloc(cbEncodedBlob)))
     HandleError("Memory allocation failed.");

//--------------------------------------------------------------------
//   Call CryptSignMessage a second time to
//   copy the signed and encoded message to the buffer.

if( CryptSignMessage(
     &SignMessagePara,
     FALSE,
     1,
     rgpbToBeSigned,
     rgcbToBeSigned,
     pbEncodedBlob,
     &cbEncodedBlob))
{
     printf("Signing worked \n");
}
else
{
     HandleError("Signing failed.\n");
}

//--------------------------------------------------------------------
//  Clean up after signing and encoding.

if(pSignerCert)
   CertFreeCertificateContext(pSignerCert);
if(hSystemStoreHandle)
   CertCloseStore(hSystemStoreHandle,CERT_CLOSE_STORE_FORCE_FLAG);

//--------------------------------------------------------------------
//  The following code decodes the message and
//  verifies the message signature.
//  This code would normally be in a stand-alone program that would
//  read the signed and encoded message and its length from a file
//  from an e-mail message, or from some other source.

//--------------------------------------------------------------------
//  Open a message for decoding.

if(hMsg = CryptMsgOpenToDecode(
   MY_ENCODING_TYPE,      // Encoding type.
   0,                     // Flags.
   0,                     // Use the default message type.
                          // The message type is
                          // listed in the message header.
   NULL,                  // Cryptographic provider. Use NULL
                          // for the default provider.
   NULL,                  // Recipient information.
   NULL))                 // Stream information.
{
     printf("The message to decode is open. \n");
}
else
{
    HandleError("OpenToDecode failed");
}
//--------------------------------------------------------------------
//  Update the message with an encoded BLOB.
//  Both pbEncodedBlob, the encoded data,
//  and cbEnclodeBlob, the length of the encoded data,
//  must be available.

if(CryptMsgUpdate(
    hMsg,                 // Handle to the message
    pbEncodedBlob,        // Pointer to the encoded BLOB
    cbEncodedBlob,        // Size of the encoded BLOB
    TRUE))                // Last call
{
      printf("The encoded BLOB has been added to the message. \n");
}
else
{
    HandleError("Decode MsgUpdate failed");
}

//--------------------------------------------------------------------
//  Get the number of bytes needed for a buffer
//  to hold the decoded message.

if(CryptMsgGetParam(
    hMsg,                  // Handle to the message
    CMSG_CONTENT_PARAM,    // Parameter type
    0,                     // Index
    NULL,
    &cbDecoded))           // Size of the returned
                           // information.
{
    printf("The message parameter has been acquired. \n");
}
else
{
    HandleError("Decode CMSG_CONTENT_PARAM failed");
}
//--------------------------------------------------------------------
// Allocate memory.

if(!(pbDecoded = (BYTE *) malloc(cbDecoded)))
{
    HandleError("Decode memory allocation failed");
}

//--------------------------------------------------------------------
// Copy the content to the buffer.

if(CryptMsgGetParam(
   hMsg,                 // Handle to the message
   CMSG_CONTENT_PARAM,   // Parameter type
   0,                    // Index
   pbDecoded,            // Address for returned
                         // information.
   &cbDecoded))          // Size of the returned
                         // information.
{
   printf("    The message is =>\n%s.\n\n",(LPSTR) pbDecoded);
}
else
{
   HandleError("Decode CMSG_CONTENT_PARAM #2 failed");
}

//--------------------------------------------------------------------
// Verify the signature.
// First, get the signer CERT_INFO from the message.

//--------------------------------------------------------------------
// Get the size of memory required for the certificate.

if(CryptMsgGetParam(
   hMsg,                         // Handle to the message
   CMSG_SIGNER_CERT_INFO_PARAM,  // Parameter type
   0,                            // Index
   NULL,
   &cbSignerCertInfo))           // Size of the returned
                                 // information.
{
   printf("%d bytes needed for the buffer.\n", cbSignerCertInfo);
}
else
{
   HandleError("Verify SIGNER_CERT_INFO #1 failed");
}

//--------------------------------------------------------------------
// Allocate memory.

if(!(pSignerCertInfo = (PCERT_INFO) malloc(cbSignerCertInfo)))
{
    HandleError("Verify memory allocation failed");
}

//--------------------------------------------------------------------
// Get the message certificate information (CERT_INFO
// structure).

if(!(CryptMsgGetParam(
     hMsg,                         // Handle to the message
     CMSG_SIGNER_CERT_INFO_PARAM,  // Parameter type
     0,                            // Index
     pSignerCertInfo,              // Address for returned
                                   //information.
     &cbSignerCertInfo)))          // Size of the returned
                                   //information.
{
    HandleError("Verify SIGNER_CERT_INFO #2 failed");
}

//--------------------------------------------------------------------
// Open a certificate store in memory using CERT_STORE_PROV_MSG,
// which initializes it with the certificates from the message.

if(hStoreHandle = CertOpenStore(
   CERT_STORE_PROV_MSG,         // Store provider type
   MY_ENCODING_TYPE,            // Encoding type
   NULL,                        // Cryptographic provider
                                // Use NULL for the default.
   0,                           // Flags
   hMsg))                       // Handle to the message
{
    printf("The certificate store to be used for message\n ");
    printf("    verification has been opened. \n");
}
else
{
    HandleError("Verify open store failed");
}

//--------------------------------------------------------------------
// Find the signer's certificate in the store.

if(pSignerCertContext = CertGetSubjectCertificateFromStore(
    hStoreHandle,       // Handle to store
    MY_ENCODING_TYPE,   // Encoding type
    pSignerCertInfo))   // Pointer to retrieved CERT_CONTEXT
{
  if(CertGetNameString(
     pSignerCertContext,
     CERT_NAME_SIMPLE_DISPLAY_TYPE,
     0,
     NULL,
     pszNameString,
     MAX_NAME) > 1)
  {
     printf("The message signer is  %s \n",pszNameString);
  }
  else
  {
     HandleError("Getting the signer's name failed.\n");
  }
}
else
{
    HandleError("Verify GetSubjectCert failed");
}

//--------------------------------------------------------------------
// Use the CERT_INFO from the signer certificate to verify
// the signature.

if(CryptMsgControl(
     hMsg,                       // Handle to the message
     0,                          // Flags
     CMSG_CTRL_VERIFY_SIGNATURE, // Control type
     pSignerCertContext->pCertInfo))    // Pointer to the CERT_INFO
{
     printf("Verify signature succeeded. \n");
}
else
{
    printf("The signature was not verified. \n");
    ReportFailure();
}
//--------------------------------------------------------------------
// Clean up.
if(pbEncodedBlob)
   free(pbEncodedBlob);
if(pbDecoded)
   free(pbDecoded);
if(pSignerCertInfo)
   free(pSignerCertInfo);
if(pSignerCertContext)
   CertFreeCertificateContext(pSignerCertContext);
if(hStoreHandle)
   CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_FORCE_FLAG);
if(hMsg)
    CryptMsgClose(hMsg);

printf("This program ran to completion without error. \n");
} //  End of main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError

Void ReportFailure()
{
switch (GetLastError())
{
     case CRYPT_E_AUTH_ATTR_MISSING:
          printf("Message does not contain an expected attribute.\n");
          break;
     case CRYPT_E_BAD_ENCODE:
          printf("An error encountered encoding or decoding.\n");
          break;
     case CRYPT_E_HASH_VALUE:
          printf("The hash value is not correct.\n");
          break;
     case CRYPT_E_INVALID_MSG_TYPE:
          printf("The message type is invalid.\n");
          break;
     case CRYPT_E_OSS_ERROR:
          printf("OSS error.\n");
          break;
     case CRYPT_E_SIGNER_NOT_FOUND:
          printf("Signer not found.\n");
          break;
     case CRYPT_E_UNEXPECTED_ENCODING:
          printf("Unexpected encoding. \n");
          break;
     case CRYPT_E_UNKNOWN_ALGO:
          printf("Unknow algorithm.\n");
          break;
     case E_OUTOFMEMORY:
          printf("Out of memory.\n");
          break;
     case ERROR_INVALID_HANDLE:
          printf("Invalid Handle from verify signature function.\n");
          break;
     case ERROR_INVALID_PARAMETER:
          printf("Invalid parameter from verify signature.\n");
          break;
     case NTE_BAD_FLAGS:
          printf("Bad Flags from verify signature function.\n");
          break;
     case NTE_BAD_HASH:
          printf("Bad Hash from verify signature function.\n");
          break;
     case NTE_BAD_KEY:
          printf("Bad Key from verify signature function.\n");
          break;
     case NTE_BAD_SIGNATURE:
          printf("Bad signature from verify signature function.\n");
          break;
     case NTE_BAD_UID:
          printf("Bad UID from verify signature function.\n");
          break;
}  // end switch
}  // end ReportFailure


Example C Program: Sending and Receiving a Signed and Encrypted Message

This example program signs a message using a sender's private key and encrypts the signed message using a receiver's public key. The program then decrypts the message using the receiver's private key and verifies the signature using the sender's public key. The sender's certificate containing the needed public key is included in the encrypted message. This program also writes the signed and encrypted message to a file. See Example C Program: Receiving a Signed and Encrypted Message.

To sign the message, the signer's private key and the signer's certificate must be available. To encrypt the signed message, a receiver's certificate including the receiver's public key must be available.

To decrypt the message, the receiver's private key must be available. Once the message is decrypted, the signature is verified using the public key from the certificate included in the encrypted message.

Note Not all of the certificates in a certificate store provide access to the private key associated with that certificate. When the message is signed and encrypted, a certificate belonging to the signer with access to the private key of that signer must be used. In addition, the receiver of the message must have access to the private key associated with the public key used to encrypt the message.

This example program illustrates the following tasks:

  • Opening and closing system certificate stores.
  • Finding certificates for a message sender and message receiver in the open certificate stores.
  • Finding and printing the subject name from certificates.
  • Initializing data structures needed to sign, encrypt, decrypt, and verify a message.
  • Calling a CryptoAPI function to find the required size of a buffer, allocating the buffer of the required size, and calling the CryptoAPI function again to fill the buffer. For more information, see Retrieving Data of Unknown Length.
  • Displaying some of the encrypted contents of a buffer. The included local function, ShowBytes, displays characters in the buffer with values between '0' and 'z'. All other characters are displayed as the '-' character.

This program uses the following CryptoAPI functions:

  • CertOpenStore
  • CertFindCertificateInStore
  • CertGetNameString
  • CryptAcquireCertificatePrivateKey
  • CryptSignAndEncryptMessage
  • CryptDecryptAndVerifyMessageSignature
  • CertFreeCertificateContext
  • CertCloseStore

This example code uses separate functions to show the signing/encryption process and the decryption/signature-verification process. It also uses HandleError to exit the program gracefully in case of any failure. The C code HandleError is included with the sample and can also be found along with other auxiliary functions under General Purpose Functions.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
#define MAX_NAME  128

//--------------------------------------------------------------------
//   SIGNER_NAME is used with the CertFindCertificateInStore function
//   to retrieve the certificate of the message signer.
//   Replace the Unicode string below with the certificate subject
//   name of the message signer.

#define SIGNER_NAME L"DUMMY_SIGNER_NAME"

//--------------------------------------------------------------------
//    The local function HandleError is declared here and
//    defined after main.

void HandleError( char *s);

//--------------------------------------------------------------------
//  The local function ShowBytes is declared here and defined after
//  main.

void ShowBytes(BYTE *s, DWORD len);

//--------------------------------------------------------------------
//   Declare local functions SignAndEncrypt, DecryptAndVerify, and
//   WriteSignedAndEncryptedBlob.
//   These functions are defined after main.

BYTE *SignAndEncrypt(
     const BYTE     *pbToBeSignedAndEncrypted,
     DWORD          cbToBeSignedAndEncrypted,
     DWORD          *pcbSignedAndEncryptedBlob);

BYTE *DecryptAndVerify(
     BYTE  *pbSignedAndEncryptedBlob,
     DWORD  cbSignedAndEncryptedBlob);

void WriteSignedAndEncryptedBlob(
     DWORD  cbBlob,
     BYTE   *pbBlob);

void main (void){

//--------------------------------------------------------------------
//  Declare and initialize local variables.

//--------------------------------------------------------------------
//   pbToBeSignedAndEncrypted is the message to be
//   encrypted and signed.

const BYTE     *pbToBeSignedAndEncrypted =
        (const unsigned char *)"Where do you want to go today?";
//--------------------------------------------------------------------
//    This is the length of the message to be
//    encrypted and signed. Note that it is one
//    more that the length returned by strlen()
//    to include the terminal NULL.

DWORD          cbToBeSignedAndEncrypted  =
     strlen((const char *)pbToBeSignedAndEncrypted)+1;

//--------------------------------------------------------------------
//    Pointer to a buffer that will hold the
//    encrypted and signed message.

BYTE                 *pbSignedAndEncryptedBlob;

//--------------------------------------------------------------------
//    A double word to hold the length of the signed
//    and encrypted message.

DWORD                 cbSignedAndEncryptedBlob;
BYTE                  *pReturnMessage;

//------------------------------------------------------
//  Call the local function SignAndEncrypt.
//  This function returns a pointer to the
//  signed and encrypted BLOB and also returns
//  the length of that BLOB.

pbSignedAndEncryptedBlob = SignAndEncrypt(
     pbToBeSignedAndEncrypted,
     cbToBeSignedAndEncrypted,
     &cbSignedAndEncryptedBlob);

printf("The following is the signed and encrypted message.\n");
ShowBytes(pbSignedAndEncryptedBlob,cbSignedAndEncryptedBlob/4);

// Open a file and write the signed and encrypted message to the file.

WriteSignedAndEncryptedBlob(
     cbSignedAndEncryptedBlob,
     pbSignedAndEncryptedBlob);

//--------------------------------------------------------------
//   Call the local function DecryptAndVerify.
//   This function decrypts and displays the
//   encrypted message and also verifies the
//   message's signature.

if(pReturnMessage = DecryptAndVerify(
     pbSignedAndEncryptedBlob,
     cbSignedAndEncryptedBlob))
{
     printf("    The returned, verified message is ->\n%s\n",pReturnMessage);
     printf("    The program executed without error.\n");
}
else
{
     printf("Verification failed.\n");
}

} // End Main.

//--------------------------------------------------------------------
//     Begin definition of the SignAndEncrypt function.

BYTE *SignAndEncrypt(
     const BYTE     *pbToBeSignedAndEncrypted,
     DWORD          cbToBeSignedAndEncrypted,
     DWORD          *pcbSignedAndEncryptedBlob)
{

//--------------------------------------------------------------------
//   Declare and initialize local variables.

FILE  *hToSave;
HCERTSTORE              hCertStore;

//--------------------------------------------------------------------
//   pSignerCertContext will be the certificate of the
//   the message signer.

PCCERT_CONTEXT          pSignerCertContext ;

//--------------------------------------------------------------------
//   pReceiverCertContext will be the certificate of the
//   message receiver.

PCCERT_CONTEXT          pReceiverCertContext;

char pszNameString[256];
CRYPT_SIGN_MESSAGE_PARA       SignPara;
CRYPT_ENCRYPT_MESSAGE_PARA    EncryptPara;
DWORD                         cRecipientCert;
PCCERT_CONTEXT                rgpRecipientCert[5];
BYTE                          *pbSignedAndEncryptedBlob = NULL;
CERT_NAME_BLOB                Subject_Blob;
BYTE                          *pbDataIn;
DWORD                         dwKeySpec;
HCRYPTPROV                    hCryptProv;

//--------------------------------------------------------------------
//     Open the MY certificate store.
//     For details, see the CertOpenStore function
//     PSDK reference page..

if ( !( hCertStore = CertOpenStore(
   CERT_STORE_PROV_SYSTEM,
   0,
   NULL,
   CERT_SYSTEM_STORE_CURRENT_USER,
   L"my")))
{
     HandleError("The MY store could not be opened.");
}

//--------------------------------------------------------------------
// Get the certificate for the signer.

if(!(pSignerCertContext = CertFindCertificateInStore(
     hCertStore,
     MY_TYPE,
     0,
     CERT_FIND_SUBJECT_STR,
     SIGNER_NAME,
     NULL)))
{
     HandleError("Cert not found.\n");
}

//--------------------------------------------------------------------
//   Get and print the name of the message signer.
//   The following two calls to CertGetNameString with different values
//   for the second parameter get two different forms of the certificate
//   subject's name.

if(CertGetNameString(
     pSignerCertContext ,
     CERT_NAME_SIMPLE_DISPLAY_TYPE,
     0,
     NULL,
     pszNameString,
     MAX_NAME) > 1)
{
     printf("The SIMPLE_DISPLAY_TYPE message signer's name is  %s \n",pszNameString);
}
else
{
     HandleError("Getting the name of the signer failed.\n");
}

if(CertGetNameString(
     pSignerCertContext,
     CERT_NAME_RDN_TYPE,
     0,
     NULL,
     pszNameString,
     MAX_NAME) > 1)
{
     printf("The RDM_TYPE message signer's name is  %s \n",pszNameString);
}
else
{
     HandleError("Getting the name of the signer failed.\n");
}

if(!( CryptAcquireCertificatePrivateKey(
     pSignerCertContext,
     0,
     NULL,
     &hCryptProv,
     &dwKeySpec,
     NULL)))
{
     HandleError("CryptAcquireCertificatePrivateKey.\n");
}

//--------------------------------------------------------------------
// Get the certificate for the receiver. In this case, a BLOB with the
// name of the receiver is saved in a file.

// Note: To decrypt the message signed and encrypted here,
// this program must use the certificate of the intended receiver.
// The signed and encrypted message can only be decrypted and verified
// by the owner of the recipient certificate. That user must have
// access to the private key associated with the public key of the
// recipient's certificate.

// To run this sample, the file contains information that allows the
// program to find one of the current user's certificates. The
// current user should have access to the private key of the
// certificate and thus can test the verification and decryption.

// In normal use, the file would contain information used to find
// the certificate of an intended receiver of the message.
// The signed and encrypted message would be written
// to a file or otherwise sent to the intended receiver.

//--------------------------------------------------------------------
//  Open a file and read in the receiver name
//  BLOB.

if( !(hToSave= fopen("s.txt","rb")))
{
     HandleError("Source file was not opened.\n");
}

fread(
     &(Subject_Blob.cbData),
     sizeof(DWORD),
     1,
     hToSave);

if(ferror(hToSave))
{
     HandleError("The size of the BLOB was not read.\n");
}

if(!(pbDataIn = (BYTE *) malloc(Subject_Blob.cbData)))
{
    HandleError("Memory allocation error.");
}

fread(
     pbDataIn,
     Subject_Blob.cbData,
     1,
     hToSave);

if(ferror(hToSave))
{
     HandleError("BLOB not read.");
}

fclose(hToSave);

Subject_Blob.pbData = pbDataIn;

//--------------------------------------------------------------------
//  Use the BLOB just read in from the file to find its associated
//  certificate in the MY store.
//  This call to CertFindCertificateInStore uses the
//  CERT_FIND_SUBJECT_NAME dwFindType.

if(!(pReceiverCertContext = CertFindCertificateInStore(
     hCertStore,
     MY_TYPE,
     0,
     CERT_FIND_SUBJECT_NAME,
     &Subject_Blob,
     NULL)))
{
     HandleError("Receiver certificate not found.");
}

//--------------------------------------------------------------------
//  Get and print the subject name from the receiver's certificate.

if(CertGetNameString(
     pReceiverCertContext ,
     CERT_NAME_SIMPLE_DISPLAY_TYPE,
     0,
     NULL,
     pszNameString,
     MAX_NAME) > 1)
{
     printf("The message receiver is  %s \n",pszNameString);
}
else
{
     HandleError("Getting the name of the receiver failed.\n");
}

//--------------------------------------------------------------------
//  Initialize variables and data structures
//  for the call to CryptSignAndEncryptMessage.

SignPara.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
SignPara.dwMsgEncodingType = MY_TYPE;
SignPara.pSigningCert = pSignerCertContext ;
SignPara.HashAlgorithm.pszObjId = szOID_RSA_MD2;
SignPara.HashAlgorithm.Parameters.cbData = 0;
SignPara.pvHashAuxInfo = NULL;
SignPara.cMsgCert = 1;
SignPara.rgpMsgCert = &pSignerCertContext ;
SignPara.cMsgCrl = 0;
SignPara.rgpMsgCrl = NULL;
SignPara.cAuthAttr = 0;
SignPara.rgAuthAttr = NULL;
SignPara.cUnauthAttr = 0;
SignPara.rgUnauthAttr = NULL;
SignPara.dwFlags = 0;
SignPara.dwInnerContentType = 0;

EncryptPara.cbSize = sizeof(CRYPT_ENCRYPT_MESSAGE_PARA);
EncryptPara.dwMsgEncodingType = MY_TYPE;
EncryptPara.hCryptProv = 0;
EncryptPara.ContentEncryptionAlgorithm.pszObjId = szOID_RSA_RC4;
EncryptPara.ContentEncryptionAlgorithm.Parameters.cbData = 0;
EncryptPara.pvEncryptionAuxInfo = NULL;
EncryptPara.dwFlags = 0;
EncryptPara.dwInnerContentType = 0;

cRecipientCert = 1;
rgpRecipientCert[0] = pReceiverCertContext;
*pcbSignedAndEncryptedBlob = 0;
pbSignedAndEncryptedBlob = NULL;

if( CryptSignAndEncryptMessage(
   &SignPara,
   &EncryptPara,
   cRecipientCert,
   rgpRecipientCert,
   pbToBeSignedAndEncrypted,
   cbToBeSignedAndEncrypted,
   NULL,                      // the pbSignedAndEncryptedBlob
   pcbSignedAndEncryptedBlob))
{
   printf("%d bytes for the buffer .\n",*pcbSignedAndEncryptedBlob);
}
else
{
     HandleError("Getting the buffer length failed.");
}

//--------------------------------------------------------------------
//    Allocated memory for the buffer

if(!(pbSignedAndEncryptedBlob=(unsigned char *)
     malloc(*pcbSignedAndEncryptedBlob)))
     HandleError("Memory allocation failed.");

//--------------------------------------------------------------------
//   Call the function a second time to copy the signed and encrypted
//   message into the buffer.

if( CryptSignAndEncryptMessage(
   &SignPara,
   &EncryptPara,
   cRecipientCert,
   rgpRecipientCert,
   pbToBeSignedAndEncrypted,
   cbToBeSignedAndEncrypted,
   pbSignedAndEncryptedBlob,
   pcbSignedAndEncryptedBlob))
{
     printf("The message is signed and encrypted.\n");
}
else
{
     HandleError("The message failed to sign and encrypt.");
}

//--------------------------------------------------------------------
//   Clean up.

if(pSignerCertContext )
{
     CertFreeCertificateContext (pSignerCertContext );
}
if(pReceiverCertContext )
{
     CertFreeCertificateContext (pReceiverCertContext );
}
CertCloseStore(
     hCertStore,
     0);

//--------------------------------------------------------------------
//   Return the signed and encrypted message.

return pbSignedAndEncryptedBlob;

}  // End SignandEncrypt.

//--------------------------------------------------------------------
//   Define the DecryptAndVerify function.

BYTE  *DecryptAndVerify(
     BYTE  *pbSignedAndEncryptedBlob,
     DWORD  cbSignedAndEncryptedBlob)
{

//--------------------------------------------------------------------
//  Declare and initialize local variables.

HCERTSTORE                     hCertStore;
CRYPT_DECRYPT_MESSAGE_PARA     DecryptPara;
CRYPT_VERIFY_MESSAGE_PARA      VerifyPara;
DWORD                          dwSignerIndex = 0;
BYTE                           *pbDecrypted;
DWORD                          cbDecrypted;

//--------------------------------------------------------------------
//   Open the certificate store

if ( !( hCertStore = CertOpenStore(
   CERT_STORE_PROV_SYSTEM,
   0,
   NULL,
   CERT_SYSTEM_STORE_CURRENT_USER,
   L"my")))
{
     HandleError("The MY store could not be openned.");
}

//--------------------------------------------------------------------
//   Initialize the needed data structures.

DecryptPara.cbSize = sizeof(CRYPT_DECRYPT_MESSAGE_PARA);
DecryptPara.dwMsgAndCertEncodingType = MY_TYPE;
DecryptPara.cCertStore = 1;
DecryptPara.rghCertStore = &hCertStore;

VerifyPara.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);
VerifyPara.dwMsgAndCertEncodingType = MY_TYPE;
VerifyPara.hCryptProv = 0;
VerifyPara.pfnGetSignerCertificate = NULL;
VerifyPara.pvGetArg = NULL;
pbDecrypted = NULL;
cbDecrypted = 0;

//--------------------------------------------------------------------
//     Call CryptDecryptAndVerifyMessageSignature a first time
//     to determine the needed size of the buffer to hold the
//     decrypted message.

if(!(CryptDecryptAndVerifyMessageSignature(
   &DecryptPara,
   &VerifyPara,
   dwSignerIndex,
   pbSignedAndEncryptedBlob,
   cbSignedAndEncryptedBlob,
   NULL,           // pbDecrypted
   &cbDecrypted,
   NULL,
   NULL)))
{
     HandleError("Failed getting size.");
}

//--------------------------------------------------------------------
//    Allocate memory for the buffer to hold the decrypted message.

if(!(pbDecrypted = (BYTE *)malloc(cbDecrypted)))
    HandleError("Memory allocation failed.");

if(!(CryptDecryptAndVerifyMessageSignature(
   &DecryptPara,
   &VerifyPara,
   dwSignerIndex,
   pbSignedAndEncryptedBlob,
   cbSignedAndEncryptedBlob,
   pbDecrypted,
   &cbDecrypted,
   NULL,
   NULL)))
{
     pbDecrypted = NULL;
}

//--------------------------------------------------------------------
//  Close the certificate store.

CertCloseStore(
     hCertStore,
     0);

//--------------------------------------------------------------------
//    Return the decrypted string or NULL

return pbDecrypted;

} // end of DecryptandVerify

//--------------------------------------------------------------------
//   Define the HandleError function.

void WriteSignedAndEncryptedBlob(
     DWORD  cbBlob,
     BYTE   *pbBlob)
{
// Open an output file, write the file, and close the file.
// This function would be used to save the signed and encrypted
// message to a file that would be sent to the intended receiver.
// Note: the only receiver able to decrypt and verify this message
// will have access to the private key associated
// with the public key from the certificate used when the message was
// encrypted.

FILE *hOutputFile;

if( !(hOutputFile= fopen("sandvout.txt","wb")))
{
     HandleError("Output file was not opened.\n");
}

fwrite(
     &cbBlob,
     sizeof(DWORD),
     1,
     hOutputFile);

if(ferror(hOutputFile))
{
     HandleError("The size of the BLOB was not written.\n");
}

fwrite(
     pbBlob,
     cbBlob,
     1,
     hOutputFile);

if(ferror(hOutputFile))
{
     HandleError("The bytes of the BLOB were not written.\n");
}
else
{
     printf(" The BLOB has been written to the file.\n");
}
fclose(hOutputFile);
}  // end of WriteSignedAndEcryptedBlob

void HandleError(char *s)
{
     printf("%s\n",s);
     exit(1);
} // end of HandleError

//--------------------------------------------------------------------
//  Define the ShowBytes function.
//  This function displays the contents of a BYTE buffer. Characters
//  less than '0' or greater than 'z' are all displayed as '-'.

void ShowBytes(BYTE *s, DWORD len)
{
     DWORD TotalChars = 0;
     DWORD ThisLine = 0;
while(TotalChars < len)
{
     if(ThisLine > 70)
     {
          ThisLine = 0;
          printf("\n");
     }
     if( s[TotalChars] < '0' || s[TotalChars] > 'z')
     {
          printf("-");
     }
     else
     {
          printf("%c",s[TotalChars]);
     }
     TotalChars++;
     ThisLine++;
}
printf("\n");
} // End of ShowBytes.


Example C Program: Receiving a Signed and Encrypted Message

This example program works in conjunction with the program in Example C Program: Sending and Receiving a Signed and Encrypted Message. It reads the signed and encrypted message, then decrypts and verifies the message.

To decrypt and verify the message, the private key of of the message's intended receiver must be available. The certificate of the signer is included in the messge BLOB read in from the file.

This example program illustrates the following tasks:

  • Opening and closing system certificate stores.
  • Reading a CERT_NAME_BLOB from a file.
  • Initializing data structures needed to decrypt and verify a message.
  • Calling a CryptoAPI function to find the required size of a buffer, allocating the buffer of the required size, and calling the CryptoAPI function again to fill the buffer. For more information, see Retrieving Data of Unknown Length.

This program uses the following CryptoAPI functions:

  • CertOpenStore
  • CryptDecryptAndVerifyMessageSignature
  • CertCloseStore

This example code uses HandleError to exit the program gracefully in case of any failure. The C code HandleError is included with the sample and can also be found along with other auxiliary functions under General Purpose Functions.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

//--------------------------------------------------------------------
//    The local function HandleError is declared here and
//    defined after main.

void HandleError( char *s);

//--------------------------------------------------------------------
//   The local function DecryptAndVerify is declared here and
//   defined after main.

BYTE *DecryptAndVerify(DWORD cbBlob, BYTE *pbBlob);

//--------------------------------------------------------------------
//   The local function ReadBlob is declared here and
//   defined after main.

BYTE *ReadBlob(DWORD *cbBlob);

//--------------------------------------------------------------------
//   Main calls ReadBlob to read in the signed and encrypted message.
//   It then calls DecryptAndVerify which, if successful, decrypts
//   and verifys the message.
//   The function main prints the returned, decrypted message
//   if the verification and decryption is successful.

//   Note: The file with the signed and encrypted file must be
//   available and the user running this program must have access to
//   the private key of the intended message receiver.

//   Also note that this program does not use CryptAcquireContext.

void main()
{
BYTE                  *pReturnMessage;
BYTE                  *pbBlob;
DWORD                 cbBlob;

if( (pbBlob = ReadBlob(&cbBlob)) == NULL )
{
    HandleError("Read Blob did not return the BLOB. ");
}

if(pReturnMessage = DecryptAndVerify(cbBlob,pbBlob))
{
     printf("    The returned, verified message is ->\n%s\n",pReturnMessage);
     printf("    The program executed without error.\n");
}
else
{
     printf("Verification failed.\n");
}

} // end of main.

BYTE  *DecryptAndVerify(DWORD cbBlob, BYTE *pbBlob)
{
//--------------------------------------------------------------------
//  Declare and initialize local variables.

HCERTSTORE                     hCertStore;
CRYPT_DECRYPT_MESSAGE_PARA     DecryptPara;
CRYPT_VERIFY_MESSAGE_PARA      VerifyPara;
DWORD                          dwSignerIndex = 0;
BYTE                           *pbDecrypted;
DWORD                          cbDecrypted;

//--------------------------------------------------------------------
//   Open the certificate store

if ( !( hCertStore = CertOpenStore(
   CERT_STORE_PROV_SYSTEM,
   0,
   NULL,
   CERT_SYSTEM_STORE_CURRENT_USER,
   L"my")))
{
     HandleError("The MY store could not be openned.");
}

//--------------------------------------------------------------------
//   Initialize the needed data structures.

DecryptPara.cbSize = sizeof(CRYPT_DECRYPT_MESSAGE_PARA);
DecryptPara.dwMsgAndCertEncodingType = MY_TYPE;
DecryptPara.cCertStore = 1;
DecryptPara.rghCertStore = &hCertStore;

VerifyPara.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);
VerifyPara.dwMsgAndCertEncodingType = MY_TYPE;
VerifyPara.hCryptProv = 0;
VerifyPara.pfnGetSignerCertificate = NULL;
VerifyPara.pvGetArg = NULL;
pbDecrypted = NULL;
cbDecrypted = 0;

//--------------------------------------------------------------------
//     Call CryptDecryptAndVerifyMessageSignature a first time
//     to determine the needed size of the buffer to hold the
//     decrypted message.
//     Note: the sixth parameter is NULL in this call in order to
//     get the required size of the bytes string to contain the
//     decrypted message..

if(!(CryptDecryptAndVerifyMessageSignature(
   &DecryptPara,
   &VerifyPara,
   dwSignerIndex,
   pbBlob,
   cbBlob,
   NULL,
   &cbDecrypted,
   NULL,
   NULL)))
{
     HandleError("Failed getting size.");
}

//--------------------------------------------------------------------
//    Allocate memory for the buffer to hold the decrypted message.

if(!(pbDecrypted = (BYTE *)malloc(cbDecrypted)))
    HandleError("Memory allocation failed.");

if(!(CryptDecryptAndVerifyMessageSignature(
   &DecryptPara,
   &VerifyPara,
   dwSignerIndex,
   pbBlob,
   cbBlob,
   pbDecrypted,
   &cbDecrypted,
   NULL,
   NULL)))
{
     pbDecrypted = NULL;
}

//--------------------------------------------------------------------
//  Close the certificate store.

CertCloseStore(
     hCertStore,
     0);

//--------------------------------------------------------------------
//    Return the decrypted string or NULL

return pbDecrypted;

} // end of DecryptandVerify

BYTE *ReadBlob( DWORD *cbBlob)
{

FILE                           *hInputFile;
BYTE                           *pbBlob;

// Open the input file and read in the signed and encrypted Blob.
// This file would be created by a program such as the example program
// "Example C Program: Sending and Receiving a Signed and Encrypted
//  Message"in the Platform SDK.
// Change the pathname for this file if it is not in the same
//  directory as the executable.

if( !(hInputFile= fopen("sandvout.txt","rb")))
{
     HandleError("Input file was not opened.\n");
}

fread(
     cbBlob,
     sizeof(DWORD),
     1,
     hInputFile);

if(ferror(hInputFile))
{
     HandleError("The size of the BLOB was not read.\n");
}

if(!(pbBlob = (BYTE *) malloc(*cbBlob)))
{
    HandleError("Memory allocation failed.");
}

fread(
     pbBlob,
     *
     cbBlob,
     1,
     hInputFile);

if(ferror(hInputFile))
{
     HandleError("The bytes  of the BLOB were not read.\n");
}

fclose(hInputFile);
return pbBlob;
}  // End of ReadBlob

void HandleError(char *s)
{
     printf("%s\n",s);
     exit(1);
}


Enveloped Data

The following sections deal with working with enveloped data:

  • Encoding Enveloped Data
  • Decoding Enveloped Data
  • Example C Program: Encoding and Decoding an Enveloped Message
  • Alternate Code for Encoding an Enveloped Message
  • Example C Program: Encoding an Enveloped, Signed Message


Encoding Enveloped Data

Enveloped data consists of encrypted content of any type and encrypted content-encryption session keys for one or more recipients. Enveloped messages keep the contents of the message secret and allow only specified persons or entities to retrieve the contents.

Beginning with Windows 2000, cryptographic message syntax (CMS) can be used for enveloped messages. Using CMS, three key management techniques are supported: key transport, key agreement, and previously distributed symmetric key-encryption keys (KEK). Previously distributed symmetric key-encryption keys are also known as mailing list key distribution.

In each case, a single session key is generated to encrypt the enveloped message. Key management issues deal with the way that session key is encrypted by the sender and decrypted by a receiver. A single encrypted message may be distributed to many recipients using a mixture of the key management techniques.

Key transport key management uses an intended receiver's public key to encrypt the session key. The receiver decrypts the session key using the private key associated with the public key used to encrypt, and uses the decrypted session key to decrypt the enveloped data. When key transport is used, the receiver has not confirmed information on the identity of the sender.

In key agreement management, a temporary, ephemeral Diffie-Hellman private key is generated and used to encrypt the session key. The public key corresponding to the ephemeral private key is included as part of the message's recipient information. The message receiver decrypts the session key using the received ephemeral key and uses this decrypted session key to decrypt the enveloped message. Using ephemeral key agreement in conjunction with the receiver's private key, the message receiver does have confirmed information on the identity of the sender.

For key management using previously distributed symmetric keys, each message includes the content-encryption key that has been encrypted with a previously distributed key-encryption key. Receivers use the previously distributed key-encryption key to decrypt the content encryption key, then use the decrypted content-encryption key to decrypt the enveloped message.

The typical, non CMS, sequence of events for encoding enveloped data, as depicted in the previous illustration, is as follows:

The sequence of events for encoding enveloped data, as depicted in the previous illustration, is as follows:

  1. A pointer to the plaintext message is retrieved.
  2. A symmetric (session) key is generated.
  3. The symmetric key and specified encryption algorithm are used to encrypt the message data.
  4. A certificate store is opened.
  5. The recipient's certificate is retrieved from the store.
  6. The public key is retrieved from the recipient's certificate.
  7. Using the recipient's public key, the symmetric key is encrypted.
  8. From the recipient's certificate, the recipient's ID is retrieved.
  9. The following information is included in the digitally enveloped message: the data encryption algorithm, the encrypted data, the encrypted symmetric key, and the recipient information structure.

To use low-level message functions to accomplish the typical tasks just listed, use the following procedure.

To encode an enveloped message

  1. Create or retrieve the content.
  2. Get a cryptographic provider.
  3. Get a recipient certificate.
  4. Initialize the CMSG_ENVELOPED_ENCODE_INFO structure.
  5. Call CryptMsgCalculateEncodedLength to get the size of the encoded message BLOB. Allocate memory for it.
  6. Call CryptMsgOpenToEncode, passing in CMSG_ENVELOPED for dwMsgType and a pointer to CMSG_ENVELOPED_ENCODE_INFO for pvMsgEncodeInfo. As a result of this call, you will get a handle to the opened message.
  7. Call CryptMsgUpdate, passing in the handle retrieved in step 6 and a pointer to the data that is to be encrypted, enveloped, and encoded. This function can be called as many times as necessary to complete the encoding process.
  8. Call CryptMsgGetParam, passing in the handle retrieved in step 6 and the appropriate parameter types to access the desired, encoded data. For example, pass in CMSG_CONTENT_PARAM to get a pointer to the entire PKCS #7 message.

    If the result of this encoding is to be used as the inner data for another encoded message, such as an enveloped message, the CMSG_BARE_CONTENT_PARAM parameter must be passed. For example code showing this, see Alternate Code for Encoding an Enveloped Message.

  9. Close the message by calling CryptMsgClose.

The result of this procedure is an encoded message that contains the encrypted data, the symmetric key that is encrypted with the recipient's public keys, and the recipient information data structures. The combination of encrypted content and an encrypted symmetric key for a recipient is a digital envelope for that recipient. Any type of content can be enveloped for multiple recipients.

For C code details, see Example C Program: Encoding an Enveloped, Signed Message.


Decoding Enveloped Data

The general tasks required to decode an enveloped message are depicted in the following illustration and described in the list that follows it.

The sequence of events for decoding enveloped data using key transport key management, as depicted in the previous illustration, is as follows:

  1. A pointer to the digitally enveloped message is retrieved.
  2. A certificate store is opened.
  3. From the message, the recipient ID (My ID) is retrieved.
  4. The recipient ID is used to retrieve the certificate.
  5. The private key associated with that certificate is retrieved.
  6. The private key is used to decrypt the symmetric (session) key.
  7. The encryption algorithm is retrieved from the message.
  8. Using the private key and encryption algorithm, the data is decrypted.

The following procedure uses low-level message functions to accomplish the tasks just listed.

To decode an enveloped message

  1. Get a pointer to the encoded BLOB.
  2. Call CryptMsgOpenToDecode, passing the necessary arguments.
  3. Call CryptMsgUpdate once, passing in the handle retrieved in step 2 and a pointer to the data that is to be decoded. This causes the appropriate actions to be taken on the message, depending on the message type.
  4. Call CryptMsgGetParam, passing in the handle retrieved in step 2 and CMSG_TYPE_PARAM to verify that the message is of the enveloped data type.
  5. Again call CryptMsgGetParam, passing in CMSG_INNER_CONTENT_TYPE_PARAM, to get the data type of the inner content.
  6. If the inner content data type is data, proceed to decrypt and decode the content. Otherwise, run a decoding procedure appropriate for the content data type.
  7. Assuming the inner content type is "data", initialize the CMSG_CTRL_DECRYPT_PARA data structure, and call CryptMsgControl, passing in CMSG_CTRL_DECRYPT and the address of the structure. The content will be decrypted.
  8. Call CryptMsgGetParam, passing in CMSG_CONTENT_PARAM to get a pointer to the decoded content data BLOB (BYTE string).
  9. Call CryptMsgClose to close the message.

The result of this procedure is that the message is decoded and decrypted, and a pointer is retrieved to the content data BLOB.

For C code details, see Example C Program: Encoding an Enveloped, Signed Message.


Example C Program: Encoding and Decoding an Enveloped Message

The following example program demonstrates the process of encoding, decoding, and decrypting an enveloped message that has a data inner-content data type.

This example program illustrates the following tasks and CryptoAPI functions:

  • CryptAcquireContext.
  • CertOpenSystemStore.
  • CryptMsgCalculateEncodedLength.
  • CryptMsgOpenToEncode.
  • CryptMsgUpdate.
  • CryptMsgGetParam.
  • CertCloseStore.
  • CryptMsgClose.
  • CertEnumCertificatesInStore.
  • CertNameToStr.
  • CertFreeCertificateContext.
  • CryptMsgOpenToDecode.
  • Using CryptReleaseContext to release the CSP.

This example code uses the function HandleError. The C code for these functions is included with the sample. Code for this and other auxiliary functions is also listed under General Purpose Functions.

// Example code for encoding and decoding an enveloped message

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

//--------------------------------------------------------------------
//   Define the name of a certificate subject.
//   To use this program, the definition of SIGNER_NAME
//   must be changed to the name of the subject of
//   a certificate that has access to a private key.
//   That certificate must have either the CERT_KEY_PROV_INFO_PROP_ID,
//   or CERT_KEY_CONTEXT_PROP_ID property set for the context to
//   provide access to the private signature key.

#define SIGNER_NAME L"Zeke"
void HandleError(char *s);

//--------------------------------------------------------------------
// This program uses the function DecodeEnvelopedMessage declared here
// and defined after main.

void DecodeEnvelopedMessage(
    DWORD cbEncodedBlob,
    BYTE *pbEncodedBlob,
    HCRYPTPROV  hCryptProv);

void main()
{
//--------------------------------------------------------------------
// Declare and initialize variables. This includes
// a pointer to the content of the message to be enveloped.
// Usually, the content will exist somewhere
// and a pointer to it will get passed to the application.

LPWSTR pswzCertSubject = SIGNER_NAME; // The name searched for in the
                                      // certificate subject.
BYTE*  pbContent = (BYTE*) "Encoding is not the same as encrypting.";
                                 // Pointer to message content
DWORD  cbContent = strlen((char*)pbContent)+1;
                                 // Size of message
HCRYPTPROV  hCryptProv;          // Provider handle
HCERTSTORE hStoreHandle;
PCCERT_CONTEXT  pRecipCert;
PCERT_INFO  RecipCertArray[1];
DWORD  ContentEncryptAlgSize;
CRYPT_ALGORITHM_IDENTIFIER  ContentEncryptAlgorithm;
CMSG_ENVELOPED_ENCODE_INFO  EnvelopedEncodeInfo;
DWORD  cbEncodedBlob;
BYTE  *pbEncodedBlob;
HCRYPTMSG    hMsg;

//--------------------------------------------------------------------
//   Begin processing. Display the message to be enveloped and
//   encoded.

printf("About to begin. \n");
printf("The message is \n    %s.\n",pbContent);

//--------------------------------------------------------------------
// Get a handle to a cryptographic provider.

if(CryptAcquireContext(
        &hCryptProv,       // Address for handle to be returned.
        NULL,              // Use the current user's logon name.
        NULL,              // Use the default provider.
        PROV_RSA_FULL,     // Provider type.
        0))                // Zero allows access to private keys.
{
    printf("A cryptographic provider has been acquired. \n");
}
else
{
    HandleError("CryptAcquireContext failed.");
}
//--------------------------------------------------------------------
// Open the system certificate store.

if(hStoreHandle = CertOpenSystemStore(
        hCryptProv,
        "MY"))
{
    printf("The MY certificate store is open. \n");
}
else
{
    HandleError( "Error getting store handle.");
}
//--------------------------------------------------------------------
// Get a pointer to the recipient certificate.

if(pRecipCert = CertFindCertificateInStore(
      hStoreHandle,
      MY_ENCODING_TYPE,            // Use X509_ASN_ENCODING.
      0,                           // No dwFlags needed.
      CERT_FIND_SUBJECT_STR,       // Find a certificate with a
                                   // subject that matches the string
                                   // in the next parameter.
      pswzCertSubject,             // The Unicode string to be found
                                   // in a certificate's subject.
      NULL))                       // NULL for the first call to the
                                   // function. In all subsequent
                                   // calls, it is the last pointer
                                   // returned by the function.
{
     printf("A certificate for %S was found. \n", pswzCertSubject);
}
else
{
    HandleError( "Error getting recipient certificate.");
}
//--------------------------------------------------------------------
// Create an array of CERT_INFOs. In this example, there is a single
// recipient.

RecipCertArray[0] = pRecipCert->pCertInfo;

//--------------------------------------------------------------------
// Initialize the symmetric encryption algorithm identifier
// structure.
// This particular object identifier (OID) does not require any
// parameters. Some OIDs, however, will need parameter members
// initialized.

ContentEncryptAlgSize = sizeof(ContentEncryptAlgorithm);
memset(&ContentEncryptAlgorithm,
       0,
       ContentEncryptAlgSize); // Initialize to zero.

ContentEncryptAlgorithm.pszObjId = szOID_RSA_RC4;

//--------------------------------------------------------------------
// Initialize the CMSG_ENVELOPED_ENCODE_INFO structure.

memset(&EnvelopedEncodeInfo,
       0,
       sizeof(CMSG_ENVELOPED_ENCODE_INFO));

EnvelopedEncodeInfo.cbSize = sizeof(CMSG_ENVELOPED_ENCODE_INFO);
EnvelopedEncodeInfo.hCryptProv = hCryptProv;
EnvelopedEncodeInfo.ContentEncryptionAlgorithm =
                                        ContentEncryptAlgorithm;
EnvelopedEncodeInfo.pvEncryptionAuxInfo = NULL;
EnvelopedEncodeInfo.cRecipients = 1;
EnvelopedEncodeInfo.rgpRecipients = RecipCertArray;

//--------------------------------------------------------------------
// Get the size of the encoded message BLOB.

if(cbEncodedBlob = CryptMsgCalculateEncodedLength(
             MY_ENCODING_TYPE,         // Message encoding type
             0,                        // Flags
             CMSG_ENVELOPED,           // Message type
             &EnvelopedEncodeInfo,     // Pointer to structure
             NULL,                     // Inner content OID
             cbContent))               // Size of content
{
    printf("The length for the message is %d.\n",cbEncodedBlob);
}
else
{
    HandleError("Getting cbEncodedBlob length failed.");
}
//--------------------------------------------------------------------
// Allocate memory for the encoded BLOB.

if(pbEncodedBlob = (BYTE *) malloc(cbEncodedBlob))
{
    printf("Memory has been allocated for the encoded BLOB. \n");
}
else
{
    HandleError("Memory allocation for the encoded BLOB failed.");
}
//--------------------------------------------------------------------
// Open a message to encode.

if(hMsg = CryptMsgOpenToEncode(
          MY_ENCODING_TYPE,        // Encoding type
          0,                       // Flags
          CMSG_ENVELOPED,          // Message type
          &EnvelopedEncodeInfo,    // Pointer to structure
          NULL,                    // Inner content OID
          NULL))                   // Stream information (not used)
{
    printf("The message to be encoded has been opened. \n");
}
else
{
    HandleError("OpenToEncode failed.");
}
//-------------------------------------------------------------
// Update the message with the data.

if(CryptMsgUpdate(
         hMsg,         // Handle to the message
         pbContent,    // Pointer to the content
         cbContent,    // Size of the content
         TRUE))        // Last call
{
    printf("Content has been added to the open message. \n");
}
else
{
    HandleError("MsgUpdate failed.");
}
//--------------------------------------------------------------------
// Get the resulting encoded message.

if(CryptMsgGetParam(
         hMsg,                  // Handle to the message
         CMSG_CONTENT_PARAM,    // Parameter type
         0,                     // Index
         pbEncodedBlob,         // Pointer to the BLOB
         &cbEncodedBlob))       // Size of the BLOB
{
    printf("Message encoded successfully  \n");
}
else
{
    HandleError("MsgGetParam failed");
}
//--------------------------------------------------------------------
// pbEncodedBlob points to the encoded, enveloped content.

//--------------------------------------------------------------------
//  Close the message.

if(hMsg)
   CryptMsgClose(hMsg);

//--------------------------------------------------------------------
//  Decode the enveloped message.

DecodeEnvelopedMessage(
     cbEncodedBlob,    // The length of the BLOB to be decoded
     pbEncodedBlob,    // Pointer to the BLOB to be decoded
     hCryptProv);
//--------------------------------------------------------------------
//   Close the store and the message.

if(CertCloseStore(
     hStoreHandle,
     CERT_CLOSE_STORE_CHECK_FLAG))
{
    printf("The store closed with no certificates left open. \n");
}
else
{
    printf("The store closed but certificates are still open. \n");
}
//--------------------------------------------------------------------
// Release the CSP.

if(hCryptProv)
   CryptReleaseContext(hCryptProv,0);
printf("The program ran to completion without error. \n");
}  //  End of main

//--------------------------------------------------------------------
//   Define the function DecodeEnvelopedMessage.

void DecodeEnvelopedMessage(
     DWORD cbEncodedBlob,    // Length of the encoded message
     BYTE *pbEncodedBlob,    // Pointer to the encoded message
     HCRYPTPROV  hCryptProv)
{
//--------------------------------------------------------------------
//  Declare and initialize local variables.

DWORD cbData = sizeof(DWORD);
DWORD dwMsgType;
DWORD cbInnerContentObjId = sizeof(DWORD);
BYTE *pbInnerContentObjId;
LPSTR pszInnerContentObjId;
DWORD cbDecoded;
BYTE *pbDecoded;
HCRYPTMSG hMsg;
CMSG_CTRL_DECRYPT_PARA DecryptPara;

//--------------------------------------------------------------------
//  Open a message for decoding.

if(hMsg = CryptMsgOpenToDecode(
       MY_ENCODING_TYPE,       // Encoding type
       0,                      // Flags
       0,                      // Message type (get from message)
       hCryptProv,             // Cryptographic provider
       NULL,                   // Recipient information
       NULL))                  // Stream information
{
    printf("The message to decode has been opened. \n");
}
else
{
    HandleError("OpenToDecode failed");
}
//--------------------------------------------------------------------
// Update the message with the encoded BLOB, using the data
// that was encoded in previous code.

if(CryptMsgUpdate(
        hMsg,                 // Handle to the message
        pbEncodedBlob,        // Pointer to the encoded BLOB
        cbEncodedBlob,        // Size of the encoded BLOB
        TRUE))                // Last call
{
    printf("The message to decode has been updated. \n");
}
else
{
    HandleError("Decode MsgUpdate failed");
}
//--------------------------------------------------------------------
// Get the message type.

if(CryptMsgGetParam(
        hMsg,                   // Handle to the message
        CMSG_TYPE_PARAM,        // Parameter type
        0,                      // Index
        &dwMsgType,             // Address for returned
                                // information
        &cbData))               // Size of the returned
                                // information
{
    printf("The message type has been retrieved. \n");
}
else
{
    HandleError("Decode CMSG_TYPE_PARAM failed");
}
//--------------------------------------------------------------------
// Applications might use a switch statement here
// and process the message differently, depending on the
// message type. For simplicity, this program will only
// handle CMSG_ENVELOPED material.

if(dwMsgType == CMSG_ENVELOPED)
{
   printf("The message is an enveloped message. Continue. \n");
}
else
{
    HandleError("Wrong message type.");
}
//-------------------------------------------------------------
// Get the size of inner content type BYTE string. If there is
// prior knowledge of inner data type, the next two function
// calls and the tests for the inner content type can be
// eliminated, and the decoding for that type of inner content
// can be implemented directly.

if((CryptMsgGetParam(
    hMsg,                          // Handle to the message
    CMSG_INNER_CONTENT_TYPE_PARAM, // Parameter type
    0,                             // Index
    NULL,                          // Address for returned
                                   // information
    &cbInnerContentObjId)))        // Size of the returned
                                   // information
{
   printf("Inner content size -> %d\n",cbInnerContentObjId);
}
else
{
   HandleError("Decode CMSG_INNER_CONTENT_TYPE_PARAM failed");
}
//-------------------------------------------------------------
// Allocate memory for the string.

if(pbInnerContentObjId = (BYTE *) malloc(cbInnerContentObjId))
{
    printf("%d bytes of memory allocated.\n",cbInnerContentObjId);
}
else
{
    HandleError("Decode inner content malloc operation failed.");
}
//-------------------------------------------------------------
// Get the inner content type.

if(CryptMsgGetParam(
           hMsg,                          // Handle to the message
           CMSG_INNER_CONTENT_TYPE_PARAM, // Parameter type
           0,                             // Index
           pbInnerContentObjId,           // Address for returned
                                          // information
           &cbInnerContentObjId))         // Size of the returned
                                          // information
{
    printf("The OID of the inner content type is retrieved. \n");
}
else
{
    HandleError("Decode CMSG_INNER_CONTENT_TYPE_PARAM #2 failed");
}
//--------------------------------------------------------------------
// Process according to the inner content type.

pszInnerContentObjId = (LPSTR) pbInnerContentObjId;

//--------------------------------------------------------------------
// Test for the enveloped data type.

if(strcmp(pszInnerContentObjId, szOID_RSA_envelopedData))
{
   printf("The inner content is RSA enveloped data. Continue. \n");
}
else
{
   HandleError("This program will only decode RSA enveloped data.");
}
//----------------------------------------------------------------
// Initialize the CMSG_CONTROL_DECRYPT_PARA structure.

memset(&DecryptPara, 0, sizeof(CMSG_CTRL_DECRYPT_PARA));
DecryptPara.cbSize = sizeof(CMSG_CTRL_DECRYPT_PARA);
DecryptPara.hCryptProv = hCryptProv; // Using handle opened in
                                     // "encode" code sect.
DecryptPara.dwKeySpec = AT_KEYEXCHANGE;
DecryptPara.dwRecipientIndex = 0;

//----------------------------------------------------------------
// Decrypt the enveloped message.

if(CryptMsgControl(
        hMsg,                 // Message handle
        0,                    // Flags
        CMSG_CTRL_DECRYPT,    // Control type
        &DecryptPara))        // Address of the parameters
{
     printf("CryptMsgControl worked. \n");
}
else
{
    printf("Decode decryption failed. \n");
}
//----------------------------------------------------------------
// Get the size of the content.

if(CryptMsgGetParam(
           hMsg,                   // Handle to the message
           CMSG_CONTENT_PARAM,     // Parameter type
           0,                      // Index
           NULL,                   // Address for returned
                                   // information
           &cbDecoded))            // Size of the returned
                                   // information
{
    printf("Size of the data to decode ->%d\n",cbDecoded);
}
else
{
    HandleError("Decode CMSG_CONTENT_PARAM failed");
}
//----------------------------------------------------------------
// Allocate memory.

if(pbDecoded = (BYTE *) malloc(cbDecoded))
{
     printf("%d bytes allocated for pbDecoded.\n",cbDecoded);
}
else
{
    HandleError("Decode memory allocation failed");
}
//----------------------------------------------------------------
// Get a pointer to the content.

if(CryptMsgGetParam(
          hMsg,                   // Handle to the message
          CMSG_CONTENT_PARAM,     // Parameter type
          0,                      // Index
          pbDecoded,              // Address for returned
                                  // information
          &cbDecoded))            // Size of the returned
                                  // information
{
    printf("Message decoded successfully. \n");
    printf("The message is %s.\n",(LPSTR) pbDecoded);
}
else
{
     HandleError("Decode CMSG_CONTENT_PARAM #2 failed");
}
//--------------------------------------------------------------------
// Clean up.

if(pbDecoded)
    free(pbDecoded);
if(pbEncodedBlob)
     free(pbEncodedBlob);
if(hMsg)
     CryptMsgClose(hMsg);
} // End of function DecodeEnvelopedMessage

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError


Alternate Code for Encoding an Enveloped Message

The following example code demonstrates an alternate process of encoding a signed message, using that signed message as the inner content for an enveloped message. The inner content is tested to determine its inner-content type in preparation for decoding.

This example program illustrates the following CryptoAPI functions:

  • CryptAcquireContext.
  • CertOpenSystemStore.
  • CryptMsgCalculateEncodedLength.
  • CryptMsgOpenToEncode.
  • CryptMsgUpdate.
  • CryptMsgGetParam.
  • CryptMsgOpenToDecode.
  • CertFindCertificateInStore.
  • CryptMsgClose.
  • CertCloseStore.
  • CryptReleaseContext.

This example code also uses the functions HandleError and GetSignerCert. C code for these functions is included with the sample.

Code for these and other auxiliary functions is also listed under General Purpose Functions.

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);

//--------------------------------------------------------------------
// This program uses the function GetSignerCert, declared here and
// defined after main.

PCCERT_CONTEXT GetSignerCert(
     HCERTSTORE hCertStore);

void main(void)
{
//--------------------------------------------------------------------
// Declare and initialize variables. This includes declaring and
// initializing a pointer to message content to be countersigned and
// and encoded. Usually, the message content will exist somewhere
// and a pointer to it is passed to the application.

BYTE* pbContent = (BYTE*)"The message to be countersigned.";
                               // The message
DWORD cbContent;               // Size of message
HCRYPTPROV hCryptProv;         // CSP handle
HCERTSTORE hStoreHandle;       // Store handle
PCCERT_CONTEXT pSignerCert;    // Signer certificate
DWORD HashAlgSize;
CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
CMSG_SIGNER_ENCODE_INFO SignerEncodeInfo;
CMSG_SIGNER_ENCODE_INFO SignerEncodeInfoArray[1];
CERT_BLOB SignerCertBlob;
CERT_BLOB SignerCertBlobArray[1];
CMSG_SIGNED_ENCODE_INFO SignedMsgEncodeInfo;
DWORD cbEncodedBlob;
BYTE* pbEncodedBlob;
HCRYPTMSG hMsg;
DWORD cbDecoded;
BYTE *pbDecoded;
PCCERT_CONTEXT pCntrSigCert;
CMSG_SIGNER_ENCODE_INFO CountersignerInfo;
CMSG_SIGNER_ENCODE_INFO CntrSignArray[1];
DWORD cbSignerInfo;
PBYTE pbSignerInfo;
DWORD cbCountersignerInfo;
PCRYPT_ATTRIBUTES pCountersignerInfo;

//--------------------------------------------------------------------
// Begin processing.

cbContent = strlen((char *) pbContent)+1;
            // One is added to include the final NULL character.
printf("Processing begins.\n");
printf("The length of the original message is %d.\n",cbContent);
printf("Example message:->%s\n", pbContent);

//--------------------------------------------------------------------
// Get a handle to a cryptographic provider.

if(CryptAcquireContext(
      &hCryptProv,        // Address for handle to be returned.
      NULL,               // Use the current user's logon name.
      NULL,               // Use the default provider.
      PROV_RSA_FULL,      // Provider type
      0))                 // Zero allows access to private keys.
{
   printf("The CSP has been opened.");
}
else
{
    HandleError("CryptAcquireContext failed");
}
//--------------------------------------------------------------------
// Open the MY system certificate store.

if(hStoreHandle = CertOpenStore(
     CERT_STORE_PROV_SYSTEM, // The system store will be a
                             // virtual store.
     0,                      // Encoding type not needed with
                             // this PROV.
     NULL,                   // Accept the default HCRYPTPROV.
     CERT_SYSTEM_STORE_CURRENT_USER,
                             // Set the system store location in the
                             // registry.
     L"MY"))                 // Other predefined system stores
                             // could have been used,
                             // including trust, CA, or root.
{
   printf("Opened the MY system store. \n");
}else
{
   HandleError( "Could not open the MY system store.");
}
//--------------------------------------------------------------------
// Get a pointer to a signer's signature certificate.

if(pSignerCert = GetSignerCert(hStoreHandle))
{
   printf("A signer certificate was found. \n");
}
else
{
   HandleError("Error getting signer certificate.");
}
//--------------------------------------------------------------------
// Initialize the algorithm identifier structure.

HashAlgSize = sizeof(HashAlgorithm);
memset(&HashAlgorithm, 0, HashAlgSize);  // Init. to zero.
HashAlgorithm.pszObjId = szOID_RSA_MD5;  // Then set the
                                         // necessary member.

//--------------------------------------------------------------------
// Initialize the CMSG_SIGNER_ENCODE_INFO structure.

memset(&SignerEncodeInfo, 0, sizeof(CMSG_SIGNER_ENCODE_INFO));
SignerEncodeInfo.cbSize = sizeof(CMSG_SIGNER_ENCODE_INFO);
SignerEncodeInfo.pCertInfo = pSignerCert->pCertInfo;
SignerEncodeInfo.hCryptProv = hCryptProv;
SignerEncodeInfo.dwKeySpec = AT_KEYEXCHANGE;
SignerEncodeInfo.HashAlgorithm = HashAlgorithm;
SignerEncodeInfo.pvHashAuxInfo = NULL;

//--------------------------------------------------------------------
// Initialize the first element of an array of signers.
// Note: Currently, there can be only one signer.

SignerEncodeInfoArray[0] = SignerEncodeInfo;

//--------------------------------------------------------------------
// Initialize the CMSG_SIGNED_ENCODE_INFO structure.

SignerCertBlob.cbData = pSignerCert->cbCertEncoded;
SignerCertBlob.pbData = pSignerCert->pbCertEncoded;

//--------------------------------------------------------------------
//  Initialize the first element of an array of signer BLOBs.
//  Note: In this program, there is only one signer BLOB used.

SignerCertBlobArray[0] = SignerCertBlob;
memset(&SignedMsgEncodeInfo, 0, sizeof(CMSG_SIGNED_ENCODE_INFO));
SignedMsgEncodeInfo.cbSize = sizeof(CMSG_SIGNED_ENCODE_INFO);
SignedMsgEncodeInfo.cSigners = 1;
SignedMsgEncodeInfo.rgSigners = SignerEncodeInfoArray;
SignedMsgEncodeInfo.cCertEncoded = 1;
SignedMsgEncodeInfo.rgCertEncoded = SignerCertBlobArray;
SignedMsgEncodeInfo.rgCrlEncoded = NULL;

//--------------------------------------------------------------------
// Get the size of the encoded message BLOB.

if(cbEncodedBlob = CryptMsgCalculateEncodedLength(
       MY_ENCODING_TYPE,     // Message encoding type
       0,                    // Flags
       CMSG_SIGNED,          // Message type
       &SignedMsgEncodeInfo, // Pointer to structure
       NULL,                 // Inner content OID
       cbContent))           // Size of content
{
   printf("The size for the encoded BLOB is %d.\n",cbEncodedBlob);
}
else
{
    HandleError("Getting cbEncodedBlob length failed.");
}
//--------------------------------------------------------------------
// Allocate memory for the encoded BLOB.

if(pbEncodedBlob = (BYTE *) malloc(cbEncodedBlob))
{
   printf("Memory has been allocated for the BLOB. \n");
}
else
{
   HandleError("Malloc operation failed.");
}
//--------------------------------------------------------------------
// Open a message to encode.

if(hMsg = CryptMsgOpenToEncode(
         MY_ENCODING_TYPE,      // Encoding type
         0,                     // Flags
         CMSG_SIGNED,           // Message type
         &SignedMsgEncodeInfo,  // Pointer to structure
         NULL,                  // Inner content OID
         NULL))                 // Stream information (not used)
{
   printf("The message to encode is open. \n");
}
else
{
   HandleError("OpenToEncode failed");
}
//-------------------------------------------------------------
// Update the message with the data.

if(CryptMsgUpdate(
      hMsg,       // Handle to the message
      pbContent,  // Pointer to the content
      cbContent,  // Size of the content
      TRUE))      // Last call
{
   printf("Message to encode has been updated. \n");
}
else
{
   HandleError("MsgUpdate failed");
}
//--------------------------------------------------------------------
// Get the resulting message.

if(CryptMsgGetParam(
        hMsg,               // Handle to the message
        CMSG_CONTENT_PARAM, // Parameter type
        0,                  // Index
        pbEncodedBlob,      // Pointer to the BLOB
        &cbEncodedBlob))    // Size of the BLOB
{
   printf("Message successfully signed. \n");
}
else
{
   HandleError("MsgGetParam failed.");
}
//--------------------------------------------------------------------
// pbEncodedBlob points to the encoded, signed content.
// Include any further processing here.

CryptMsgClose(hMsg); // The message is complete -- close the handle.

//--------------------------------------------------------------------
// Next, countersign the signed message.
// Assume that the message just created and that a pointer
// (pbEncodedBlob) to the message was sent to the intended
// recipient.
// The following code, from the recipient's point of view, adds a
// countersignature to the signed message.
//
// Before countersigning, the message must be decoded.

//--------------------------------------------------------------------
// Open a message for decoding.

if(hMsg = CryptMsgOpenToDecode(
       MY_ENCODING_TYPE,   // Encoding type
       0,                  // Flags
       0,                  // Message type (get from message)
       hCryptProv,         // Cryptographic provider
       NULL,               // Recipient information
       NULL))              // Stream information
{
   printf("The message for decoding has been opened. \n");
}
else
{
   HandleError("OpenToDecode failed.");
}
//--------------------------------------------------------------------
// Update the message with the data (encoded BLOB).
// In this example, pbEncodedBlob and cbEncodedBlob were
// created in the previous code.

if(CryptMsgUpdate(
   hMsg,            // Handle to the message
   pbEncodedBlob,   // Pointer to the encoded BLOB
   cbEncodedBlob,   // Size of the encoded BLOB
   TRUE))           // Last call
{
   printf("The message to be decoded has been updated. \n");
}
else
{
   HandleError("Decode MsgUpdate failed.");
}
//--------------------------------------------------------------------
// Get the size of the content.

if(CryptMsgGetParam(
      hMsg,                    // Handle to the message
      CMSG_CONTENT_PARAM,      // Parameter type
      0,                       // Index
      NULL,                    // Address for returned
                               // information
      &cbDecoded))             // Size of the returned
                               // information
{
   printf("The message to be decoded is %d bytes long. \n", cbDecoded);
}
else
{
   HandleError("Decode CMSG_CONTENT_PARAM failed");
}
//--------------------------------------------------------------------
// Allocate memory.

if(pbDecoded = (BYTE *) malloc(cbDecoded))
{
   printf("Memory has been allocated. \n");
}
else
{
   HandleError("Decode memory allocation failed");
}
//--------------------------------------------------------------------
// Get a pointer to the content.

if(CryptMsgGetParam(
      hMsg,                // Handle to the message
      CMSG_CONTENT_PARAM,  // Parameter type
      0,                   // Index
      pbDecoded,           // Address for returned information
      &cbDecoded))         // Size of the returned information
{
    printf("The successfully decoded message is =>%s\n",pbDecoded);
}
else
{
   HandleError("Decode CMSG_CONTENT_PARAM #2 failed.");
}
//--------------------------------------------------------------------
// Proceed with the countersigning.

//--------------------------------------------------------------------
// Initialize the CRYPT_ALGORITHM_IDENTIFIER structure. In this
// case, the initialization performed for signing the message in
// the previous code is used.

//--------------------------------------------------------------------
// Get the countersigner's certificate. A certificate with a subject
// name matching the string in parameter 5 must be in the MY store and
// must have its CERT_KEY_PROV_INFO_PROP_ID property set.

if(pCntrSigCert=CertFindCertificateInStore(
      hStoreHandle,
      MY_ENCODING_TYPE,            // Use X509_ASN_ENCODING.
      0,                           // No dwFlags needed.
      CERT_FIND_SUBJECT_STR,       // Find a certificate with a
                                   // subject that matches the string
                                   // in the next parameter.
      L"Full Test Cert",           // The Unicode string to be found
                                   // in a certificate's subject.
      NULL))                       // NULL for the first call to the
                                   // function. In all subsequent
                                   // calls, it is the last pointer
                                   // returned by the function.
{
  printf("The desired certificate was found. \n");
}
else
{
   HandleError("Could not find the countersigner's certificate.");
}
//--------------------------------------------------------------------
// Initialize the PCMSG_SIGNER_ENCODE_INFO structure.

memset(&CountersignerInfo, 0, sizeof(CMSG_SIGNER_ENCODE_INFO));
CountersignerInfo.cbSize = sizeof(CMSG_SIGNER_ENCODE_INFO);
CountersignerInfo.pCertInfo = pCntrSigCert->pCertInfo;
CountersignerInfo.hCryptProv = hCryptProv;
CountersignerInfo.dwKeySpec = AT_KEYEXCHANGE;
CountersignerInfo.HashAlgorithm = HashAlgorithm;

CntrSignArray[0] = CountersignerInfo;

//--------------------------------------------------------------------
// Countersign the message.

if(CryptMsgCountersign(
       hMsg,
       0,
       1,
       CntrSignArray))
{
    printf("Countersign succeeded. \n");
}
else
{
    HandleError("Countersign failed.");
}
//--------------------------------------------------------------------
// Get a pointer to the new, countersigned message BLOB.
// Get the size of memory required.

if(CryptMsgGetParam(
      hMsg,                  // Handle to the message
      CMSG_ENCODED_MESSAGE,  // Parameter type
      0,                     // Index
      NULL,                  // Address for returned information
      &cbEncodedBlob))       // Size of the returned information
{
   printf("The size for the encoded BLOB is %d.\n",cbEncodedBlob);
}
else
{
   HandleError("Sizing of cbSignerInfo failed.");
}
//--------------------------------------------------------------------
// Allocate memory.

if(pbEncodedBlob = (BYTE*) malloc(cbEncodedBlob))
{
   printf("%d bytes allocated .\n", cbEncodedBlob);
}
else
{
    HandleError("cbSignerInfo memory allocation failed");
}
//--------------------------------------------------------------------
// Get the new message encoded BLOB.

if(CryptMsgGetParam(
     hMsg,                   // Handle to the message
     CMSG_ENCODED_MESSAGE,   // Parameter type
     0,                      // Index
     pbEncodedBlob,          // Address for returned information
     &cbEncodedBlob))        // Size of the returned information
{
    printf("The message is complete. \n");
}
else
{
    HandleError("Getting pbEncodedBlob failed");
}
//-------------------------------------------------------------------
//  The message is complete -- close the handle.
CryptMsgClose(hMsg);

//--------------------------------------------------------------------
// Verify the countersignature.
// Assume that the countersigned message went back to the originator,
// where, again, it will be decoded.

//--------------------------------------------------------------------
// Before verifying the countersignature, the message must first
// be decoded.

//--------------------------------------------------------------------
// Open a message for decoding.

if(hMsg = CryptMsgOpenToDecode(
      MY_ENCODING_TYPE,    // Encoding type
      0,                   // Flags
      0,                   // Message type (get from message)
      hCryptProv,          // Cryptographic provider
      NULL,                // Recipient information
      NULL))               // Stream information
{
   printf("The message to decode has been opened. \n");
}
else
{
   HandleError("OpenToDecode failed.");
}
//--------------------------------------------------------------------
// Update the message with the encoded BLOB.
// In this example, pbEncodedBlob and cbEncodedBlob were
// initialized in the previous code.

if(CryptMsgUpdate(
      hMsg,            // Handle to the message
      pbEncodedBlob,   // Pointer to the encoded BLOB
      cbEncodedBlob,   // Size of the encoded BLOB
      TRUE))           // Last call
{
   printf("The message to decode has been updated. \n");
}
else
{
    HandleError("Updating of the verified countersignature message failed.");
}
//-------------------------------------------------------------
// Get a pointer to the CERT_INFO member of countersigner's
// certificate. In this case, the certificate retrieved in the
// previous code segment will be used (pCntrSigCert).

//--------------------------------------------------------------
// Retrieve the signer information from the message.
// Get the size of memory required.

if(CryptMsgGetParam(
      hMsg,                  // Handle to the message
      CMSG_ENCODED_SIGNER,   // Parameter type
      0,                     // Index
      NULL,                  // Address for returned information
      &cbSignerInfo))        // Size of the returned information
{
   printf("The size of the signer information has been retrieved .\n");
}
else
{
    HandleError("Sizing of cbSignerInfo failed.");
}
//--------------------------------------------------------------------
// Allocate memory.

if(pbSignerInfo = (BYTE*) malloc(cbSignerInfo))
{
   printf("%d bytes allocated for the signer information. \n", cbSignerInfo);
}
else
{
    HandleError("cbSignerInfo memory allocation failed");
}
//--------------------------------------------------------------------
// Get the message signer information.

if(CryptMsgGetParam(
      hMsg,                 // Handle to the message
      CMSG_ENCODED_SIGNER,  // Parameter type
      0,                    // Index
      pbSignerInfo,         // Address for returned information
      &cbSignerInfo))       // Size of the returned information
{
   printf("The signer information is retrieved. \n");
}
else
{
   HandleError("Getting pbSignerInfo failed.");
}
//--------------------------------------------------------------------
// Retrieve the countersigner information from the message.
// Get the size of memory required.

if(CryptMsgGetParam(
       hMsg,                         // Handle to the message
       CMSG_SIGNER_UNAUTH_ATTR_PARAM,// Parameter type
       0,                            // Index
       NULL,                         // Address for returned
                                     // information
       &cbCountersignerInfo))        // Size of returned
                                     // information
{
   printf("The length of the countersigner's information is retrieved. \n");
}
else
{
   HandleError("Sizing of cbCountersignerInfo failed.");
}
//--------------------------------------------------------------------
// Allocate memory.

if(pCountersignerInfo =
         (CRYPT_ATTRIBUTES*)malloc(cbCountersignerInfo))
{
   printf("%d bytes allocated. \n", cbCountersignerInfo);
}
else
{
    HandleError("pbCountersignInfo memory allocation failed.");
}
//--------------------------------------------------------------------
// Get the message SIGNER_INFO.

if(CryptMsgGetParam(
     hMsg,                           // Handle to the message
     CMSG_SIGNER_UNAUTH_ATTR_PARAM,  // Parameter type
     0,                              // Index
     pCountersignerInfo,             // Address for returned
                                     // information
     &cbCountersignerInfo))          // Size of the returned
                                     // information
{
   printf("Countersigner information retrieved. \n");
}
else
{
    HandleError("Getting pbCountersignerInfo failed.");
}
//--------------------------------------------------------------------
// Verify the countersignature.

if(CryptMsgVerifyCountersignatureEncoded(
     hCryptProv,
     MY_ENCODING_TYPE,
     pbSignerInfo,
     cbSignerInfo,
     pCountersignerInfo->rgAttr->rgValue->pbData,
     pCountersignerInfo->rgAttr->rgValue->cbData,
     pCntrSigCert->pCertInfo))
{
     printf("Verification of countersignature succeeded. \n");
}
else
{
     printf("Verification of countersignature failed. \n");
}
//--------------------------------------------------------------------
// Clean up.

free(pbEncodedBlob);
free(pbDecoded);
free(pbSignerInfo);
free(pCountersignerInfo);
CertCloseStore(
     hStoreHandle,
     CERT_CLOSE_STORE_FORCE_FLAG);
CryptMsgClose(hMsg);
CryptReleaseContext(hCryptProv,0);

} // End of main

//--------------------------------------------------------------------
//  Define function HandleError
void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr,"Error number %x.\n",GetLastError());
    fprintf(stderr,"Program terminating. \n");
    exit(1);
}

// GetSignerCert enumerates the certificates in a store and
// finds the first certificate that has a signature key. If a
// certificate is found, a pointer to the certificate is returned.

PCCERT_CONTEXT GetSignerCert(
        HCERTSTORE hCertStore)
//--------------------------------------------------------------------
//   Parameter passed in:
//      hCertStore, the handle of the store to be searched.

{
//--------------------------------------------------------------------
//   Declare and initialize local variables.

PCCERT_CONTEXT       pCertContext = NULL;
BOOL                 fMore = TRUE;
DWORD                dwSize = NULL;
CRYPT_KEY_PROV_INFO* pKeyInfo = NULL;
DWORD                PropId = CERT_KEY_PROV_INFO_PROP_ID;

//--------------------------------------------------------------------
//  Find certificates in the store until the end of the store
//  is reached or a certificate with an AT_SIGNATURE key is found.

while(fMore &&
  (pCertContext= CertFindCertificateInStore(
     hCertStore,           // Handle of the store to be searched.
     0,                    // Encoding type. Not used for this search.
     0,                    // dwFindFlags. Special find criteria.
                           // Not used in this search.
     CERT_FIND_PROPERTY,   // Find type. Determines the kind of search
                           // to be done. In this case, search for
                           // certificates that have a specific
                           // extended property.
     &PropId,              // pvFindPara. Gives the specific
                           // value searched for, here the identifier
                           // of an extended property.
     pCertContext)))       // pCertContext is NULL for the
                           // first call to the function.
                           // If the function were being called
                           // in a loop, after the first call,
                           // pCertContext would be the certificate
                           // returned by the previous call.
{
//-------------------------------------------------------------
// For simplicity, this code only searches
// for the first occurrence of an AT_SIGNATURE key.
// In many situations, a search would also look for a
// specific subject name as well as the key type.

//-------------------------------------------------------------
// Call CertGetCertificateContextProperty once to get the
// returned structure size.

   if(!(CertGetCertificateContextProperty(
                 pCertContext,
                 CERT_KEY_PROV_INFO_PROP_ID,
                 NULL,
                 &dwSize)))
   {
      HandleError("Error getting key property");
   }
//--------------------------------------------------------------
// Allocate memory for the returned structure.

   if(pKeyInfo)
        free(pKeyInfo);
   if(!(pKeyInfo = (CRYPT_KEY_PROV_INFO*)malloc(dwSize)))
   {
       HandleError("Error allocating memory for pKeyInfo");
   }
   //--------------------------------------------------------------
   // Get the key information structure.

   if(!(CertGetCertificateContextProperty(
       pCertContext,
       CERT_KEY_PROV_INFO_PROP_ID,
       pKeyInfo,
       &dwSize)))
   {
       HandleError("The second call to the function failed.");
   }
   //-------------------------------------------
   // Check the dwKeySpec member for a signature key.
   if(pKeyInfo->dwKeySpec == AT_SIGNATURE)
   {
        fMore  = FALSE;
    }
}  // End of while loop

if(pKeyInfo)
   free(pKeyInfo);
return (pCertContext);
}  // End of GetSignerCert


Example C Program: Encoding an Enveloped, Signed Message

This example program creates, signs, and envelopes a message.

This example program illustrates the following tasks and CryptoAPI functions:

  • Acquiring the handle of a CSP using CryptAcquireContext.
  • Opening a system store using CertOpenStore.
  • Finding a signer and recipient certificates using CertFindCertificateInStore.
  • Initializing appropriate data structures for signing an enveloped message.
  • Finding the length of the enveloped message using CryptMsgCalculateEncodedLength.
  • Creating and signs the message using CryptMsgOpenToEncode, CryptMsgUpdate, and CryptMsgGetParam.
  • Enveloping the signed and encoded message for a receiver using CryptMsgOpenToEncode, CryptMsgUpdate, and CryptMsgGetParam.

This example code will fail if a usable private key does not exist in the default key container. If the needed private key is not available, code using CryptAcquireCertificatePrivateKey, as demonstrated in the code sample Example C Program: Sending and Receiving a Signed and Encrypted Message, can be used.

This example code uses the function HandleError. The C code for this function is included with the sample. Code for this and other auxiliary functions is also listed under General Purpose Functions.

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);

void main(void)
{
//--------------------------------------------------------------------
// Declare and initialize variables.

BYTE* pbContent = (BYTE*) "Security is our only business.";
                                    // A byte pointer
DWORD cbContent = strlen((char *) pbContent)+1;
                                    // The size of the message
HCERTSTORE hStoreHandle;
HCRYPTPROV hCryptProv;
PCCERT_CONTEXT pSignerCert;         // Signer's certificate
PCCERT_CONTEXT pRecipCert;          // Receiver's certificate
LPWSTR pswzRecipientName = L"Hortense";
LPWSTR pswzCertSubject = L"Full Test Cert";
PCERT_INFO RecipCertArray[1];
DWORD ContentEncryptAlgSize;
CRYPT_ALGORITHM_IDENTIFIER ContentEncryptAlgorithm;
CMSG_ENVELOPED_ENCODE_INFO EnvelopedEncodeInfo;
DWORD cbEncodedBlob;
BYTE *pbEncodedBlob;
DWORD cbSignedBlob;
BYTE *pbSignedBlob;
HCRYPTMSG hMsg;
DWORD HashAlgSize;
CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
CMSG_SIGNER_ENCODE_INFO SignerEncodeInfo;
CERT_BLOB SignerCertBlob;
CERT_BLOB SignerCertBlobArray[1];
CMSG_SIGNER_ENCODE_INFO SignerEncodeInfoArray[1];
CMSG_SIGNED_ENCODE_INFO SignedMsgEncodeInfo;

//--------------------------------------------------------------------
//  Begin processing. Display the original message.

printf("The original message => %s\n",pbContent);

//--------------------------------------------------------------------
// Acquire a cryptographic provider.

if(CryptAcquireContext(
        &hCryptProv,      // Address for handle to be returned.
        NULL,             // Use the current user's logon name.
        NULL,             // Use the default provider.
        PROV_RSA_FULL,    // Provider type.
        0))               // Zero allows access to private keys.
{
    printf("Context CSP acquired. \n");
}
else
{
   if ( GetLastError() == NTE_BAD_KEYSET)
   {
        printf("A Usable private key was not found \n");
        printf("in the default key container. Either a \n");
        printf("private key must be generated in that container \n");
        printf("or CryptAquireCertificatePrivateKey can be used \n");
        printf("to gain access to the needed private key.");
   }
    HandleError("CryptAcquireContext failed.");
}
//--------------------------------------------------------------------
// Open the MY system certificate store.

if(hStoreHandle = CertOpenStore(
       CERT_STORE_PROV_SYSTEM,
       0,
       NULL,
       CERT_SYSTEM_STORE_CURRENT_USER,
       L"MY"))
{
    printf("The MY system store is open. \n");
}
else
{
    HandleError( "Error getting store handle.");
}
//--------------------------------------------------------------------
//   Get the signer's certificate. This certificate must be in the
//   MY store, and its private key must be available.

if(pSignerCert = CertFindCertificateInStore(
   hStoreHandle,
   MY_ENCODING_TYPE,
   0,
   CERT_FIND_SUBJECT_STR,
   pswzCertSubject,
   NULL))
{
    printf("Found certificate for %S.\n",pswzCertSubject);
}
else
{
    HandleError("Signer certificate not found.");
}
//--------------------------------------------------------------------
// Initialize the algorithm identifier structure.

HashAlgSize = sizeof(HashAlgorithm);
memset(&HashAlgorithm, 0, HashAlgSize);    // Init. to zero.
HashAlgorithm.pszObjId = szOID_RSA_MD5;    // Initialize the
                                           //   necessary member.
//--------------------------------------------------------------------
// Initialize the CMSG_SIGNER_ENCODE_INFO structure.

memset(&SignerEncodeInfo, 0, sizeof(CMSG_SIGNER_ENCODE_INFO));
SignerEncodeInfo.cbSize = sizeof(CMSG_SIGNER_ENCODE_INFO);
SignerEncodeInfo.pCertInfo = pSignerCert->pCertInfo;
SignerEncodeInfo.hCryptProv = hCryptProv;
SignerEncodeInfo.dwKeySpec = AT_KEYEXCHANGE;
SignerEncodeInfo.HashAlgorithm = HashAlgorithm;
SignerEncodeInfo.pvHashAuxInfo = NULL;

//--------------------------------------------------------------------
// Create an array of one.
// Note: The current program is set up for only a single signer.

SignerEncodeInfoArray[0] = SignerEncodeInfo;

//--------------------------------------------------------------------
// Initialize the CMSG_SIGNED_ENCODE_INFO structure.

SignerCertBlob.cbData = pSignerCert->cbCertEncoded;
SignerCertBlob.pbData = pSignerCert->pbCertEncoded;

//--------------------------------------------------------------------
// Initialize the array of one CertBlob.

SignerCertBlobArray[0] = SignerCertBlob;
memset(&SignedMsgEncodeInfo, 0, sizeof(CMSG_SIGNED_ENCODE_INFO));
SignedMsgEncodeInfo.cbSize = sizeof(CMSG_SIGNED_ENCODE_INFO);
SignedMsgEncodeInfo.cSigners = 1;
SignedMsgEncodeInfo.rgSigners = SignerEncodeInfoArray;
SignedMsgEncodeInfo.cCertEncoded = 1;
SignedMsgEncodeInfo.rgCertEncoded = SignerCertBlobArray;
SignedMsgEncodeInfo.rgCrlEncoded = NULL;

//--------------------------------------------------------------------
// Get the size of the encoded, signed message BLOB.

if(cbSignedBlob = CryptMsgCalculateEncodedLength(
    MY_ENCODING_TYPE,       // Message encoding type
    0,                      // Flags
    CMSG_SIGNED,            // Message type
    &SignedMsgEncodeInfo,   // Pointer to structure
    NULL,                   // Inner content OID
    cbContent))             // Size of content
{
    printf("%d, the length of data calculated. \n",cbSignedBlob);
}
else
{
   if ( GetLastError() == NTE_BAD_KEYSET)
   {
        printf("A Usable private key was not found \n");
        printf("in the default key container. Either a \n");
        printf("private key must be generated in that container \n");
        printf("or CryptAquireCertificatePRivateKey can be used \n");
        printf("to gain access to the needed private key.");
    }
    HandleError("Getting cbSignedBlob length failed.");
}
//--------------------------------------------------------------------
// Allocate memory for the encoded BLOB.

if(pbSignedBlob = (BYTE *) malloc(cbSignedBlob))
{
   printf("Memory has been allocated for the signed message. \n");
}
else
{
   HandleError("Memory allocation failed.");
}
//--------------------------------------------------------------------
// Open a message to encode.

if(hMsg = CryptMsgOpenToEncode(
    MY_ENCODING_TYPE,        // Encoding type
    0,                       // Flags
    CMSG_SIGNED,             // Message type
    &SignedMsgEncodeInfo,    // Pointer to structure
    NULL,                    // Inner content OID
    NULL))                   // Stream information (not used)
{
    printf("The message to be encoded has been opened. \n");
}
else
{
    HandleError("OpenToEncode failed.");
}
//--------------------------------------------------------------------
// Update the message with the data.

if(CryptMsgUpdate(
     hMsg,         // Handle to the message
     pbContent,    // Pointer to the content
     cbContent,    // Size of the content
     TRUE))        // Last call
{
    printf("Content has been added to the encoded message. \n");
}
else
{
    HandleError("MsgUpdate failed.");
}
//--------------------------------------------------------------------
// Get the resulting message.

if(CryptMsgGetParam(
    hMsg,                      // Handle to the message
    CMSG_CONTENT_PARAM,        // Parameter type
    0,                         // Index
    pbSignedBlob,              // Pointer to the BLOB
    &cbSignedBlob))            // Size of the BLOB
{
    printf("Message encoded successfully. \n");
}
else
{
    HandleError("MsgGetParam failed.");
}
//--------------------------------------------------------------------
// pbSignedBlob now points to the encoded, signed content.

//--------------------------------------------------------------------
// Get a pointer to the recipient certificate.
// For this program, the recipient's certificate must also be in the
// MY store. At this point, only the recipient's public key is needed.
// In order to open the enveloped message, however, the recipient's
// private key must also be available.

if(pRecipCert=CertFindCertificateInStore(
      hStoreHandle,
      MY_ENCODING_TYPE,            // Use X509_ASN_ENCODING.
      0,                           // No dwFlags needed.
      CERT_FIND_SUBJECT_STR,       // Find a certificate with a
                                   // subject that matches the string
                                   // in the next parameter.
      pswzRecipientName,           // The Unicode string to be found
                                   // in a certificate's subject.
      NULL))                       // NULL for the first call to the
                                   // function. In all subsequent
                                   // calls, it is the last pointer
                                   // returned by the function.
{
     printf("Certificate for %S found. \n", pswzRecipientName);
}
else
{
     HandleError("Could not find the countersigner's certificate.");
}
//--------------------------------------------------------------------
// Initialize the first element of the array of CERT_INFOs.
// In this example, there is only a single recipient.

RecipCertArray[0] = pRecipCert->pCertInfo;

//--------------------------------------------------------------------
// Initialize the symmetric-encryption algorithm identifier
// structure.

ContentEncryptAlgSize = sizeof(ContentEncryptAlgorithm);
memset(&ContentEncryptAlgorithm,
       0,
       ContentEncryptAlgSize);                    // Init. to zero.

//--------------------------------------------------------------------
// Initialize the necessary members. This particular OID does not
// need any parameters. Some OIDs, however, will require that
// the other members be initialized.

ContentEncryptAlgorithm.pszObjId = szOID_RSA_RC4;

//--------------------------------------------------------------------
// Initialize the CMSG_ENVELOPED_ENCODE_INFO structure.

memset(&EnvelopedEncodeInfo,
       0,
       sizeof(CMSG_ENVELOPED_ENCODE_INFO));
EnvelopedEncodeInfo.cbSize = sizeof(CMSG_ENVELOPED_ENCODE_INFO);
EnvelopedEncodeInfo.hCryptProv = hCryptProv;
EnvelopedEncodeInfo.ContentEncryptionAlgorithm =
                                        ContentEncryptAlgorithm;
EnvelopedEncodeInfo.pvEncryptionAuxInfo = NULL;
EnvelopedEncodeInfo.cRecipients = 1;
EnvelopedEncodeInfo.rgpRecipients = RecipCertArray;

//--------------------------------------------------------------------
// Get the size of the encoded message BLOB.

if(cbEncodedBlob = CryptMsgCalculateEncodedLength(
     MY_ENCODING_TYPE,        // Message encoding type
     0,                       // Flags
     CMSG_ENVELOPED,          // Message type
     &EnvelopedEncodeInfo,    // Pointer to structure
     szOID_RSA_signedData,    // Inner content OID
     cbSignedBlob))           // Size of content
{
    printf("Length of the encoded BLOB will be %d.\n",cbEncodedBlob);
}
else
{
    HandleError("Getting enveloped cbEncodedBlob length failed.");
}
//--------------------------------------------------------------------
// Allocate memory for the encoded BLOB.

if(pbEncodedBlob = (BYTE *) malloc(cbEncodedBlob))
{
    printf("Memory has been allocated for the BLOB. \n");
}
else
{
    HandleError("Enveloped malloc operation failed.");
}
//--------------------------------------------------------------------
// Open a message to encode.

if(hMsg = CryptMsgOpenToEncode(
     MY_ENCODING_TYPE,        // Encoding type
     0,                       // Flags
     CMSG_ENVELOPED,          // Message type
     &EnvelopedEncodeInfo,    // Pointer to structure
     szOID_RSA_signedData,    // Inner content OID
     NULL))                   // Stream information (not used)
{
    printf("The message to encode is open. \n");
}
else
{
    HandleError("Enveloped OpenToEncode failed.");
}
//--------------------------------------------------------------------
// Update the message with the data.

if(CryptMsgUpdate(
     hMsg,              // Handle to the message
     pbSignedBlob,      // Pointer to the signed data BLOB
     cbSignedBlob,      // Size of the data BLOB
     TRUE))             // Last call
{
    printf("The signed BLOB has been added to the message. \n");
}
else
{
    HandleError("Enveloped MsgUpdate failed.");
}
//--------------------------------------------------------------------
// Get the resulting message.

if(CryptMsgGetParam(
     hMsg,                  // Handle to the message
     CMSG_CONTENT_PARAM,    // Parameter type
     0,                     // Index
     pbEncodedBlob,         // Pointer to the enveloped,
                            //   signed data BLOB
     &cbEncodedBlob))       // Size of the BLOB
{
    printf("Enveloped message encoded successfully. \n");
}
else
{
    HandleError("Enveloped MsgGetParam failed.");
}
//--------------------------------------------------------------------
//  Clean up.

CertFreeCertificateContext(pRecipCert);
if(CertCloseStore(
     hStoreHandle,
     CERT_CLOSE_STORE_CHECK_FLAG))
{
  printf("The certificate store closed without a certificate left open. \n");
}
else
{
  printf("The store closed but a certificate was still open. \n");
}
if(hMsg)
   CryptMsgClose(hMsg);
if(hCryptProv)
   CryptReleaseContext(hCryptProv,0);
} // End of main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError


Countersigning

The following sections deal with countersigning messages and countersignature verification:

  • Countersigning a Message
  • Example C Program: Encoding and Decoding a Countersigned Message
  • Verifying a Countersignature
  • Creating, Signing, and Storing a CTL


Countersigning a Message

To countersign a signed message using CryptMsgCountersign

  1. Call CryptMsgOpenToDecode to get a handle to the signed message.
  2. Initialize a CMSG_SIGNER_ENCODE_INFO structure for the countersigner.
  3. Add the CMSG_SIGNER_ENCODE_INFO structure to an array of countersigners (only one countersigner is currently supported).
  4. Call CryptMsgCountersign to add the countersignature or countersignatures.

If all of the function calls succeed, the original message now has a countersignature included as an unauthenticated attribute.

To countersign a signed message using CryptMsgCountersignEncoded

  1. Call CryptMsgOpenToDecode to get a handle to the signed message.
  2. Call CryptMsgGetParam to retrieve the encoded signer information of the signed message.
  3. Initialize a CMSG_SIGNER_ENCODE_INFO structure for the countersigner.
  4. Add the CMSG_SIGNER_ENCODE_INFO structure to an array of countersigners (only one countersigner is currently supported).
  5. Call CryptMsgCountersignEncoded to create the encoded countersignature attribute.
  6. Call CryptMsgControl to add the countersignature attribute to the original message as an unauthenticated attribute.

If all of the function calls succeed, a countersignature attribute is added to the original message.


Example C Program: Encoding and Decoding a Countersigned Message

This example program demonstrates the encoding and decoding of a countersigned message.

This example code uses the function HandleError. The C code for this function is included with the sample. Code for this and other auxiliary functions is also listed under General Purpose Functions.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

//--------------------------------------------------------------------
//   Define the names of two certificate subjects.
//   To use this program, the definitions of SIGNER_NAME and
//   COUNTER_SIGNER_NAME must be changed to the names of
//   the subjects of certificates that have access to private keys.
//   These certificates must have either the
//   CERT_KEY_PROV_INFO_PROP_ID or CERT_KEY_CONTEXT_PROP_ID
//   property set for the contexts to provide access to private
//   signature keys.

#define SIGNER_NAME L"John"
#define COUNTER_SIGNER_NAME L"Zeke"

#define MAX_NAME 256

void HandleError(char *s);

void main(void)
{
//--------------------------------------------------------------------
// Declare and initialize variables. This includes declaring and
// initializing a pointer to message content to be countersigned and
// and encoded. Usually, the message content will exist somewhere
// and a pointer to it is passed to the application.

BYTE* pbContent = (BYTE*)"I must go back to where all messages start.";
                               // The message
DWORD cbContent;               // Size of message
HCRYPTPROV hCryptProv;         // CSP handle
HCERTSTORE hStoreHandle;       // Store handle
PCCERT_CONTEXT pSignerCert;    // Signer certificate
CMSG_SIGNER_ENCODE_INFO SignerEncodeInfo;
CMSG_SIGNER_ENCODE_INFO SignerEncodeInfoArray[1];
CERT_BLOB SignerCertBlob;
CERT_BLOB SignerCertBlobArray[1];
CMSG_SIGNED_ENCODE_INFO SignedMsgEncodeInfo;
DWORD cbEncodedBlob;
BYTE* pbEncodedBlob;
HCRYPTMSG hMsg;
DWORD cbDecoded;
BYTE *pbDecoded;
PCCERT_CONTEXT pCntrSigCert;
CMSG_SIGNER_ENCODE_INFO CountersignerInfo;
CMSG_SIGNER_ENCODE_INFO CntrSignArray[1];
DWORD cbSignerInfo;
PBYTE pbSignerInfo;
DWORD cbCountersignerInfo;
PCRYPT_ATTRIBUTES pCountersignerInfo;
char pszNameString[MAX_NAME];
CRYPT_VERIFY_MESSAGE_PARA VerifyParams;
BYTE  *pbDecodedMessageBlob;
DWORD  cbDecodedMessageBlob;

//--------------------------------------------------------------------
// Begin processing.

//--------------------------------------------------------------------
//  Initialize cbContent to the length of pbContent
//  including the terminal NULL character.

cbContent = strlen((char *) pbContent)+1;

printf("        The example message is :->\n");
printf("%s\n\n", pbContent);

//--------------------------------------------------------------------
// Get a handle to a cryptographic provider.

if(!(CryptAcquireContext(
      &hCryptProv,        // Address for handle to be returned.
      NULL,               // Use the current user's logon name.
      NULL,               // Use the default provider.
      PROV_RSA_FULL,      // Provider type
      0)))                // Zero allows access to private keys.
{
    HandleError("CryptAcquireContext failed");
}

//--------------------------------------------------------------------
// Open the MY system certificate store.

if(!(hStoreHandle = CertOpenStore(
     CERT_STORE_PROV_SYSTEM, // The system store will be a
                             // virtual store.
     0,                      // Encoding type not needed with
                             // this PROV.
     NULL,                   // Accept the default HCRYPTPROV.
     CERT_SYSTEM_STORE_CURRENT_USER,
                             // Set the system store location in the
                             // registry.
     L"MY")))                // Other predefined system stores
                             // could have been used,
                             // including trust, CA, or root.
{
   HandleError( "Could not open the MY system store.");
}

//--------------------------------------------------------------------
// Get a pointer to a signer's signature certificate.

if(pSignerCert = CertFindCertificateInStore(
     hStoreHandle,
     MY_ENCODING_TYPE,
     0,
     CERT_FIND_SUBJECT_STR,
     SIGNER_NAME,
     NULL))
{
//--------------------------------------------------------------------
//   A certificate was found. Get and print the name of the subject
//   of the certificate.

     if(CertGetNameString(
       pSignerCert ,
       CERT_NAME_SIMPLE_DISPLAY_TYPE,
       0,
       NULL,
       pszNameString,
       MAX_NAME) > 1)
     {
         printf("The message signer is  %s \n",pszNameString);
     }
     else
     {
        HandleError("Getting the name of the signer failed.\n");
     }
}
else
{
     HandleError("Cert not found.\n");
}

//--------------------------------------------------------------------
// Initialize the CMSG_SIGNER_ENCODE_INFO structure.

memset(&SignerEncodeInfo, 0, sizeof(CMSG_SIGNER_ENCODE_INFO));
SignerEncodeInfo.cbSize = sizeof(CMSG_SIGNER_ENCODE_INFO);
SignerEncodeInfo.pCertInfo = pSignerCert->pCertInfo;
SignerEncodeInfo.hCryptProv = hCryptProv;
SignerEncodeInfo.dwKeySpec = AT_KEYEXCHANGE;
SignerEncodeInfo.HashAlgorithm.pszObjId = szOID_RSA_MD5;
SignerEncodeInfo.pvHashAuxInfo = NULL;

//--------------------------------------------------------------------
// Initialize the first element of an array of signers.
// Note: Currently, there is only one signer.

SignerEncodeInfoArray[0] = SignerEncodeInfo;

//--------------------------------------------------------------------
// Initialize the CMSG_SIGNED_ENCODE_INFO structure.

SignerCertBlob.cbData = pSignerCert->cbCertEncoded;
SignerCertBlob.pbData = pSignerCert->pbCertEncoded;

//--------------------------------------------------------------------
//  Initialize the first element of an array of signer BLOBs.
//  Note: In this program, there is only one signer BLOB used.

SignerCertBlobArray[0] = SignerCertBlob;
memset(&SignedMsgEncodeInfo, 0, sizeof(CMSG_SIGNED_ENCODE_INFO));
SignedMsgEncodeInfo.cbSize = sizeof(CMSG_SIGNED_ENCODE_INFO);
SignedMsgEncodeInfo.cSigners = 1;
SignedMsgEncodeInfo.rgSigners = SignerEncodeInfoArray;
SignedMsgEncodeInfo.cCertEncoded = 1;
SignedMsgEncodeInfo.rgCertEncoded = SignerCertBlobArray;

//--------------------------------------------------------------------
// Get the size of the encoded message BLOB.

if(!(cbEncodedBlob = CryptMsgCalculateEncodedLength(
     MY_ENCODING_TYPE,     // Message encoding type
     0,                    // Flags
     CMSG_SIGNED,          // Message type
     &SignedMsgEncodeInfo, // Pointer to structure
     NULL,                 // Inner content OID
     cbContent)))          // Size of content
{
    HandleError("Getting cbEncodedBlob length failed.");
}

//--------------------------------------------------------------------
// Allocate memory for the encoded BLOB.

if(!(pbEncodedBlob = (BYTE *) malloc(cbEncodedBlob)))
{
   HandleError("Malloc operation failed.");
}

//--------------------------------------------------------------------
// Open a message to encode.

if(!(hMsg = CryptMsgOpenToEncode(
     MY_ENCODING_TYPE,      // Encoding type
     0,                     // Flags
     CMSG_SIGNED,           // Message type
     &SignedMsgEncodeInfo,  // Pointer to structure
     NULL,                  // Inner content OID
     NULL)))                // Stream information (not used)
{
   HandleError("OpenToEncode failed");
}

//-------------------------------------------------------------
// Update the message with the data.

if(!(CryptMsgUpdate(
      hMsg,       // Handle to the message
      pbContent,  // Pointer to the content
      cbContent,  // Size of the content
      TRUE)))     // Last call
{
   HandleError("MsgUpdate failed");
}

//--------------------------------------------------------------------
// Get the resulting message.

if(CryptMsgGetParam(
    hMsg,               // Handle to the message
    CMSG_CONTENT_PARAM, // Parameter type
    0,                  // Index
    pbEncodedBlob,      // Pointer to the BLOB
    &cbEncodedBlob))    // Size of the BLOB
{
   printf("Message successfully signed. \n");
}
else
{
   HandleError("MsgGetParam failed.");
}

//-------------------------------------------------------------------
// The message is signed and encoded.
// Close the message handle and the certificate store.

CryptMsgClose(hMsg);
CertCloseStore(
     hStoreHandle,
     CERT_CLOSE_STORE_FORCE_FLAG);

//--------------------------------------------------------------------
// Next, countersign the signed message.
// Assume that pbEncodedBlob, the message just created, was sent to
// an intended recipient.

// The following code, from the recipient's point of
// view,
//     1.  decodes the message
//     2.  verifies the signature on the message
//     3.  adds a countersignature to the signed message
//  The counter-signed message is returned to the original signer of //  the message where the counter-signature is verified.

//--------------------------------------------------------------------
// Open a message for decoding.

if(!(hMsg = CryptMsgOpenToDecode(
       MY_ENCODING_TYPE,   // Encoding type
       0,                  // Flags
       0,                  // Message type (get from message)
       NULL,               // Cryptographic provider
                           // Use NULL for the default provider.
       NULL,               // Recipient information
       NULL)))             // Stream information
{
   HandleError("OpenToDecode failed.");
}

//--------------------------------------------------------------------
// Update the message with the encoded BLOB.
// In this example, pbEncodedBlob and cbEncodedBlob were
// created in the previous code.

if(!(CryptMsgUpdate(
   hMsg,            // Handle to the message
   pbEncodedBlob,   // Pointer to the encoded BLOB
   cbEncodedBlob,   // Size of the encoded BLOB
   TRUE)))          // Last call
{
     HandleError("Decode MsgUpdate failed.");
}

//--------------------------------------------------------------------
// Get the size of the message.

if(CryptMsgGetParam(
      hMsg,                    // Handle to the message
      CMSG_CONTENT_PARAM,      // Parameter type
      0,                       // Index
      NULL,                    // Address for returned
                               // information
      &cbDecoded))             // Size of the returned
                               // information
{
   printf("The message to decoded is %d bytes long. \n", cbDecoded);
}
else
{
   HandleError("Decode CMSG_CONTENT_PARAM failed");
}

//--------------------------------------------------------------------
// Allocate memory.

if(!(pbDecoded = (BYTE *) malloc(cbDecoded)))
{
   HandleError("Decode memory allocation failed");
}

//--------------------------------------------------------------------
// Copy the message to the buffer.

if(CryptMsgGetParam(
      hMsg,                // Handle to the message
      CMSG_CONTENT_PARAM,  // Parameter type
      0,                   // Index
      pbDecoded,           // Address for returned information
      &cbDecoded))         // Size of the returned information
{
     printf("    The successfully decoded message is =>\n");
     printf("%s\n\n",pbDecoded);
}
else
{
     HandleError("Decode CMSG_CONTENT_PARAM #2 failed.");
}

//--------------------------------------------------------------------
//  Check the signature.
//  Initialize the VerifyParams data structure.

VerifyParams.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);
VerifyParams.dwMsgAndCertEncodingType = MY_ENCODING_TYPE;
VerifyParams.hCryptProv = 0;
VerifyParams.pfnGetSignerCertificate = NULL;
VerifyParams.pvGetArg = NULL;

if(!(CryptVerifyMessageSignature(
    &VerifyParams,        // Verify parameters.
    0,                    // Signer index.
    pbEncodedBlob,        // Pointer to signed BLOB.
    cbEncodedBlob,        // Size of signed BLOB.
    NULL,                 // Buffer for decoded message.
    &cbDecodedMessageBlob,// Size of buffer.
    NULL)))               // Pointer to signer certificate.
{
    printf("Getting the size of the verification message failed. \n");
}

if(!(pbDecodedMessageBlob = (BYTE *)(cbDecodedMessageBlob)))
    HandleError("Memory allocation failed.");

if(CryptVerifyMessageSignature(
    &VerifyParams,           // Verify parameters.
    0,                       // Signer index.
    pbEncodedBlob,           // Pointer to signed BLOB.
    cbEncodedBlob,           // Size of signed BLOB.
    pbDecodedMessageBlob,    // Buffer for decoded message.
    &cbDecodedMessageBlob,   // Size of buffer.
    NULL))                   // Pointer to signer certificate.
{
     printf("     The Signature verified message is -> \n");
     printf("%s \n\n",pbDecodedMessageBlob);
}
else
{
     HandleError("Verification message failed.");
}

//--------------------------------------------------------------------
// Proceed with the countersigning.
// First, open a certificate store.

if(!(hStoreHandle = CertOpenStore(
     CERT_STORE_PROV_SYSTEM,
     0,
     NULL,
     CERT_SYSTEM_STORE_CURRENT_USER,
     L"MY")))
{
   HandleError( "Could not open the MY system store.");
}

//--------------------------------------------------------------------
// Get the countersigner's certificate.

if(pCntrSigCert=CertFindCertificateInStore(
      hStoreHandle,
      MY_ENCODING_TYPE,
      0,
      CERT_FIND_SUBJECT_STR,
      COUNTER_SIGNER_NAME,
      NULL))
{
  if(CertGetNameString(
       pCntrSigCert ,
       CERT_NAME_SIMPLE_DISPLAY_TYPE,
       0,
       NULL,
       pszNameString,
       MAX_NAME) > 1)
  {
       printf("The counter signer is  %s \n",pszNameString);
  }
  else
  {
       HandleError("Getting the counter signer name failed.\n");
  }
}
else
{
   HandleError("Could not find the countersigner's certificate.");
}

//--------------------------------------------------------------------
// Initialize the CMSG_SIGNER_ENCODE_INFO structure.

memset(&CountersignerInfo, 0, sizeof(CMSG_SIGNER_ENCODE_INFO));
CountersignerInfo.cbSize = sizeof(CMSG_SIGNER_ENCODE_INFO);
CountersignerInfo.pCertInfo = pCntrSigCert->pCertInfo;
CountersignerInfo.hCryptProv = hCryptProv;
CountersignerInfo.dwKeySpec = AT_KEYEXCHANGE;
CountersignerInfo.HashAlgorithm.pszObjId = szOID_RSA_MD5;

CntrSignArray[0] = CountersignerInfo;

//--------------------------------------------------------------------
// Countersign the message.

if(CryptMsgCountersign(
    hMsg,
    0,
    1,
    CntrSignArray))
{
    printf("Countersign succeeded. \n");
}
else
{
    HandleError("Countersign failed.");
}

//--------------------------------------------------------------------
//  Check the message, its countersignature and
//  it signature.

//--------------------------------------------------------------------
// Get a pointer to the new, countersigned message BLOB.
// Get the size of memory required.

if(CryptMsgGetParam(
      hMsg,                  // Handle to the message
      CMSG_ENCODED_MESSAGE,  // Parameter type
      0,                     // Index
      NULL,                  // Address for returned information
      &cbEncodedBlob))       // Size of the returned information
{
   printf("The size for the encoded BLOB is %d.\n",cbEncodedBlob);
}
else
{
   HandleError("Sizing of cbSignerInfo failed.");
}

//--------------------------------------------------------------------
// Allocate memory.

if(pbEncodedBlob = (BYTE*) malloc(cbEncodedBlob))
{
   printf("%d bytes allocated .\n", cbEncodedBlob);
}
else
{
    HandleError("cbSignerInfo memory allocation failed");
}

//--------------------------------------------------------------------
// Get the new message encoded BLOB.

if(CryptMsgGetParam(
     hMsg,                   // Handle to the message
     CMSG_ENCODED_MESSAGE,   // Parameter type
     0,                      // Index
     pbEncodedBlob,          // Address for returned information
     &cbEncodedBlob))        // Size of the returned information
{
    printf("The message is complete. \n");
}
else
{
    HandleError("Getting pbEncodedBlob failed");
}

//-------------------------------------------------------------------
//  The message is complete -- close the handle.

CryptMsgClose(hMsg);

//--------------------------------------------------------------------
// Verify the countersignature.
// Assume that the countersigned message
// went back to the originator,
// where, again, it will be decoded.

//--------------------------------------------------------------------
// Before verifying the countersignature,
// the message must first
// be decoded.

//--------------------------------------------------------------------
// Open a message for decoding.

if(hMsg = CryptMsgOpenToDecode(
      MY_ENCODING_TYPE,    // Encoding type
      0,                   // Flags
      0,                   // Message type (get from message)
      0,                   // Cryptographic provider
      NULL,                // Recipient information
      NULL))               // Stream information
{
   printf("The message to decode has been opened. \n");
}
else
{
   HandleError("OpenToDecode failed.");
}

//--------------------------------------------------------------------
// Update the message with the encoded BLOB.
// In this example, pbEncodedBlob and cbEncodedBlob were
// initialized in the previous code.

if(CryptMsgUpdate(
      hMsg,            // Handle to the message
      pbEncodedBlob,   // Pointer to the encoded BLOB
      cbEncodedBlob,   // Size of the encoded BLOB
      TRUE))           // Last call
{
   printf("The message to decode has been updated. \n");
}
else
{
   HandleError("Updating the countersignature message failed.");
}

//-------------------------------------------------------------
// Get a pointer to the CERT_INFO member of
// countersigner's  certificate.
// In this case, the certificate retrieved in the
// previous code segment will be used (pCntrSigCert).

//--------------------------------------------------------------
// Retrieve the signer information from the message.
// Get the size of memory required.

if(CryptMsgGetParam(
      hMsg,                  // Handle to the message
      CMSG_ENCODED_SIGNER,   // Parameter type
      0,                     // Index
      NULL,                  // Address for returned information
      &cbSignerInfo))        // Size of the returned information
{
   printf("Signer information is %d bytes. \n", cbSignerInfo);
}
else
{
    HandleError("Sizing of cbSignerInfo failed.");
}
//--------------------------------------------------------------------
// Allocate memory.

if(!(pbSignerInfo = (BYTE*) malloc(cbSignerInfo)))
{
    HandleError("cbSignerInfo memory allocation failed");
}

//--------------------------------------------------------------------
// Get the message signer information.

if(!(CryptMsgGetParam(
      hMsg,                 // Handle to the message
      CMSG_ENCODED_SIGNER,  // Parameter type
      0,                    // Index
      pbSignerInfo,         // Address for returned information
      &cbSignerInfo)))      // Size of the returned information
{
   HandleError("Getting pbSignerInfo failed.");
}

//--------------------------------------------------------------------
// Retrieve the countersigner information from the message.
// Get the size of memory required.

if(CryptMsgGetParam(
       hMsg,                         // Handle to the message
       CMSG_SIGNER_UNAUTH_ATTR_PARAM,// Parameter type
       0,                            // Index
       NULL,                         // Address for returned
                                     // information
       &cbCountersignerInfo))        // Size of returned
                                     // information
{
   printf("Counter Signer information is %d bytes. \n", cbCountersignerInfo);
}
else
{
   HandleError("Sizing of cbCountersignerInfo failed.");
}

//--------------------------------------------------------------------
// Allocate memory.

if(!(pCountersignerInfo =
         (CRYPT_ATTRIBUTES*)malloc(cbCountersignerInfo)))
{
    HandleError("pbCountersignInfo memory allocation failed.");
}

//--------------------------------------------------------------------
// Get the message counter signer info.

if(!(CryptMsgGetParam(
     hMsg,                           // Handle to the message
     CMSG_SIGNER_UNAUTH_ATTR_PARAM,  // Parameter type
     0,                              // Index
     pCountersignerInfo,             // Address for returned
                                     // information
     &cbCountersignerInfo)))         // Size of the returned
                                     // information
{
    HandleError("Getting pbCountersignerInfo failed.");
}

//--------------------------------------------------------------------
//  Verify the countersignature.

if(CryptMsgVerifyCountersignatureEncoded(
     0,
     MY_ENCODING_TYPE,
     pbSignerInfo,
     cbSignerInfo,
     pCountersignerInfo->rgAttr->rgValue->pbData,
     pCountersignerInfo->rgAttr->rgValue->cbData,
     pCntrSigCert->pCertInfo))
{
     printf("Verification of countersignature succeeded. \n");
}
else
{
     printf("Verification of countersignature failed. \n");
     if(GetLastError() == NTE_BAD_SIGNATURE )
     {
           printf("Bad signature.\n");
     }
     else
     {
           printf("Other verification errror. \n");
     }
}

//--------------------------------------------------------------------
// Clean up.

free(pbEncodedBlob);
free(pbDecoded);
free(pbSignerInfo);
free(pCountersignerInfo);
CertCloseStore(
     hStoreHandle,
     CERT_CLOSE_STORE_FORCE_FLAG);
CryptMsgClose(hMsg);
CryptReleaseContext(hCryptProv,0);

} // End of main

//--------------------------------------------------------------------
//  Define function HandleError
void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr,"Error number %x.\n",GetLastError());
    fprintf(stderr,"Program terminating. \n");
    exit(1);
}


Verifying a Countersignature

To verify a countersignature

  1. Call CryptMsgOpenToDecode to get a handle to the signed message.
  2. Get a pointer to the countersigner's certificate (CERT_INFO).
  3. Call CryptMsgGetParam to retrieve the signer information from the message.
  4. Call CryptMsgGetParam to retrieve the countersignature from the message.
  5. Call CryptMsgVerifyCountersignatureEncoded to verify the countersignature.

If the CryptMsgVerifyCountersignatureEncoded function call succeeds, the countersignature is verified.


Creating, Signing, and Storing a CTL

The following procedures create a signed CTL and save it to a certificate store.

To create and sign a CTL

  1. Create an array of items to be stored in the CTL. In the case of trusted certificates, this must be the SHA1 or MD5 hashes of the trusted certificates.
  2. Initialize a CTL_INFO structure that includes the array of items just created.
  3. Initialize a CMSG_SIGNED_ENCODE_INFO structure.
  4. Call CryptMsgEncodeAndSignCTL. This function call returns a pointer to a signed, encoded CTL (in PKCS #7 format) that contains the list of items created in step 1.

To add a CTL to a certificate store

  1. Get a pointer to a signed and encoded CTL.
  2. Open the target certificate store with a call to CertOpenStore.
  3. Call CertAddEncodedCTLToStore.


Encrypting and Decrypting

The following sections deal with encrypting messages and files:

  • Manual Session Key Exchanges.
  • Encrypting a Message.
  • Decrypting a Message.
  • Example C Program: Using CryptEncryptMessage and CryptDecryptMessage.
  • Example C Program: Using CryptProtectData.
  • Example C Program: Encrypting a File.
  • Example C Program: Decrypting a File.


Manual Session Key Exchanges

Note The procedure described in this section assumes that the users (or CryptoAPI clients) already possess their own set of public/private key pairs and have also obtained each other's public keys.

The following illustration shows how to use this procedure to send an encrypted message.

This approach is vulnerable to at least one common form of attack. An eavesdropper can acquire copies of one or more encrypted messages and the encrypted keys. Then, at some later time, the eavesdropper can send one of these messages to the receiver and the receiver will have no way of knowing the message did not come directly from the original sender. This risk can be reduced by time-stamping all messages or by using serial numbers.

The easiest way to send encrypted messages to another user is to send the message encrypted with a random session key along with the session key encrypted with the receiver's key exchange public key. Following are the steps for sending an encrypted session key.

To send an encrypted session key

  1. Create a random session key by using the CryptGenKey function.
  2. Encrypt the message by using the session key. This procedure is discussed in Data Encryption and Decryption.
  3. Export the session key into a key BLOB with the CryptExportKey function, specifying that the key be encrypted with the destination user's key exchange public key.
  4. Send both the encrypted message and the encrypted key BLOB to the destination user.
  5. The destination user imports the key BLOB into his or her CSP by using the CryptImportKey function. This will automatically decrypt the session key, provided the destination user's key exchange public key was specified in step 3.
  6. The destination user can then decrypt the message by using the session key, following the procedure discussed in Data Encryption and Decryption.


Encrypting a Message

The following procedure describes steps to take to encrypt a message with the Base Cryptography Functions. To encrypt messages using PKCS #7 standards, see Low-Level Message Functions and Simplified Message Functions.

To encrypt a message

  1. Generate a session key by using the CryptGenKey function.

    Making this call generates a random key and returns a handle so the key can be used to encrypt and decrypt data. The encryption algorithm to use is also specified at this point. Because the CryptoAPI does not permit applications to use public-key algorithms to encrypt bulk data, specify a symmetric algorithm such as RC2 or RC4 with the CryptGenKey call.

  2. Alternatively, use the CryptDeriveKey function to transform a password into a key suitable for encryption.

    If an application needs to encrypt the message so that anyone with a specified password can decrypt the data, use CryptDeriveKey to transform the password into a key suitable for encryption. Note that, in this case, this function is called instead of the CryptGenKey function and the subsequent CryptExportKey calls are not needed.

  3. If necessary, set extra cryptographic properties of the key by using the CryptSetKeyParam function

    After the key has been generated, extra cryptographic properties of the key can be set with the CryptSetKeyParam function. For example, this function allows different sections of the file to be encrypted with different key salts and provides a way to change the cipher mode or initialization vector of the key. These parameters can be used to make the encryption conform with a particular data encryption standard.

  4. Encrypt the data in the file with the CryptEncrypt function.

    The CryptEncrypt function takes the session key that was generated in the previous step and encrypts a buffer of data. Note that as the data is encrypted, the data may be slightly expanded by the encryption algorithm. The application is responsible for remembering the length of the encrypted data so the proper length can later be specified for the CryptDecrypt function.

  5. Optionally, use the CryptExportKey function to allow the current user to decrypt the data in the future.

    To allow the current user to decrypt the data in the future, the CryptExportKey function is used to save the decryption key in an encrypted form (a key BLOB) that can only be decrypted with the user's private key. This function requires the user's key exchange public key for this purpose, which can be obtained by using the CryptGetUserKey function. The CryptExportKey function will return a key BLOB that must be stored by the application for use in decrypting the file.

Note If the application has certificates (or public keys) for other users, it can permit other users to decrypt the file by performing CryptExportKey calls for each user who should receive access. The returned key BLOBs must be stored by the application, as in step 5.

Creating an Encrypted Message

The simplified message functions make it easier to encrypt and decrypt data. The following illustration depicts the individual tasks that must be accomplished to encrypt a message. The steps are described in the list that follows the illustration.

To encrypt a message

  1. Get a pointer to the plaintext message.
  2. Generate a symmetric (session) key.
  3. Using the symmetric key and specified encryption algorithm, encrypt the message data.
  4. Open a certificate store.
  5. Get the recipient's certificate.
  6. Get the public key from the recipient's certificate.
  7. Using the recipient's public key, encrypt the symmetric key.
  8. Get the recipient's identifier from the recipient's certificate.
  9. Include the following in the digitally enveloped message: the data encryption algorithm, the encrypted data, the encrypted symmetric key, and the recipient identifier.


Decrypting a Message

In this section, the steps to decrypt an encrypted message are presented. The following illustration depicts the individual tasks that must be accomplished. The steps are described in the list following the illustration.

To decrypt an encrypted message

  1. Get a pointer to the digitally enveloped message.
  2. Open a certificate store.
  3. From the message, retrieve the recipient identifier (My ID).
  4. Use the recipient identifier to retrieve the certificate.
  5. Get the private key for the certificate.
  6. Use the private key to decrypt the symmetric (session) key.
  7. Retrieve the encryption algorithm from the message.
  8. Using the private key and encryption algorithm, decrypt the data.

CryptDecryptMessage does all of these tasks for decrypting a message; however, initialization of structures and other data is still necessary. The following illustration shows the relationship between those function parameters that point to structures or arrays and their initialized data.

To decrypt data using CryptDecryptMessage

  1. Get a pointer to the encrypted BLOB.
  2. Open a certificate store.
  3. Create a certificate store array.
  4. Initialize the CRYPT_DECRYPT_MESSAGE_PARA structure.
  5. Call CryptDecryptMessage to decrypt the data contained in the message.

Example C Program: Using CryptEncryptMessage and CryptDecryptMessage implements the procedure just presented. Comments show which code elements accomplish each step in the procedure. For details about the function, see CryptDecryptMessage, and for details about the data structure, see CRYPT_DECRYPT_MESSAGE_PARA.


Example C Program: Using CryptEncryptMessage and CryptDecryptMessage

CryptEncryptMessage is the only function call necessary to accomplish all of the tasks listed in Encrypting a Message. Initialization of data structures is necessary. The following illustration shows the relationship between those function parameters that point to structures or arrays and their initialized data. This sample program also decrypts the message using CryptDecryptMessage.

To encrypt data

  1. Get a pointer to the content to be encrypted.
  2. Get the size of the content to be encrypted.
  3. Get a handle to a cryptographic provider.
  4. Open a certificate store.
  5. Get the recipient certificate.
  6. Create the recipient certificate array.
  7. Initialize the CRYPT_ALGORITHM_IDENTIFIER structure.
  8. Initialize the CRYPT_ENCRYPT_MESSAGE_PARA structure.
  9. Call CryptEncryptMessage to encrypt the content and create a digitally enveloped message.

The following example code implements this procedure.

Comments relate code fragments to each step in the procedure. For details about the function, see CryptEncryptMessage. For details about the data structures, see CRYPT_ALGORITHM_IDENTIFIER and CRYPT_ENCRYPT_MESSAGE_PARA.

This example code uses the function HandleError, ByteToStr. The C code for this function is included with the sample. Code for this and other auxiliary functions is also listed under General Purpose Functions.

//--------------------------------------------------------------------
// Example code for encrypting data and creating an enveloped
// message using CryptEncryptMessage.

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);
//--------------------------------------------------------------------
// This program uses the function GetRecipientCert, declared here and
// defined after main.

PCCERT_CONTEXT GetRecipientCert(
     HCERTSTORE hCertStore);

//--------------------------------------------------------------------
// This program uses the function ByteToStr, declared here and
// defined after main. Code for ByteToStr can also be found as one
// of the general purpose functions.

void ByteToStr(
     DWORD cb,
     void* pv,
     LPSTR sz);

//--------------------------------------------------------------------
// This program uses the function DecryptMessage, declared here and
// defined after main.

BOOL DecryptMessage(
       BYTE *pbEncryptedBlob,
       DWORD cbEncryptedBlob,
       HCRYPTPROV hCryptProv,
       HCERTSTORE hStoreHandle);

void main()
{
//--------------------------------------------------------------------
// Declare and initialize variables. This includes getting a pointer
// to the message to be encrypted. This code creates a message
// and gets a pointer to it. In reality, the message content
// usually exists somewhere and a pointer to the message is passed to
// to the application.

BYTE* pbContent = (BYTE*) "Security is our business.";
                                            // The message
DWORD cbContent = strlen((char *)pbContent)+1;
                                            // Size of message
HCRYPTPROV hCryptProv;                      // CSP handle
HCERTSTORE hStoreHandle;
PCCERT_CONTEXT pRecipientCert;
PCCERT_CONTEXT RecipientCertArray[1];
DWORD EncryptAlgSize;
CRYPT_ALGORITHM_IDENTIFIER EncryptAlgorithm;
CRYPT_ENCRYPT_MESSAGE_PARA EncryptParams;
DWORD EncryptParamsSize;
BYTE*    pbEncryptedBlob;
DWORD    cbEncryptedBlob;

//--------------------------------------------------------------------
//  Begin processing.

printf("About to begin with the message %s.\n",pbContent);
printf("The message length is %d bytes. \n", cbContent);

//--------------------------------------------------------------------
// Get a handle to a cryptographic provider.

if(CryptAcquireContext(
            &hCryptProv,         // Address for handle to be returned.
            NULL,                // Use the current user's logon name.
            NULL,                // Use the default provider.
            PROV_RSA_FULL,       // Need to both encrypt and sign.
            NULL))               // No flags needed.
{
    printf("A CSP has been acquired. \n");
}
else
{
    HandleError("Cryptographic context could not be acquired.");
}
//--------------------------------------------------------------------
// Open a system certificate store.

if(hStoreHandle = CertOpenSystemStore(
     hCryptProv,
     "MY"))
{
    printf("The MY store is open. \n");
}
else
{
    HandleError( "Error getting store handle.");
}
//--------------------------------------------------------------------
// Get a pointer to the recipient's certificate.
// by calling GetRecipientCert.

if(pRecipientCert = GetRecipientCert(
     hStoreHandle))
{
    printf("A recipient's certificate has been acquired. \n");
}
else
{
    printf("No certificate with a CERT_KEY_CONTEXT_PROP_ID \N");
    printf("property and an AT_KEYEXCHANGE private key available. \n");
    printf("While the message could be encrypted, in this case, \n");
    printf("it could not be decrypted in this program. \n");
    printf("For more information, see the documentation for \n");
    printf("CrypteEncryptMessage and CryptDecryptMessage.\n\n");
    HandleError( "No Certificate with AT_KEYEXCHANGE key in store.");
}
//--------------------------------------------------------------------
// Create a RecipientCertArray.

RecipientCertArray[0] = pRecipientCert;

//--------------------------------------------------------------------
// Initialize the algorithm identifier structure.

EncryptAlgSize = sizeof(EncryptAlgorithm);

//--------------------------------------------------------------------
// Initialize the structure to zero.

memset(&EncryptAlgorithm, 0, EncryptAlgSize);

//--------------------------------------------------------------------
// Set the necessary member.

EncryptAlgorithm.pszObjId = szOID_RSA_RC4;

//--------------------------------------------------------------------
// Initialize the CRYPT_ENCRYPT_MESSAGE_PARA structure.

EncryptParamsSize = sizeof(EncryptParams);
memset(&EncryptParams, 0, EncryptParamsSize);
EncryptParams.cbSize =  EncryptParamsSize;
EncryptParams.dwMsgEncodingType = MY_ENCODING_TYPE;
EncryptParams.hCryptProv = hCryptProv;
EncryptParams.ContentEncryptionAlgorithm = EncryptAlgorithm;

//--------------------------------------------------------------------
// Call CryptEncryptMessage.

if(CryptEncryptMessage(
          &EncryptParams,
          1,
          RecipientCertArray,
          pbContent,
          cbContent,
          NULL,
          &cbEncryptedBlob))
{
    printf("The encrypted message is %d bytes. \n",cbEncryptedBlob);
}
else
{
    HandleError( "Getting EncrypBlob size failed.");
}
//--------------------------------------------------------------------
// Allocate memory for the returned BLOB.

if(pbEncryptedBlob = (BYTE*)malloc(cbEncryptedBlob))
{
    printf("Memory has been allocated for the encrypted BLOB. \n");
}
else
{
    HandleError("Memory allocation error while encrypting.");
}
//--------------------------------------------------------------------
// Call CryptEncryptMessage again to encrypt the content.

if(CryptEncryptMessage(
          &EncryptParams,
          1,
          RecipientCertArray,
          pbContent,
          cbContent,
          pbEncryptedBlob,
          &cbEncryptedBlob))
{
    printf( "Encryption succeeded. \n");
}
else
{
    HandleError("Encryption failed.");
}

//--------------------------------------------------------------------
// Call the function DecryptMessage, whose code follows main,
// to decrypt the message.

if(DecryptMessage(
     pbEncryptedBlob,
     cbEncryptedBlob,
     hCryptProv,
     hStoreHandle))
{
   printf("Decryption succeeded. \n");
}
else
{
   printf("Decryption failed. \n");
}
//--------------------------------------------------------------------
// Clean up memory.

CertFreeCertificateContext(pRecipientCert);
if(CertCloseStore(
          hStoreHandle,
          CERT_CLOSE_STORE_CHECK_FLAG))
{
    printf("The MY store was closed without incident. \n");
}
else
{
   printf("Store closed after encryption -- \n"
        "but not all certificates or CRLs were freed. \n");
}
if(hCryptProv)
{
    CryptReleaseContext(hCryptProv,0);
    printf("The CSP has been released. \n");
}
else
{
    printf("CSP was NULL. \n");
}
} // End of main

//--------------------------------------------------------------------
//  Define the function DecryptMessage.

BOOL DecryptMessage(
     BYTE *pbEncryptedBlob,
     DWORD cbEncryptedBlob,
     HCRYPTPROV hCryptProv,
     HCERTSTORE hStoreHandle)

//--------------------------------------------------------------------
// Example function for decrypting an encrypted message using
// CryptDecryptMessage. Its parameters are pbEncryptedBlob,
// an encrypted message; cbEncryptedBlob, the length of that
// message; hCryptProv, a CSP; and hStoreHandle, the handle
// of an open certificate store.

{
//--------------------------------------------------------------------
// Declare and initialize local variables.

DWORD cbDecryptedMessage;
char* EncryptedString = new char[(cbEncryptedBlob * 2) +1];
HCERTSTORE CertStoreArray[] = {hStoreHandle};
CRYPT_DECRYPT_MESSAGE_PARA  DecryptParams;
DWORD  DecryptParamsSize = sizeof(DecryptParams);
BYTE*  pbDecryptedMessage;
LPSTR  DecryptedString;
BOOL   fReturn = TRUE;

//--------------------------------------------------------------------
// Get a pointer to the encrypted message, pbEncryptedBlob,
// and its length, cbEncryptedBlob. In this sample program, these are
// passed as parameters along with a CSP and an open store handle.

//--------------------------------------------------------------------
// View the encrypted BLOB.
// Call a function, ByteToStr, to convert the byte BLOB to ASCII
// hexadecimal format.

ByteToStr(
    cbEncryptedBlob,
    pbEncryptedBlob,
    EncryptedString);

//--------------------------------------------------------------------
// Print the converted string.

printf("The encrypted string is: \n%s\n",EncryptedString);

//--------------------------------------------------------------------
//   In this example, the handle to the MY store was passed in as a
//   parameter.

//--------------------------------------------------------------------
//   Create a "CertStoreArray."
//   In this sample program, this step was done in the declaration
//   and initialization of local variables, because the store handle
//   was passed into the function as a parameter.

//--------------------------------------------------------------------
//   Initialize the CRYPT_DECRYPT_MESSAGE_PARA structure.

memset(&DecryptParams, 0, DecryptParamsSize);
DecryptParams.cbSize = DecryptParamsSize;
DecryptParams.dwMsgAndCertEncodingType = MY_ENCODING_TYPE;
DecryptParams.cCertStore = 1;
DecryptParams.rghCertStore = CertStoreArray;

//--------------------------------------------------------------------
//  Decrypt the message data.
//  Call CryptDecryptMessage to get the returned data size.

if(CryptDecryptMessage(
          &DecryptParams,
          pbEncryptedBlob,
          cbEncryptedBlob,
          NULL,
          &cbDecryptedMessage,
          NULL))
{
    printf("The size for the decrypted message is: %d.\n",cbDecryptedMessage);
}
else
{
    HandleError( "Error getting decrypted message size");
}
//--------------------------------------------------------------------
// Allocate memory for the returned decrypted data.

if(pbDecryptedMessage = (BYTE*)malloc(
       cbDecryptedMessage))
{
    printf("Memory has been allocated for the decrypted message. \n");
}
else
{
    HandleError("Memory allocation error while decrypting");
}
//--------------------------------------------------------------------
// Call CryptDecryptMessage to decrypt the data.

if(CryptDecryptMessage(
          &DecryptParams,
          pbEncryptedBlob,
          cbEncryptedBlob,
          pbDecryptedMessage,
          &cbDecryptedMessage,
          NULL))
{
    DecryptedString = (LPSTR) pbDecryptedMessage;
    printf("Message Decrypted Successfully. \n");
    printf("The decrypted string is: %s\n",DecryptedString);
}
else
{
    printf("Error decrypting the message \n");
    printf("Error code %x \n",GetLastError());
    fReturn = FALSE;
}

//--------------------------------------------------------------------
// Clean up memory.

free(pbEncryptedBlob);
free(pbDecryptedMessage);
return fReturn;
}  // End of DecryptMessage

//--------------------------------------------------------------------
// Define the function ByteToStr.

void ByteToStr(
     DWORD cb,
     void* pv,
     LPSTR sz)
//--------------------------------------------------------------------
// Parameters passed are:
//    pv is the array of BYTEs to be converted.
//    cb is the number of BYTEs in the array.
//    sz is a pointer to the string to be returned.

{
//--------------------------------------------------------------------
//  Declare and initialize local variables.

BYTE* pb = (BYTE*) pv; // Local pointer to a BYTE in the BYTE array
DWORD i;               // Local loop counter
int b;                 // Local variable

//--------------------------------------------------------------------
//  Begin processing loop.

for (i = 0; i<cb; i++)
{
   b = (*pb & 0xF0) >> 4;
   *sz++ = (b <= 9) ? b + '0' : (b - 10) + 'A';
   b = *pb & 0x0F;
   *sz++ = (b <= 9) ? b + '0' : (b - 10) + 'A';
   pb++;
}
*sz++ = 0;
} // End of ByteToStr

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError

//--------------------------------------------------------------------
// GetRecipientCert enumerates the certificates in a store and finds
// the first certificate that has an AT_EXCHANGE key. If a certificate
// is found, a pointer to that certificate is returned.

PCCERT_CONTEXT GetRecipientCert(
    HCERTSTORE hCertStore)
//--------------------------------------------------------------------
// Parameter passed in:
// hCertStore, the handle of the store to be searched.
{
//--------------------------------------------------------------------
// Declare and initialize local variables.

PCCERT_CONTEXT pCertContext = NULL;
BOOL fMore = TRUE;
DWORD dwSize = NULL;
CRYPT_KEY_PROV_INFO* pKeyInfo = NULL;
DWORD PropId = CERT_KEY_PROV_INFO_PROP_ID;

//--------------------------------------------------------------------
// Find certificates in the store until the end of the store
// is reached or a certificate with an AT_KEYEXCHANGE key is found.

while(fMore && (pCertContext= CertFindCertificateInStore(
   hCertStore, // Handle of the store to be searched.
   0,          // Encoding type. Not used for this search.
   0,          // dwFindFlags. Special find criteria.
               // Not used in this search.
   CERT_FIND_PROPERTY,
               // Find type. Determines the kind of search
               // to be done. In this case, search for
               // certificates that have a specific
               // extended property.
   &PropId,    // pvFindPara. Gives the specific
               // value searched for, here the identifier
               // of an extended property.
   pCertContext)))
               // pCertContext is NULL for the
               // first call to the function.
               // If the function were being called
               // in a loop, after the first call
               // pCertContext would be the pointer
               // returned by the previous call.
{
//-------------------------------------------------------------
// For simplicity, this code only searches
// for the first occurrence of an AT_KEYEXCHANGE key.
// In many situations, a search would also look for a
// specific subject name as well as the key type.

//-------------------------------------------------------------
// Call CertGetCertificateContextProperty once to get the
// returned structure size.

if(!(CertGetCertificateContextProperty(
     pCertContext,
     CERT_KEY_PROV_INFO_PROP_ID,
     NULL, &dwSize)))
{
     HandleError("Error getting key property.");
}

//--------------------------------------------------------------
// Allocate memory for the returned structure.

if(pKeyInfo)
    free(pKeyInfo);
if(!(pKeyInfo = (CRYPT_KEY_PROV_INFO*)malloc(dwSize)))
{
     HandleError("Error allocating memory for pKeyInfo.");
}

//--------------------------------------------------------------
// Get the key information structure.

if(!(CertGetCertificateContextProperty(
   pCertContext,
   CERT_KEY_PROV_INFO_PROP_ID,
   pKeyInfo,
   &dwSize)))
{
    HandleError("The second call to the function failed.");
}

//-------------------------------------------
// Check the dwKeySpec member for an exchange key.

if(pKeyInfo->dwKeySpec == AT_KEYEXCHANGE)
{
    fMore = FALSE; }
}    // End of while loop

if(pKeyInfo)
      free(pKeyInfo);
return (pCertContext);
} // End of GetRecipientCert


Example C Program: Using CryptProtectData

The following code sample encrypts and decrypts a data BLOB using CryptProtectData and CryptUnprotectData. Both of these functions require Microsoft® Windows® 2000 or later.

This example program illustrates the following tasks and CryptoAPI functions:

  • Initializing a CRYPTPROTECT_PROMPTSTRUCT data structure.
  • Using CryptProtectData to encrypt a data BLOB.
  • Using CryptUnprotectData to decrypt the data.
  • Using LocalFree to release allocated memory.

This example code uses the function HandleError. The C code for this function is included with the sample. Code for this and other auxiliary functions is also listed under General Purpose Functions.

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);

void main()
{

// Encrypt data from DATA_BLOB DataIn to DATA_BLOB DataOut.
// Then decrypt to DATA_BLOB DataVerify.

//--------------------------------------------------------------------
// Declare and initialize variables.

DATA_BLOB DataIn;
DATA_BLOB DataOut;
DATA_BLOB DataVerify;
BYTE *pbDataInput =(BYTE *)"Hello world of data protection.";
DWORD cbDataInput = strlen((char *)pbDataInput)+1;
DataIn.pbData = pbDataInput;
DataIn.cbData = cbDataInput;
CRYPTPROTECT_PROMPTSTRUCT PromptStruct;
LPWSTR pDescrOut = (LPWSTR)0xbaadf00d ; // NULL;

//--------------------------------------------------------------------
//  Begin processing.

printf("The data to be encrypted is: %s\n",pbDataInput);

//--------------------------------------------------------------------
//  Initialize PromptStruct.

ZeroMemory(&PromptStruct, sizeof(PromptStruct));
PromptStruct.cbSize = sizeof(PromptStruct);
PromptStruct.dwPromptFlags = CRYPTPROTECT_PROMPT_ON_PROTECT;
PromptStruct.szPrompt = L"This is a user prompt.";

//--------------------------------------------------------------------
//  Begin protect phase.

if(CryptProtectData(
     &DataIn,
     L"This is the description string.", // A description sting.
     NULL,                               // Optional entropy not used.
     NULL,                               // Reserved.
     &PromptStruct,                      // Pass a PromptStruct.
     0,
     &DataOut))
{
     printf("The encryption phase worked. \n");
}
else
{
    HandleError("Encryption error!");
}
//-----------------------------------------------------------------
//   Begin unprotect phase.

if (CryptUnprotectData(
        &DataOut,
        &pDescrOut,
        NULL,                 // Optional entropy
        NULL,                 // Reserved
        &PromptStruct,        // Optional PromptStruct
        0,
        &DataVerify))
{
     printf("The decrypted data is: %s\n", DataVerify.pbData);
     printf("The description of the data was: %S\n",pDescrOut);
}
else
{
    HandleError("Decryption error!");
}
//-------------------------------------------------------------------
// At this point, memcmp could be used to compare DataIn.pbData and
// DataVerify.pbDate for equality. If the two functions worked
// correctly, the two byte strings are identical.

//-------------------------------------------------------------------
//  Clean up.

LocalFree(pDescrOut);
LocalFree(DataOut.pbData);
LocalFree(DataVerify.pbData);
} // End of main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError


Example C Program: Encrypting a File

The following code sample encrypts a data file. The program interactively requests the name of the file containing plaintext to be encrypted and the name of a file where the encrypted data is to be written.

The program asks the user to supply the name of an input file and an output file. It also asks if a password is to be used to create the encryption session key. If a password is used in the encryption of the data, the same password must be used in the program that decrypts the file. For more information, see Example C Program: Decrypting a File.

Due to changing export control restrictions, the default CSP and default key length may change between operating system releases. It is important that both the encryption and decryption use the same CSP and that the key length be explicitly set to ensure interoperability on different operating system platforms.

This example code uses the function HandleError. The C code for this function is included with the sample. Code for this and other auxiliary functions is also listed under General Purpose Functions.

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the following #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
#define KEYLENGTH  0x00800000
void HandleError(char *s);

//--------------------------------------------------------------------
//  These additional #define statements are required.
#define ENCRYPT_ALGORITHM CALG_RC4
#define ENCRYPT_BLOCK_SIZE 8

//   Declare the function EncryptFile. The function definition
//   follows main.

BOOL EncryptFile(
     PCHAR szSource,
     PCHAR szDestination,
     PCHAR szPassword);

//--------------------------------------------------------------------
//   Begin main.

void main(void)
{
    PCHAR szSource;
    PCHAR szDestination;
    PCHAR szPassword;
    char  response;

if(!(szSource=(char *)malloc(100)))
    HandleError("Memory allocation failed.");
if(!(szDestination=(char *)malloc(100)))
    HandleError("Memory allocation failed.");
if(!(szPassword=(char *)malloc(100)))
    HandleError("Memory allocation failed.");

printf("Encrypt a file. \n\n");
printf("Enter the name of the file to be encrypted: ");
scanf("%s",szSource);
printf("Enter the name of the output file: ");
scanf("%s",szDestination);
printf("Use a password to encrypt this file? ( y/n ) ");
getchar();
scanf("%c",&response);
if(response == 'y')
{
    printf("Enter the password:");
    scanf("%s",szPassword);
}
else
{
    printf("The key will be generated without using a password. \n");
    free(szPassword);
    szPassword = NULL;
}

//--------------------------------------------------------------------
// Call EncryptFile to do the actual encryption.

if(EncryptFile(szSource, szDestination, szPassword))
{
       printf("Encryption of the file %s was a success. \n", szSource);
       printf("The encrypted data is in file %s.\n",szDestination);
}
else
{
      HandleError("Error encrypting file!");
}
} // End of main

//--------------------------------------------------------------------
//   Code for the function EncryptFile called by main.

static BOOL EncryptFile(
        PCHAR szSource,
        PCHAR szDestination,
        PCHAR szPassword)
//--------------------------------------------------------------------
//   Parameters passed are:
//     szSource, the name of the input, a plaintext file.
//     szDestination, the name of the output, an encrypted file to be
//         created.
//     szPassword, either NULL if a password is not to be used or the
//          string that is the password.
{
//--------------------------------------------------------------------
//   Declare and initialize local variables.

FILE *hSource;
FILE *hDestination;

HCRYPTPROV hCryptProv;
HCRYPTKEY hKey;
HCRYPTKEY hXchgKey;
HCRYPTHASH hHash;

PBYTE pbKeyBlob;
DWORD dwKeyBlobLen;

PBYTE pbBuffer;
DWORD dwBlockLen;
DWORD dwBufferLen;
DWORD dwCount;

//--------------------------------------------------------------------
// Open source file.

if(hSource = fopen(szSource,"rb"))
{
   printf("The source plaintext file, %s, is open. \n", szSource);
}
else
{
   HandleError("Error opening source plaintext file!");
}
//--------------------------------------------------------------------
// Open destination file.

if(hDestination = fopen(szDestination,"wb"))
{
     printf("Destination file %s is open. \n", szDestination);
}
else
{
    HandleError("Error opening destination ciphertext file!");
}
// Get handle to the default provider.
if(CryptAcquireContext(
      &hCryptProv,
      NULL,
      MS_ENHANCED_PROV,
      PROV_RSA_FULL,
      0))
{
   printf("A cryptographic provider has been acquired. \n");
}
else
{
   HandleError("Error during CryptAcquireContext!");
}
//--------------------------------------------------------------------
//   Create the session key.

if(!szPassword )
{
     //---------------------------------------------------------------
     // No password was passed.
     // Encrypt the file with a random session key and write the key
     // to a file.

     //---------------------------------------------------------------
     // Create a random session key.

     if(CryptGenKey(
          hCryptProv,
          ENCRYPT_ALGORITHM,
          KEYLENGTH | CRYPT_EXPORTABLE,
          &hKey))
      {
          printf("A session key has been created. \n");
      }
      else
      {
          HandleError("Error during CryptGenKey. \n");
      }
     //---------------------------------------------------------------
     // Get handle to the encrypter's exchange public key.

     if(CryptGetUserKey(
           hCryptProv,
           AT_KEYEXCHANGE,
           &hXchgKey))
      {
            printf("The user public key has been retrieved. \n");
       }
       else
       {
             HandleError("User public key is not available \
                and may not exist.");
       }
     //---------------------------------------------------------------
     // Determine size of the key BLOB, and allocate memory.

     if(CryptExportKey(
           hKey,
           hXchgKey,
           SIMPLEBLOB,
           0,
           NULL,
           &dwKeyBlobLen))
      {
           printf("The key BLOB is %d bytes long. \n",dwKeyBlobLen);
       }
       else
       {
            HandleError("Error computing BLOB length! \n");
       }
       if(pbKeyBlob =(BYTE *)malloc(dwKeyBlobLen))
       {
          printf("Memory is allocated for the key BLOB. \n");
       }
       else
       {
          HandleError("Out of memory. \n");
       }
     //---------------------------------------------------------------
     // Encrypt and export session key into a simple key BLOB.

     if(CryptExportKey(
          hKey,
          hXchgKey,
          SIMPLEBLOB,
          0,
          pbKeyBlob,
          &dwKeyBlobLen))
       {
           printf("The key has been exported. \n");
       }
       else
       {
           HandleError("Error during CryptExportKey!\n");
       }
     //---------------------------------------------------------------
     // Release key exchange key handle.
     CryptDestroyKey(hXchgKey);
     hXchgKey = 0;

     //---------------------------------------------------------------
     // Write size of key BLOB to destination file.

     fwrite(&dwKeyBlobLen, sizeof(DWORD), 1, hDestination);
     if(ferror(hDestination))
     {
         HandleError("Error writing header.");
     }
     else
     {
         printf("A file header has been written. \n");
     }
     //--------------------------------------------------------------
     // Write key BLOB to destination file.

     fwrite(pbKeyBlob, 1, dwKeyBlobLen, hDestination);
     if(ferror(hDestination))
     {
        HandleError("Error writing header");
     }
     else
     {
        printf("The key BLOB has been written to the file. \n");
     }
}
else
{
//--------------------------------------------------------------------
// The file will be encrypted with a session key derived from a
// password.
// The session key will be recreated when the file is decrypted
// only if the password used to create the key is available.

//--------------------------------------------------------------------
// Create a hash object.

if(CryptCreateHash(
       hCryptProv,
       CALG_MD5,
       0,
       0,
       &hHash))
    {
        printf("A hash object has been created. \n");
    }
    else
    {
         HandleError("Error during CryptCreateHash!\n");
    }
//--------------------------------------------------------------------
// Hash the password.

if(CryptHashData(
       hHash,
       (BYTE *)szPassword,
       strlen(szPassword),
       0))
 {
    printf("The password has been added to the hash. \n");
 }
 else
 {
    HandleError("Error during CryptHashData. \n");
 }
//--------------------------------------------------------------------
// Derive a session key from the hash object.

if(CryptDeriveKey(
       hCryptProv,
       ENCRYPT_ALGORITHM,
       hHash,
       KEYLENGTH,
       &hKey))
 {
   printf("An encryption key is derived from the password hash. \n");
 }
 else
 {
   HandleError("Error during CryptDeriveKey!\n");
 }
//--------------------------------------------------------------------
// Destroy the hash object.

CryptDestroyHash(hHash);
hHash = 0;
}
//--------------------------------------------------------------------
//  The session key is now ready. If it is not a key derived from a
//  password, the session key encrypted with the encrypter's private
//  key has been written to the destination file.

//--------------------------------------------------------------------
// Determine number of bytes to encrypt at a time.
// This must be a multiple of ENCRYPT_BLOCK_SIZE.
// ENCRYPT_BLOCK_SIZE is set by a #define statement.

dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;

//--------------------------------------------------------------------
// Determine the block size. If a block cipher is used,
// it must have room for an extra block.

if(ENCRYPT_BLOCK_SIZE > 1)
    dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE;
else
    dwBufferLen = dwBlockLen;

//--------------------------------------------------------------------
// Allocate memory.
if(pbBuffer = (BYTE *)malloc(dwBufferLen))
{
    printf("Memory has been allocated for the buffer. \n");
}
else
{
    HandleError("Out of memory. \n");
}
//--------------------------------------------------------------------
// In a do loop, encrypt the source file and write to the source file.

do
{

//--------------------------------------------------------------------
// Read up to dwBlockLen bytes from the source file.
dwCount = fread(pbBuffer, 1, dwBlockLen, hSource);
if(ferror(hSource))
{
    HandleError("Error reading plaintext!\n");
}

//--------------------------------------------------------------------
// Encrypt data.
if(!CryptEncrypt(
     hKey,
     0,
     feof(hSource),
     0,
     pbBuffer,
     &dwCount,
     dwBufferLen))
{
   HandleError("Error during CryptEncrypt. \n");
}

//--------------------------------------------------------------------
// Write data to the destination file.

fwrite(pbBuffer, 1, dwCount, hDestination);
if(ferror(hDestination))
{
    HandleError("Error writing ciphertext.");
}

}
while(!feof(hSource));
//--------------------------------------------------------------------
//  End the do loop when the last block of the source file has been
//  read, encrypted, and written to the destination file.

//--------------------------------------------------------------------
// Close files.

if(hSource)
    fclose(hSource);
if(hDestination)
    fclose(hDestination);

//--------------------------------------------------------------------
// Free memory.

if(pbBuffer)
     free(pbBuffer);

//--------------------------------------------------------------------
// Destroy session key.

if(hKey)
    CryptDestroyKey(hKey);

//--------------------------------------------------------------------
// Release key exchange key handle.

if(hXchgKey)
    CryptDestroyKey(hXchgKey);

//--------------------------------------------------------------------
// Destroy hash object.

if(hHash)
    CryptDestroyHash(hHash);

//--------------------------------------------------------------------
// Release provider handle.

if(hCryptProv)
    CryptReleaseContext(hCryptProv, 0);
return(TRUE);
} // End of Encryptfile

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError


Example C Program: Decrypting a File

The following code sample demonstrates the decryption of a file. The program asks the user for the name of an encrypted file and the name of a file where the decrypted data will be written. The file with the encrypted data must exist. The program creates or overwrite an output file.

The program also requests a string used as a password. If a password was used to create the encryption session key, that same password must be entered to create the decryption session key. For more information, see Example C Program: Encrypting a File.

Due to changing export control restrictions, the default CSP and default key length may change between operating system releases. It is important that both the encryption and decryption use the same CSP and that the key length be explicitly set to ensure interoperability on different operating system platforms.

This example code uses the function HandleError. The C code for this function is included with the sample. Code for this and other auxiliary functions is also listed under General Purpose Functions.

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
#define KEYLENGTH  0x00800000
void HandleError(char *s);

//--------------------------------------------------------------------
//   The following #define statements are also required.

#define ENCRYPT_ALGORITHM CALG_RC4
#define ENCRYPT_BLOCK_SIZE 8

//--------------------------------------------------------------------
//    Declare the function DecryptFile. Code for the function follows
//    main.

BOOL DecryptFile(
     PCHAR szSource,
     PCHAR szDestination,
     PCHAR szPassword);

void main(void)
{
//--------------------------------------------------------------------
//    Declare and initialize variables.

PCHAR szSource;
PCHAR szDestination;
PCHAR szPassword;
char  response;

if(!(szSource=(char *)malloc(100)))
    HandleError("Memory allocation failed.");
if(!(szDestination=(char *)malloc(100)))
    HandleError("Memory allocation failed.");
if(!(szPassword=(char *)malloc(100)))
    HandleError("Memory allocation failed.");

printf("Decrypt a file. \n\n");
printf("Enter the name of the file to be decrypted: ");
scanf("%s",szSource);
printf("Enter the name of the output file: ");
scanf("%s",szDestination);
printf("Was a password used to encrypt this file? ( y/n ) ");
getchar();
scanf("%c",&response);
if(response == 'y')
{
    printf("Enter the password:");
    scanf("%s",szPassword);
}
else
{
    printf("The key will be generated without using a password. \n");
    free(szPassword);
    szPassword = NULL;
}
if(!DecryptFile(szSource, szDestination, szPassword))
{
    printf("\nError decrypting file. \n");
}
else
{
    printf("\nDecryption of file %s succeeded. \n", szSource);
    printf("The decrypted file is %s .\n",szDestination);
}
} // End of main

//--------------------------------------------------------------------
//    Define the function Decryptfile.

static BOOL DecryptFile(
     PCHAR szSource,
     PCHAR szDestination,
     PCHAR szPassword)
{
//--------------------------------------------------------------------
//   Declare and initialize local variables.

FILE *hSource;
FILE *hDestination;

HCRYPTPROV hCryptProv;
HCRYPTKEY hKey;
HCRYPTHASH hHash;

PBYTE pbKeyBlob = NULL;
DWORD dwKeyBlobLen;

PBYTE pbBuffer;
DWORD dwBlockLen;
DWORD dwBufferLen;
DWORD dwCount;

BOOL status = FALSE;

//--------------------------------------------------------------------
// Open source file.
if(!(hSource = fopen(szSource,"rb")))
{
   HandleError("Error opening ciphertext file!");
}
//--------------------------------------------------------------------
// Open destination file.

if(!(hDestination = fopen(szDestination,"wb")))
{
    HandleError("Error opening plaintext file!");
}
//--------------------------------------------------------------------
// Get a handle to the default provider.
if(!CryptAcquireContext(
      &hCryptProv,
      NULL,
      MS_ENHANCED_PROV,
      PROV_RSA_FULL,
      0))
{
   HandleError("Error during CryptAcquireContext!");
}
//--------------------------------------------------------------------
//  Check for existence of a password.

if(!szPassword)
{
//--------------------------------------------------------------------
// Decrypt the file with the saved session key.

// Read key BLOB length from source file, and allocate memory.
fread(&dwKeyBlobLen, sizeof(DWORD), 1, hSource);
if(ferror(hSource) || feof(hSource))
{
    HandleError("Error reading file header!");
}
if(!(pbKeyBlob = (BYTE *)malloc(dwKeyBlobLen)))
{
    HandleError("Memory allocation error.");
}
//--------------------------------------------------------------------
// Read key BLOB from source file.

fread(pbKeyBlob, 1, dwKeyBlobLen, hSource);
if(ferror(hSource) || feof(hSource))
{
    HandleError("Error reading file header!\n");
}
//--------------------------------------------------------------------
// Import key BLOB into CSP.
if(!CryptImportKey(
      hCryptProv,
      pbKeyBlob,
      dwKeyBlobLen,
      0,
      0,
      &hKey))
{
   HandleError("Error during CryptImportKey!");
}
}
else
{
//--------------------------------------------------------------------
// Decrypt the file with a session key derived from a password.

//--------------------------------------------------------------------
// Create a hash object.
if(!CryptCreateHash(
       hCryptProv,
       CALG_MD5,
       0,
       0,
       &hHash))
{
    HandleError("Error during CryptCreateHash!");
}
//--------------------------------------------------------------------
// Hash in the password data.

if(!CryptHashData(
       hHash,
       (BYTE *)szPassword,
       strlen(szPassword),
       0))
{
    HandleError("Error during CryptHashData!");
}
//--------------------------------------------------------------------
// Derive a session key from the hash object.

if(!CryptDeriveKey(
      hCryptProv,
      ENCRYPT_ALGORITHM,
      hHash,
      KEYLENGTH,
      &hKey))
{
   HandleError("Error during CryptDeriveKey!");
}
//--------------------------------------------------------------------
// Destroy the hash object.

CryptDestroyHash(hHash);
hHash = 0;
}
//--------------------------------------------------------------------
//   The decryption key is now available, either having been imported
//   from a BLOB read in from the source file or having been created
//   using the password. This point in the program is not reached if
//   the decryption key is not available.

//--------------------------------------------------------------------
// Determine the number of bytes to decrypt at a time.
// This must be a multiple of ENCRYPT_BLOCK_SIZE.

dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;
dwBufferLen = dwBlockLen;

//--------------------------------------------------------------------
// Allocate memory.

if(!(pbBuffer = (BYTE *)malloc(dwBufferLen)))
{
   HandleError("Out of memory!\n");
}
//--------------------------------------------------------------------
// Decrypt source file, and write to destination file.

do {
//--------------------------------------------------------------------
// Read up to dwBlockLen bytes from source file.

dwCount = fread(
     pbBuffer,
     1,
     dwBlockLen,
     hSource);
if(ferror(hSource))
{
    HandleError("Error reading ciphertext!");
}
//--------------------------------------------------------------------
// Decrypt data.
if(!CryptDecrypt(
      hKey,
      0,
      feof(hSource),
      0,
      pbBuffer,
      &dwCount))
{
   HandleError("Error during CryptDecrypt!");
}
//--------------------------------------------------------------------
// Write data to destination file.

fwrite(
    pbBuffer,
    1,
    dwCount,
    hDestination);
if(ferror(hDestination))
{
   HandleError("Error writing plaintext!");
}
}
while(!feof(hSource));
status = TRUE;

//--------------------------------------------------------------------
// Close files.
if(hSource)
   fclose(hSource);
if(hDestination)
    fclose(hDestination);

//--------------------------------------------------------------------
// Free memory.

if(pbKeyBlob)
     free(pbKeyBlob);

if(pbBuffer)
     free(pbBuffer);

//--------------------------------------------------------------------
// Destroy session key.

if(hKey)
    CryptDestroyKey(hKey);

//--------------------------------------------------------------------
// Destroy hash object.
if(hHash)
    CryptDestroyHash(hHash);

//--------------------------------------------------------------------
// Release provider handle.

if(hCryptProv)
    CryptReleaseContext(hCryptProv, 0);

return status;
} // End of Decryptfile

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError


Working with Certificate Stores

The following topics present code fragments and example C programs dealing with operations with certificate stores:

  • Example C Code for Opening Certificate Stores.
  • Example C Program: Collection and Sibling Certificate Store Operations.
  • Example C Program: Registering Physical and System Certificate Stores.
  • Example C Program: Setting and Getting Certificate Store Properties.
  • Example C Program: Listing System and Physical Stores.


Example C Code for Opening Certificate Stores

The following examples provide code to open a variety of common certificate stores. This is a series of code fragments and is not a stand-alone program.

// 1. Open the MY system store.

HCERTSTORE hSysStore;
hSysStore = CertOpenStore(
   CERT_STORE_PROV_SYSTEM,   // The store provider type.
   0,                        // The encoding type is not needed.
   NULL,                     // Use the default HCRYPTPROV.
   CERT_SYSTEM_STORE_CURRENT_USER,
                             // Set the store location in a
                             // registry location.
   L"MY"                     // The store name as a Unicode string.
   );

// Substitute other common system store names for "MY"
// including "root", "trust", or "CA".

//--------------------------------------------------------------------
// 2. Open a memory store.

HCERTSTORE hMemStore;
hMemStore = CertOpenStore(
   CERT_STORE_PROV_MEMORY,   // The memory provider type.
   0,                        // The encoding type is not needed.
   NULL,                     // Use the default HCRYPTPROV.
   0,                        // Accept the default dwFlags.
   NULL                      // pvPara is not used.
   );

//--------------------------------------------------------------------
// 3. Open a store from disk.
// In this example, the read-only flag is set.
HANDLE       hFile;
HCERTSTORE   hFileStore;
LPCSTR       pszFileName = "TestStor2.sto"
//  Obtain a file handle.
hFile = CreateFile(
     pszFileName,                  // The file name
     GENERIC_READ|GENERIC_WRITE,   // Access mode:
                                   // Read from and write to this file
     0,                            // Share mode
     NULL,                         // Security
     OPEN_ALWAYS,                  // How to create
     FILE_ATTRIBUTE_NORMAL,        // File attributes
     NULL);                        // Template

//--------------------------------------------------------------------
//   At this point, read and use data in the open file that precedes
//   the serialized certificate store data. The file pointer must
//   be placed at the beginning of the certificate store data before
//   CertOpenStore is called with the CERT_STORE_PROV_FILE provider.
//   Open the store.

hFileStore = CertOpenStore(
    CERT_STORE_PROV_FILE,     //  Load certificates from a file.
    0,                        //  Encoding type not used.
    NULL,                     //  Use the default HCRYPTPROV.
    CERT_STORE_READONLY_FLAG  //  See the LOWORD of dwFlags to make
                              //  the store read-only.
    hFile                     //  The handle for the open file
                              //  that is the source of the
                              //  certificates.
    );

//--------------------------------------------------------------------
// Include code to work with the certificates.
// The data file from which the certificate store information has been
// read is still open. Any data in that file that follows the
// serialized store can be read from the file and used at this point.

//--------------------------------------------------------------------
// Close the file store and the file.

CertCloseStore(
        file_store,
        CERT_CLOSE_STORE_CHECK_FLAG);

CloseHandle(hFile);

//--------------------------------------------------------------------
// 4. Open a file-based store using CERT_STORE_PROV_FILENAME.
//  The pvPara parameter here is the name of an existing file.
//  The function fails if the file does not exist.
//  The file is not opened using CreateFile before the call to
//  CertOpenStore.
//  CERT_STORE_PROV_FILENAME_A is used if the file name is in ASCII,
//  CERT_STORE_PROV_FILENAME would be used if the file name was a
//  Unicode string.

#define ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
HCERTSTORE    hFileStoreHandle;

hFileStoreHandle = CertOpenStore(
       CERT_STORE_PROV_FILENAME,    // The store provider type.
       ENCODING_TYPE,               // If needed, use the usual
                                    // encoding types.
       NULL,                        // Use the default HCRYPTPROV.
       0,                           // Accept the default for all
                                    // dwFlags.
       L"FileStore.sto" );          // The name of an existing file
                                    // as a Unicode string.

//--------------------------------------------------------------------
// 5. Open a collection store.
// Note that the collection store is empty.
// Certificates, CRLs, and CTLs can be added to and found in
// stores that are added as sibling stores to the collection store.

HCERTSTORE  hCollectionStoreHandle;
HCERTSTORE  hSiblingStoreHandle;
hCollectionStoreHandle = CertOpenStore(
     CERT_STORE_PROV_COLLECTION,
     0,        // For CERT_STORE_PROV_COLLECTION,
               // the rest of the parameters
               // are 0 or NULL.
     NULL,
     0,
     NULL);

//--------------------------------------------------------------------
// Open the sibling store as a file-based store.

hSiblingStoreHandle = CertOpenStore(
       CERT_STORE_PROV_FILENAME,    // The store provider type.
       ENCODING_TYPE,               // If needed, use the usual
                                    // encoding type.
       NULL,                        // Use the default HCRYPTPROV.
       0,                           // Accept the default for all
                                    // dwFlags.
       L"siblstore.sto");           // The name of an existing file
                                    // as a Unicode string.

//--------------------------------------------------------------------
// The open sibling store can now be added to the collection
// using CertAddStoreToCollection and processing of certificates can
// begin.

CertAddStoreToCollection(
          hCollectionStoreHandle,
          hSiblingStoreHandle,
          CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG,
          1);

//--------------------------------------------------------------------
// All processing of the certificates in the
// collection store will also involve the certificates in the sibling
// store.

//--------------------------------------------------------------------
// 6. Open a register store

HKEY hkResult;
HCERTSTORE  hRegStore = NULL;

//--------------------------------------------------------------------
// A register subkey be opened with RegOpenKeyEx or
// RegCreateKeyEx. A handle to the open register subkey, hkResult, is
// returned in one of parameters of RegOpenKeyEx or RegCreateKeyEx.
hRegStore = CertOpenStore(
      CERT_STORE_PROV_REG,
      0,                    // No encoding type is needed.
      NULL,                 // Accept the default HCRYPTPROV.
      0,                    // Accept the default dwFlags.
      hkResult);            // hkResult is the handle of a
                            // register subkey opened by RegOpenKeyEX
                            // or created and opened by
                            // RegCreateKeyEX.

//--------------------------------------------------------------------
// 7. Open a certificate store based on a PKCS7 message.
HCERTSTORE        hSystemStore;
HCERTSTORE        hLastStore;
CRYPT_DATA_BLOB   message_BLOB;

//--------------------------------------------------------------------
// Initialize the message BLOB.

HCERTSTORE hSystemStore = CertOpenStore(
   CERT_STORE_PROV_SYSTEM,   // The store provider type.
   0,                        // The encoding type is not needed.
   NULL,                     // Use the default HCRYPTPROV.
   CERT_SYSTEM_STORE_CURRENT_USER,
                             // Set the store location in a registry
                             // location.
   L"CA");                   // The store name as a Unicode string.

message_BLOB.cbData = 0;
message_BLOB.pbData = NULL;

//--------------------------------------------------------------------
// Get the cbData length.

if(CertSaveStore(
        hSystemStore,
        PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
        CERT_STORE_SAVE_AS_PKCS7,
        CERT_STORE_SAVE_TO_MEMORY,
        &message_BLOB,
        0))
{
    printf("The length is %d \n",message_BLOB.cbData);
}
else
{
// An error has occurred in saving the store. Print an error
// message and exit.
   HandleError("Error saving a file store.");
}

//--------------------------------------------------------------------
// Allocate the memory or pbData.

if( message_BLOB.pbData = (BYTE *)malloc(message_BLOB.cbData))
{
       printf("The function succeeded. \n");
}
else
{
// An error has occurred in memory allocation. Print an error
// message and exit.
   HandleError("Error in memory allocation.");
}

//--------------------------------------------------------------------
//  Get the contents of pbData.

if(CertSaveStore(
        hSystemStore,
        PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
        CERT_STORE_SAVE_AS_PKCS7,
        CERT_STORE_SAVE_TO_MEMORY,
        &message_BLOB,
        0))
{
   printf("Saved the store to a memory BLOB. \n");
}
else
{
// An error has occurred in saving the store. Print an error
// message and exit.
   HandleError("Error saving file store.");
}

if( hLastStore = CertOpenStore(
   CERT_STORE_PROV_PKCS7,
   PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
   NULL,
   0,
   &message_BLOB))
{
       printf("The function succeeded. \n");
}
else
{
// An error has occurred in opening the store. Print an error
// message and exit.
   HandleError("Error opening file store.");
}


Example C Program: Collection and Sibling Certificate Store Operations

The following example program demonstrates the concept of the collection store, a temporary certificate store that actually includes the contents of several certificate stores. One or more stores may be added to a collection that can access the contents of any of the stores in the collection with a single function call.

This example program illustrates the following tasks and CryptoAPI functions:

  • Opening and closing a collection store, a memory store and a system store using CertOpenStore and CertCloseStore.
  • Adding a sibling store to a collection store using CertAddStoreToCollection.
  • Finding certificates and links to certificates in stores that meets some criteria using CertFindCertificateInStore.
  • Adding a retrieved certificate to a store in memory using CertAddCertificateContextToStore.
  • Adding a link to a certificate to a store using CertAddCertificateLinkToStore.
  • Saving the store in memory to a file on disk.
  • Opening and closing a file-based certificate store.
  • Removing a sibling store from a collection using CertRemoveStoreFromCollection.

This example code uses the function HandleError. The C code for this function is included with the sample. Code for this and other auxiliary functions is also listed under General Purpose Functions.

//--------------------------------------------------------------------
// This program opens a collection store, creates a new certificate
// store in memory, and adds the new store as a sibling store to the
// collection store.
// The program then opens a system store and retrieves a certificate.
// That certificate is added the memory store.
// A second certificate is retrieved from the system store and
// a link to that certificate is added to the memory store.
// The certificate and the link are then retrieved from the
// collection store showing that certificates and links in a
// sibling store can be retrieved from the collection store.
// The memory is saved to disk.
// The memory store is then removed from the collection. The link
// added to the memory store can still be found in the memory store
// but can no longer be found in the collection store.
// All of the stores and files are closed, then the file store is
// reopened and a search is done for the certificate link.
// The success of this program depends upon a MY store being
// available. That store must included a certificate with
// the subject "Full Test Cert" and a second certificate with
// the subject "Microsoft". The names of the subjects
// should be changed to the names of certificate subjects that are
// known to be in the MY store.

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define  MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);

void main(void)
{
//--------------------------------------------------------------------
// Declare and initialize variables.

HCERTSTORE  hCollectionStore;           // The collection store
                                        // handle.
HCERTSTORE  hSystemStore;               // The system store handle.
HCERTSTORE  hMemoryStore;               // A memory store handle.
PCCERT_CONTEXT  pDesiredCert = NULL;    // Set to NULL for the first
                                        // call to
                                        // CertFindCertificateInStore.
HANDLE hStoreFileHandle ;                // Output file handle.
LPCSTR pszFileName = "TestStor.sto";     // Output file name.
LPWSTR pswzFirstCert = L"Full Test Cert";// Subject of the first
                                         // certificate.
LPWSTR pswzSecondCert = L"Microsoft";    // Subject of the second
                                         // certificate.

//-------------------------------------------------------------------
// Open a collection certificate store.

if(hCollectionStore = CertOpenStore(
      CERT_STORE_PROV_COLLECTION, // A collection store.
      0,                          // Encoding type.
                                  // Not used with a collection store.
      NULL,                       // Use the default provider.
      0,                          // No flags.
      NULL))                      // Not needed.
{
   printf("Opened a collection store. \n");
}
else
{
   HandleError( "Error opening the collection store.");
}
//-------------------------------------------------------------------
// Open a new certificate store in memory.

if(hMemoryStore = CertOpenStore(
      CERT_STORE_PROV_MEMORY,    // A memory store.
      0,                         // Encoding type.
                                 // Not used with a memory store.
      NULL,                      // Use the default provider.
      0,                         // No flags.
      NULL))                     // Not needed.
{
   printf("Opened a memory store. \n");
}
else
{
   HandleError( "Error opening a memory store.");
}
//-------------------------------------------------------------------
// Open the MY system store using CertOpenStore.

if(hSystemStore = CertOpenStore(
     CERT_STORE_PROV_SYSTEM, // The system store will be a
                             // virtual store.
     0,                      // Encoding type not need with this PROV.
     NULL,                   // Accept the default HCRYPTPROV.
     CERT_SYSTEM_STORE_CURRENT_USER,
     L"MY"))                 // System store name.
{
   printf("Opened the MY system store. \n");
}
else
{
   HandleError( "Could not open the MY system store.");
}
//-------------------------------------------------------------------
// Get a certificate that has the string "Full Test Cert" in its subject.
if(pDesiredCert)
    CertFreeCertificateContext(pDesiredCert);
if(pDesiredCert=CertFindCertificateInStore(
      hSystemStore,
      MY_ENCODING_TYPE,            // Use X509_ASN_ENCODING.
      0,                           // No dwFlags needed.
      CERT_FIND_SUBJECT_STR,       // Find a certificate with a
                                   // subject that matches the string
                                   // in the next parameter.
      pswzFirstCert,               // The Unicode string to be found
                                   // in a certificate's subject.
      NULL))                       // NULL is used so that the
                                   // search will begin at the
                                   // beginning of the certificate
                                   // store.
{
  printf("The %S certificate was found. \n",pswzFirstCert);
}
else
{
   HandleError("Could not find the desired certificate.");
}
//-------------------------------------------------------------------
// pDesiredCert is a pointer to a certificate with a subject that
// includes the string passed as parameter 5 to the function.

//--------------------------------------------------------------------
// Add the certificate from the MY store to the memory store.

if(CertAddCertificateContextToStore(
      hMemoryStore,                // The store handle
      pDesiredCert,                // The pointer to a certificate
      CERT_STORE_ADD_USE_EXISTING,
      NULL))
{
   printf("Certificate added to the memory store. \n");
}
else
{
   HandleError("Could not add the certificate to the memory store.");
}

//-------------------------------------------------------------------
//  Add the memory store as a sibling to the collection store.
//  All certificates in the memory store will now be available in
//  the collection store. Any new certificates added to the memory
//  store will also be available in the collection store.

if(CertAddStoreToCollection(
   hCollectionStore,
   hMemoryStore,
   CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG,// New certificates can be
                                       // added to the sibling store.
   1))                                 // The sibling store's
                                       // priority.
                                       // As this is the store with
                                       // the highest priority,
                                       // certificates added to
                                       // the collection store will
                                       // actually be stored in this
                                       // store.
{
     printf("The memory store is added to the collection store.\n");
}
else
{
     HandleError("The memory store was not added to the collection.");
}
//-------------------------------------------------------------------
//  Find a different certificate in the MY store, and add a link to it
//  to the memory store.
if(pDesiredCert)
    CertFreeCertificateContext(pDesiredCert);
if(pDesiredCert=CertFindCertificateInStore(
      hSystemStore,
      MY_ENCODING_TYPE,            // Use X509_ASN_ENCODING.
      0,                           // No dwFlags needed.
      CERT_FIND_SUBJECT_STR,       // Find a certificate with a
                                   // subject that matches the string
                                   // in the next parameter.
      pswzSecondCert,              // The Unicode string to be found
                                   // in a certificate's subject.
      NULL))                       // NULL is used so that the
                                   // search will begin at the
                                   // beginning of the certificate
                                   // store.
{
  printf("The %S certificate was found. \n",pswzSecondCert);
}
else
{
   HandleError("Could not find the second certificate.");
}
//--------------------------------------------------------------------
// Add a link to a second certificate from the MY store to the new
// memory store.

if(CertAddCertificateLinkToStore(
      hMemoryStore,                // The store handle
      pDesiredCert,                // The pointer to a certificate
      CERT_STORE_ADD_USE_EXISTING,
      NULL))
{
   printf("%S link added to the memory store. \n",pswzSecondCert);
}
else
{
   HandleError("Could not add the certificate link to the memory store.");
}
//--------------------------------------------------------------------
// Find the first certificate in the memory store.
if(pDesiredCert)
    CertFreeCertificateContext(pDesiredCert);
if(pDesiredCert=CertFindCertificateInStore(
      hMemoryStore,                // Store Handle
      MY_ENCODING_TYPE,            // Use X509_ASN_ENCODING.
      0,                           // No dwFlags needed.
      CERT_FIND_SUBJECT_STR,       // Find a certificate with a
                                   // subject that matches the string
                                   // in the next parameter.
      pswzFirstCert,               // The Unicode string to be found
                                   // in a certificate's subject.
      NULL))                       // NULL is used so that the
                                   // search will begin at the
                                   // beginning of the certificate
                                   // store.
{
  printf("The %S certificate was found in the memory store. \n",pswzFirstCert);
}
else
{
   printf("The %S certificate was not in the memory store.\n", pswzFirstCert);
}
//--------------------------------------------------------------------
//  Find that same certificate in the collection store.
if(pDesiredCert)
    CertFreeCertificateContext(pDesiredCert);
if(pDesiredCert=CertFindCertificateInStore(
      hCollectionStore,
      MY_ENCODING_TYPE,            // Use X509_ASN_ENCODING.
      0,                           // No dwFlags needed.
      CERT_FIND_SUBJECT_STR,       // Find a certificate with a
                                   // subject that matches the string
                                   // in the next parameter.
      pswzFirstCert,               // The Unicode string to be found
                                   // in a certificate's subject.
      NULL))                       // NULL is used so that the
                                   // search will begin at the
                                   // beginning of the certificate
                                   // store.
{
  printf("The %S certificate was found in the collection store. \n", pswzFirstCert);
}
else
{
  printf("The %S certificate was not in the memory collection.\n", pswzFirstCert);
}
//--------------------------------------------------------------------
//  Find the certificate link in the memory store.
if(pDesiredCert)
    CertFreeCertificateContext(pDesiredCert);
if(pDesiredCert=CertFindCertificateInStore(
      hCollectionStore,
      MY_ENCODING_TYPE,            // Use X509_ASN_ENCODING.
      0,                           // No dwFlags needed.
      CERT_FIND_SUBJECT_STR,       // Find a certificate with a
                                   // subject that matches the string
                                   // in the next parameter.
      pswzSecondCert,              // The Unicode string to be found
                                   // in a certificate's subject.
      NULL))                       // NULL is used so that the
                                   // search will begin at the
                                   // beginning of the certificate
                                   // store.
{
  printf("The %S link was found in the collection store. \n", pswzSecondCert);
}
else
{
   printf("The %S certificate link was not in the memory store.\n", pswzSecondCert);
}
//-------------------------------------------------------------------
// Create a file to save the new store and certificate into.

if(hStoreFileHandle = CreateFile(
      pszFileName,             // File path
      GENERIC_WRITE,           // Access mode
      0,                       // Share mode
      NULL,                    // Security
      CREATE_ALWAYS,           // How to create the file
      FILE_ATTRIBUTE_NORMAL,   // File attributes
      NULL))                   // File template
{
   printf("Created a new file on disk. \n");
}
else
{
   HandleError("Could not create a file on disk.");
}
//-------------------------------------------------------------------
// hStoreFileHandle is the output file handle.
// Save the memory store and its certificate to the output file.

if( CertSaveStore(
      hMemoryStore,            // Store handle.
      0,                       // Encoding type not needed here.
      CERT_STORE_SAVE_AS_STORE,
      CERT_STORE_SAVE_TO_FILE,
      hStoreFileHandle,        // The handle of an open disk file.
      0))                      // dwFlags. No flags are needed here.
{
   printf("Saved the memory store to disk. \n");
}
else
{
   HandleError("Could not save the memory store to disk.");
}
//--------------------------------------------------------------------
//  Remove the sibling store from the collection.
//  CertRemoveStoreFromCollection returns void.

printf("\nRemoving the memory store from the collection.\n");
CertRemoveStoreFromCollection(
    hCollectionStore,
    hMemoryStore);

//--------------------------------------------------------------------
//   Find the link in the memory store.
if(pDesiredCert)
    CertFreeCertificateContext(pDesiredCert);
if(pDesiredCert=CertFindCertificateInStore(
      hMemoryStore,
      MY_ENCODING_TYPE,            // Use X509_ASN_ENCODING.
      0,                           // No dwFlags needed.
      CERT_FIND_SUBJECT_STR,       // Find a certificate with a
                                   // subject that matches the string
                                   // in the next parameter.
      pswzSecondCert,              // The Unicode string to be found
                                   // in a certificate's subject.
      NULL))                       // NULL is used so that the
                                   // search will begin at the
                                   // beginning of the certificate
                                   // store.
{
  printf("The %S link is still in the memory store. \n", pswzSecondCert);
}
else
{
   printf("The certificate link was not in the memory store.\n");
}
//--------------------------------------------------------------------
//  Try to find it in the collection store.
if(pDesiredCert)
    CertFreeCertificateContext(pDesiredCert);
if(pDesiredCert=CertFindCertificateInStore(
      hCollectionStore,
      MY_ENCODING_TYPE,
      0,
      CERT_FIND_SUBJECT_STR,
      pswzSecondCert,
      NULL))
{
  printf("The %S link was found in the collection store. \n", pswzSecondCert);
}
else
{
   printf("Removing the store from the collection worked.\n");
   printf("The %S link is not in the collection store.\n",pswzSecondCert);
}
//-------------------------------------------------------------------
// Close the stores and the file. Reopen the file store and check its
// contents.

if(hMemoryStore)
    CertCloseStore(
        hMemoryStore,
        CERT_CLOSE_STORE_CHECK_FLAG);

if(hSystemStore)
    CertCloseStore(
        hSystemStore,
        CERT_CLOSE_STORE_CHECK_FLAG);

if(hStoreFileHandle)
     CloseHandle(hStoreFileHandle);

printf("All of the stores and files are closed. \n");

//-------------------------------------------------------------------
//  Reopen the file store.

if(hMemoryStore = CertOpenStore(
       CERT_STORE_PROV_FILENAME,    // The store provider type.
       MY_ENCODING_TYPE,            // If needed, use the usual
                                    // encoding types.
       NULL,                        // Use the default HCRYPTPROV.
       0,                           // Accept the default for all
                                    // dwFlags.
       L"TestStor.sto" ))           // The name of an existing file
                                    // as a Unicode string.
{
     printf("The file store has been reopened. \n");
}
else
{
    printf("The file store could not be reopened. \n");
}
//--------------------------------------------------------------------
//  Find the certificate link in the reopened file store.
if(pDesiredCert)
    CertFreeCertificateContext(pDesiredCert);
if(pDesiredCert=CertFindCertificateInStore(
      hMemoryStore,
      MY_ENCODING_TYPE,
      0,
      CERT_FIND_SUBJECT_STR,
      pswzSecondCert,
      NULL))
{
  printf("The %S certificate link was found in the file store. \n",pswzSecondCert);
}
else
{
   printf("The certificate link was not in the file store.\n");
}

//-------------------------------------------------------------------
// Clean up memory and end.

if(pDesiredCert)
    CertFreeCertificateContext(pDesiredCert);

if(hMemoryStore)
    CertCloseStore(
        hMemoryStore,
        CERT_CLOSE_STORE_CHECK_FLAG);

printf("All of the stores and files are closed. \n");

} // End of main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError


Example C Program: Registering Physical and System Certificate Stores

Physical stores may be made more or less permanent members of a system store. When a physical store is a member of a system store, operations on the system store such as finding a certificate will look in all of the physical stores that are registered as members of the system store. A physical store can be removed from membership in a system store using an unregister function.

This example program illustrates the following tasks and CryptoAPI functions:

  • Registering (creating) a new system store using CertRegisterSystemStore.
  • Opening a newly created system store using CertOpenStore.
  • Registering a physical store as a member of a system store using CertRegisterPhysicalStore.
  • Unregistering (deleting) a system store using CertUnregisterSystemStore.

This program also demonstrates the creation and deletion of system stores.

//--------------------------------------------------------------------
// Example code using CertRegisterSystemStore
//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);

void main()
{
//--------------------------------------------------------------------
// Declare and initialize variables.

HCERTSTORE hSystemStore;
DWORD dwFlags= CERT_SYSTEM_STORE_CURRENT_USER;
LPCWSTR pvSystemName= L"NEWSTORE";  // For this setting of
                                    // dwFlags, the store name may
                                    // be prefixed with a user name.
CERT_PHYSICAL_STORE_INFO PhysicalStoreInfo;
BYTE fResponse  = 'n';

if(CertRegisterSystemStore(
    pvSystemName,
    dwFlags,
    NULL,
    NULL))
  printf("System store %S is registered. \n",pvSystemName);
else
  printf("The system store did not register. \n");

//--------------------------------------------------------------------
//   Open the NEWSTORE as a system store.

if(hSystemStore = CertOpenStore(
   CERT_STORE_PROV_SYSTEM,   // The store provider type.
   0,                        // The encoding type is not needed.
   NULL,                     // Use the default HCRYPTPROV.
   CERT_SYSTEM_STORE_CURRENT_USER,
                             // Set store location in a registry
                             // location.
   pvSystemName ))           // The store name as a Unicode string.
{
     printf("The new store has been opened as a system store.\n");
}
else
{
     printf("The new store was not opened as a system store.\n");
}
if(hSystemStore)
{
    if(CertCloseStore(hSystemStore,0))
    {
        printf("The system store has been closed.\n");
    }
    else
    {
        printf("The system store could not be closed.\n");
    }
}
else
{
   printf("The system store did not need to be closed.\n");
}
//--------------------------------------------------------------------
// Initialize PhysicalStoreInfo.

PhysicalStoreInfo.cbSize=sizeof(CERT_PHYSICAL_STORE_INFO);
PhysicalStoreInfo.pszOpenStoreProvider=(char *)CERT_STORE_PROV_FILENAME;
PhysicalStoreInfo.dwFlags=CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG;
PhysicalStoreInfo.dwPriority=1;
PhysicalStoreInfo.dwOpenEncodingType=MY_ENCODING_TYPE;

//--------------------------------------------------------------------
// Register the physical store.

if(CertRegisterPhysicalStore(
      L"NEWSTORE",
      dwFlags,
      L"TESTOR.STO",
      &PhysicalStoreInfo,
      NULL
      ))
{
       printf("Physical store is registered. \n");
}
else
{
       printf("The physical store was not registered.\n");
}
//--------------------------------------------------------------------
//  Next, unregister the store.

printf("Would you like to unregister the %S store? (y/n) ",pvSystemName);
scanf("%c",&fResponse);

if(fResponse=='y')
{
   if(CertUnregisterSystemStore(
     pvSystemName,
     dwFlags))
   {
      printf("System store %S has been unregistered.\n",pvSystemName);
   }
   else
   {
      printf("The system store was not unregistered.\n");
   }
}
}  // End main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError


Example C Program: Setting and Getting Certificate Store Properties

This program sets and gets a certificate store property, the localized store name. This property is not persisted when the store is closed.

This example program illustrates the following tasks and CryptoAPI functions:

  • Opening a certificate store using CertOpenStore.
  • Setting the localized name of the store using CertSetStoreProperty.
  • Retrieving the localized name of the store using CertGetStoreProperty.
  • Retrieving the predefined localized store name using CryptFindLocalizedName.
  • Save the certificate store as a PKCS7 message to a file using CertSaveStore.
  • Save the certificate store to a memory BLOB using CertSaveStore.
  • Determine the number of signers of the PKCS7 message using CryptGetMessageSignercount.
  • Open a certificate store from a PKCS7 message in memory using CryptGetMessageCertificates.
  • Initialize the CRYPT_ALGORITHM_IDENTIFIER and CRYPT_HASH_MESSAGE_PARA data structures needed to hash the message.
  • Hash and encode the message using CryptHashMessage.
  • Determine whether changes have been made to an open certificate store and synchronizing the store if needed using CertControlStore.
  • Closing a certificate store using CertCloseStore with the CERT_CLOSE_STORE_FORCE_FLAG.
//--------------------------------------------------------------------
// Example C program.
// This program demonstrates the use of the following functions:
//     CreateEvent
//     CertOpenStore
//     CertSetStoreProperty
//     CertGetStoreProperty
//     CryptFindLocalizedName
//     CertSaveStore
//     CryptGetMessageSignerCount
//     CryptGetMessageCertificates
//     CryptHashMessage
//     CertControlStore
//     WaitForSingleObjectEx
//     CertCloseStore
//------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);

void main()
{
//--------------------------------------------------------------------
// Declare and initialize variables.

HCERTSTORE hCertStore;     // Original certificate store
HCERTSTORE hNewStore;      // Store to be created from a PKCS7 message
HANDLE     hEvent;
void *pvData;
DWORD cbData;
DWORD dwSignerCount;
CRYPT_DATA_BLOB Property_Name_Blob;   // Blob to hold store property
CRYPT_DATA_BLOB Save_Store_Blob;      // Blob to hold the PKCS7
                                      // message
CRYPT_HASH_MESSAGE_PARA      HashPara;  // Data structure used to hash
                                        // a message
const BYTE*                  rgpbToBeHashed[1];
DWORD                        rgcbToBeHashed[1];
                                        // Arrays of messages to be
                                        // hashed
BYTE                         *pbHashedBlob;

DWORD                        cbHashedBlob;
                                        // Length of the hash BLOB
CRYPT_ALGORITHM_IDENTIFIER   AlgId;     // Data structure to hold the
                                        // hash algorithm identifier
BOOL       fSignal;

//--------------------------------------------------------------------
// Initialize an event.

if(hEvent = CreateEvent(
    NULL,
    FALSE,          // Manual reset is FALSE.
    FALSE,          // The initial state of the event is FALSE.
    NULL))
{
     printf("An event has been created.\n");
}
else
{
     HandleError("The event was not created.");
}

//--------------------------------------------------------------------
// Open the MY certificate store.

if ( hCertStore = CertOpenStore(
    CERT_STORE_PROV_SYSTEM,
    0,
    NULL,
    CERT_SYSTEM_STORE_CURRENT_USER,
    L"MY"))
{
     printf("The MY store is open.\n");
}
else
{
     HandleError("The MY store did not open.");
}

//--------------------------------------------------------------------
// Prepare a data structure to set a store property.
// Initialize the members of the CRYPT_DATA_BLOB.

Property_Name_Blob.pbData =(BYTE *) L"The Local MY Store";
Property_Name_Blob.cbData =
       (wcslen((LPWSTR)Property_Name_Blob.pbData)+1) * sizeof(WCHAR);

//--------------------------------------------------------------------
// Set the store's localized name property.

if (CertSetStoreProperty(
    hCertStore,
    CERT_STORE_LOCALIZED_NAME_PROP_ID,
    0,
    &Property_Name_Blob))
{
     printf("The name of the store has been set. Continue. \n");
}
else
{
     HandleError("Setting the store's localized name failed.");
}
//--------------------------------------------------------------------
// Call CertGetStoreProperty a first time
// to get the length of the store name string to be returned.

if(CertGetStoreProperty(
    hCertStore,
    CERT_STORE_LOCALIZED_NAME_PROP_ID,
    NULL,     // NULL on the first call
              // to establish the length of the string to
              // to be returned
    &cbData))
{
     printf("The length of the property is %d. \n",cbData);
}
else
{
     HandleError("The length of the property was not calculated.");
}

//--------------------------------------------------------------------
// cbData is the length of a string to be allocated.
// Allocate the space for the string, and call the function a
// the second time.

if(pvData = malloc(cbData))
{
  printf("%d bytes of memory allocated.\n",cbData);
}
else
{
     HandleError("Memory was not allocated.");
}
if(CertGetStoreProperty(
    hCertStore,
    CERT_STORE_LOCALIZED_NAME_PROP_ID,
    pvData,
    &cbData))
{
     printf("The localized name is %S.\n",pvData);
}
else
{
     HandleError("CertGetStoreProperty failed.");
}
//--------------------------------------------------------------------
//   Find and print the predefined localized name for the MY store.
//   Note that changing the localized store name property does not \
//   change the predefined localized store name.

printf("The pre-defined localized name of the MY store is still %S.\n"
         , CryptFindLocalizedName(L"my"));

//---------------------------------------------------------------
// Save the store to a PKCS7 message in a file.

if(CertSaveStore(
   hCertStore,
   MY_ENCODING_TYPE,
   CERT_STORE_SAVE_AS_PKCS7,
   CERT_STORE_SAVE_TO_FILENAME_A,
   "pkcsseven.dat",
   0))
{
     printf("The store has been saved to a PKCS7 message file.\n");
}
else
{
     HandleError("The store has not been saved.");
}

//---------------------------------------------------------------
// Save the store to a PKCS7 message in a file.
// Initialize the BLOB.

Save_Store_Blob.cbData=0;
Save_Store_Blob.pbData=NULL;

if(CertSaveStore(
   hCertStore,
   MY_ENCODING_TYPE,
   CERT_STORE_SAVE_AS_PKCS7,
   CERT_STORE_SAVE_TO_MEMORY,
   (void *)&Save_Store_Blob,
   0))
{
     printf("The store length, %d, has been determined.\n",
          Save_Store_Blob.cbData);
}
else
{
     HandleError("The store length could not be determined.");
}

if(Save_Store_Blob.pbData=(BYTE *) malloc(Save_Store_Blob.cbData))
{
     printf("Memory has been allocated.\n");
}
else
{
     HandleError("Memory allocation failure.");
}

if(CertSaveStore(
   hCertStore,
   MY_ENCODING_TYPE,
   CERT_STORE_SAVE_AS_PKCS7,
   CERT_STORE_SAVE_TO_MEMORY,
   (void *)&Save_Store_Blob,
   0))
{
     printf("The store has been saved to memory.\n");
}
else
{
     HandleError("The store was not saved to memory.");
}
//--------------------------------------------------------------------
//  Retrieve the number of signers of the PKCS7 message.

if ( dwSignerCount = CryptGetMessageSignerCount(
     MY_ENCODING_TYPE,
     Save_Store_Blob.pbData,
     Save_Store_Blob.cbData))
{
     printf("The number of signers is %d.\n",dwSignerCount);
}
else
{
     printf("The number of signers is zero or could not be found.\n");
}
//--------------------------------------------------------------------
//   Open a certificate store from the PKCS7 message stored to
//   memory.

if(hNewStore=CryptGetMessageCertificates(
   MY_ENCODING_TYPE,
   NULL,
   0,
   Save_Store_Blob.pbData,
   Save_Store_Blob.cbData))
{
     printf("A new store has been opened from a PKCS7.\n");
}
else
{
     HandleError("Opening the store from the PKCS7 message failed.");
}
//--------------------------------------------------------------------
//  Next, hash the message.
//  Store the message and its length in the appropriate arrays.

rgpbToBeHashed[0]=Save_Store_Blob.pbData;
rgcbToBeHashed[0]=Save_Store_Blob.cbData;

//--------------------------------------------------------------------
//  Initialize the CRYPT_ALGORITHM_IDENTIFIER data structure.

AlgId.pszObjId=szOID_RSA_MD5;
AlgId.Parameters.cbData=0;

//--------------------------------------------------------------------
//  Initialize the CRYPT_HASH_MESSAGE_PARA data structure.

HashPara.cbSize = sizeof(CRYPT_HASH_MESSAGE_PARA);
HashPara.dwMsgEncodingType=MY_ENCODING_TYPE;
HashPara.hCryptProv=NULL;
HashPara.HashAlgorithm=AlgId;
HashPara.pvHashAuxInfo= NULL;

//--------------------------------------------------------------------
// Calculate the size of the hashed and encoded message.

if(CryptHashMessage(
      &HashPara,
      FALSE,
      1,
      rgpbToBeHashed,
      rgcbToBeHashed,
      NULL,
      &cbHashedBlob,
      NULL,
      NULL))
{
     printf("The size of the hashed, encoded message is %d.\n",
          cbHashedBlob);
}
else
{
     HandleError("The size of the hash could not be determined.");
}

//-------------------------------------------------------------------
//  Allocated memory for the hashed, encoded BLOB.

if(pbHashedBlob = (BYTE*)malloc(cbHashedBlob))
{
     printf("Memory allocated for the hashed, encoded BLOB.\n");
}
else
{
     HandleError("Memory allocation failed.");
};

//--------------------------------------------------------------------
// Hash and encode the message.

if(CryptHashMessage(
       &HashPara,
       FALSE,
       1,
       rgpbToBeHashed,
       rgcbToBeHashed,
       pbHashedBlob,
       &cbHashedBlob,
       NULL,
       NULL))
{
     printf("The message has been hashed and encoded.\n");
}
else
{
     HandleError("The message was not hashed. ");
}

//--------------------------------------------------------------------
//  Call CertControlStore the first time with
//  CERT_CONTROL_STORE_NOTIFY_CHANGE.

if(CertControlStore(
    hCertStore,                    // The store to be controlled
    0,                             // Not used
    CERT_STORE_CTRL_NOTIFY_CHANGE, // Control action type
    &hEvent))                      // Points to the event handle.
                                   //  When a change is detected,
                                   //  a signal is written to the
                                   //  space pointed to by
                                   //  hHandle.
{
  printf("Notify change worked \n");
}
else
{
  HandleError("Notify change failed. \n");
}
//--------------------------------------------------------------------
// Wait for the store to change.

fSignal =(WAIT_OBJECT_0 == WaitForSingleObjectEx(
    hEvent,
    1000 ,               // Number of milliseconds to wait.
                         // Use INFINITE to wait indefinitely for
                         // a change
    FALSE));

if (fSignal)
//--------------------------------------------------------------------
// The store has changed.
// Call the function a second time with CERT_STORE_CTRL_RESYNC.

  if(CertControlStore(
          hCertStore,                // in, the store to be controlled
          0,                         // in, not used.
          CERT_STORE_CTRL_RESYNC,    // in, control action type
          &hEvent))                  // in, the handle of the event
                                     // to be rearmed.
    printf("Resynchronization worked. \n");
  else
    HandleError("Resyncronization failed.");
else
{
  printf("The store was not changed. \n");
  printf("Resyncronization was not needed. \n");
}

// Free memory.

free (pbHashedBlob);

if(pvData)
     free(pvData);
if(CertCloseStore(
       hCertStore,
       CERT_CLOSE_STORE_FORCE_FLAG))
{
     printf("The store has been closed. \n");
}
else
{
     HandleError("The store could not be closed.");
}
printf("The program ran to completion without error. \n");
}  // End main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program.\n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr,"Error number %x.\n",GetLastError());
    fprintf(stderr,"Program terminating.\n");
    exit(1);
} // End of HandleError


Example C Program: Listing System and Physical Stores

This code enumerates the system certificate store locations, the system certificate stores, and the physical stores associated with each system store. The code demonstrates the creation of callback functions and callback functions that call other callback functions.

This example program illustrates the following CryptoAPI functions:

  • CertEnumSystemStoreLocation.
  • CertEnumSystemStore.

This example code also uses the function HandleError. C code for this function is included with the sample.

Code for this and other auxiliary functions is also listed under General Purpose Functions.

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);

typedef struct _ENUM_ARG {
    BOOL        fAll;
    BOOL        fVerbose;
    DWORD       dwFlags;
    const void  *pvStoreLocationPara;
    HKEY        hKeyBase;
} ENUM_ARG, *PENUM_ARG;

//--------------------------------------------------------------------
// Declare callback functions.
// Definitions of these functions follow main.

static BOOL WINAPI EnumPhyCallback(
       const void *pvSystemStore,
       DWORD dwFlags,
       LPCWSTR pwszStoreName,
       PCERT_PHYSICAL_STORE_INFO pStoreInfo,
       void *pvReserved,
       void *pvArg);

static BOOL WINAPI EnumSysCallback(
       const void *pvSystemStore,
       DWORD dwFlags,
       PCERT_SYSTEM_STORE_INFO pStoreInfo,
       void *pvReserved,
       void *pvArg);

static BOOL WINAPI EnumLocCallback(
       LPCWSTR pwszStoreLocation,
       DWORD dwFlags,
       void *pvReserved,
       void *pvArg);

//--------------------------------------------------------------------
// Begin main.

void main(void)
{
//--------------------------------------------------------------------
// Declare and initialize variables.

DWORD dwExpectedError = 0;
DWORD dwLocationID = CERT_SYSTEM_STORE_CURRENT_USER_ID;
DWORD dwFlags = 0;
CERT_PHYSICAL_STORE_INFO PhyStoreInfo;
ENUM_ARG EnumArg;
LPSTR pszStoreParameters = NULL;
LPWSTR pwszStoreParameters = NULL;
LPWSTR pwszSystemName = NULL;
LPWSTR pwszPhysicalName = NULL;
LPWSTR pwszStoreLocationPara = NULL;
void *pvSystemName;
void *pvStoreLocationPara;
DWORD dwNameCnt = 0;
LPCSTR pszTestName;
HKEY hKeyRelocate = HKEY_CURRENT_USER;
LPSTR pszRelocate = NULL;
HKEY hKeyBase = NULL;

//--------------------------------------------------------------------
//  Initialize data structure variables.

memset(&PhyStoreInfo, 0, sizeof(PhyStoreInfo));
PhyStoreInfo.cbSize = sizeof(PhyStoreInfo);
PhyStoreInfo.pszOpenStoreProvider = sz_CERT_STORE_PROV_SYSTEM_W;
pszTestName = "Enum";
pvSystemName = pwszSystemName;
pvStoreLocationPara = pwszStoreLocationPara;

memset(&EnumArg, 0, sizeof(EnumArg));
EnumArg.dwFlags = dwFlags;
EnumArg.hKeyBase = hKeyBase;

EnumArg.pvStoreLocationPara = pvStoreLocationPara;
EnumArg.fAll = TRUE;
dwFlags &= ~CERT_SYSTEM_STORE_LOCATION_MASK;
dwFlags |= (dwLocationID << CERT_SYSTEM_STORE_LOCATION_SHIFT) &
    CERT_SYSTEM_STORE_LOCATION_MASK;

printf("Begin enumeration of store locations. \n");
if(CertEnumSystemStoreLocation(
    dwFlags,
    &EnumArg,
    EnumLocCallback
    ))
{
    printf("\nFinished enumerating locations. \n");
}
else
{
    HandleError("Enumeration of locations failed.");
}
printf("\nBegin enumeration of system stores. \n");

if(CertEnumSystemStore(
    dwFlags,
    pvStoreLocationPara,
    &EnumArg,
    EnumSysCallback
    ))
{
    printf("\nFinished enumerating system stores. \n");
}
else
{
    HandleError("Enumeration of system stores failed.");
}

printf("\n\nEnumerate the physical stores for the MY system store. \n");
if(CertEnumPhysicalStore(
    L"MY",
    dwFlags,
    &EnumArg,
    EnumPhyCallback
    ))
{
    printf("Finished enumeration of the physical stores. \n");
}
else
{
    HandleError("Enumeration of physical stores failed.");
}
}    //   End of main

//--------------------------------------------------------------------
//   Define function GetSystemName.

static BOOL GetSystemName(
    const void *pvSystemStore,
    DWORD dwFlags,
    PENUM_ARG pEnumArg,
    LPCWSTR *ppwszSystemName )
{
//-------------------------------------------------------------------
// Declare local variables.

*ppwszSystemName = NULL;

if (pEnumArg->hKeyBase && 0 == (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG))
{
  printf("Failed => RELOCATE_FLAG not set in callback. \n");
  return FALSE;
}
else
{
  if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
  {
     PCERT_SYSTEM_STORE_RELOCATE_PARA pRelocatePara;
     if (!pEnumArg->hKeyBase)
     {
        HandleError("Failed => RELOCATE_FLAG is set in callback");
     }
     pRelocatePara = (PCERT_SYSTEM_STORE_RELOCATE_PARA)
                   pvSystemStore;
     if (pRelocatePara->hKeyBase != pEnumArg->hKeyBase)
     {
         HandleError("Wrong hKeyBase passed to callback");
     }
     *ppwszSystemName = pRelocatePara->pwszSystemStore;
  }
  else
  {
    *ppwszSystemName = (LPCWSTR) pvSystemStore;
  }
}
return TRUE;
}

//--------------------------------------------------------------------
// Define the callback functions.

static BOOL WINAPI EnumPhyCallback(
      const void *pvSystemStore,
      DWORD dwFlags,
      LPCWSTR pwszStoreName,
      PCERT_PHYSICAL_STORE_INFO pStoreInfo,
      void *pvReserved,
      void *pvArg )
{
//--------------------------------------------------------------------
//  Declare and initialize local variables.
PENUM_ARG pEnumArg = (PENUM_ARG) pvArg;
LPCWSTR pwszSystemStore;

//--------------------------------------------------------------------
//  Begin callback process.

if (GetSystemName(
       pvSystemStore,
       dwFlags,
       pEnumArg,
       &pwszSystemStore))
{
printf("    %S", pwszStoreName);
}
else
{
   HandleError("GetSystemName failed.");
}
if (pEnumArg->fVerbose &&
      (dwFlags & CERT_PHYSICAL_STORE_PREDEFINED_ENUM_FLAG))
      printf(" (implicitly created)");
printf("\n");
return TRUE;
}

static BOOL WINAPI EnumSysCallback(
    const void *pvSystemStore,
    DWORD dwFlags,
    PCERT_SYSTEM_STORE_INFO pStoreInfo,
    void *pvReserved,
    void *pvArg)
//--------------------------------------------------------------------
//  Begin callback process.
{
//--------------------------------------------------------------------
//  Declare and initialize local variables.

PENUM_ARG pEnumArg = (PENUM_ARG) pvArg;
LPCWSTR pwszSystemStore;
static int line_counter=0;
char x;

//--------------------------------------------------------------------
//  Begin processing.

//--------------------------------------------------------------------
//   Control break. If 5 or more lines have been printed,
//   pause and reset the line counter.

if(line_counter++ > 5)
{
   printf("Enumeration of system store: Press Enter to continue.");
   scanf("%c",&x);
   line_counter=0;
}

//--------------------------------------------------------------------
//  Prepare and display the next detail line.

if (GetSystemName(pvSystemStore, dwFlags, pEnumArg, &pwszSystemStore))
{
     printf("  %S\n", pwszSystemStore);
}
else
{
     HandleError("GetSystemName failed.");
}
if (pEnumArg->fAll || pEnumArg->fVerbose)
{
    dwFlags &= CERT_SYSTEM_STORE_MASK;
    dwFlags |= pEnumArg->dwFlags & ~CERT_SYSTEM_STORE_MASK;
    if (!CertEnumPhysicalStore(
       pvSystemStore,
       dwFlags,
       pEnumArg,
       EnumPhyCallback
       ))
    {
        DWORD dwErr = GetLastError();
        if (!(ERROR_FILE_NOT_FOUND == dwErr ||
            ERROR_NOT_SUPPORTED == dwErr))
        {
               printf("    CertEnumPhysicalStore");
        }
    }
}
return TRUE;
}

static BOOL WINAPI EnumLocCallback(
    LPCWSTR pwszStoreLocation,
    DWORD dwFlags,
    void *pvReserved,
    void *pvArg)

{
//--------------------------------------------------------------------
//  Declare and initialize local variables.

PENUM_ARG pEnumArg = (PENUM_ARG) pvArg;
DWORD dwLocationID = (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) >>
   CERT_SYSTEM_STORE_LOCATION_SHIFT;
static int linecount=0;
char x;

//--------------------------------------------------------------------
//  Begin processing.

//--------------------------------------------------------------------
// Break if more than 5 lines have been printed.

if(linecount++ > 5)
{
   printf("Enumeration of store locations: Press Enter to continue.");
   scanf("%c",&x);
   linecount=0;
}

//--------------------------------------------------------------------
//  Prepare and display the next detail line.

printf("======   %S   ======\n", pwszStoreLocation);
if (pEnumArg->fAll)
{
    dwFlags &= CERT_SYSTEM_STORE_MASK;
    dwFlags |= pEnumArg->dwFlags & ~CERT_SYSTEM_STORE_LOCATION_MASK;
    CertEnumSystemStore(
         dwFlags,
         (void *) pEnumArg->pvStoreLocationPara,
         pEnumArg,
         EnumSysCallback );
}
return TRUE;
}

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError


Using Certificates

The following sections deal with creating and using certificates, including decoding information from certificate data structures, changing and encoding data into certificates, and working with certificate properties:

  • Using a CERT_INFO Data Structure.
  • Example C Program: Listing the Certificates in a Store.
  • Example C Program: Deleting Certificates from a Certificate Store.
  • Example C Program: Certificate Store Operations.
  • Example C Program: Serializing Certificates and Adding Serialized Elements to Stores.
  • Example C Program: Getting and Setting Certificate Properties.
  • Example C Program: Converting Names from Certificates to ASN1 and Back.


Using a CERT_INFO Data Structure

CERT_CONTEXT AND CERT_INFO are the main data structures holding the information in a certificate. When a certificate is used, it may need to be decoded. For more information, see Decoding a CERT_INFO Structure. Information may be added to a decoded CERT_INFO structure and then the structure can be re-encoded. For details, see Encoding a CERT_INFO Structure.


Decoding a CERT_INFO Structure

Given a certificate, the first step in decoding the certificate BLOB is to call CertCreateCertificateContext, passing it a pointer to the encoded certificate (BLOB). When this function is called, it creates a duplicate of the encoded certificate, creates a structure of type CERT_CONTEXT, and creates a structure of type CERT_INFO. As shown in the following illustration, a certificate context includes the original certificate BLOB, a C structure of type CERT_CONTEXT, and a C structure of type CERT_INFO. One of the members of the CERT_CONTEXT structure points to the CERT_INFO structure and another to the encoded certificate BLOB.

The encoded object (data member) is always provided as the input to the CryptDecodeObject function, and the output is a C structure that may or may not have encoded members, depending on how far into the process you are.

There is one other member that requires some decoding, and that is the Extension member. Although it is not encoded at the CERT_INFO level, it does contain some encoded information. To decode this information, proceed as shown in the following illustration.

In the CERT_INFO structure, data member rgExtension is a pointer to an array of CERT_EXTENSION structures. Each CERT_EXTENSION structure has a Value data member that is in encoded form and needs to be decoded. The Value data member is passed to the CryptDecodeObject function, and then the output from the function depends on the value of the pszObjId data member. Notice that in the illustration, two different structures are produced, one of type CERT_BASIC_CONSTRAINTS_INFO and one of type CERT_AUTHORITY_KEY_ID_INFO, depending on the value of pszObjId.


Encoding a CERT_INFO Structure

The encoding process is the reverse of the decoding process described in Decoding a CERT_INFO Structure. For example, the following procedure would add an encoded Issuer to a CERT_INFO structure. Also see the illustration that follows the procedure.

To add an encoded Issuer to a CERT_INFO structure

  1. Create a string containing the issuer name to be used.
  2. Create an array of CERT_RDN_ATTR structures, which will be initialized to contain the proper information about the issuer name string just created.
  3. Create an array of CERT_RDN structures, one of which has the information about the array of CERT_RDN_ATTR structures just initialized.
  4. Create a CERT_NAME_INFO structure that has a pointer to the array of CERT_RDN structures that just created.
  5. Call CryptEncodeObject to get the size of the output encoded BLOB, passing it the address of the CERT_NAME_INFO structure that you just created.
  6. Allocate memory for the output encoded BLOB.
  7. Call CryptEncodeObject again, passing it the same information, but now passing it the address of the memory just allocated.
  8. Set the Issuer.cbData member of the CERT_INFO structure to the size returned in step 5, and the Issuer.pbData member to the address obtained in step 6. The encoded Issuer BLOB now resides there.

To initialize and encode some certificate extension information, use the following procedure. Also see the illustration that follows the procedure.

To add encoded extension information to a CERT_INFO structure

  1. Create and initialize an extension information structure—for this example, it is a CERT_BASIC_CONSTRAINTS_INFO structure.
  2. Call CryptEncodeObject, passing it the address of the structure just created, to get the size of the output encoded BLOB.
  3. Allocate memory for the output encoded BLOB.
  4. Call CryptEncodeObject again, passing the same information, except now pass in the address of the allocated memory.
  5. Create an array of CERT_EXTENSION structures.
  6. Initialize one of the CERT_EXTENSION structures so that the pszObjId is the proper string for the data contained in Value, and that Value contains the encrypted data BLOB that was output from the call to CryptEncodeObject.
  7. Initialize the rgExtension member of the CERT_INFO structure to point to the array of CERT_EXTENSION structures.


Example C Program: Listing the Certificates in a Store

The following is an example program that lists all of the certificates in a system certificate store and the name of the subject and all of the certificate context properties of each of those certificates. The program gets the name of the certificate store from the user and thus can be used to list the contents of any system certificate store.

This example program illustrates the following tasks and CryptoAPI functions:

  • Opening a system store using CertOpenSystemStore.
  • In a loop, enumerating all of the certificates in the open store using CertEnumCertificatesInStore.
  • Getting the name of the certificate's subject using CertGetNameString.
  • In a loop, using CertEnumCertificateContextProperties to get the property identifiers of all of the properties associated with the certificate.
  • Using CertGetCertificateContextProperty to get each of the properties.
  • Closing the certificate store using CertCloseStore.

This example code uses the function HandleError. C code for this function is included with the sample.

Code for this and other auxiliary functions is also listed under General Purpose Functions.

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
void HandleError(char *s);

void main(void){

//--------------------------------------------------------------------
// This program lists all of the certificates in a system certificate
// store and all of the property identifier numbers of those
// certificates.

//--------------------------------------------------------------------
// Declare and initialize variables.

HCERTSTORE       hCertStore;
PCCERT_CONTEXT   pCertContext=NULL;
char pszNameString[256];
char pszStoreName[256];
void*            pvData;
DWORD            cbData;
DWORD            dwPropId = 0;
            // Zero must be used on the first
            // call to the function. After that,
            // the last returned property identifier is passed.

//--------------------------------------------------------------------
//  Begin processing. Get the name of the system certificate store
//  to be enumerated. Output here is to stderr so that the program can
//  be run from the command line and stdout can be redirected to a
//  file.

fprintf(stderr,"Please enter the store name:");
scanf("%s",pszStoreName);
fprintf(stderr,"The store name is %s .\n",pszStoreName);

//--------------------------------------------------------------------
// Open a system certificate store.

if ( hCertStore = CertOpenSystemStore(
     NULL,
     pszStoreName))
{
     fprintf(stderr,"The %s store has been opened. \n", pszStoreName);
}
else
{
// If the store was not opened, exit to an error routine.
     HandleError("The store was not opened.");
}

//--------------------------------------------------------------------
// Use CertEnumCertificatesInStore to get the certificates
// from the open store.

while(pCertContext= CertEnumCertificatesInStore(
     hCertStore,
     pCertContext))
{
//--------------------------------------------------------------------
// A certificate was retrieved. Continue.

if(CertGetNameString(
   pCertContext,
   CERT_NAME_SIMPLE_DISPLAY_TYPE,
   0,
   NULL,
   pszNameString,
   128))
{
   printf("\nCertificate for %s \n",pszNameString);
}
else
   fprintf(stderr,"CertGetName failed. \n");

//--------------------------------------------------------------------
// Loop to find all of the property identifiers for the specified
// certificate. The loop continues until
// CertEnumCertificateContextProperties returns zero.

while(dwPropId = CertEnumCertificateContextProperties(
       pCertContext, // The context whose properties are to be listed.
       dwPropId))    // Number of the last property found. This must
                     // be zero to find the first property identifier.
{
//--------------------------------------------------------------------
// When the loop is executed, a property identifier has been found.
// Print the property number.

   printf("Property # %d found->", dwPropId);

//--------------------------------------------------------------------
//  Indicate the kind of property found.

   switch(dwPropId)
   {
     case CERT_FRIENDLY_NAME_PROP_ID:
     {
       printf("Friendly name: ");
       break;
     }
     case CERT_SIGNATURE_HASH_PROP_ID:
     {
       printf("Signature hash identifier ");
       break;
     }
     case CERT_KEY_PROV_HANDLE_PROP_ID:
     {
       printf("KEY PROVE HANDLE");
       break;
     }
     case CERT_KEY_PROV_INFO_PROP_ID:
     {
       printf("KEY PROV INFO PROP ID ");
       break;
     }
     case CERT_SHA1_HASH_PROP_ID:
     {
        printf("SHA1 HASH identifier");
        break;
     }
     case CERT_MD5_HASH_PROP_ID:
     {
        printf("md5 hash identifier ");
        break;
     }
     case CERT_KEY_CONTEXT_PROP_ID:
     {
        printf("KEY CONTEXT PROP identifier");
        break;
     }
     case CERT_KEY_SPEC_PROP_ID:
     {
        printf("KEY SPEC PROP identifier");
        break;
      }
      case CERT_ENHKEY_USAGE_PROP_ID:
      {
        printf("ENHKEY USAGE PROP identifier");
        break;
      }
      case CERT_NEXT_UPDATE_LOCATION_PROP_ID:
      {
        printf("NEXT UPDATE LOCATION PROP identifier");
        break;
      }
      case CERT_PVK_FILE_PROP_ID:
      {
         printf("PVK FILE PROP identifier ");
         break;
      }
      case CERT_DESCRIPTION_PROP_ID:
      {
        printf("DESCRIPTION PROP identifier ");
        break;
      }
      case CERT_ACCESS_STATE_PROP_ID:
      {
        printf("ACCESS STATE PROP identifier ");
        break;
      }
      case CERT_SMART_CARD_DATA_PROP_ID:
      {
         printf("SMAART_CARD DATA PROP identifier ");
         break;
      }
      case CERT_EFS_PROP_ID:
      {
        printf("EFS PROP identifier ");
        break;
      }
      case CERT_FORTEZZA_DATA_PROP_ID:
      {
        printf("FORTEZZA DATA PROP identifier ");
        break;
      }
      case CERT_ARCHIVED_PROP_ID:
      {
        printf("ARCHIVED PROP identifier ");
        break;
      }
      case CERT_KEY_IDENTIFIER_PROP_ID:
      {
        printf("KEY IDENTIFIER PROP identifier ");
        break;
      }
      case CERT_AUTO_ENROLL_PROP_ID:
      {
        printf("AUTO ENROLL identifier. ");
        break;
      }
   } // End switch

//--------------------------------------------------------------------
// Retrieve information on the property by first getting the size
// of the property size.
// For details, see CertGetCertificateContextProperty.

   if(CertGetCertificateContextProperty(
         pCertContext,
         dwPropId ,
         NULL,
         &cbData))
    {
    //  Continue.
    }
    else
    {
    // If the first call to the function failed,
    // exit to an error routine.
        HandleError("Call #1 to GetCertContextProperty failed.");
    }
//--------------------------------------------------------------------
// The call succeeded. Use the size to allocate memory
// for the property.

   if(pvData = (void*)malloc(cbData))
   {
   // Memory is allocated. Continue.
   }
   else
   {
   // If memory allocation failed, exit to an error routine.
      HandleError("Memory allocation failed.");
   }
   //-----------------------------------------------------------------
   // Allocation succeeded. Retrieve the property data.

   if(CertGetCertificateContextProperty(
      pCertContext,
      dwPropId,
      pvData,
      &cbData))
    {
    // The data has been retrieved. Continue.
    }
    else
    {
    // If error occurred in the second call, exit to an error routine.
      HandleError("Call #2 failed.");
    }
    //----------------------------------------------------------------
    // Show the results.

   printf("The Property Content is %d \n", pvData);

   //-----------------------------------------------------------------
   // Free the certificate context property memory.

   free(pvData);
  }  // End inner while
} // End outer while

//--------------------------------------------------------------------
// Clean up.

CertFreeCertificateContext(pCertContext);
CertCloseStore(hCertStore,0);
printf("The function completed successfully. \n");
} // End of main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError


Example C Program: Deleting Certificates from a Certificate Store

The following program lists the certificates in a system certificate store, displaying the name of the subject of each certificate. The program allows the user to choose to delete any certificates from the store. The program gets the name of the certificate store from the user and thus can be used to maintain the contents of any system certificate store.

This example program illustrates the following tasks and CryptoAPI functions:

  • Opening a system certificate store using CertOpenSystemStore.
  • Listing the certificates in a certificate store using CertEnumCertificatesInStore.
  • Getting the name of the subject of a certificate using CertGetNameString.
  • Comparing the name of the subject of the certificate with the name of the issuer of the certificate using CertCompareCertificateName.
  • Checking to see if the public key of the current certificate matches the public key of a previous certificate using CertComparePublicKeyInfo.
  • Duplicating a pointer to a certificate context using CertDuplicateCertificateContext.
  • Comparing the CERT_INFO members of each certificate using CertCompareCertificate.
  • Deleting a certificate from a store using CertDeleteCertificateFromStore.
  • Closing a certificate store using CertCloseStore.
//------------------------------------------------------
// This program gets the name of a system certificate store
// from the user, opens that store, and goes through the
// certificates in that store.
// For each certificate, the name of the certificate's
// subject is displayed and the user is given an option
// to delete that certificate.

//------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);

void main(void)
{
// Declare and initialize variables.

HANDLE          hStoreHandle;
PCCERT_CONTEXT  pCertContext=NULL;
PCCERT_CONTEXT  pDupCertContext;
PCERT_PUBLIC_KEY_INFO pOldPubKey = NULL;
PCERT_PUBLIC_KEY_INFO pNewPubKey;
char pszStoreName[256];
char pszNameString[256];
char fResponse ='n';
char x;

//--------------------------------------------------------------------
// Get the name of the certificate store to open.
printf("This program maintains the contents of a certificate\n");
printf("store by allowing you to delete any excess certificates\n");
printf("from a store. \n\n");
printf("Please enter the name of the system store to maintain:");
scanf("%s%c",pszStoreName,&x);
printf("Certificates will be deleted from the %s store.\n",pszStoreName);

//--------------------------------------------------------------------
// Open a system certificate store.

if ( hStoreHandle = CertOpenSystemStore(
     NULL,
     pszStoreName))
{
     printf("The %s store has been opened. \n", pszStoreName);
}
else
{
     HandleError("The store was not opened.");
}
//-------------------------------------------------------------------
// Find the certificates in the system store.

while(pCertContext= CertEnumCertificatesInStore(
    hStoreHandle,
    pCertContext)) // On the first call to the function,
                   // this parameter is NULL. On all subsequent
                   // calls, it is the last pointer returned by
                   // the function.
{
//--------------------------------------------------------------------
//   Get and display the name of subject of the certificate.

if(CertGetNameString(
   pCertContext,
   CERT_NAME_SIMPLE_DISPLAY_TYPE,
   0,
   NULL,
   pszNameString,
   128))
{
   printf("\nCertificate for %s \n",pszNameString);
}
else
{
   HandleError("CertGetName failed.");
}
//-------------------------------------------------------------------
//  Check to see if the issuer and the subject are the same.

if(CertCompareCertificateName(
   MY_ENCODING_TYPE,
   &(pCertContext->pCertInfo->Issuer),
   &(pCertContext->pCertInfo->Subject)))
{
     printf("The certificate subject and issuer are the same.\n");
}
else
{
     printf("The certificate subject and issuer are not the same.\n");
}
//--------------------------------------------------------------------
//  Find out if this certificate's public key matches the public key
// of the last certificate.

pNewPubKey = &(pCertContext->pCertInfo->SubjectPublicKeyInfo);
if(pOldPubKey)
   if(CertComparePublicKeyInfo(
       MY_ENCODING_TYPE,
       pOldPubKey,
       pNewPubKey))
   {
       printf("The public keys are the same.\n");
   }
   else
   {
       printf("This certificate has a different public key.\n");
   }
//--------------------------------------------------------------------
//   Reset the old key.

pOldPubKey = pNewPubKey;

//--------------------------------------------------------------------
//  Find out if this certificate is to be deleted.

printf("Would you like to delete this certificate? (y/n) ");
scanf("%c",&fResponse);
if(fResponse == 'y')
{
   //-----------------------------------------------------------------
   //  Create a duplicate pointer to the certificate to be
   //  deleted. In this way, the original pointer is not freed
   //  when the certificate is deleted from the store
   //  and the enumeration of the certificates in the store can
   //  continue. If the original pointer is used, after the
   //  certificate is deleted, the enumeration loop stops.

   if(pDupCertContext = CertDuplicateCertificateContext(
      pCertContext))
   {
       printf("A duplicate pointer was created. Continue. \n");
   }
   else
   {
        HandleError("Duplication of the certificate pointer failed.");
   }

//--------------------------------------------------------------------
// Compare the pCertInfo members of the two certificates
// to determine whether they are identical.

if(CertCompareCertificate(
      X509_ASN_ENCODING,
      pDupCertContext->pCertInfo,
      pCertContext->pCertInfo))
{
     printf("The two certificates are identical. \n");
}
else
{
     printf("The two certificates are not identical. \n");
}
//--------------------------------------------------------------------
// Delete the certificate.
   if(CertDeleteCertificateFromStore(
     pDupCertContext))
   {
       printf("The certificate has been deleted. Continue. \n");
   }
   else
   {
      printf("The deletion of the certificate failed.\n");
   }
} // End if

//--------------------------------------------------------------------
//  Clear the input buffer.

scanf("%c",&x);

} // End of while

//--------------------------------------------------------------------
//   Clean up.

CertCloseStore(
   hStoreHandle,
   0);
printf("The program ran to completion successfully. \n");
} // End of main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError


Example C Program: Certificate Store Operations

This sample program demonstrates a number of common certificate store operations.

This example program illustrates the following tasks and CryptoAPI functions:

  • Opening and closing memory and system stores using CertOpenStore and CertCloseStore.
  • Duplicating an open store using CertDuplicateStore.
  • Finding in stores certificates that meet some criteria using CertFindCertificateInStore.
  • Creating a new certificate context from the encoded portion of an existing certificate using CertCreateCertificateContext.
  • Adding a retrieved certificate to a store in memory using CertAddCertificateContextToStore.
  • Adding a link to a certificate to a store using CertAddCertificateLinkToStore.
  • Saving the store in memory to a file on disk.
  • Opening and closing a file-based certificate store.

This example code uses the function HandleError. The C code for this function is included with the sample. Code for this and other auxiliary functions is also listed under General Purpose Functions.

//------------------------------------------------------
// This program creates a certificate store in
// memory. A system store is opened and duplicated.
// A certificate is retrieved from the system store.
// A new certificate is created from the encoded portion of the
// certificate retrieved.
// The certificate retrieved is added to the memory store.
// A second certificate is retrieved from the MY store and
// a link to that certificate is added to the memory store.
// The certificate and the link are then retrieved from the
// memory store and the memory is saved to
// disk.
// All of the stores and files are closed.
// Next, the file store is reopened and a search is done
// for the certificate link.

// The success of this program depends upon a MY store being
// available. That store must included a certificate with
// the subject "Microsoft," and a second certificate with
// the subject "Test Certificate." The names of the subjects
// may be changed to the names of certificate subjects that are
// known to be in the MY store.

//------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);

void main(void)
{
//--------------------------------------------------------------------
// Declare and initialize variables.

HCERTSTORE  hSystemStore;              // The system store handle.
HCERTSTORE  hMemoryStore;              // A memory store handle.
HCERTSTORE  hDuplicateStore;           // Handle for a store to be
                                       //created
                                       // as a duplicate of an open
                                       //store.
PCCERT_CONTEXT  pDesiredCert = NULL;   // Set to NULL for the first
                                       // call to
                                       // CertFindCertificateInStore.
PCCERT_CONTEXT  pCertContext;
HANDLE  hStoreFileHandle ;             // Output file handle.
LPCSTR  pszFileName = "TestStor.sto";  // Output file name.

//-------------------------------------------------------------------
// Open a new certificate store in memory.

if(hMemoryStore = CertOpenStore(
      CERT_STORE_PROV_MEMORY,    // A memory store.
      0,                         // Encoding type.
                                 // Not used with a memory store.
      NULL,                      // Use the default provider.
      0,                         // No flags.
      NULL))                     // Not needed.
{
   printf("Opened a memory store. \n");
}
else
{
   HandleError( "Error opening a memory store.");
}
//-------------------------------------------------------------------
// Open the MY system store using CertOpenStore.

if(hSystemStore = CertOpenStore(
     CERT_STORE_PROV_SYSTEM, // The system store will be a
                             // virtual store.
     0,                      // Encoding type not need with this PROV.
     NULL,                   // Accept the default HCRYPTPROV.
     CERT_SYSTEM_STORE_CURRENT_USER,
                             // Set the system store location in the
                             // registry.
     L"MY"))                 // Could have used other predefined
                             // system stores
                             // including Trust, CA, or Root.
{
   printf("Opened the MY system store. \n");
}
else
{
   HandleError( "Could not open the MY system store.");
}
//--------------------------------------------------------------------
// Create a duplicate of the MY store.

if(hDuplicateStore = CertDuplicateStore(hSystemStore))
{
  printf("The MY store is duplicated.\n");
}
else
{
  printf("Duplication of the MY store failed.\n.");
}
//-------------------------------------------------------------------
// Get a certificate that has the string "Microsoft" in its subject.

if(pDesiredCert=CertFindCertificateInStore(
      hSystemStore,
      MY_ENCODING_TYPE,            // Use X509_ASN_ENCODING.
      0,                           // No dwFlags needed.
      CERT_FIND_SUBJECT_STR,       // Find a certificate with a
                                   // subject that matches the string
                                   // in the next parameter.
      L"Microsoft",                // The Unicode string to be found
                                   // in a certificate's subject.
      NULL))                       // NULL for the first call to the
                                   // function. In all subsequent
                                   // calls, it is the last pointer
                                   // returned by the function.
{
  printf("The desired certificate was found. \n");
}
else
{
   HandleError("Could not find the desired certificate.");
}
//-------------------------------------------------------------------
// pDesiredCert is a pointer to a certificate with a subject that
// includes the string "Microsoft", the string passed as parameter
// #5 to the function.

//------------------------------------------------------------------
//  Create a new certificate from the encoded part of
//  an available certificate.

if(pCertContext = CertCreateCertificateContext(
    MY_ENCODING_TYPE  ,            // The encoding type
    pDesiredCert->pbCertEncoded,   // The encoded data from
                                   // the certificate retrieved
    pDesiredCert->cbCertEncoded))  // The length of the encoded data
{
  printf("A new certificate as been created.\n");
}
else
{
  HandleError("A new certificate could not be created.");
}

//--------------------------------------------------------------------
// Add the certificate from the MY store to the new memory store.

if(CertAddCertificateContextToStore(
      hMemoryStore,                // The store handle
      pDesiredCert,                // The pointer to a certificate
      CERT_STORE_ADD_USE_EXISTING,
      NULL))
{
   printf("Certificate added to the memory store. \n");
}
else
{
   HandleError("Could not add the certificate to the memory store.");
}
//-------------------------------------------------------------------
//  Find a different certificate in the MY store and add a link to it
//  to the memory store.

//-------------------------------------------------------------------
// Find the certificate context just added to the memory store.

if(pDesiredCert=CertFindCertificateInStore(
      hSystemStore,
      MY_ENCODING_TYPE,            // Use X509_ASN_ENCODING.
      0,                           // No dwFlags needed.
      CERT_FIND_SUBJECT_STR,       // Find a certificate with a
                                   // subject that matches the string
                                   // in the next parameter.
      L"TEST CERTIFICATE",         // The Unicode string to be found
                                   // in a certificate's subject.
      NULL))                       // NULL for the first call to the
                                   // function. In all subsequent
                                   // calls, it is the last pointer
                                   // returned by the function.
{
  printf("The TEST CERTIFICATE certificate was found. \n");
}
else
{
   HandleError("Could not find the TEST CERTIFICATE certificate.");
}
//--------------------------------------------------------------------
// Add a link to the TEST CERTIFICATE certificate from the MY store to
// the new memory store.

if(CertAddCertificateLinkToStore(
      hMemoryStore,           // The store handle
      pDesiredCert,           // The pointer to a certificate
      CERT_STORE_ADD_USE_EXISTING,
      NULL))
{
   printf("Certificate link added to the memory store. \n");
}
else
{
   HandleError("Could not add the certificate link to the memory store.");
}
//--------------------------------------------------------------------
// Find the first certificate in the memory store.

if(pDesiredCert=CertFindCertificateInStore(
      hMemoryStore,
      MY_ENCODING_TYPE,            // Use X509_ASN_ENCODING.
      0,                           // No dwFlags needed.
      CERT_FIND_SUBJECT_STR,       // Find a certificate with a
                                   // subject that matches the string
                                   // in the next parameter.
      L"Microsoft",                // The Unicode string to be found
                                   // in a certificate's subject.
      NULL))                       // NULL for the first call to the
                                   // function. In all subsequent
                                   // calls, it is the last pointer
                                   // returned by the function.
{
  printf("The desired certificate was found in the memory store. \n");
}
else
{
   printf("Certificate not in the memory store.\n");
}
//--------------------------------------------------------------------
//  Find the certificate link in the memory store.

if(pDesiredCert=CertFindCertificateInStore(
      hMemoryStore,
      MY_ENCODING_TYPE,            // Use X509_ASN_ENCODING.
      0,                           // No dwFlags needed.
      CERT_FIND_SUBJECT_STR,       // Find a certificate with a
                                   // subject that matches the string
                                   // in the next parameter.
      L"TEST CERTIFICATE",         // The Unicode string to be found
                                   // in a certificate's subject.
      NULL))                       // NULL for the first call to the
                                   // function. In all subsequent
                                   // calls, it is the last pointer
                                   // returned by the function.
{
  printf("The TEST CERTIFICATE certificate link was found in the memory store. \n");
}
else
{
   printf("The certificate link was not in the memory store.\n");
}
//-------------------------------------------------------------------
// Create a file to save the new store and certificate into.

if(hStoreFileHandle = CreateFile(
      pszFileName,        // File path
      GENERIC_WRITE,      // Access mode
      0,                  // Share mode
      NULL,               // Security
      CREATE_ALWAYS,      // How to create the file
      FILE_ATTRIBUTE_NORMAL,
                          // File attributes
      NULL))              // Template
{
   printf("Created a new file on disk. \n");
}
else
{
   HandleError("Could not create a file on disk.");
}
//-------------------------------------------------------------------
// hStoreFileHandle is the output file handle.
// Save the memory store and its certificate to the output file.

if( CertSaveStore(
      hMemoryStore,        // Store handle.
      0,                   // Encoding type not needed here.
      CERT_STORE_SAVE_AS_STORE,
      CERT_STORE_SAVE_TO_FILE,
      hStoreFileHandle,    // This is the handle of an open disk file.
      0))                  // dwFlags. No flags needed here.
{
   printf("Saved the memory store to disk. \n");
}
else
{
   HandleError("Could not save the memory store to disk.");
}
//-------------------------------------------------------------------
// Close the stores and the file. Reopen the file store, and check its
// contents.

if(hMemoryStore)
    CertCloseStore(
        hMemoryStore,
        CERT_CLOSE_STORE_CHECK_FLAG);

if(hSystemStore)
    CertCloseStore(
        hSystemStore,
        CERT_CLOSE_STORE_CHECK_FLAG);

if(hStoreFileHandle)
     CloseHandle(hStoreFileHandle);

printf("All of the stores and files are closed. \n");

//-------------------------------------------------------------------
//  Reopen the file store.

if(hMemoryStore = CertOpenStore(
       CERT_STORE_PROV_FILENAME,    // The store provider type.
       MY_ENCODING_TYPE,            // If needed, use the usual
                                    // encoding types.
       NULL,                        // Use the default HCRYPTPROV.
       0,                           // Accept the default for all
                                    // dwFlags.
       L"TestStor.sto" ))           // The name of an existing file
                                    // as a Unicode string.
{
     printf("The file store has been reopened. \n");
}
else
{
    printf("The file store could not be reopened. \n");
}
//--------------------------------------------------------------------
//  Find the certificate link in the reopened file store.

if(pDesiredCert=CertFindCertificateInStore(
      hMemoryStore,
      MY_ENCODING_TYPE,            // Use X509_ASN_ENCODING.
      0,                           // No dwFlags needed.
      CERT_FIND_SUBJECT_STR,       // Find a certificate with a
                                   // subject that matches the string
                                   // in the next parameter.
      L"FULL TEST CERT",           // The Unicode string to be found
                                   // in a certificate's subject.
      NULL))                       // NULL for the first call to the
                                   // function. In all subsequent
                                   // calls, it is the last pointer
                                   // returned by the function.
{
  printf("The certificate link was found in the file store. \n");
}
else
{
   printf("The certificate link was not in the file store.\n");
}
//-------------------------------------------------------------------
// Clean up memory and end.

if(pDesiredCert)
    CertFreeCertificateContext(pDesiredCert);
if(hMemoryStore)
    CertCloseStore(
        hMemoryStore,
        CERT_CLOSE_STORE_CHECK_FLAG);
if(hSystemStore)
    CertCloseStore(
        hSystemStore,
        CERT_CLOSE_STORE_CHECK_FLAG);
if(hStoreFileHandle)
     CloseHandle(hStoreFileHandle);
printf("All of the stores and files are closed. \n");
return;
} // End of main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError


Example C Program: Serializing Certificates and Adding Serialized Elements to Stores

The following is an example program that serializes a certificate context and its properties into a form that can be stored in a file, sent with an e-mail message, or otherwise transmitted to another user. The program also shows how the serialized certificate can be changed back into a certificate and added to a certificate store. The same process works also with CRLs and CTLs using CertSerializeCRLStoreElement and CertSerializeCTLStoreElement.

This example program illustrates the following tasks and CryptoAPI functions:

  • Opening a system certificate store using CertOpenSystemStore.
  • Opening a certificate store using CertOpenStore.
  • Retrieving a certificate from a store using CertEnumCertificatesInStore.
  • Getting the name of the certificate's subject using CertGetNameString.
  • Creating a serialized form of a certificate context and its properties using CertSerializeCertificateStoreElement.
  • Creating a new certificate from a serialized string and adding it into a certificate store using CertAddSerializedElementToStore.
  • Using CertAddEncodedCertificateToStore to create a new certificate from the encoded portion of an existing certificate.
  • Using CertCloseStore to close a certificate store.
//------------------------------------------------------
// Example code using CertSerializeCertificateStoreElement to
// serialize the data from a certificate,
// and CertAddSerializedElementToStore to add that data as a new
// certificate to a store.
// CertAddEncodeCertificateToStore is also demonstrated.

//------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);

void main(void)
{
//--------------------------------------------------------------------
// Declare and initialize variables.

HCERTSTORE         hSystemStore;
HCERTSTORE         hFileStore;
PCCERT_CONTEXT     pCertContext = NULL;
char               pszNameString[256];
BYTE*              pbElement;
DWORD              cbElement;

//--------------------------------------------------------------------
// Open a system certificate store.

if(hSystemStore = CertOpenSystemStore(
    0,
    "CA"))
{
  printf("The CA system store is open. Continue.\n");
}
else
{
  HandleError("The first system store did not open.");
}
//--------------------------------------------------------------------
// Open a second store.
// In order to work, a file-based certificate store named teststor.sto
// must be available in the working directory.

if(hFileStore = CertOpenStore(
   CERT_STORE_PROV_FILENAME,
   MY_ENCODING_TYPE,
   NULL,
   0,
   L"testStor.sto" ))
{
     printf("The file store is open. Continue.\n");
}
else
{
     HandleError("The file store did not open.");
}
//--------------------------------------------------------------------
// Retrieve the first certificate from the Root store.
// CertFindCertificateInStore could be used here to find
// a certificate with a specific property.

if(pCertContext=CertEnumCertificatesInStore(
    hSystemStore,
    pCertContext))
{
printf("A certificate is available. Continue.\n");
}
else
{
     HandleError("No certificate available. The store may be empty.");
}
//--------------------------------------------------------------------
//  Find and print the name of the subject of the certificate
//  just retrieved.

if(CertGetNameString(
   pCertContext,
   CERT_NAME_SIMPLE_DISPLAY_TYPE,
   0,
   NULL,
   pszNameString,
   128))
{
     printf("Certificate for %s has been retrieved.\n",pszNameString);
}
else
{
     printf("CertGetName failed. \n");
}
//--------------------------------------------------------------------
// Find out how much memory to allocate for the serialized element.

if(CertSerializeCertificateStoreElement(
    pCertContext,      // The existing certificate.
    0,                 // Accept default for dwFlags,
    NULL,              // NULL for the first function call.
    &cbElement))       // Address where the length of the
                       // serialized element will be placed.
{
     printf("The length of the serialized string is %d.\n",cbElement);
}
else
{
     HandleError("Finding the length of the serialized element failed.");
}
//--------------------------------------------------------------------
// Allocate memory for the serialized element.

if(pbElement = (BYTE*)malloc(cbElement))
{
     printf("Memory has been allocated. Continue.\n");
}
else
{
     HandleError("The allocation of memory failed.");
}
//--------------------------------------------------------------------
// Create the serialized element from a certificate context.

if(CertSerializeCertificateStoreElement(
    pCertContext,        // The certificate context source for the
                         // serialized element.
    0,                   // dwFlags. Accept the default.
    pbElement,           // A pointer to where the new element will
                         // be stored.
    &cbElement))         // The length of the serialized element,
{
     printf("The encoded element has been serialized. \n");
}
else
{
     HandleError("The element could not be serialized.");
}
//--------------------------------------------------------------------
//  pbElement could be written to a file or be sent by e-mail
//  to another user.
//  The following process uses the serialized
//  pbElement and its length, cbElement, to
//  add a new certificate to a store.

if(CertAddSerializedElementToStore(
    hFileStore,          // Store where certificate is to be added.
    pbElement,           // The serialized element for another
                         // certificate.
    cbElement,           // The length of pbElement.
    CERT_STORE_ADD_REPLACE_EXISTING,
                         // Flag to indicate what to do if a matching
                         // certificate is already in the store.
    0,                   // dwFlags. Accept the default.
    CERT_STORE_CERTIFICATE_CONTEXT_FLAG,
    NULL,
    NULL
    ))
{
     printf("The new certificate is added to the second store.\n");
}
else
{
     HandleError("The new element was not added to a store.");
}
//--------------------------------------------------------------------
//  Next, another certificate will be retrieved from the system store
//  and its encoded part, pCertContext->pbCertEncoded, will be used to
//  create a new certificate to be added to the file store.

if(pCertContext=CertEnumCertificatesInStore(
    hSystemStore,
    pCertContext))
{
printf("Another certificate is available. Continue.\n");
}
else
{
     HandleError("No certificate is available. The store may be empty.");
}

//--------------------------------------------------------------------
//  Find and print the name of the subject of the certificate
//  just retrieved.

if(CertGetNameString(
   pCertContext,
   CERT_NAME_SIMPLE_DISPLAY_TYPE,
   0,
   NULL,
   pszNameString,
   128))
{
     printf("Certificate for %s has been retrieved.\n",pszNameString);
}
else
{
     printf("CertGetName failed. \n");
}
//--------------------------------------------------------------------
//  Create a new certificate from the encoded portion of pCertContext
//  and add it to the file-based store.

if(CertAddEncodedCertificateToStore(
     hFileStore,
     MY_ENCODING_TYPE,
     pCertContext->pbCertEncoded,
     pCertContext->cbCertEncoded,
     CERT_STORE_ADD_USE_EXISTING,
     NULL))
{
     printf("Another certificate is added to the file store.\n");
}
else
{
     HandleError("The new certificate was not added to the file store.");
}
//--------------------------------------------------------------------
// Free memory.

free(pbElement);
CertCloseStore(hSystemStore,0);
CertCloseStore(hFileStore,0);
printf("The program ran without error to the end.\n");

} // End of main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError


Example C Program: Getting and Setting Certificate Properties

This example program gets and sets certificate properties, and illustrates the following tasks and CryptoAPI functions:

  • Opening a system store using CertOpenSystemStore.
  • Using CertEnumCertificatesInStore to list all of thecertificates in the open store.
  • Retrieving and printing the subject name from the certificate using CertGetNameString.
  • Setting the enhanced key usage property on certificates using the CertAddEnhancedKeyUsageIdentifier function.
  • Setting the friendly name property on the certificate using CertSetCertificateContextProperty.
  • Retrieving a certificate's properties using CertGetCertificateContextProperty.
  • Closing a certificate store using CertCloseStore with the CERT_CLOSE_STORE_CHECK_FLAG flag.
#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>

//--------------------------------------------------------------------
//   Declare functions HandleError and My_Wait.
//   These functions are defined at the end of the file.

void HandleError(char *s );

void My_Wait();

//--------------------------------------------------------------------
//  Begin main.

void main (void)
{

//--------------------------------------------------------------------
// This program shows all of the certificates in a
// certificate store and lists all of the property ID numbers of all
// of the certificate contexts.

// It also adds an enhanced key usage identifier to every other
// certificate.

//--------------------------------------------------------------------
//  Declare and initialize local variables.

HANDLE           hCertStore;
PCCERT_CONTEXT   pCertContext=NULL;
CRYPT_KEY_PROV_INFO *pCryptKeyProvInfo;
char pszNameString[256];
char pszStoreName[256];
char fResponse;
char fExtra;
BYTE *pName = (BYTE *)"Temp Name.";
CRYPT_DATA_BLOB  Friendly_Name_Blob={32,pName};
void*            pvData;
DWORD            cbData;
DWORD            dwFlags =  CERT_STORE_NO_CRYPT_RELEASE_FLAG;
DWORD            dwPropId = 0;   // 0 must be used on the first
                                 // call to the function. After that,
                                 // the last returned property ID is
                                 // passed.
LPCSTR  pszUsageIdentifier = szOID_RSA_RC4;
int count = 0;

fprintf(stderr,"Please enter the store name :");
scanf("%s",pszStoreName);
fprintf(stderr,"The store name is %s .\n",pszStoreName);
My_Wait();

//--------------------------------------------------------------------
// Open the named system certificate store.

if (!( hCertStore = CertOpenSystemStore(
   NULL,
   pszStoreName)))
{
     HandleError("Store not opened.");
}

//--------------------------------------------------------------------
// The file is open. Continue.
// In a loop, use CertEnumCertificatesInStore to get the each
// certificate in the store.

while(pCertContext= CertEnumCertificatesInStore(
     hCertStore,
     pCertContext))
{
//--------------------------------------------------------------------
//  First, retrieve and print the subject name from the certificate.

     if(CertGetNameString(
        pCertContext,
        CERT_NAME_SIMPLE_DISPLAY_TYPE,
        0,
        NULL,
        pszNameString,
        128))
     {
          printf("\nNew Cert for %s \n",pszNameString);
     }
     else
     {
          printf("The get name failed.\n");
     }
//--------------------------------------------------------------------
//  Set the enhanced key usage property on every other certificate.

     if(count == 0)
     {
          count++;
          if(CertAddEnhancedKeyUsageIdentifier(
               pCertContext,
               pszUsageIdentifier))
          {
               printf("Enhanced key usage set.\n");
          }
          else
          {
               printf("Enhanced key usage was not set.\n");
          }
     }
     else
//--------------------------------------------------------------------
//   Do not set the usage, but reset the counter so that the property
//   will be set on the next certificate.
//   Ask if the user would like to set a friendly name.
     {
         printf("Would you like to set the friendly name ?");
         scanf("%c%c",&fResponse,&fExtra);
         if(fResponse == 'y')
         {
           if(CertSetCertificateContextProperty(
                pCertContext,
                CERT_FRIENDLY_NAME_PROP_ID,
                0,
                &Friendly_Name_Blob))
           {
               printf("A name has been set.\n");
           }
           else
           {
                printf("The friendly name was not set.\n");
            }
         }
          count = 0;
     }

//--------------------------------------------------------------------
// In a loop, find all of the property IDs for the given certificate.
// The loop continues until the CertEnumCertificateContextProperties
// returns 0.

     while(dwPropId = CertEnumCertificateContextProperties(
       pCertContext, // the context whose properties are to be listed.
       dwPropId))    // number of the last property found. Must be
                     // 0 to find the first property ID.
     {
//--------------------------------------------------------------------
// Each time through the loop, a property ID has been found.
// Print the property number and information about the property.

        printf("Property # %d found->", dwPropId);
        switch(dwPropId)
        {
        case CERT_FRIENDLY_NAME_PROP_ID:
        {
//--------------------------------------------------------------------
//  Retrieve the actual friendly name certificate property.
//  First, get the length of the property setting the
//  pvData parameter to NULL to get a value for cbData
//  to be used to allocate memory for the pvData buffer.
          printf("FRIENDLY_NAME_PROP_ID ");
          if(!(CertGetCertificateContextProperty(
            pCertContext,
            dwPropId,
            NULL,
            &cbData)))
          {
             HandleError("Call #1 to property length failed.");
          }
//--------------------------------------------------------------------
// The call succeeded. Use the size to allocate memory for the
// property.
          if(!(pvData = (void*)malloc(cbData)))
          {
            HandleError("Memory allocation failed.");
          }
//--------------------------------------------------------------------
// Allocation succeeded. Retrieve the property data.
          if(!(CertGetCertificateContextProperty(
              pCertContext,
              dwPropId,
              pvData,
              &cbData)))
          {
             HandleError("Call #2 getting the data failed.");
          }
          else
          {
             printf("\n  The friendly name is -> %s.", pvData);
             free(pvData);
          }
          break;
        }
        case CERT_SIGNATURE_HASH_PROP_ID:
        {
           printf("Signature hash ID. ");
           break;
        }
        case CERT_KEY_PROV_HANDLE_PROP_ID:
        {
           printf("KEY PROVE HANDLE.");
           break;
        }
        case CERT_KEY_PROV_INFO_PROP_ID:
        {
          printf("KEY PROV INFO PROP ID.");
          if(!(CertGetCertificateContextProperty(
             pCertContext,  // A pointer to the certificate
                            // where the property will be set.
             dwPropId,      // An identifier of the property to get.
                            // In this case,
                            // CERT_KEY_PROV_INFO_PROP_ID
             NULL,          // NULL on the first call to get the
                            // length.
             &cbData)))     // The number of bytes that must be
                            // allocated for the structure.
          {
             HandleError("The property length was not retrieved.");
          }
          if(!(pCryptKeyProvInfo =
                   (CRYPT_KEY_PROV_INFO *)malloc(cbData)))
          {
             HandleError("Error in allocation of memory.");
           }
           if(CertGetCertificateContextProperty(
                pCertContext,
                dwPropId,
                pCryptKeyProvInfo,
                &cbData))
           {
               printf("\n The current key container is %S.",
                   pCryptKeyProvInfo->pwszContainerName);
               free(pCryptKeyProvInfo);
           }
           else
           {
               free(pCryptKeyProvInfo);
               HandleError("The property was not retrieved.");
           }
           break;
        }
        case CERT_SHA1_HASH_PROP_ID:
        {
          printf("SHA1 HASH id.");
          break;
        }
        case CERT_MD5_HASH_PROP_ID:
        {
          printf("md5 hash id. ");
          break;
        }
        case CERT_KEY_CONTEXT_PROP_ID:
        {
          printf("KEY CONTEXT PROP id.");
          break;
        }
        case CERT_KEY_SPEC_PROP_ID:
        {
          printf("KEY SPEC PROP id.");
          break;
        }
        case CERT_ENHKEY_USAGE_PROP_ID:
        {
          printf("ENHKEY USAGE PROP id.");
          break;
        }
        case CERT_NEXT_UPDATE_LOCATION_PROP_ID:
        {
          printf("NEXT UPDATE LOCATION PROP id.");
          break;
        }
        case CERT_PVK_FILE_PROP_ID:
        {
          printf("PVK FILE PROP id. ");
          break;
        }
        case CERT_DESCRIPTION_PROP_ID:
        {
          printf("DESCRIPTION PROP id. ");
          break;
        }
        case CERT_ACCESS_STATE_PROP_ID:
        {
          printf("ACCESS STATE PROP id. ");
          break;
        }
        case CERT_SMART_CARD_DATA_PROP_ID:
        {
          printf("SMAART_CARD DATA PROP id. ");
          break;
        }
        case CERT_EFS_PROP_ID:
        {
          printf("EFS PROP id. ");
          break;
        }
        case CERT_FORTEZZA_DATA_PROP_ID:
        {
          printf("FORTEZZA DATA PROP id.");
         break;
        }
        case CERT_ARCHIVED_PROP_ID:
        {
          printf("ARCHIVED PROP id.");
          break;
        }
        case CERT_KEY_IDENTIFIER_PROP_ID:
        {
          printf("KEY IDENTIFIER PROP id. ");
          break;
        }
        case CERT_AUTO_ENROLL_PROP_ID:
        {
          printf("AUTO ENROLL id. ");
          break;
        }
        }  // end switch
        printf("\n");
      } // end the inner while loop. This is the end of the display of
        // a single property of a single certificate.

      My_Wait();
} // end the outer while loop. Move on to the next certificate.

//--------------------------------------------------------------------
// Free Memory and close the open store.
if(pCertContext)
{
    CertFreeCertificateContext(pCertContext);
}
CertCloseStore(hCertStore,0);
printf("The function completed successfully.\n");
}

//--------------------------------------------------------------------
//  Define functions HandleError and My_Wait.

void HandleError( char *s)
{
     printf("%s\n",s);
     exit(1);
}

void My_Wait()
{

     printf("Hit enter to continue.");
     getchar();
}


Example C Program: Converting Names from Certificates to ASN1 and Back

Platform SDK: Security

Example C Program: Converting Names from Certificates to ASN.1 and Back

This example program enumerates the certificates in a certificate store, displays the subject and user of each certificate, and converts the subject name from each certificate into its ASN.1 encoded form, and then back in to its decoded from.

This example program illustrates the following tasks and CryptoAPI functions:

  • Opening a system store using CertOpenSystemStore.
  • Using CertEnumCertificatesInStore to get the first certificate from the open store.
  • Using CertGetNameString to get the subject name and the user name from the certificate.
  • Using CertNameToStr to convert the subject name from the certificate into its ANS1 encoded form.
  • Using CertStrToName to convert an ANS1 encoded string into its decoded form.
  • Closing a certificate store using CertCloseStore with the CERT_CLOSE_STORE_CHECK_FLAG flag.
//--------------------------------------------------------------------
//   Example C Program:
//   Converting a name from a certificate to an ASN.1 encoded string
//   and back.

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>

#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

//--------------------------------------------------------------------
//   Declare auxiliary functions

void HandleError(char *s);

void Local_wait();

void main(void)
{
//--------------------------------------------------------------------
//      Declare and initialize main's variables.

HCERTSTORE               hCertStore;
PCCERT_CONTEXT           pCertContext = NULL;
PCERT_BLOB               pCert_Blob;
DWORD                    dwFlags=0;
DWORD                    dwStrType = CERT_OID_NAME_STR;
LPSTR                    pszName;
DWORD                    cbName;
DWORD                    cbNameLen;
LPSTR                    sz;

//--------------------------------------------------------------------
//      Begin Processing by opening a certificate store.

if(!(hCertStore=CertOpenStore(
     CERT_STORE_PROV_SYSTEM,
     MY_ENCODING_TYPE,
     NULL,
     CERT_SYSTEM_STORE_CURRENT_USER,
     L"MY")))
{
   HandleError("The MY system store did not open.");
}

//--------------------------------------------------------------------
//       Loop through the certificates in the store.
//       For each certificate,
//             get and print the name of the
//                  certificate subject and issuer.
//             convert the subject name from the certificate
//                  to an ASN.1 encoded string and print the
//                  octets from that string.
//             convert the encoded string back into its form
//                  in the certificate.

while(pCertContext = CertEnumCertificatesInStore(
             hCertStore,
             pCertContext))
{

//--------------------------------------------------------------------
//        Get and display
//        the name of subject of the certificate.

if(!(cbNameLen = CertGetNameString(
   pCertContext,
   CERT_NAME_SIMPLE_DISPLAY_TYPE,
   0,
   NULL,
   NULL,
   0)))
{
   HandleError("CertGetName 1 failed.");
}

if(!(sz = (char *) malloc(cbNameLen+1)))
    HandleError("Memory allocation failed.");

if(CertGetNameString(
   pCertContext,
   CERT_NAME_SIMPLE_DISPLAY_TYPE,
   0,
   NULL,
   (char *)sz,
   cbNameLen+1))
{
   printf("\nSubject -> %s.\n",sz);
}
else
{
   HandleError("CertGetName failed.");
}
free(sz);
//--------------------------------------------------------------------
//        Get and display
//        the name of Issuer of the certificate.

if(!(cbNameLen = CertGetNameString(
   pCertContext,
   CERT_NAME_SIMPLE_DISPLAY_TYPE,
   CERT_NAME_ISSUER_FLAG,
   NULL,
   NULL,
   0)))
{
   HandleError("CertGetName 1 failed.");
}

if(!(sz = (char *) malloc(cbNameLen+1)))
    HandleError("Memory allocation failed.");

if(CertGetNameString(
   pCertContext,
   CERT_NAME_SIMPLE_DISPLAY_TYPE,
   CERT_NAME_ISSUER_FLAG,
   NULL,
   (char *)sz,
   cbNameLen+1))
{
   printf("Issuer  -> %s.\n",sz);
}
else
{
   HandleError("CertGetName failed.");
}

//--------------------------------------------------------------------
//       Free the memory allocated for the string.

free(sz);

//--------------------------------------------------------------------
//       Convert the subject name to an ASN.1 encoded
//       string and print the octets in that string.

//       First : Get the number of bytes that must
//       be allocated for the string.

cbName = CertNameToStr(
   MY_ENCODING_TYPE,
   &(pCertContext->pCertInfo->Subject),
   dwStrType,
   NULL,
   0);

//--------------------------------------------------------------------
//  The function CertNameToStr returns the number
//  of bytes needed for a string to hold the
//  converted name. If it returns zero, there
//  has been an error.

if (0 == cbName)
{
     HandleError("Getting lenght of name failed.");
}

//--------------------------------------------------------------------
//        Allocated the needed buffer. Note that this
//        memory must be freed inside the loop or the
//        application could use up all memory.

if(!(pszName = (char *)malloc(cbName)))
{
     HandleError("Memory allocation failed.");
}

//--------------------------------------------------------------------
//       Call the function again to get the string

cbName = CertNameToStr(
   MY_ENCODING_TYPE,
   &(pCertContext->pCertInfo->Subject),
   dwStrType,
   pszName,
   cbName);

//--------------------------------------------------------------------
//      If the function succeeded, it returns the
//      number of bytes copied to the pszName buffer.

if (cbName < 1)
{
     HandleError("Getting name failed.");
}

//--------------------------------------------------------------------
//    Get the length needed to convert the string back
//    back into the name as it was in the certificate.

if(!(CertStrToName(
       MY_ENCODING_TYPE,
       pszName,
       dwStrType,
       NULL,
       NULL,        // NULL to get the number of bytes
                    // needed for the buffer.
       &cbName,     // Pointer to a DWORD to hold the
                    // number of bytes needed for the
                    // buffer
       NULL )))     // Optional address of a pointer to
                    // old the location for an error in the
                    // input string.
{
     HandleError("Could not get the lenth of the BLOB.");
}

if (!(pCert_Blob=(CERT_BLOB *)malloc(cbName)))
{
     HandleError("Memory Allocation for the BLOB failed.");
}

if(CertStrToName(
       MY_ENCODING_TYPE,
       pszName,
       dwStrType,
       NULL,
       (BYTE *)pCert_Blob,
       &cbName,
       NULL))
{
     printf("CertStrToName created the BLOB.\n");
}
else
{
     HandleError("Could not create the BLOB.");
}

//--------------------------------------------------------------------
//       Free the memory .

free(pCert_Blob);
free(pszName);

//--------------------------------------------------------------------
//       Pause before information on the next certificate
//       is displayed.

Local_wait();

} // End of while loop

printf("\nThere are no more certificates in the store. \n");

//--------------------------------------------------------------------
//   Close the MY store.

if(CertCloseStore(
     hStoreHandle,
     CERT_CLOSE_STORE_CHECK_FLAG))
{
   printf("The store is closed. All certificates are released.\n");
}
else
{
  printf("The store was closed, but certificates still in use.\n");
}

printf("This demonstration program ran to completion without error.\n");

} // End of main

//--------------------------------------------------------------------
//    This example uses the function HandleError, a simple error
//    handling function, to print an error message to the standard error
//    (stderr) file and exit the program.
//    For most applications, replace this function with one
//    that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError

void Local_wait()
{
//--------------------------------------------------------------------
//  This function prints a prompt string
//  and wait for the user to hit enter.
//  It provides a pause with its length controlled by the user.

     printf("Hit enter to continue : ");
     getchar();
}


Other Extended C Code Examples

The following topics present other procedures and extended C code examples using CryptoAPI functions:

  • Verifying a CTL.
  • Verifying Signed Messages by Using CTLs.
  • Example C Program: Certificate Verification Operations.
  • Example C Program: Working with Key Identifiers.
  • Example C Program: Creating a Certificate Chain.
  • Example C Program: Making a Certificate Request.
  • Example C Program: ASN1 Encoding and Decoding.
  • Example C Program: Using CertOIDToAlgId and CertCompareIntegerBlob.


Verifying a CTL

To make it more difficult for an interloper to substitute a bogus CTL for an existing one, verify the signature on the CTL each time the CTL is used. Do not use a CTL that does not contain a trusted signature.

To verify a CTL signature

  1. Open the certificate store containing the desired CTL.
  2. Get a handle to a CTL_CONTEXT for the CTL. This can be done by calling any of the functions that return a handle to the CTL_CONTEXT, such as CertFindCTLInStore.
  3. Call CryptMsgGetAndVerifySigner, passing the CTL_CONTEXT retrieved in step 2 in the hCryptMsg parameter, a handle to the certificate store containing the certificate of the trusted source for CTLs in the rghSignerStore parameter, and the CMSG_TRUSTED_SIGNER_FLAG in the dwFlags parameter. If the function returns TRUE, the signature was verified, and a pointer to the CTL signer's PCCERT_CONTEXT is returned in the ppSigner parameter.


Verifying Signed Messages by Using CTLs

One of the advantages of using CTLs is that applications can be designed that can automatically verify signed messages against trusted certificates without bothering the user with dialog boxes. It also gives a network administrator control sources to be trusted. The following procedure can be used to verify the signature of a signed message by using a CTL.

To verify a signed message by using a CTL

  1. Decode the message as follows:
    1. Get a pointer to the received message (the encoded BLOB).
    2. Call CryptMsgOpenToDecode, passing the necessary arguments.
    3. Call CryptMsgUpdate once, passing in the handle retrieved in step b and a pointer to the data that is to be decoded. This causes the appropriate actions to be taken on the message, depending on the message type.
  2. Verify the signature of the decoded, signed message, and get a pointer to the signer's CERT_CONTEXT.

    This can be done by calling CryptMsgGetAndVerifySigner, passing the message handle retrieved in step 1c as the hCryptMsg parameter. If the function call returns TRUE, the signature was verified, and a pointer to the signer's PCCERT_CONTEXT is returned in the ppSigner parameter.

  3. Confirm that the signer is a trusted source as follows:
    1. Open the certificate store containing the appropriate CTL.
    2. Get a pointer to the CTL_CONTEXT by calling CertFindCTLInStore.
    3. To confirm that the signer is a trusted source, call CertFindSubjectInCTL, passing the pointer retrieved in the previous step in the pCtlContext parameter, CTL_CERT_SUBJECT_TYPE in the dwSubjectType parameter, and the pointer to the CERT_CONTEXT retrieved in step 2 in the pvSubject parameter. If the function call returns TRUE, the CERT_CONTEXT passed to the function is a trusted source in the CTL.


Example C Program: Certificate Verification Operations

This example program illustrates the following tasks and CryptoAPI functions:

  • Opening and closing the system store.
  • Finding a certificate by subject name.
  • Using CertVerifyTimeValidity to check the certificate's validity.

This sample program uses the following CryptoAPI functions:

  • CertOpenStore
  • CertFindCertificateInStore
  • CertVerifyTimeValidity
  • CertFreeCertificateContext
  • CertCloseStore

This example code uses the function HandleError. The C code for this function is included with the sample. Code for this and other auxiliary functions is also listed under General Purpose Functions.

//-------------------------------------------------------------------
//  This codes demonstrates:
//      1. Opening and closing a system store.
//      2. Finding a certificate by subject name.
//      3. Using the CertVerifyTimeValidity function to check the
//                certificate's validity.

//--------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);

void main(void)
{
//--------------------------------------------------------------------
// Declare and initialize variables.

HCERTSTORE      hSystemStore;
PCCERT_CONTEXT  pTargetCert=NULL;
PCERT_INFO          pTargetCertInfo;
char            szSubjectName[] = "Microsoft"; // A string to be found
                                               // in a certificate
                                               // subject

//--------------------------------------------------------------------
// Call CertOpenStore to open the Root store.

if(hSystemStore = CertOpenStore(
      CERT_STORE_PROV_SYSTEM,
      0,
      NULL,
      CERT_SYSTEM_STORE_CURRENT_USER,
      L"ROOT"))
{
   printf("CertOpenStore succeeded. The Root store is open. \n");
}
else
{
   HandleError( "Error opening the Root store.");
}
//--------------------------------------------------------------------
// Get a particular certificate using CertFindCertificateInStore.

if(pTargetCert = CertFindCertificateInStore(
      hSystemStore,           // Store handle.
      MY_ENCODING_TYPE,       // Encoding type.
      0,                      // Not used.
      CERT_FIND_SUBJECT_STR_A,// Find type. Find a string in the
                              // certificate's subject.
      szSubjectName,          // The string to be searched for.
      pTargetCert))           // Previous context.
{
   printf("Found the certificate. \n");
}
else
{
   HandleError("Could not find the required certificate");
}
//--------------------------------------------------------------------
// pTargetCert is a pointer to the desired certificate.
// Check the certificate's validity.

pTargetCertInfo = pTargetCert->pCertInfo;
switch(CertVerifyTimeValidity(
      NULL,               // Use current time.
      pTargetCertInfo))   // Pointer to CERT_INFO.
{
   case -1 :
   {
        printf("Certificate not valid yet. \n");
        break;
   }
   case 1:
   {
       printf("Certificate is expired. \n");
       break;
   }
   case 0:
   {
      printf("Certificate is valid. \n");
      break;
    }
};
//--------------------------------------------------------------------
// Clean up memory and quit.

if (pTargetCert)
   CertFreeCertificateContext(pTargetCert);
if(hSystemStore)
   CertCloseStore(
        hSystemStore,
        CERT_CLOSE_STORE_CHECK_FLAG);

printf("The certificate has been freed and the store closed. \n");
printf("The certificate verification program ran to completion without error. \n");
} // End of main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError


Example C Program: Working with Key Identifiers

The following C program demonstrates ways of working with key identifiers. This example program illustrates the following tasks and CryptoAPI functions:

  • Creating a key identifier using CryptCreateKeyIdentifierFromCSP.
  • Setting a property on a key identifier using CryptSetKeyIdentifierProperty.
  • Retrieving the contents of a key identifier property using CryptGetKeyIdentifierProperty.
  • Listing the properties of a key indentifier using CryptEnumKeyIdentifierProperties.
  • Declaring, defining, and using a callback function.
#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>

//--------------------------------------------------------------------
// This program demonstrates the following Key Identifier functions:
//         CryptCreateKeyIdentifierFromCSP
//         CryptSetKeyIdentifierProperty
//         CryptGetKeyIdentifierProperty
//         CryptEnumKeyIdentifierProperties
// The callback function pfnEnum is also demonstrated.

//--------------------------------------------------------------------
// Declare the Callback function

static BOOL WINAPI pfnEnum (
const CRYPT_HASH_BLOB *pKeyIdentifier, // in- pKeyIdentifier
DWORD dwFlags,                         // in- Flag values
void *pvReserved,                      // Reserved
void *pvArg,                           // in- Passthrough argument
DWORD cProp,                           // in- cProp
DWORD *rgdwPropId,                     // in- array of PropIds
void **rgpvData,                       // in- array of
                                       //  CRYPT_KEY_PROV_INFO
                                       //  structures
DWORD *rgcbData                        // in- rgcbData
);

//--------------------------------------------------------------------
//  Declare the HandleError function.

void HandleError(char *s);

void main(void)
{
//--------------------------------------------------------------------
// Declare and initialize variables.

PUBLICKEYSTRUC *pPubKeyStruc;
DWORD cbPubKeyStruc= sizeof(PUBLICKEYSTRUC);
if(!(pPubKeyStruc= (PUBLICKEYSTRUC *) malloc (cbPubKeyStruc))
    HandleError("Memory allocation failed.");

pPubKeyStruc->bType= PUBLICKEYBLOB;
pPubKeyStruc->bVersion= CUR_BLOB_VERSION;
pPubKeyStruc->reserved= 0;
pPubKeyStruc->aiKeyAlg= CALG_RSA_KEYX;

BYTE *pbHash;
DWORD cbHash;
PCRYPT_KEY_PROV_INFO pData;

CRYPT_HASH_BLOB KeyIdentifier;

DWORD cbData;
void *pvArg;         // Pass through argument.
cbHash= 20;          // define cbHash to the size of a SHA1
                     // string- there is no need for a 2 pass
                     // call to determine size of cbHash.

//--------------------------------------------------------------------
// Allocate memory for the pbHash buffer

if(!(pbHash= (BYTE *) malloc (cbHash))
    HandleError("Memory allocation failed.");

//--------------------------------------------------------------------
// Create a Key Identifier

if(CryptCreateKeyIdentifierFromCSP(
   X509_ASN_ENCODING, // dwCertEncodingType
   NULL,              // pszPubKeyOID- NULL to
                      // use default OID.
   pPubKeyStruc,      // pPubKeyStruc- defined above
   cbPubKeyStruc,     // cbPubKeyStruc
   0,                 // dwFlags
   NULL,              // pvReserved
   pbHash,            // pbHash
   &cbHash            // pcbHash
   ))
{
   printf("Call to CryptCreateKeyIdentifierFromCSP succeeded.\n");
}
else
{
   HandleError("A key identifier was not created");
}
//--------------------------------------------------------------------
// Set the members of the key identifier.

KeyIdentifier.cbData= cbHash;
KeyIdentifier.pbData= (BYTE*) pbHash;

//--------------------------------------------------------------------
// Initalize the pdata structure.

if(!(pData= (CRYPT_KEY_PROV_INFO*) malloc (sizeof(CRYPT_KEY_PROV_INFO))))
    HandleError("Memory allocation failed.");
pData->pwszContainerName= L"New Key container name";
pData->pwszProvName= MS_ENHANCED_PROV_W;
pData->dwProvType= PROV_RSA_FULL;
pData->dwFlags= 0;
pData->cProvParam= 0;
pData->rgProvParam= NULL;
pData->dwKeySpec= AT_SIGNATURE;

//--------------------------------------------------------------------
// Set a property on the created key identifier.

if(CryptSetKeyIdentifierProperty(
  &KeyIdentifier,             // in- defined above
  CERT_KEY_PROV_INFO_PROP_ID, // in- dwPropId
  CRYPT_KEYID_MACHINE_FLAG,   // in- dwFlags- use local computer
  NULL,                       // in- pwszComputerName
  NULL,                       // Reserved
  pData                       // in- pointer to a CRYPT_KEY_PROV_INFO.
  ))
{
  printf("A property is set on the key identifier.\n");
}
else
{
  HandleError("Setting the property failed.");
}

//--------------------------------------------------------------------
// Call CryptGetKeyIdentifierProperty to set the size
// of the property to be retrieved.

if(CryptGetKeyIdentifierProperty(
   &KeyIdentifier,             // in- defined above
   CERT_KEY_PROV_INFO_PROP_ID, // in- dwPropId
   CRYPT_KEYID_MACHINE_FLAG,   // in- dwFlags
   NULL,                       // in, optional- pwszComputerName
   NULL,                       // in, optional- pvReserved
   NULL,                       // out- pvData
   &cbData                     // in, out- pcbData
   ))
{
   printf("First call to get property succeeded.\n");
}
else
{
   HandleError("Call 1 to CryptGetKeyIdentifierProperty failed.");
}

//--------------------------------------------------------------------
// Free the memory allocated for pData,

free(pData);
//--------------------------------------------------------------------
// Allocate memory for the buffer to receive the property.

if(!(pData= (CRYPT_KEY_PROV_INFO*) malloc (cbData)))
    HandleError("Memory allocation failed.");

//--------------------------------------------------------------------
// Call CryptGetKeyIdentifierProperty a second time
// To retrieve the property into the allocated buffer.

if(CryptGetKeyIdentifierProperty(
   &KeyIdentifier,             // pKeyIdentifier
   CERT_KEY_PROV_INFO_PROP_ID, // dwPropId
   CRYPT_KEYID_MACHINE_FLAG,   // dwFlags
   NULL,                       // pwszComputerName
   NULL,                       // Reserved
   pData,                      // pData
   &cbData                     // pcbData
   ))
{
   printf("The property has been retrieved.\n");
}
else
{
   HandleError("Second call failed.");
}

//--------------------------------------------------------------------
// Print part of the retrieved property.

printf("Some of the properties obtained are;\n");
printf("container name= %S\n",pData->pwszContainerName);
printf("Provider name= %S\n", pData->pwszProvName);
printf("Provider type= %i\n", pData->dwProvType);
printf("length= %i\n\n", cbData);

//--------------------------------------------------------------------
// Set the pass through argument for the callback function.

pvArg= pPubKeyStruc;

//--------------------------------------------------------------------
// Call CryptEnumKeyIdentifierProperties.

printf("\nCalling CryptEnumKeyIdentifierProperties.\n");
if(CryptEnumKeyIdentifierProperties(
   &KeyIdentifier,           // in- pKeyIdentifier-
   0,                        // in- dwPropId
   CRYPT_KEYID_MACHINE_FLAG, // in- dwFlags, use LocalMachine.
   NULL,                     // in, optional- pwszComputerName set
                             //   to NULL to use LocalMachine.
   NULL,                     // Reserved
   pvArg,                    // in, optional- Pointer to the
                             //   passthrough argument
  (PFN_CRYPT_ENUM_KEYID_PROP )pfnEnum
                             // in- Callback function.
   ))
{
   printf("The function call succeeded.\n");
}
else
{
  HandleError("Call to CryptEnumKeyIdentifierProperties failed.");
}

//--------------------------------------------------------------------
// Free all allocated memory

free (pData);
free (pPubKeyStruc);
printf("all memory free\n");
printf("The program ran to completion without error.\n");
}  // end main.

//--------------------------------------------------------------------
// Define the Callback function

static BOOL WINAPI pfnEnum (
const CRYPT_HASH_BLOB *pKeyIdentifier, // in- pKeyIdentifier
DWORD dwFlags,                         // in- Flag values
void *pvReserved,                      // Reserved
void *pvArg,                           // in- Passthrough argument
DWORD cProp,                           // in- cProp
DWORD *rgdwPropId,                     // in- rgdwPropId
void **rgpvData,                       // in- rgpvData- points to an
                                       // array of CRYPT_KEY_PROV_INFO
                                       // structures
DWORD *rgcbData                        // in- rgcbData
)
{
//--------------------------------------------------------------------
//  Declare and initalize local variables.

PUBLICKEYSTRUC *pArg= (PUBLICKEYSTRUC *) pvArg;

//--------------------------------------------------------------------
//  Begin processing

printf("The argument passed is a structure.\n");
printf("Blob type= %x   ", pArg->bType);
printf("Version= %x\n", pArg->bVersion);
printf("Algorithm= %x\n\n", pArg->aiKeyAlg);
return TRUE;
} // end callback function.

//--------------------------------------------------------------------
//  Define HandleError

void HandleError(char *s)
{
printf("\n An error has occurred. \n");
printf("The error message is %s \n",s);
printf("Last error is %x \n",GetLastError());
exit(1);
} // end HandleError.


Example C Program: Creating a Certificate Chain

The following is an example program that creates and installs a non-default certificate chain engine. The engine is used to build certificate chains for each of the certificates in a certificate store.

This example program illustrates the following tasks and CryptoAPI functions:

  • Preparing to create a non-default certificate chain engine by declaring and initializing a CERT_CHAIN_ENGINE_CONFIG data structure.
  • Creating the search engine using CertCreateCertificateChainEngine.
  • Using CertOpenSystemStore to open the MY system store.
  • Retrieving all of the certificates from the open store using CertEnumCertificatesInStore in a loop.
  • For each certificate in the open store, retrieving the subject name from the certificate using CertGetNameString.
  • Building a certificate chain for each certificate using CertGetCertificateChain.
  • Create a duplicate of the certificate chain using CertDuplicateCertificateChain.
  • Using CertFreeCertificateChain to release each chain before the next chain is built.
//   Example C Program: Working with Certificate Chains
//------------------------------------------------------
//   In this and all other sample and example code,
//   use the #define and #include statements listed
//   under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>

void HandleError(char *s);

void main(void)
{
//---------------------------------------------------------
// Declare and initialize variables.

HCERTCHAINENGINE         hChainEngine;
CERT_CHAIN_ENGINE_CONFIG ChainConfig;
PCCERT_CHAIN_CONTEXT     pChainContext;
PCCERT_CHAIN_CONTEXT     pDupContext;
HCERTSTORE               hCertStore;
PCCERT_CONTEXT           pCertContext = NULL;
CERT_ENHKEY_USAGE        EnhkeyUsage;
CERT_USAGE_MATCH         CertUsage;
CERT_CHAIN_PARA          ChainPara;
DWORD                    dwFlags=0;
BYTE                     *pszNameString;

//---------------------------------------------------------
// Initialize data structures.

if(!(pszNameString=(BYTE *)malloc(256)))
    HandleError("Memory allocation failed.");
EnhkeyUsage.cUsageIdentifier = 0;
EnhkeyUsage.rgpszUsageIdentifier=NULL;
CertUsage.dwType = USAGE_MATCH_TYPE_AND;
CertUsage.Usage  = EnhkeyUsage;
ChainPara.cbSize = sizeof(CERT_CHAIN_PARA);
ChainPara.RequestedUsage=CertUsage;

ChainConfig.cbSize = sizeof(CERT_CHAIN_ENGINE_CONFIG);
ChainConfig.hRestrictedRoot= NULL ;
ChainConfig.hRestrictedTrust= NULL ;
ChainConfig.hRestrictedOther= NULL ;
ChainConfig.cAdditionalStore=0 ;
ChainConfig.rghAdditionalStore = NULL ;
ChainConfig.dwFlags = CERT_CHAIN_CACHE_END_CERT;
ChainConfig.dwUrlRetrievalTimeout= 0 ;
ChainConfig.MaximumCachedCertificates=0 ;
ChainConfig.CycleDetectionModulus = 0;

//---------------------------------------------------------
//   Create the non-default certificate chain engine.

if(CertCreateCertificateChainEngine(
         &ChainConfig,
         &hChainEngine))
{
    printf("A chain engine has been created.\n");
}
else
{
    HandleError("The engine creation function failed.");
}
//  Open the MY system store.

if(hCertStore=CertOpenSystemStore(NULL,"MY"))
{
       printf("The MY Store is open.\n");
}
else
{
       HandleError("The MY system store did not open.");
}

//-------------------------------------------------------
//  Loop through the certificates in the store,
//  and create a chain for each.

while(pCertContext = CertEnumCertificatesInStore(
             hCertStore,
             pCertContext))
{
//--------------------------------------------------------------------
//   Get and display the name of subject of the certificate.

if(CertGetNameString(
   pCertContext,
   CERT_NAME_SIMPLE_DISPLAY_TYPE,
   0,
   NULL,
   (char *)pszNameString,
   128))
{
   printf("\nCertificate for %s found.\n",pszNameString);
}
else
{
   HandleError("CertGetName failed.");
}

//----------------------------------------------------------------
//        Build a chain using CertGetCertificateChain
//        and the certificate retrieved.

if(CertGetCertificateChain(
    NULL,                  // Use the default chain engine.
    pCertContext,          // Pointer to the end certificate.
    NULL,                  // Use the default time.
    NULL,                  // Search no additional stores.
    &ChainPara,            // Use AND logic, and enhanced key usage
                           // as indicated in the ChainPara
                           // data structure.
    dwFlags,
    NULL,                  // Currently reserved.
    &pChainContext))       // Return a pointer to the chain created.
{
    printf("The chain has been created. \n");
}
else
{
    HandleError("The chain could not be created.");
}

//---------------------------------------------------------------
// Display some of the contents of the chain.

printf("The size of the chain context is %d. \n",pChainContext->cbSize);
printf("%d simple chains found.\n",pChainContext->cChain);
printf("\nError status for the chain:\n");

switch(pChainContext->TrustStatus.dwErrorStatus)
{
case CERT_TRUST_NO_ERROR :
     printf("No error found for this certificate or chain.\n");
     break;
case CERT_TRUST_IS_NOT_TIME_VALID:
     printf("This certificate or one of the certificates in the certificate chain is not time-valid.\n");
     break;
case CERT_TRUST_IS_NOT_TIME_NESTED:
     printf("Certificates in the chain are not properly time-nested.\n");
     break;
case CERT_TRUST_IS_REVOKED:
     printf("Trust for this certificate or one of the certificates in the certificate chain has been revoked.\n");
     break;
case CERT_TRUST_IS_NOT_SIGNATURE_VALID:
     printf("The certificate or one of the certificates in the certificate chain does not have a valid signature.\n");
     break;
case CERT_TRUST_IS_NOT_VALID_FOR_USAGE:
     printf("The certificate or certificate chain is not valid in its proposed usage.\n");
     break;
case CERT_TRUST_IS_UNTRUSTED_ROOT:
     printf("The certificate or certificate chain is based on an untrusted root.\n");
     break;
case CERT_TRUST_REVOCATION_STATUS_UNKNOWN:
     printf("The revocation status of the certificate or one of the certificates in the certificate chain is unknown.\n");
     break;
case CERT_TRUST_IS_CYCLIC :
     printf("One of the certificates in the chain was issued by a certification authority that the original certificate had certified.\n");
     break;
case CERT_TRUST_IS_PARTIAL_CHAIN:
     printf("The certificate chain is not complete.\n");
     break;
case CERT_TRUST_CTL_IS_NOT_TIME_VALID:
     printf("A CTL used to create this chain was not time-valid.\n");
     break;
case CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID:
     printf("A CTL used to create this chain did not have a valid signature.\n");
     break;
case CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE:
     printf("A CTL used to create this chain is not valid for this usage.\n");
} // End switch

printf("\nInfo status for the chain:\n");
switch(pChainContext->TrustStatus.dwInfoStatus)
{
case 0:
     printf("No information status reported.\n");
     break;
case CERT_TRUST_HAS_EXACT_MATCH_ISSUER :
     printf("An exact match issuer certificate has been found for this certificate.\n");
     break;
case CERT_TRUST_HAS_KEY_MATCH_ISSUER:
    printf("A key match issuer certificate has been found for this certificate.\n");
     break;
case CERT_TRUST_HAS_NAME_MATCH_ISSUER:
    printf("A name match issuer certificate has been found for this certificate.\n");
     break;
case CERT_TRUST_IS_SELF_SIGNED:
     printf("This certificate is self-signed.\n");
     break;
case CERT_TRUST_IS_COMPLEX_CHAIN:
     printf("The certificate chain created is a complex chain.\n");
     break;
} // End switch

//--------------------------------------------------------------------
//    Duplicate the original chain.
if(pDupContext = CertDuplicateCertificateChain(
       pChainContext ))
{
  printf("Duplicated the chain.\n");
}
else
{
  printf("Duplication failed.\n");
}
//--------------------------------------------------------------------
//  Free both chains.

CertFreeCertificateChain(pDupContext);
printf("The duplicate chains is free.\n");
CertFreeCertificateChain(pChainContext);
printf("The Original chain is free.\n");
printf("\nPress any key to continue.");
getchar();
} // End of while loop

printf("\nThere are no more certificates in the store. \n");

//---------------------------------------------------------
//  Free the chain engine.

CertFreeCertificateChainEngine(hChainEngine);
printf("The chain engine has been release.\n");

printf("The demo program ran to competion without error.\n");
} // End of main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError


Example C Program: Making a Certificate Request

The following example code demonstrates the procedure outlined in the previous section. This example code creates a simple certificate request with one signer, a single relative distinguished name (RDN) attribute, and no general attributes.

This example program illustrates the following CryptoAPI functions:

  • CryptEncodeObject.
  • CryptAcquireContext.
  • CryptExportPublicKeyInfo.
  • CryptSignAndEncodeCertificate.

This example code also uses the functions ByteToStr and HandleError. C code for these function is included with the sample.

General Purpose Functions lists C code for these and other auxiliary functions.

//-------------------------------------------------------------------
// This example code demonstrates how to create and encode a
// certificate request.
//-------------------------------------------------------------------
//   In this and all other sample and example code,
//   use the following #define and #include statements. These are
//   also listed under #includes and #defines.

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void HandleError(char *s);

//-------------------------------------------------------------------
//   This program use this additional #define statement.

#define CERT_SUBJECT_NAME "This certificate user"

//--------------------------------------------------------------------
// This program uses the function ByteToStr to convert an array
// of BYTEs to a char string.

void ByteToStr(
     DWORD cb,
     void* pv,
     LPSTR sz)
//--------------------------------------------------------------------
// Parameters passed are:
//    pv is the array of BYTEs to be converted.
//    cb is the number of BYTEs in the array.
//    sz is a pointer to the string to be returned.

{
//--------------------------------------------------------------------
//  Declare and initialize local variables.

BYTE* pb = (BYTE*) pv; // local pointer to a BYTE in the BYTE array
DWORD i;               // local loop counter
int b;                 // local variable

//--------------------------------------------------------------------
//  Begin processing loop.

for (i = 0; i<cb; i++)
{
   b = (*pb & 0xF0) >> 4;
   *sz++ = (b <= 9) ? b + '0' : (b - 10) + 'A';
   b = *pb & 0x0F;
   *sz++ = (b <= 9) ? b + '0' : (b - 10) + 'A';
   pb++;
}
*sz++ = 0;
}

void main(void)
{
//-------------------------------------------------------------------
// Declare and initialize variables

// Declare and initialize a CERT_RDN_ATTR array.
// In this code, only one array element is used.

CERT_RDN_ATTR rgNameAttr[] = {
        "2.5.4.3",                             // pszObjId
        CERT_RDN_PRINTABLE_STRING,             // dwValueType
        strlen(CERT_SUBJECT_NAME),             // value.cbData
        (BYTE*)CERT_SUBJECT_NAME};             // value.pbData

//-------------------------------------------------------------------
// Declare and initialize a CERT_RDN array.
// In this code, only one array element is used.

CERT_RDN rgRDN[] = {
         1,                 // rgRDN[0].cRDNAttr
         &rgNameAttr[0]};   // rgRDN[0].rgRDNAttr

//-------------------------------------------------------------------
// Declare and initialize a CERT_NAME_INFO structure.

CERT_NAME_INFO Name = {
           1,                  // Name.cRDN
           rgRDN};             // Name.rgRDN

//-------------------------------------------------------------------
// Declare and initialize all other variables and structures.

CERT_REQUEST_INFO  CertReqInfo;
CERT_NAME_BLOB  SubjNameBlob;
DWORD  cbNameEncoded;
BYTE*  pbNameEncoded;
HCRYPTPROV  hCryptProv;
DWORD  cbPublicKeyInfo;
CERT_PUBLIC_KEY_INFO*  pbPublicKeyInfo;
DWORD  cbEncodedCertReqSize;
CRYPT_OBJID_BLOB  Parameters;
CRYPT_ALGORITHM_IDENTIFIER  SigAlg;
BYTE*  pbSignedEncodedCertReq;
char*  pSignedEncodedCertReqBlob;

//-------------------------------------------------------------------
//    Begin processing.

if(CryptEncodeObject(
    MY_ENCODING_TYPE,     // Encoding type
    X509_NAME,            // Structure type
    &Name,                // Address of CERT_NAME_INFO structure
    NULL,                 // pbEncoded
    &cbNameEncoded))      // pbEncoded size
{
    printf("The first call to CryptEncodeObject succeeded. \n");
}
else
{
    HandleError("First call to CryptEncodeObject failed.\
      \nA public/private key pair may not exit in the container. \n");
}
//-------------------------------------------------------------------
//     Allocate memory for the encoded name.

if(!(pbNameEncoded = (BYTE*)malloc(cbNameEncoded)))
    HandleError("pbNamencoded malloc operation failed.\n");

//-------------------------------------------------------------------
//  Call CryptEncodeObject to do the actual encoding of the name.

if(CryptEncodeObject(
        MY_ENCODING_TYPE,    // Encoding type
        X509_NAME,           // Structure type
        &Name,               // Address of CERT_NAME_INFO structure
        pbNameEncoded,       // pbEncoded
        &cbNameEncoded))     // pbEncoded size
{
    printf("The object is encoded. \n");
}
else
{
    free(pbNameEncoded);
    HandleError("Second call to CryptEncodeObject failed.\n");
}
//--------------------------------------------------------------------
// Set the subject member of CertReqInfo to point to
// a CERT_NAME_INFO structure that
// has been initialized with the data from cbNameEncoded
// and pbNameEncoded.

SubjNameBlob.cbData = cbNameEncoded;
SubjNameBlob.pbData = pbNameEncoded;
CertReqInfo.Subject = SubjNameBlob;

//--------------------------------------------------------------------
// Generate custom information. This step is not
// implemented in this code.

CertReqInfo.cAttribute = 0;
CertReqInfo.rgAttribute = NULL;
CertReqInfo.dwVersion = CERT_REQUEST_V1;

//--------------------------------------------------------------------
//    Call CryptExportPublicKeyInfo to return an initialized
//    CERT_PUBLIC_KEY_INFO structure.
//    First, get a cryptographic provider.

if(CryptAcquireContext(
    &hCryptProv,        // Address for handle to be returned.
    NULL,               // Use the current user's logon name.
    NULL,               // Use the default provider.
    PROV_RSA_FULL,      // Need to both encrypt and sign.
    NULL))              // No flags needed.
{
     printf("A cryptographic provider has been acquired. \n");
}
else
{
    free(pbNameEncoded);
    HandleError("CryptAcquireContext failed.");
}
//--------------------------------------------------------------------
// Call CryptExportPublicKeyInfo to get the size of the returned
// information.

if(CryptExportPublicKeyInfo(
          hCryptProv,            // Provider handle
          AT_SIGNATURE,          // Key spec
          MY_ENCODING_TYPE,      // Encoding type
          NULL,                  // pbPublicKeyInfo
          &cbPublicKeyInfo))     // Size of PublicKeyInfo
{
     printf("The keyinfo structure is %d bytes.\n",cbPublicKeyInfo);
}
else
{
    free(pbNameEncoded);
    HandleError("First call to CryptExportPublickKeyInfo failed.\
       \nProbable cause: No key pair in the key container. \n");
}
//--------------------------------------------------------------------
// Allocate the necessary memory.

if(pbPublicKeyInfo =
   (CERT_PUBLIC_KEY_INFO*)malloc(cbPublicKeyInfo))
{
    printf("Memory is allocated for the public key structure. \n");
}
else
{
    free(pbNameEncoded);
    HandleError("Memory allocation failed.");
}
//--------------------------------------------------------------------
// Call CryptExportPublicKeyInfo to get pbPublicKeyInfo.

if(CryptExportPublicKeyInfo(
          hCryptProv,            // Provider handle
          AT_SIGNATURE,          // Key spec
          MY_ENCODING_TYPE,      // Encoding type
          pbPublicKeyInfo,       // pbPublicKeyInfo
          &cbPublicKeyInfo))     // Size of PublicKeyInfo
{
     printf("The key has been exported. \n");
}
else
{
    free(pbNameEncoded);
    free(pbPublicKeyInfo);
    HandleError("Second call to CryptExportPublicKeyInfo failed.");
}
//--------------------------------------------------------------------
// Set the SubjectPublicKeyInfo member of the
// CERT_REQUEST_INFO structure to point to the CERT_PUBLIC_KEY_INFO
// structure created.

CertReqInfo.SubjectPublicKeyInfo = *pbPublicKeyInfo;

memset(&Parameters, 0, sizeof(Parameters));
SigAlg.pszObjId = szOID_OIWSEC_sha1RSASign;
SigAlg.Parameters = Parameters;

//--------------------------------------------------------------------
// Call CryptSignAndEncodeCertificate to get the size of the
// returned BLOB.

if(CryptSignAndEncodeCertificate(
          hCryptProv,                      // Crypto provider
          AT_KEYEXCHANGE,                  // Key spec
          MY_ENCODING_TYPE,                // Encoding type
          X509_CERT_REQUEST_TO_BE_SIGNED,  // Structure type
          &CertReqInfo,                    // Structure information
          &SigAlg,                         // Signature algorithm
          NULL,                            // Not used
          NULL,                            // pbSignedEncodedCertReq
          &cbEncodedCertReqSize))          // Size of certificate
                                           // required
{
    printf("The size of the encoded certificate is set. \n");
}
else
{
    free(pbNameEncoded);
    free(pbPublicKeyInfo);
    HandleError("First call to CryptSignandEncode failed.");
}
//--------------------------------------------------------------------
// Allocate memory for the encoded certificate request.

if(pbSignedEncodedCertReq = (BYTE*)malloc(cbEncodedCertReqSize))
{
    printf("Memory has been allocated.\n");
}
else
{
    free(pbNameEncoded);
    free(pbPublicKeyInfo);
    HandleError("Malloc operation failed.");
}
//--------------------------------------------------------------------
// Call CryptSignAndEncodeCertificate to get the
// returned BLOB.

if(CryptSignAndEncodeCertificate(
          hCryptProv,                     // Crypto provider
          AT_KEYEXCHANGE,                 // Key spec
          MY_ENCODING_TYPE,               // Encoding type
          X509_CERT_REQUEST_TO_BE_SIGNED, // Struct type
          &CertReqInfo,                   // Struct info
          &SigAlg,                        // Signature algorithm
          NULL,                           // Not used
          pbSignedEncodedCertReq,         // Pointer
          &cbEncodedCertReqSize))         // Length of the message
{
     printf("The message is encoded and signed. \n");
}
else
{
    free(pbNameEncoded);
    free(pbPublicKeyInfo);
    free(pbSignedEncodedCertReq);
    HandleError("Second call to CryptSignAndEncode failed.");
}
//--------------------------------------------------------------------
// View the signed and encoded certificate request BLOB.

pSignedEncodedCertReqBlob =
                        new char[(cbEncodedCertReqSize *2) +1];

//--------------------------------------------------------------------
// Call ByteToStr, one of the general purpose functions, to convert
// the byte BLOB to ASCII hexadecimal format.

ByteToStr(cbEncodedCertReqSize,
          pbSignedEncodedCertReq,
          pSignedEncodedCertReqBlob);

//--------------------------------------------------------------------
// Print the string.
printf("The string created is:\n");
printf("%s\n",pSignedEncodedCertReqBlob);

//--------------------------------------------------------------------
// Free memory.

free(pbNameEncoded);
free(pbPublicKeyInfo);
free(pbSignedEncodedCertReq);
CryptReleaseContext(hCryptProv,0);

printf("\nMemory freed. Program ran without error. \n");
} // End of main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program. \n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr, "Error number %x.\n", GetLastError());
    fprintf(stderr, "Program terminating. \n");
    exit(1);
} // End of HandleError


Example C Program: ASN1 Encoding and Decoding

Platform SDK: Security

Example C Program: ASN.1 Encoding and Decoding

The following example code demonstrates using CryptEncodeObjectEx and CryptDecodeObjectEx. This example code can easily be modified to use CryptEncodeObject and CryptDecodeObject.

This example code also uses a modified version of the function ByteToStr to print out an ASN.1 encoded series of octets. It also uses HandleError. C code for these functions is included with the sample.

#include <stdio.h>
#include <windows.h>
#include "wincrypt.h"
//--------------------------------------------------------------------
//  Only X509_ASN_ENCODING is needed with these
//  functions.

#define MY_TYPE   X509_ASN_ENCODING

//--------------------------------------------------------------------
//  Declare function ByteToString

void ByteToStr(
     DWORD cb,
     void* pv,
     LPSTR sz);
//--------------------------------------------------------------------
//   Declare function HandleError.
void HandleError(char *s);

//--------------------------------------------------------------------
//   Begin main.

void main(void)
{

//--------------------------------------------------------------------
//   Declare and intitalize local variables.

char *Cert_Sub_Name ="Test User Name";

//--------------------------------------------------------------------
// initalize a single RDN struture

CERT_RDN_ATTR rgNameAttr =
{
   "2.5.4.3",                // The OID.
   CERT_RDN_PRINTABLE_STRING,// Type of string
   strlen(Cert_Sub_Name)+1,  // String length including
                             // the NULL terminator.
   (BYTE *)Cert_Sub_Name     // Pointer to the string.
};
//--------------------------------------------------------------------
// Declare and initalize a structure to include
// the array of RDN structures

CERT_RDN rgRDN[] =
{
   1,               // The number of elements in the array
   &rgNameAttr      // Pointer to the array.
};

//--------------------------------------------------------------------
//  Declare and initialize a CERT_NAME_INFO
//  structure that includes a CERT_RND.

CERT_NAME_INFO CertName =
{
    1,          // number of elements in the CERT_RND's array.
    rgRDN
};

//--------------------------------------------------------------------
//  Declare addtional variables.

CERT_NAME_INFO *pDecodeName;  // Point variable to hold
                              // The address of the decoded
                              // buffer.
DWORD cbEncoded;              // Variable to hold the
                              // length of the encoded string.
DWORD cbDecoded;              // Variable to hold the
                              // length of the decoded buffer.

BYTE *pbEncoded;              // Variable to hold a pointer to the
                              // encoded buffer.
BYTE *pbDecoded;              // Variable to hold a pointer to the
                              // decoded buffer.
LPSTR sz;

//--------------------------------------------------------------------
//    Allocate memory for a large buffer.

if(sz=(char *)malloc(512))
{
     printf("Memory for sz allocated\n");
}
else
{
    HandleError("Memory allocation failed.");
}

//--------------------------------------------------------------------
// call CrypteEncodeObjectEx to get
// length to allocate for pbEncoded.

if( CryptEncodeObjectEx(
     MY_TYPE,        // the encoding/decoding type.
     X509_NAME,
     &CertName,
     0,
     NULL,
     NULL,
     &cbEncoded))    // Fill in the length needed for
                     // the encoded buffer.
{
     printf("The number of bytes needed is %d \n",cbEncoded);
}
else
{
     HandleError("The first call to the function failed.\n");
}

if( pbEncoded = (BYTE*)malloc(cbEncoded))
{
     printf("Memory for pvEncoded has been allocated.\n");
}
else
{
    HandleError("Memory allocation failed.");
}

if(CryptEncodeObjectEx(
     MY_TYPE,
     X509_NAME,
     &CertName,
     0,
     NULL,
     pbEncoded,
     &cbEncoded))
{
     ByteToStr(cbEncoded, pbEncoded,sz);
     printf("The Encoded octets are \n%s\n",sz);
}
else
{
     HandleError("Encoding failed.");
}

//--------------------------------------------------------------------
// Decode the encoded buffer.

//--------------------------------------------------------------------
//  Get the length needed for the decoded buffer.

if(CryptDecodeObjectEx(
     MY_TYPE,
     X509_NAME,
     pbEncoded,     // The buffer to be decoded.
     cbEncoded,
     CRYPT_DECODE_NOCOPY_FLAG,
     NULL,
     NULL,
     &cbDecoded))
{
     printf("The needed buffer length is %d\n",cbDecoded);
}
else
{
    HandleError("The first decode pass failed.");
}

//--------------------------------------------------------------------
// Allocate memory for the decoded information

if(!(pbDecoded = (BYTE*)malloc(cbDecoded)))
{
     HandleError("Decode buffer memory allocation failed.");
}

//--------------------------------------------------------------------
// Decode the encoded buffer.

if(CryptDecodeObjectEx(
     MY_TYPE,
     X509_NAME,
     pbEncoded,     // The buffer to be decoded.
     cbEncoded,
     CRYPT_DECODE_NOCOPY_FLAG,
     NULL,
     pbDecoded,
     &cbDecoded))
{
    pDecodeName = ( CERT_NAME_INFO     *)pbDecoded;
    printf("The cRDN is -> %d \n",pDecodeName->cRDN);
    printf("The OID is -> ");
    printf("%s\n",pDecodeName->rgRDN->rgRDNAttr->pszObjId);
    printf("The string is ->");
    printf(" %s\n",pDecodeName->rgRDN->rgRDNAttr->Value.pbData);}
else
{
     HandleError("Decode failed.");
}

printf("Processing completed without error.\n");
}  // End of main()

//--------------------------------------------------------------------
//  Define ByteToStr

void ByteToStr(
     DWORD cb,
     void* pv,
     LPSTR sz)

//--------------------------------------------------------------------
// Parameters passed are :
//    pv is the Array of BYTES to be converted.
//    cb is the number of BYTEs in the array.
//    sz is a pointer to the string to be returned.

{

//--------------------------------------------------------------------
//  Declare and initialize local variables.

BYTE* pb = (BYTE*) pv; // local pointer to a BYTE in the BYTE array.
DWORD i;               // local loop counter
int b;                 // local variable.

//--------------------------------------------------------------------
//  Begin processing loop.

for (i = 0; i<cb; i++)
{
   b = (*pb & 0xF0) >> 4;
   *sz++ = (b <= 9) ? b + '0' : (b - 10) + 'A';
   b = *pb & 0x0F;
   *sz++ = (b <= 9) ? b + '0' : (b - 10) + 'A';
   pb++;
   *sz++=' ';
}
*sz++ = 0;
}  // End of ByteToStr

void HandleError(char *s)
{
printf("An error occurred in running the program.\n"); printf("%s\n",s);
printf("Program terminating.\n");
exit(1);
} // End of HandleError


Example C Program: Using CertOIDToAlgId and CertCompareIntegerBlob

The following example code demonstrates using the CertOIDToAlgId and CertCompareIntegerBlob functions.

First, all available OIDs are enumerated using CryptEnumOIDInfo. Code used with this function also demonstrates the use of a callback function. The callback function demonstrates break logic to pause between each OID group and after presenting information on a set number of OIDs.

Secondly, three object identifier (OID) strings are converted into DWORD algorithm identifier integers using CertOIDToAlgId. The code also demonstrates that all OID strings do not have related algorithm identifiers.

Finally, the program demonstrates comparing integer BLOBs. This program demonstrates the truncation of leading 0x00's from positive numbers and leading 0xFF's from negative numbers.

It also shows that integers are compared as though they are stored in little-endian form with the most significant digits on the right.

#include <windows.h>
#include <stdio.h>
#include <wincrypt.h>

//--------------------------------------------------------------------
//  Declare a wait function - defined after main.

void my_wait(char *s);

//--------------------------------------------------------------------
//   Callback function to print out infomation
//   saved in each CRYPT_OID_INFO structure.
//   This function counts the number of lines printed
//   and does a wait for each new ground and after any four
//   report groups are printed.

static BOOL WINAPI EnumInfoCallback(
     PCCRYPT_OID_INFO pInfo,
     void *pvArg
    )
{
static int old_oid = 0;
static int break_counter = 0;

if( old_oid < pInfo->dwGroupId)
{
     if(old_oid > 0)
     {
          my_wait("\n Begin new group. \n Hit enter to continue.");
          break_counter=0;
     }
     old_oid = pInfo->dwGroupId;
     printf("\nNew Group ID %d \n",old_oid);
}
printf("  OID: %s\n  Name: %S\n",
       pInfo->pszOID, pInfo->pwszName);

//--------------------------------------------------------------------
//   If there is an AlgId, print it/

if( pInfo->Algid > 0)
{
     printf("  Algorithm ID hex %x \n\n",pInfo->Algid);
}
else
{
     printf("\n");
}

if(++break_counter > 4)
{
     break_counter = 0;
     my_wait("\n   Hit enter to continue.");
}
return TRUE;
}

void main()
{
//--------------------------------------------------------------------
//  Note : integer BLOBs are treated as if they
//  are stored in little-endian form with the
//  most significant digits on the right. Truncation is
//  terfor from the right.
//  Integer BLOBs are also assumed to be signed numbers
//  in two's compliment form.
//  For negative numbers, 0xFF's on the right are
//  truncated.
//  For positive numbers, 0x00's on the right are
//  truncated.

//--------------------------------------------------------------------
//  Declare and initialize local variables.

DWORD Alg_Id;
CRYPT_INTEGER_BLOB  Int1, Int2;
BYTE BLOB1data[4] = {0x88, 0xFF, 0xFF, 0xFF};
BYTE BLOB2data[2] = {0x88, 0xFF};
BYTE BLOB3data[4] = {0x01, 0x00, 0x00, 0x00};
BYTE BLOB4data[2] = {0x01, 0x00};
BYTE BLOB5data[4] = {0x01, 0x00, 0x01, 0x00};

//--------------------------------------------------------------------
//   Enumerate the algorithm OIDs available.
//   Note that his one call to the function with
//   dwGroupId set to 0 list all OIDs in all groups.

CryptEnumOIDInfo(
    0,                  // Use 0 to enumerate the OIDs in all groups,
    0,                  // dwFlags
    NULL,               // No additional parameters are to be
                        //     passed to the callback function.
    EnumInfoCallback    // Name of the callback function to be
                        //      called for each OID enumerated.
    );

//--------------------------------------------------------------------
// Use CertOIDToAlgId() to
// convert szOID_RSA_RC4 Object Identifier string to an
// algorithm identifier.

if( Alg_Id = CertOIDToAlgId(szOID_RSA_RC4))
{
   // Print the Alg_Id returned in hex.
   printf("szOID_RSA_RC4 / %s is %x\n\n",szOID_RSA_RC4, Alg_Id);
}
else
{
   printf("No ALG_ID for OID szOID_RSA_RC4 / %s.\n", szOID_RSA_RC4);
}

//--------------------------------------------------------------------
// Convert szOID_RSA_RC2CBC Object Identifier string to an
// algorithm identifier.

if( Alg_Id = CertOIDToAlgId(szOID_RSA_RC2CBC))
{
   // Print the Alg_Id returned in hex.
   printf("szOID_RSA_RC2CBC / %s is %x\n\n",szOID_RSA_RC2CBC, Alg_Id);
}
else
{
   printf("No ALG_ID for szOID_RSA_RC2CBC / %s.\n",szOID_RSA_RC2CBC);
}

//--------------------------------------------------------------------
// Convert szOID_RSA_RC5_CBCPad Object Identifier string to an
// algorithm identifier.

if( Alg_Id = CertOIDToAlgId(szOID_RSA_RC5_CBCPad))
{
   // Print the Alg_Id returned in hex.
   printf("szOID_RSA_RC5_CBCPad / %s is %x\n",szOID_RSA_RC5_CBCPad, Alg_Id);
}
else
{
   printf("No ALG_ID for szOID_RSA_RC5_CBCPad \ %s.\n",szOID_RSA_RC5_CBCPad);
}

//--------------------------------------------------------------------
// Initialize Int1 and Int2.

Int1.pbData = (BYTE*)&BLOB1data;
Int2.pbData = (BYTE*)&BLOB2data;

//--------------------------------------------------------------------
//  set the cbData members so that only
//  the left most two bytes of the
//  first are compared to the left most bytes
//  of the second.

Int1.cbData = 4;  //sizeof(BLOB1data);
Int2.cbData = 2;  // sizeof(BLOB2data);

if( CertCompareIntegerBlob(
     &Int1,
     &Int2))
{
   printf("The first two bytes of the BLOBs are identical.\n");
}
else
{
   printf("The first two bytes BLOBs are not identical.\n");
}

//--------------------------------------------------------------------
//  Reset the cbData members to compare only
//  1 byte from each

Int1.cbData=1;
Int2.cbData=1;

if( CertCompareIntegerBlob(
       &Int1,
       &Int2))
{
    printf("The BLOBs of different length are identical.\n");
}
else
{
    printf("The BLOBs of different length are not identical.\n");
}

//--------------------------------------------------------------------
// Reset to check the positive numbers.

Int1.cbData = 4;
Int2.cbData = 2;
Int1.pbData = BLOB3data;
Int2.pbData = BLOB4data;

if( CertCompareIntegerBlob(
       &Int1,
       &Int2))
{
   printf("The BLOBs 3 and 4 are identical.\n");
}
else
{
   printf("The BLOBs 3 and 4 are not identical.\n");
}

//--------------------------------------------------------------------
// Compare BLOB 1 and BLOB 3

Int1.cbData = 4;
Int2.cbData = 4;
Int1.pbData = BLOB1data;
Int2.pbData = BLOB3data;

if( CertCompareIntegerBlob(
       &Int1,
       &Int2))
{
   printf("Blobs 1 and 3 are identical.\n");
}
else
{
   printf("Blobs 1 and 3 are not identical.\n");
}

//--------------------------------------------------------------------
// Compare BLOBs BLOB 3 and 5

Int1.cbData = 4;
Int2.cbData = 4;
Int1.pbData = BLOB5data;
Int2.pbData = BLOB3data;

if( CertCompareIntegerBlob(
       &Int1,
       &Int2))
{
   printf("Blobs 5 and 3 are identical.\n");
}
else
{
   printf("Blobs 5 and 3 are not identical.\n");
}

//--------------------------------------------------------------------
// Compare the first two bytes of BLOBs BLOB 3 and 5

Int1.cbData = 2;
Int2.cbData = 2;
Int1.pbData = BLOB5data;
Int2.pbData = BLOB3data;

if( CertCompareIntegerBlob(
       &Int1,
       &Int2))
{
   printf("The first two bytes of BLOBs 5 and 3 are identical.\n");
}
else
{
   printf("The first two bytes of BLOBs 5 and 3 not identical.\n");
}
} // end of main.

void my_wait(char *s)
{

     printf(s);
     getchar();
}


Extending CryptoAPI Functionality

The future of cryptography and secure communications cannot easily be predicted. New certificate types might emerge, various certificate extensions might find common usage, and new message types might be introduced. Because of this, extensibility is part of the design of key CryptoAPI functions.

The following sections present overviews on the use of OIDs for extending CryptoAPI functions.

Topic | Contents
OID Overview | OID fundamental concepts.
Creating the New Functionality | Creating OIDs and functions to extend the use of existing APIs.
Registering the New Functionality | Setting up new OID-related functions.
Installing the New Functionality | Installing OID functions to memory to improve performance.


OID Overview

Extensibility is achieved by providing for the use of new object identifiers (OIDs), new encoding types, and new dynamic linking libraries (DLLs).

CryptoAPI OIDs can take any of the following forms:

  • A numeric string such as "1.2.3.500.88"
  • An alphanumeric string such as "MyFunction"
  • A constant with a value is less than or equal to 0xFFFF. These constants are often associated with a name through the use of a #define statement in a header file.

Extensible functions accept OID and encoding type arguments. These functions search the system registry to find a DLL associated with the OID and encoding type arguments passed to the function. If a DLL for the OID, encoding type combination is found, the DLL is loaded and its function is called. The following illustration shows this flow for the CryptEncodeObject function:

This allows the functionality of the CryptoAPI to be extended as the need arises. Use of this methodology places a burden the developer of the new functionality to write all the necessary code for that functionality. To encode some new data structure, for example, the function in the DLL must perform the entire encoding process.


Creating the New Functionality

The following functions are among the CryptoAPI functions that can be extended.

CryptoAPI function | OID function name define | OID function name string
CryptEncodeObject | CRYPT_OID_ENCODE_ OBJECT_FUNC | "CryptDllEncodeObject"
CryptDecodeObject | CRYPT_OID_DECODE_ OBJECT_FUNC | "CryptDllDEcodeObject"
CertOpenStore | CRYPT_OID_OPEN_ STORE_PROV_FUNC | "CertDllOpenStoreProv"
CertVerifyCTLUsage | CRYPT_OID_VERIFY_ CTL_USAGE_FUNC | "CertDllVerifyCTLUsage"
CertVerifyRevocation | CRYPT_OID_VERIFY_ REVOCATION_FUNC | "CertDllVerifyRevocation"

In normal use with an existing OID and encoding type, the code in the CryptoAPI function, itself, is used. If one of these functions is called with an OID and encoding type that code in the CryptoAPI was not designed to handle, a new function, containing the new functionality, must be created in a DLL. That DLL must be registered in the registry or installed in memory.

When one of the listed functions is called with the newly designated OID and encoding type, the code in the new DLL is used rather than the code provided as part of the CryptoAPI.

The name of the newly developed function can be the name listed under "OID Function Name String" in the previous table or a different name can be given when the new function code is registered.

The new function must use an appropriate prototype. In all cases except for CertOpenStore, this prototype is the same as the CryptoAPI that calls the new function. In the case of CertOpenStore, the prototype is as follows:

BOOL WINAPI CertDllOpenStoreProv(
  IN LPCSTR lpszStoreProvider,
  IN DWORD dwEncodingType,
  IN HCRYPTPROV hCryptProv,
  IN DWORD dwFlags,
  IN const void *pvPara,
  IN HCERTSTORE hCertStore,
  IN OUT PCERT_STORE_PROV_INFO pStoreProvInfo
);

Note If the prototypes do not match, the system stack will be corrupted.

In addition to providing the code for the new function in a DLL, extending the functionality of CryptEncodeObject or CryptDecodeObject require a type definition for the new C data structure to be placed in a header file included when the user's program is compiled.


Registering the New Functionality

Support for registering the new functionality in a system registry must be provided in the new DLL along with the new function. OID Support Functions functions provided assistance with this registration. Regsvr32.exe registers new functions. This utility is comes with Microsoft® Windows NT®/Microsoft® Windows® 2000 and Windows 95 and later.

The new DLL must provide DllRegisterServer and DllUnregisterServer entry points for use by Regsvr32.exe. CryptoAPI functions, such as CryptRegisterOIDFunction or CryptUnregisterOIDFunction, can be used within these entry points, as shown in the example code fragments that follow.

//  The DllRegisterServer Entry Point
STDAPI DllRegisterServer(void)
{
if(!CryptRegisterOIDFunction(
     X509_ASN_ENCODING,                  // Encoding type
     CRYPT_OID_ENCODE_OBJECT_FUNC,       // Function name
     szOID_NEW_CERTIFICATE_TYPE,         // OID
     L"NewCert.dll",                     // Dll name
     L"NewCertificateTypeEncodeObject"   // Override function
     ))                                  //   name
   {
     return E_FAIL;
   }
else
   {
     return S_OK;
   }
}
// The DllUnregisterServer Entry Point
STDAPI DllUnregisterServer(void)
{
HRESULT     hr = S_OK;

if(!CryptUnregisterOIDFunction(
      X509_ASN_ENCODING,             // Encoding type
      CRYPT_OID_ENCODE_OBJECT_FUNC,  // Function name
      szOID_NEW_CERTIFICATE_TYPE     // OID
      ))
{
   if(ERROR_FILE_NOT_FOUND != GetLastError())
           hr = E_FAIL;
}
return hr;
}

This code must be compiled and linked into the new DLL. These two entry points, along with the function entry point, must be exported.

To install the new functionality on their computers, Regsvr32.exe is run from command prompt specifying the name and path of the new DLL. Regsvr32.exe accesses CryptRegisterOIDFunction through the DllRegisterServer entry point and registers the new function and DLL.


Installing the New Functionality

Installing new functionality into memory can improve performance. The CryptoAPI function searches memory for the functionality before searching the registry for the DLL. The DLL must be loaded before its functionality can be installed.

CryptInstallOIDFunctionAddress installs the address of the new functionality. It should be placed in the DllMain function of the DLL, as shown in the following example code fragment:

#define NEW_CERT_TYPE_ENCODE_COUNT
        (sizeof(NewCertificateTypeEncodeObject)/
         sizeof(NewCertificateTypeEncodeObject[0]))

BOOL WINAPI DllMain(
        HMODULE hModule,
        ULONG  ulReason,
        LPVOID lpReserved)
{
static const CRYPT_OID_FUNC_ENTRY NewCertificateTypeEncodeObject[] =
    {
     szOID_NEW_CERTIFICATE_TYPE, NewCertificateTypeEncodeObject
    };

switch (ulReason)
{
    case DLL_PROCESS_ATTACH:
            if (!CryptInstallOIDFunctionAddress(
                  hModule,                      // Module handle
                  X509_ASN_ENCODING,            // Encoding type
                  CRYPT_OID_ENCODE_OBJECT_FUNC, // Function name
                  NEW_CERT_TYPE_ENCODE_COUNT,   // Number of
                                                //   array elements.
                  NewCertificateTypeEncodeObject, // Functions array
                  0))                             // dwFlags
            {
                printf("Install OID function address failed");
                return FALSE;
            }
            break;
     default:
            break;
    }
    return TRUE;
}

To install new functionality into memory, the DLL must have been loaded. It is good programming practice to provide the code for both registering and installing the new functionality. This way, the first call to the function loads the DLL, and subsequent calls will find the function memory thereby improving performance.

If hModule is passed to CryptInstallOIDFunctionAddress, once installed, the DLL is not unloaded until the Crypt32.dll is unloaded.


Extending CertOpenStore Functionality

The certificate store is central to all certificate management operations. The functionality of the CertOpenStore function can be extended through the use of an installable (or registered) certificate-store-provider function. For an overview of how to install or register functions for use with the CryptoAPI see OID Overview.

CertOpenStore opens an empty store in memory and calls the store provider function (if it is registered or installed) by using the OID that was passed in the lpszStoreProvider parameter. For a list of the predefined provider types that are supplied with the CryptoAPI, see CertOpenStore.

The store provider function copies its certificates and CRLs to the "in-memory" store specified by the hCertStore handle passed to it. The new store provider function can use any of the CryptoAPI certificate store functions, such as, CertAddCertificateToStore or CertAddSerializedElementToStore, to add its certificates and CRLs to the "in-memory" store. In addition, the store-provider function optionally returns values for all of the data members of the CERT_STORE_PROV_INFO structure. The function only needs to update this structure if it supports additional callback functions. For example, if the store was to be a read-only store, the support of other callback functions probably would not be needed. For details and prototypes of the possible callback functions, see Certificate Store Provider Callback Functions.

One of the data members of the CERT_STORE_PROV_INFO structure is the rgpvStoreProvFunc array. If the store provider function needs to support one or more of the callback functions, it must provide pointers for this array. These pointers must point to the callback functions that are to be used for other certificate-store activities (such as closing the store). The following illustration shows the flow of this process.

As shown in the following illustration, after the store has been opened, other CryptoAPI functions (such as CertCloseStore) use the array of pointers to access the callback functions that perform the intended task. The definition of the CERT_STORE_PROV_INFO structure and the prototypes of the default callback functions that are supplied with the CryptoAPI are shown in Certificate Store Provider Callback Functions.

In SP3, all the certificates, CRLs, and CTLs are copied into the store's cache when the certificate store is opened. The store APIs were updated in Windows NT 5.0 to allow a store provider to maintain the certificates, CRLs, and CTLs outside of the store's cache (for example, an external database of certificates, such as provided by the Microsoft Certificate Server Database).

CertOpenStore dispatches through the pszStoreProvider parameter to the appropriate CertDllOpenStoreProv installable provider function. The provider returns information in the pStoreProvInfo parameter that points to a CERT_STORE_PROV_INFO structure. The CERT_STORE_PROV_INFO structure contains a dwStoreProvFlags member. The CERT_STORE_PROV_EXTERNAL_FLAG flag was added to allow the provider to indicate that the certificates, CRLs, and CTLs are external to the store's cache:

CertDllOpenStoreProv returns an array of callback functions. An SP3 provider can implement the following callback functions:

  • CERT_STORE_PROV_CLOSE_FUNC
  • CERT_STORE_PROV_READ_CERT_FUNC
  • CERT_STORE_PROV_WRITE_CERT_FUNC
  • CERT_STORE_PROV_DELETE_CERT_FUNC
  • CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC
  • CERT_STORE_PROV_READ_CRL_FUNC
  • CERT_STORE_PROV_WRITE_CRL_FUNC
  • CERT_STORE_PROV_DELETE_CRL_FUNC
  • CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC
  • CERT_STORE_PROV_READ_CTL_FUNC
  • CERT_STORE_PROV_WRITE_CTL_FUNC
  • CERT_STORE_PROV_DELETE_CTL_FUNC
  • CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC

In Windows 2000, on calls to the WRITE_CERT, WRITE_CRL and WRITE_CTL callback functions when the CERT_STORE_PROV_WRITE_ADD_FLAG is set, the upper 16 bits of the dwFlags contains the dwAddDisposition value.

Also in Windows 2000, the following callback functions have been added to support external stores:

  • CERT_STORE_PROV_FIND_CERT_FUNC
  • CERT_STORE_PROV_FREE_FIND_CERT_FUNC
  • CERT_STORE_PROV_GET_CERT_PROPERTY_FUNC
  • CERT_STORE_PROV_FIND_CRL_FUNC
  • CERT_STORE_PROV_FREE_FIND_CRL_FUNC
  • CERT_STORE_PROV_GET_CRL_PROPERTY_FUNC
  • CERT_STORE_PROV_FIND_CTL_FUNC
  • CERT_STORE_PROV_FREE_FIND_CTL_FUNC
  • CERT_STORE_PROV_GET_CTL_PROPERTY_FUNC

The certificate callback functions have the following signatures:

typedef struct _CERT_STORE_PROV_FIND_INFO {
    DWORD               cbSize;
    DWORD               dwMsgAndCertEncodingType;
    DWORD               dwFindFlags;
    DWORD               dwFindType;
    const void          *pvFindPara;
} CERT_STORE_PROV_FIND_INFO, *PCERT_STORE_PROV_FIND_INFO;
typedef const CERT_STORE_PROV_FIND_INFO CCERT_STORE_PROV_FIND_INFO,
    *PCCERT_STORE_PROV_FIND_INFO;

typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_FIND_CERT)(
        IN HCERTSTOREPROV hStoreProv,
        IN PCCERT_STORE_PROV_FIND_INFO pFindInfo,
        IN PCCERT_CONTEXT pPrevCertContext,
        IN DWORD dwFlags,
        IN OUT void **ppvStoreProvFindInfo,
        OUT PCCERT_CONTEXT *ppProvCertContext
        );

typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_FREE_FIND_CERT)(
        IN HCERTSTOREPROV hStoreProv,
        IN PCCERT_CONTEXT pCertContext,
        IN void *pvStoreProvFindInfo,
        IN DWORD dwFlags
        );

typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_GET_CERT_PROPERTY)(
        IN HCERTSTOREPROV hStoreProv,
        IN PCCERT_CONTEXT pCertContext,
        IN DWORD dwPropId,
        IN DWORD dwFlags,
        OUT void *pvData,
        IN OUT DWORD *pcbData
        );

The signatures for the CRL and CTL callback functions are identical to the above with PCCERT_CONTEXT replaced with PCCRL_CONTEXT or PCCTL_CONTEXT.

The FIND_CERT callback is called when the store APIs enumerate, find, or add certificates. pPrevCertContext and ppvStoreProvFindInfo are set to NULL to initiate a new FIND. The returned ppvStoreProvFindInfo is passed back on the next find at which time it may be freed by the provider. The provider may set all, some, or none of the certificate properties. The provider has the option to defer until the GET_CERT_PROPERTY callback is called. It is recommended for providers to set as many properties as possible to allow copying to another store.

The following certificate find types are supported in the SP3 version of the CertFindCertificateInStore:

  • CERT_FIND_ANY
  • CERT_FIND_SHA1_HASH
  • CERT_FIND_MD5_HASH
  • CERT_FIND_PROPERTY
  • CERT_FIND_PUBLIC_KEY
  • CERT_FIND_SUBJECT_NAME
  • CERT_FIND_SUBJECT_ATTR
  • CERT_FIND_ISSUER_NAME
  • CERT_FIND_ISSUER_ATTR
  • CERT_FIND_SUBJECT_STR_A
  • CERT_FIND_SUBJECT_STR_W
  • CERT_FIND_ISSUER_STR_A
  • CERT_FIND_ISSUER_STR_W
  • CERT_FIND_KEY_SPEC
  • CERT_FIND_ENHKEY_USAGE

The FIND_CERT callback is called for each of the above find types. The parameters passed to CertFindCertificateInStore are copied directly to the CERT_STORE_PROV_FIND_INFO structure before the FIND_CERT callback is called. See CertFindCertificateInStore for details on the CERT_STORE_PROV_FIND_INFO structure's field values for the different find types.

The following certificate find types were added to support the CertGetSubjectCertificateFromStore and CertGetIssuerCertificateFromStore APIs and to determine if the certificate already exists in the store before adding:

  • CERT_FIND_SUBJECT_CERT
  • CERT_FIND_ISSUER_OF
  • CERT_FIND_EXISTING

For CERT_FIND_SUBJECT_CERT, pvFindPara points to a CERT_INFO structure containing the Issuer and SerialNumber of the subject. For CERT_FIND_ISSUER_OF, pvFindPara points to a CERT_CONTEXT structure, of the subject. For CERT_FIND_EXISTING, pvFindPara points to a CERT_CONTEXT of the certificate to check for its existence in the store.

The FREE_FIND_CERT callback is called when the certificate returned by the FIND_CERT callback was not released by being used in a subsequent next FIND_CERT, thus having its reference count decremented to zero, or by being released by a call to CertCloseStore. Before the CLOSE callback is called, all certificates returned by the FIND_CERT callback should be released to the provider by being passed to a call to the FIND_CERT callback or a call to the FREE_FIND_CERT callback. The same applies to the CRL and CTL callbacks.

The GET_CERT_PROPERTY callback is called by CertGetCertificateContextProperty if it cannot find the specified property for the pCertContext. The same is true for GET_CRL_PROPERTY and GET_CTL_PROPERTY.

The FIND_CRL callback is called when the store APIs enumerate or get CRLs and before adding a CRL. The following CRL find types will be defined:

For CRL_FIND_ISSUED_BY, pvFindPara is a pointer to a CERT_CONTEXT of the CRL issuer. For CRL_FIND_EXISTING, pvFindPara is a pointer to a CRL_CONTEXT of the CRL to check if it already exists in the store.

The FIND_CTL callback is called when the store APIs enumerate or find CTLs. The following CTL find types are supported in the SP3 version of the CertFindCTLInStore:

  • CTL_FIND_ANY
  • CTL_FIND_SHA1_HASH
  • CTL_FIND_MD5_HASH
  • CTL_FIND_USAGE
  • CTL_FIND_SUBJECT

The FIND_CTL callback is called for each of the above find types. The parameters passed to CertFindCTLInStore are copied directly to the CERT_STORE_PROV_FIND_INFO structure before the FIND_CTL callback is called. See CertFindCTLInStore for details on the CERT_STORE_PROV_FIND_INFO structure's field values for the different find types.

The CTL_FIND_EXISTING CTL find type was added to determine if the CTL already exists in the store before doing a CTL add.

For CTL_FIND_EXISTING, pvFindPara is a pointer to the CTL_CONTEXT structure of the CTL to check if it already exists in the store.


CryptoAPI Reference

This reference contains detailed information about the CryptoAPI functions, structures, data types, and defined constants. This information is divided into the following sections:

  • CryptoAPI Functions
  • Cryptographic Provider Types
  • Microsoft Cryptographic Service Providers
  • CryptoAPI Structures
  • CryptoAPI Data Types
  • CryptoAPI Constants


CryptoAPI Functions

CryptoAPI functions can be divided into the following broad groups:

  • Base Cryptography Functions
  • Certificate and Certificate Store Functions
  • Certificate Verification Functions
  • Message Functions
  • Auxiliary Functions


Base Cryptography Functions

Base cryptographic functions provide the most flexible means of developing cryptography applications. All communication with a cryptographic service provider (CSP) occurs through these functions.

A CSP is an independent module that performs all cryptographic operations. At least one CSP is required with each application that uses cryptographic functions. A single application can occasionally use more than one CSP.

If more than one CSP is used, the one to use can be specified in the CryptoAPI cryptographic function calls. One CSP, the Microsoft Base Cryptographic Provider, is bundled with the CryptoAPI. This CSP is used as a default provider by many of the CryptoAPI functions if no other CSP is specified.

Each CSP provides a different implementation of the cryptographic support provided to the CryptoAPI. Some provide stronger cryptographic algorithms, whereas others contain hardware components such as smart cards. In addition, some CSPs can occasionally communicate with users directly, such as when digital signatures are performed using the user's signature private key.

Base cryptographic functions fall into the following broad groups:

  • Service Provider Functions
  • Key Generation and Exchange Functions
  • CryptEncodeObject/CryptDecodeObject Functions
  • Data Encryption/Decryption Functions
  • Hash and Digital Signature Functions


Service Provider Functions

Applications use service provider functions to connect and disconnect a cryptographic service provider (CSP). The following table briefly describes each function.

Function | Description
CryptAcquireContext | Acquires a handle to the current user's key container within a particular CSP.
CryptContextAddRef | Adds one to the reference count on an HCRYPTPROV handle.
CryptEnumProviders | Enumerates the providers on a computer.
CryptEnumProviderTypes | Enumerates the types of providers supported on the computer.
CryptGetDefaultProvider | Determines the default CSP either for the current user or the computer for a specified provider type.
CryptGetProvParam | Retrieves attributes of a CSP.
CryptInstallDefaultContext | Installs a previously acquired HCRYPTPROV context to be used as a default context.
CryptReleaseContext | Releases the handle acquired by the CryptAcquireContext function.
CryptSetProvider and CryptSetProviderEx | Specifies the user default CSP for a particular CSP type.
CryptSetProvParam | Specifies attributes of a CSP.
CryptUninstallDefaultContext | Removes a default context previously installed by CryptInstallDefaultContext.


CryptAcquireContext

The CryptAcquireContext function is used to acquire a handle to a particular key container within a particular cryptographic service provider (CSP). This returned handle can then be used to make calls to the selected CSP.

This function first attempts to find a CSP with the characteristics described in the dwProvType and pszProvider parameters. If the CSP is found, the function attempts to find a key container within the CSP matching the name specified by the pszContainer parameter. To acquire the context and the key container of a private key associated with the public key of a certificate, use CryptAcquireCertificatePrivateKey

With the appropriate setting of dwFlags, this function can also create and destroy key containers and can provide access to a CSP with a temporary key container if access to a private key is not required..

BOOL WINAPI CryptAcquireContext(
  HCRYPTPROV *phProv,
  LPCTSTR pszContainer,
  LPCTSTR pszProvider,
  DWORD dwProvType,
  DWORD dwFlags
);

Parameters

phProv
[out] Pointer to a handle of a cryptographic service provider (CSP).
pszContainer
[in] Key container name. This is a NULL terminated string that identifies the key container to the CSP. This name is independent of the method used to store the keys. Some CSPs store their key containers internally (in hardware), some use the system registry, and others use the file system. When dwFlags is set to CRYPT_VERIFYCONTEXT, pszContainer must be set to NULL.

When pszContainer is NULL, a default key container name is used. For example, the Microsoft Base Cryptographic Provider uses the logon name of the user currently logged on as the key container name. Other CSPs can also have default key containers that can be acquired in this way.

Applications must not use the default key container to store private keys. When multiple applications use the same container, one application can change or destroy the keys that another application needs to have available. If applications use key containers linked to the application the risk is reduced of other applications tampering with keys necessary for proper function.

An application can obtain the name of the key container in use by reading the PP_CONTAINER value with the CryptGetProvParam function.

pszProvider
[in] NULL terminated string specifying the name of the CSP to be used.

If this parameter is NULL, the user default provider is used. For more information, see Cryptographic Service Provider Contexts. For a list of available cryptographic providers, see Cryptographic Provider Names.

An application can obtain the name of the CSP in use by reading the PP_NAME CSP value in the dwParam parameter with the CryptGetProvParam function.

Due to changing export control restrictions, the default CSP can change between operating system releases. To ensure interoperability on different operating system platforms, the CSP should be explicitly set using this parameter instead of using the default CSP.

dwProvType
[in] Specifies the type of provider to acquire. Defined provider types are discussed in Cryptographic Provider Types:
dwFlags
[in] Flag values. This parameter is usually set to zero, but some applications set one or more of the following flags .
CRYPT_VERIFYCONTEXT
Applications that do not need private keys use this flag. Only applications that create signatures or decrypt messages need access to a private key. All other applications should consider setting this flag. When this flag is set, the application has no access to the private keys, and the pszContainer parameter must be set to NULL. In Windows 2000 and later, when this flag is set, temporary public key pairs can be created, but they are not persised.

When CryptAcquireContext is called, many CSPs require input from the owning user before granting access to the private keys in the key container. For example, the private keys can be encrypted, requiring a password from the user before they can be used. However, if the CRYPT_VERIFYCONTEXT flag is specified, access to the private keys is not required and the user interface can be bypassed.

CRYPT_NEWKEYSET
Creates a new key container with the name specified by pszContainer. If pszContainer is NULL, a key container with the default name is created.
CRYPT_MACHINE_KEYSET
By default, keys and key containers are stored as user keys. For Base Providers, this means that user key containers are stored in the user's profile. A key container created without this flag can only be accessed by the user creating the key container and a user with administration privileges.

The CRYPT_MACHINE_KEYSET flag can be combined with all of the other flags to indicate that the key container of interest is a machine key container and the CSP treats it as such. For Base Providers, this means that the keys are stored locally on the computer that created the key container. If a key container is to be a machine container, the CRYPT_MACHINE_KEYSET flag must be used with all calls to CryptAcquireContext that reference the machine container. The key container created with CRYPT_MACHINE_KEYSET can only be accessed by its creator and by user with administrator privileges unless access rights to the container are granted using CryptSetProvParam.

The CRYPT_MACHINE_KEYSET flag is useful when the user is accessing from a service or user account that did not log on interactively When key containers are created, most CSPs do not automatically create any public/private key pairs. These keys must be created as a separate step with the CryptGenKey function.

CRYPT_DELETEKEYSET
Delete the key container specified by pszContainer. If pszContainer is NULL, the key container with the default name is deleted. All key pairs in the key container are also destroyed.

When this flag is set, the value returned in phProv is undefined, and thus, the CryptReleaseContext function need not be called afterwards.

CRYPT_SILENT
The application requests that the CSP not display any user interface (UI) for this context. If the CSP must display the UI to operate, the call fails and the NTE_SILENT_CONTEXT error code is set as the last error. In addition, if calls are made to CryptGenKey with the CRYPT_USER_PROTECTED flag with a context that has been acquired with the CRYPT_SILENT flag, the calls fail and the CSP sets NTE_SILENT_CONTEXT.

CRYPT_SILENT is intended for use with applications for which the UI cannot be displayed by the CSP.

This flag is supported with Windows 2000 or later. It is not supported in Windows 98 or Internet Explorer version 5.0.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow.

ERROR_BUSY ( 107L )
Some CSPs set this error if the CRYPT_DELETEKEYSET flag value is set and another thread or process is using this key container.
ERROR_INVALID_PARAMETER ( 87L )
One of the parameters contains an invalid value. This is most often an invalid pointer.
ERROR_NOT_ENOUGH_MEMORY ( 8L )
The operating system ran out of memory during the operation.
NTE_BAD_FLAGS ( 0x80090009L )
The dwFlags parameter has an invalid value.
NTE_BAD_KEYSET( 0x80090016L )
The key container could not be opened. A common cause of this error is that the key container does not exist. To create a key container, call CryptAcquireContext using the CRYPT_NEWKEYSET flag. This error code can also indicate that access to an existing key container is denied. Access rights to the container can be granted by the key set creator using CryptSetProvParam.
NTE_BAD_KEYSET_PARAM( 0x8009001FL )
The pszContainer or pszProvider parameter is set to an invalid value.
NTE_BAD_PROV_TYPE( 0x80090014L )
The value of the dwProvType parameter is out of range. All provider types must be from 1 to 999, inclusive.
NTE_BAD_SIGNATURE( 0x80090006L )
The provider DLL signature could not be verified. Either the DLL or the digital signature has been tampered with.
NTE_EXISTS( 0x8009000FL )
The dwFlags parameter is CRYPT_NEWKEYSET, but the key container already exists.
NTE_KEYSET_ENTRY_BAD( 0x8009001AL )
The pszContainer key container was found but is corrupt.
NTE_KEYSET_NOT_DEF( 0x80090019L )
The key container specified by pszContainer does not exist or the requested provider does not exist.
NTE_NO_MEMORY( 0x8009000EL )
The CSP ran out of memory during the operation.
NTE_PROV_DLL_NOT_FOUND( 0x80090016L )
The provider DLL file does not exist or is not on the current path.
NTE_PROV_TYPE_ENTRY_BAD( 0x80090018L )
The provider type specified by dwProvType is corrupt. This error can relate to either the user default CSP list or the computer default CSP list.
NTE_PROV_TYPE_NO_MATCH( 0x8009001BL )
The provider type specified by dwProvType does not match the provider type found. Note that this error can only occur when pszProvider specifies an actual CSP name.
NTE_PROV_TYPE_NOT_DEF( 0x80090017L )
No entry exists for the provider type specified by dwProvType.
NTE_PROVIDER_DLL_FAIL( 0x8009001DL )
The provider DLL file could not be loaded or failed to initialize.
NTE_SIGNATURE_FILE_BAD( 0x8009001CL )
An error occurred while loading the DLL file image, prior to verifying its signature.

Examples

See Example C Program: Creating a Key Container and Generating Keys and Example C Program: Using CryptAcquireContext.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on all platforms.

See Also

Service Provider Functions, CryptGenKey, CryptGetProvParam, CryptReleaseContext


CryptContextAddRef

The CryptContextAddRef function adds one to the reference count of an HCRYPTPROV cryptographic service provider (CSP) handle. This function should be used if the CSP handle is included as a member of any structure passed to another function. The CryptReleaseContext function should be called when the CSP handle is no longer needed.

BOOL WINAPI CryptContextAddRef(
  HCRYPTPROV hProv,
  DWORD *pdwReserved,
  DWORD dwFlags
);

Parameters

hProv
[in] HCRYPTPROV handle for which the reference count is being incremented. This handle must have already been created using CryptAcquireContext.
pdwReserved
[in] Reserved for future use and must be NULL.
dwFlags
[in] Reserved for future use and must be zero.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. One possible error code is the following.

Value | Meaning
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.

Remarks

The CryptContextAddRef function is used to increase the reference count on a HCRYPTPROV handle so that multiple calls to CryptReleaseContext are required to actually release the handle.

Examples

See Example C Program: Using CryptAcquireContext.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 98 or later.
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.

See Also

Service Provider Functions, CryptAcquireContext, CryptReleaseContext


CryptEnumProviders

The CryptEnumProviders function retrieves the first or next available cryptographic service providers (CSPs). Used in a loop, this function can retrieve in sequence all of the CSPs available on a computer.

Possible CSPs include Microsoft Base Cryptographic Provider version 1.0 and Microsoft Enhanced Cryptographic Provider version 1.0.

BOOL WINAPI CryptEnumProviders(
  DWORD dwIndex,
  DWORD *pdwReserved,
  DWORD dwFlags,
  DWORD *pdwProvType,
  LPTSTR pszProvName,
  DWORD *pcbProvName
);

Parameters

dwIndex
[in] Index of the next provider to be enumerated.
pdwReserved
[in] Reserved for future use and must be NULL.
dwFlags
[in] Reserved for future use and must be zero.
pdwProvType
[out] Address of the DWORD value designating the type of the enumerated provider.
pszProvName
[out] Pointer to a buffer that receives the data from the enumerated provider. This is a string including the terminating NULL character.

This parameter can be NULL to set the size of the name for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.

pcbProvName
[in/out] Pointer to a DWORD value specifying the size, in bytes, of the buffer pointed to by the pszProvName parameter. When the function returns, the DWORD value contains the number of bytes stored in the buffer.

Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow.

Value | Meaning
ERROR_MORE_DATA | The pszProvName buffer was not large enough to hold the provider name.
ERROR_NO_MORE_ITEMS | There are no more items to enumerate.
ERROR_NOT_ENOUGH_MEMORY | The operating system ran out of memory.
NTE_BAD_FLAGS | The dwFlags parameter has an unrecognized value.
NTE_FAIL | Something was wrong with the type registration.

Remarks

CryptEnumProviders is used to enumerate the providers on a computer. The provider types can be enumerated by using CryptEnumProviderTypes.

Examples

See Example C Program: Enumerating CSP Providers and Provider Types.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 98 or later.
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on all platforms.

See Also

Service Provider Functions, CryptEnumProviderTypes


CryptEnumProviderTypes

The CryptEnumProviderTypes function retrieves the first or next types of cryptographic service provider (CSP) supported on the computer. Used in a loop, this function retrieves in sequence all of the CSP types available on a computer.

Provider types include PROV_RSA_FULL, PROV_RSA_SCHANNEL, and PROV_DSS.

BOOL WINAPI CryptEnumProviderTypes(
  DWORD dwIndex,
  DWORD *pdwReserved,
  DWORD dwFlags,
  DWORD *pdwProvType,
  LPTSTR pszTypeName,
  DWORD *pcbTypeName
);

Parameters

dwIndex
[in] Index of the next provider type to be enumerated.
pdwReserved
[in] Reserved for future use and must be NULL.
dwFlags
[in] Reserved for future use and must be zero.
pdwProvType
[out] Address of the DWORD value designating the enumerated provider type.
pszTypeName
[out] Pointer to a buffer that receives the data from the enumerated provider type. This is a string including the terminating NULL character. Some provider types do not have friendly names, and in this case no name is returned and the returned value pointed to by pcbTypeName is zero.

This parameter can be NULL to get the size of the name for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.

pcbTypeName
[in/out] Pointer to a DWORD value specifying the size, in bytes, of the buffer pointed to by the pszTypeName parameter. When the function returns, the DWORD value contains the number of bytes stored or to be stored in the buffer. Some provider types do not have friendly names, and in this case no name is returned and the returned value pointed to by pcbTypeName is zero.

Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow.

Value | Meaning
ERROR_NO_MORE_ITEMS | There are no more items to enumerate.
ERROR_NOT_ENOUGH_MEMORY | The operating system ran out of memory.
NTE_BAD_FLAGS | The dwFlags parameter has an unrecognized value.
NTE_FAIL | Something was wrong with the type registration.

Remarks

The CryptEnumProviderTypes function enumerates the provider types on a computer. Providers for any specific provider type can be enumerated using CryptEnumProviders.

Examples

See Example C Program: Enumerating CSP Providers and Provider Types.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 98 or later.
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on all platforms.

See Also

Service Provider Functions, CryptEnumProviders


CryptGetDefaultProvider

The CryptGetDefaultProvider function finds the default cryptographic service provider (CSP) of a specified provider type. The CSP can be the default for either for the current user or for the computer (LocalMachine). The name of the default CSP for the provider type specified in the dwProvType parameter is returned in the pszProvName buffer.

BOOL WINAPI CryptGetDefaultProvider(
  DWORD dwProvType,
  DWORD *pdwReserved,
  DWORD dwFlags,
  LPTSTR pszProvName,
  DWORD *pcbProvName
);

Parameters

dwProvType
[in] Specifies the provider type for which the default CSP name is to be found. Defined provider types are listed in the following table.

PROV_RSA_FULL
PROV_RSA_SIG
PROV_DSS
PROV_DSS_DH
PROV_DH_SCHANNEL
PROV_FORTEZZA
PROV_MS_EXCHANGE
PROV_RSA_SCHANNEL
PROV_SSL

pdwReserved
[in] Reserved for future use and must be NULL.
dwFlags
[in] The following flag values are defined.
Value | Meaning
CRYPT_MACHINE_DEFAULT | Causes the computer default CSP of the specified type to be returned.
CRYPT_USER_DEFAULT | Causes the user default CSP of the specified type to be returned.

pszProvName
[out] Pointer to a NULL terminated character string buffer to receive the name of the default CSP.

This parameter can be NULL to find the size of the buffer for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.

pcbProvName
[in/out] Pointer to a DWORD value specifying the size, in bytes, of the buffer pointed to by the pszProvName parameter. When the function returns, the DWORD value contains the number of bytes stored or to be stored in the buffer.

Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

The error code prefaced by NTE is generated by the particular CSP being used. Possible error codes include the following.

Value | Meaning
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
ERROR_MORE_DATA | The buffer for the name is not large enough.
ERROR_NOT_ENOUGH_MEMORY | The operating system ran out of memory.
NTE_BAD_FLAGS | The dwFlags parameter has an unrecognized value.

Remarks

The CryptGetDefaultProvider function is used to determine which installed CSP is currently set as the default for the current user or the computer. This information is often displayed to the user.

Examples

See Example C Program: Enumerating CSP Providers and Provider Types.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 98 or later.
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on all platforms.

See Also

Service Provider Functions, CryptSetProvider, CryptSetProviderEx


CryptGetProvParam

The CryptGetProvParam function retrieves parameters that govern the operations of a cryptographic service provider (CSP).

BOOL WINAPI CryptGetProvParam(
  HCRYPTPROV hProv,
  DWORD dwParam,
  BYTE *pbData,
  DWORD *pdwDataLen,
  DWORD dwFlags
);

Parameters

hProv
[in] Handle of the cryptographic service provider (CSP) target of the query. This handle must have been created using CryptAcquireContext.
dwParam
[in] Specifies the nature of the query. The following queries are defined.
Parameter value | Contents returned in pbData
PP_CONTAINER | Name of the current key container as a NULL terminated char string. This string is exactly the same as the one passed in the pszContainer parameter of the CryptAcquireContext function to specify the key container to use. The pszContainer parameter can be read to determine the name of the default key container.
PP_ENUMALGS A PROV_ENUMALGS structure containing information about one algorithm supported by the CSP being queried. PP_ENUMALGS values must be read repeatedly to list all of the supported algorithms. The algorithms are not enumerated in any particular order. The first time that the PP_ENUMALGS value is read, the CRYPT_FIRST flag must be specified in dwFlags. Doing so ensures that information about the first algorithm in the enumeration list is returned. The PP_ENUMALGS value can then be repeatedly read with dwFlags set to 0 to retrieve the information about the rest of the supported algorithms. When this function fails with the ERROR_NO_MORE_ITEMS error code, the end of the enumeration list has been reached.

This function is not thread safe and all of the available algorithms might not be enumerated if this function is used in a multithread context.
PP_ENUMALGS_EX PROV_ENUMALGS_EX structure containing information about one algorithm supported by the CSP being queried. The structure returned contains more information about the algorithm than the structure returned for PP_ENUMALGS.
The PP_ENUMALGS_EX value must be read repeatedly to enumerate all the supported algorithms. The algorithms are not enumerated in any particular order. The first time that the PP_ENUMALGS_EX value is read, the CRYPT_FIRST flag must be specified in dwFlags. Doing so ensures that information about the first algorithm in the enumeration list is returned. The PP_ENUMALGS_EX value can then be repeatedly read with dwFlags set to 0 to retrieve the information about the rest of the supported algorithms. When this function fails with the ERROR_NO_MORE_ITEMS error code, the end of the enumeration list has been reached.

PP_ENUMALGS_EX is supported in Internet Explorer 4.0 or later, Windows NT version 4.0 with Service Pack 4, Windows 98 or later, and Windows 2000.

This function is not thread safe and all of the available algorithms might not be enumerated if this function is used in a multithread context.
PP_ENUMCONTAINERS | Name of one of the key containers maintained by the CSP in the form of a NULL terminated CHAR string. The PP_ENUMCONTAINERS value must be read repeatedly to enumerate all the container names. Container names are enumerated in the same way as the CSP's supported algorithms. All of the available container names might not be enumerated if this function is used in a multithread context
PP_IMPTYPE | A DWORD value that indicates how the CSP is implemented. See Remarks for a table of possible values.
PP_NAME | The name of the CSP in the form of a NULL terminated CHAR string. This string is identical to the one passed in the pszProvider parameter of the CryptAcquireContext function to specify that the current CSP be used.
PP_VERSION | The version number of the CSP. The least significant byte contains the minor version number and the next most significant byte the major version number. Version 1.0 is represented as 0x00000100. To maintain backward compatibility with earlier versions of the Microsoft Base Cryptographic Provider and the Microsoft Enhanced Cryptographic Provider, the provider names retain the "v1.0" designation in later versions. Version 2.0 of these providers are included in Windows 2000.
PP_SIG_KEYSIZE_INC The number of bits for the increment length of AT_SIGNATURE. This information is used with information returned in the PP_ENUMALGS_EX value. With the information returned when using PP_ENUMALGS_EX and PP_SIG_KEYSIZE_INC, the valid key lengths for AT_SIGNATURE can be determined. These key lengths can then be used with CryptGenKey.

For example, if a CSP enumerates CALG_RSA_SIGN (AT_SIGNATURE) with a minimum key length of 512 bits and a maximum of 1024 bits, and returns the increment length as 64 bits, then valid key lengths are 512, 576, 640,… 1024. This value is supported in Windows 2000 or later. It is not supported in Windows 98 or Internet Explorer 5.0.
PP_KEYX_KEYSIZE_INC The number of bits for the increment length of AT_KEYEXCHANGE. This information is used with information returned in the PP_ENUMALGS_EX value. With the information returned when using PP_ENUMALGS_EX and PP_KEYX_KEYSIZE_INC, the valid key lengths for AT_KEYEXCHANGE can be determined. These key lengths can then be used with CryptGenKey. For example if a CSP enumerates CALG_RSA_KEYX (AT_KEYEXCHANGE) with a minimum key length of 512 bits and a maximum of 1024 bits, and returns the increment length as 64 bits, then valid key lengths are 512, 576, 640,… 1024.

This value is supported in Windows 2000 or later. It is not supported in Windows 98 or Internet Explorer 5.0.
PP_KEYSET_SEC_DESCR | The security descriptor for the key set. Not supported under the Windows 95 operating system.
PP_UNIQUE_CONTAINER | The unique container name of the current key container in the form of a NULL terminated CHAR string. For many CSPs, this name is the same name returned when the PP_CONTAINER value is used. The CryptAcquireContext function must work with this container name.
PP_PROVTYPE | DWORD value that indicates the provider type of the CSP.
PP_USE_HARDWARE_RNG | Indicates whether a hardware random number generator (RNG) is supported. When PP_USE_HARDWARE_RNG is specified, the function succeeds and returns TRUE if a hardware RNG is supported. The function fails and returns FALSE if a hardware RNG is not supported. If a RNG is supported, PP_USE_HARDWARE_RNG can be set in CryptSetProvParam to indicate that the CSP must exclusively use the hardware RNG for this provider context. When PP_USE_HARDWARE_RNG is used, the pbData parameter must be NULL and dwFlags must be zero.
PP_KEYSPEC | Returns information on the key specifiers the CSP supports. Key specifier values are joined in a logical OR and returned in the pbData parameter of the call as a DWORD. For example, the Microsoft Base Cryptographic Provider v1.0 returns a DWORD value of AT_SIGNATURE | AT_KEYEXCHANGE. Currently, this parameter is only implemented in Windows 2000.

pbData
[out] Pointer to a buffer to receive the data. The form of this data varies depending on the value of dwParam. For dwParam set to PP_USE_HARDWARE_RNG, pbData must be set to NULL.

This parameter can be NULL to set the size of this information for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.

pdwDataLen
[in/out] Pointer to a DWORD value specifying the size, in bytes, of the buffer pointed to by the pbData parameter. When the function returns, the DWORD value contains the number of bytes stored or to be stored in the buffer.

Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

If PP_ENUMALGS, or PP_ENUMALGS_EX is set, the pdwDataLen parameter works somewhat differently. If pbData is NULL or the value pointed to by pdwDataLen is too small, the value returned in this parameter is the size of the largest item in the enumeration list instead of the size of the item currently being read.

If PP_ENUMCONTAINERS is set, the first call to the function returns the size of the maximum key-container allowed by the current provider. This is in contrast to other possible behaviors, like returning the length of the longest existing container, or the length of the current container. Subsequent enumerating calls will not change the dwLen parameter. For each enumerated container, the caller can determine the length of the null-terminated string programmatically, if desired. If one of the enumeration values is read and the pbData parameter is NULL, the CRYPT_FIRST flag must be specified for the size information to be correctly retrieved.

dwFlags
[in] If dwParam is one of the enumeration values (PP_ENUMALGS, PP_ENUMALGS_EX, or PP_ENUMCONTAINERS), the CRYPT_FIRST flag can be specified. If this flag is set, the first item in the enumeration list is returned. If this flag is not set, the next item in the list is returned.

If dwParam is PP_ENUMCONTAINERS, the CRYPT_MACHINE_KEYSET flag can be specified. This flag can be set to enumerate the key containers associated with a computer rather than the key containers associated with the current user.

If dwParam is PP_KEYSET_SEC_DESCR, the security descriptor on the key container where the keys are stored is retrieved. For this case, dwFlags is used to pass in the SECURITY_INFORMATION bit flags that indicate the requested security information, as defined in the Win32 Programmer's Reference. SECURITY_INFORMATION bit flags can be combined with a bitwise-OR operation.

The following dwFlag values are defined for use with PP_KEYSET_SEC_DESCR.
Flag value | Meaning
OWNER_SECURITY_INFORMATION | Owner identifier of the object is being referenced.
GROUP_SECURITY_INFORMATION | Primary group identifier of the object is being referenced.
DACL_SECURITY_INFORMATION | Discretionary ACL of the object is being referenced.
SACL_SECURITY_INFORMATION | System ACL of the object is being referenced.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow.

Value | Meaning
ERROR_INVALID_HANDLE | One of the parameters specifies an invalid handle.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
ERROR_MORE_DATA | If the buffer specified by the pbData parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code and stores the required buffer size, in bytes, in the variable pointed to by pdwDataLen.
ERROR_NO_MORE_ITEMS | The end of the enumeration list has been reached. No valid data has been placed in the pbData buffer. This error code is returned only when dwParam equals PP_ENUMALGS or PP_ENUMCONTAINERS.
NTE_BAD_FLAGS | The dwFlags parameter specifies an invalid flag.
NTE_BAD_TYPE | The dwParam parameter specifies an unknown value number.
NTE_BAD_UID | The CSP context specified by hProv is invalid.

Remarks

This function is not thread-safe and must not be used on a thread of a multithreaded program.

The following values are returned in pbData if dwParam is PP_IMPTYPE:

Value | Meaning
CRYPT_IMPL_HARDWARE | Implementation is in hardware.
CRYPT_IMPL_SOFTWARE | Implementation is in software.
CRYPT_IMPL_MIXED | Implementation involves both hardware and software.
CRYPT_IMPL_UNKNOWN | Implementation type is unknown.

The dwFlags parameter is used to pass in the SECURITY_INFORMATION bit flags indicating the requested security information. The pointer to the security descriptor is returned in the pbData parameter and the length of the security descriptor is returned in the pdwDataLen parameter. For Windows 2000 and later, key-container security is handled with SetFileSecurity and GetFileSecurity. The documentation on the RegGetKeySecurity and RegSetKeySecurity Win32 functions provides additional information for platforms earlier than Windows 2000.

The class of an algorithm enumerated with dwParam set to PP_ENUMALGS or PP_ENUMALGS_EX can be determined. This might be done to display a list of encryption algorithms supported and disregard the rest. The GET_ALG_CLASS(x) macro takes an algorithm identifier as an argument and returns a code indicating the general class of that algorithm. Possible return values include:

  • ALG_CLASS_DATA_ENCRYPT
  • ALG_CLASS_HASH
  • ALG_CLASS_KEY_EXCHANGE
  • ALG_CLASS_SIGNATURE

The following table lists the algorithms supported by the Microsoft Base Cryptographic Provider along with the class of each algorithm.

Name | Identifier | Class
"MD2" | CALG_MD2 | ALG_CLASS_HASH
"MD5" | CALG_MD5 | ALG_CLASS_HASH
"SHA" | CALG_SHA | ALG_CLASS_HASH
"MAC" | CALG_MAC | ALG_CLASS_HASH
"RSA_SIGN" | CALG_RSA_SIGN | ALG_CLASS_SIGNATURE
"RSA_KEYX" | CALG_RSA_KEYX | ALG_CLASS_KEY_EXCHANGE
"RC2" | CALG_RC2 | ALG_CLASS_DATA_ENCRYPT
"RC4" | CALG_RC4 | ALG_CLASS_DATA_ENCRYPT

Applications must not use an algorithm with an algorithm identifier that is not recognized. Using an unknown cryptographic algorithm can produce unpredictable results.

Examples

See Example C Program: Using CryptAcquireContext and Example C Program: Enumerating CSP Providers and Provider Types.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.

See Also

Service Provider Functions, CryptAcquireContext, CryptCreateHash, CryptDeriveKey, CryptGenKey, CryptGetKeyParam, CryptSetProvParam


CryptInstallDefaultContext

The CryptInstallDefaultContext function installs a previously-acquired HCRYPTPROV context to be used as a default context. The values of two input parameters, wDefaultType and pvDefaultPara, specify where the default context is used.

BOOL WINAPI CryptInstallDefaultContext(
  HCRYPTPROV hCryptProv,
  DWORD dwDefaultType,
  const void *pvDefaultPara,
  DWORD dwFlags,
  void *pvReserved,
  HCRYPTDEFAULTCONTEXT *phDefaultContext
);

Parameters

hCryptProv
[in] HCRYPTPROV handle to be used as the default context. This handle must have already been created using CryptAcquireContext.
dwDefaultType
[in] Sets the use of the default provider handle. The following table gives the possible values.
Flag | Meaning
CRYPT_DEFAULT_CONTEXT_CERT_SIGN_OID | Installs a default HCRYPTPROV structure used to verify a certificate signature. pvDefaultPara points to the szOID value of the certificate signature algorithm; for example, szOID_OIWSEC_md5RSA. If pvDefaultPara is NULL, the HCRYPTPROV structure is used to verify all certificate signatures. Note, pvDefaultPara cannot be NULL when the CRYPT_DEFAULT_CONTEXT_PROCESS_FLAG flag is set.
CRYPT_DEFAULT_CONTEXT_MULTI_CERT_SIGN_OID | Same as CRYPT_DEFAULT_CONTEXT_CERT_SIGN_OID. However, the default HCRYPTPROV structure is to be used for multiple signature szOID values. pvDefaultPara points to a CRYPT_DEFAULT_CONTEXT_MULTI_OID_PARA structure containing an array of szOID pointers.

pvDefaultPara
[in] Pointer to the szOID value of the certificate signature algorithm or to an array of szOID values defined in the CRYPT_DEFAULT_CONTEXT_MULTI_OID_PARA structure. It can be NULL if dwDefaultType is CRYPT_DEFAULT_CONTEXT_CERT_SIGN_OID and the default HCRYPTPROV value is used to verify all certificate signatures.
dwFlags
[in] Flags that determine the way the provider is released and, if applicable, all threads.
Flag | Meaning
CRYPT_DEFAULT_CONTEXT_AUTO_RELEASE_FLAG | The hCryptProv value is released automatically when the process or thread ends. The hCryptProv value is not released by a call to CryptUninstallDefaultContext if the function is called before process or thread exit.
CRYPT_DEFAULT_CONTEXT_PROCESS_FLAG | The hCryptProv value is applicable to all threads in the process.

pvReserved
[in] Reserved for future use.
phDefaultContext
[out] Pointer to the handle of the new default context.

Return Values

If the function succeeds, the return value is nonzero (TRUE) and *phDefaultContext is updated with the handle to be passed to CryptUninstallDefaultContext. If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Remarks

By default, the installed HCRYPTPROV value is only applicable to the current // thread. Set the CRYPT_DEFAULT_CONTEXT_PROCESS_FLAG flag to allow the HCRYPTPROV value to be used by all threads in the current process.

The installed HCRYPTPROV values are stack-ordered, thus the last installed HCRYPTPROV value is checked first. All thread-installed HCRYPTPROV values are checked before any process HCRYPTPROV values.

The installed HCRYPTPROV value remains available for default usage until CryptUninstallDefaultContext is called or the thread or process exits.

If the CRYPT_DEFAULT_CONTEXT_AUTO_RELEASE_FLAG flag is set, then the HCRYPTPROV value is released by CryptReleaseContext at thread or process exit. The provider is not re-released if CryptUninstallDefaultContext was previously called.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 98 or later.
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.


CryptReleaseContext

The CryptReleaseContext function releases the handle of a cryptographic service provider (CSP) and a key container. At each call to this function, the reference count on the CSP is reduced by one. When the reference count reaches zero, the context is fully released and it can no longer be used by any function in the application.

An application calls this function after finishing the use of the CSP. After this function is called, the released CSP handle is no longer valid. This function does not destroy key containers or key pairs.

BOOL WINAPI CryptReleaseContext(
  HCRYPTPROV hProv,
  DWORD dwFlags
);

Parameters

hProv
[in] Handle of a cryptographic service provider (CSP) created by a call to CryptAcquireContext.
dwFlags
[in] Reserved for future use and must be zero. If dwFlags is not set to zero, this function returns FALSE but the CSP is released.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. Some possible error codes are listed in the following table.

Value | Meaning
ERROR_BUSY | The CSP context specified by hProv is currently being used by another process.
ERROR_INVALID_HANDLE | One of the parameters specifies an invalid handle.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
NTE_BAD_FLAGS | The dwFlags parameter is nonzero.
NTE_BAD_UID | The hProv parameter does not contain a valid context handle.

Remarks

After this function has been called, the CSP session is finished and all existing session keys and hash objects created using the hProv handle become invalid. In practice, all of these objects should be destroyed with calls to CryptDestroyKey and CryptDestroyHash before CryptReleaseContext is called.

Examples

See Example C Program: Creating and Hashing a Session Key.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.

See Also

Service Provider Functions, CryptAcquireContext, CryptDestroyKey, CryptDestroyHash


CryptSetProvider

The CryptSetProvider function specifies the current user's default cryptographic service provider (CSP).

If a current user's default provider is set, that default provider is acquired by any call by that user to CryptAcquireContext specifying a dwProvType provider type but not a CSP name.

An enhanced version of this function, CryptSetProviderEx, is also available.

Note Typical applications do not use this function. It is intended for use solely by administrative applications.

BOOL WINAPI CryptSetProvider(
  LPCTSTR pszProvName,
  DWORD dwProvType
);

Parameters

pszProvName
[in] Name of the new default CSP. The named CSP must be installed on the computer. For a list of available cryptographic providers, see Cryptographic Provider Names..
dwProvType
[in] Provider type of the CSP specified by pszProvName.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. Some possible error codes are listed in the following table.

Value | Meaning
ERROR_INVALID_HANDLE | One of the parameters specifies an invalid handle.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
ERROR_NOT_ENOUGH_MEMORY | The operating system ran out of memory during the operation.

Errors can also be propagated from internal calls to RegCreateKeyEx and RegSetValueEx

Remarks

Typical applications do not specify a CSP name when calling CryptAcquireContext; however, an application does have the option of selecting a specific CSP. This gives a user the freedom to select a CSP with an appropriate level of security.

Since calling CryptSetProvider determines the CSP of a specified type used by all applications that run from that point on, this function must not be called without users' consent.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on all platforms.

See Also

Service Provider Functions, CryptAcquireContext


CryptSetProviderEx

The CryptSetProviderEx function specifies the default cryptographic service provider (CSP) for either the current user or the local computer. A current user default takes precedence over the computer default.

If a current user's default provider is set, that default provider is acquired by any call by that user to CryptAcquireContext specifying a dwProvType provider type but not a CSP name.

If a local computer default is set, calls to CryptAcquireContext by a user not having a current user default set and not specifying a CSP result in the use of the local computer's default CSP.

Note Typical applications do not use this function. It is intended for use solely by administrative applications.

BOOL WINAPI CryptSetProviderEx(
  LPCTSTR pszProvName,
  DWORD dwProvType,
  DWORD *pdwReserved,
  DWORD dwFlags
);

Parameters

pszProvName
[in] Name of the new default CSP. This must be a CSP installed on the computer. For a list of available cryptographic providers, see Cryptographic Provider Names.
dwProvType
[in] Provider type of the CSP specified by pszProvName.
pdwReserved
[in] Reserved for future use and must be NULL.
dwFlags
[in] The following flag values are defined.
Value | Meaning
CRYPT_MACHINE_DEFAULT | Causes the computer default CSP of the specified type to be set.
CRYPT_USER_DEFAULT | Causes the user default CSP of the specified type to be set.
CRYPT_DELETE_DEFAULT | Can be used in conjunction with CRYPT_MACHINE_DEFAULT or CRYPT_USER_DEFAULT to delete the default.

CRYPT_DELETE_DEFAULT can be combined with either of the other flags with a bitwise-OR operation.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. Possible error codes include those shown in the following table.

Value | Meaning
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
ERROR_NOT_ENOUGH_MEMORY | The operating system ran out of memory.

Remarks

Most applications do not specify a CSP name when calling the CryptAcquireContext function; however, an application can specify a CSP name thus giving the freedom to select a CSP with an appropriate level of security. Because calls to CryptSetProviderEx determine the CSP of a specified type used by all applications from that point on, CryptSetProviderEx must never be called without users consent.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 98 or later.
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on all platforms.

See Also

Service Provider Functions, CryptAcquireContext, CryptSetProvider


CryptSetProvParam

The CryptSetProvParam function customizes the operations of a cryptographic service provider (CSP). This function is commonly used to set a security descriptor on the key container associated with a CSP to control access to the private keys in that key container.

BOOL WINAPI CryptSetProvParam(
  HCRYPTPROV hProv,
  DWORD dwParam,
  BYTE *pbData,
  DWORD dwFlags
);

Parameters

hProv
[in] Handle of a cryptographic service provider (CSP) for which to set values. This handle must have already been created using CryptAcquireContext.
dwParam
[in] Currently defined settings are as follows.
Value | Meaning
PP_CLIENT_HWND | Specifies that a window handle is contained in pbData.
PP_KEYSET_SEC_DESCR | Specifies that the security descriptor on the entry where the stored key set is being assigned, and its value is contained in pbData.
PP_USE_HARDWARE_RNG | Specifies that the CSP must exclusively use the hardware random number generator (RNG). Some CSPs, such as the Microsoft CSPs, can use a hardware RNG. They can also use a mix of information from the machine to create random values. When PP_USE_HARDWARE_RNG is set, random values are taken exclusively from the hardware RNG and no other sources are used. If a hardware RNG is supported by the CSP and it can be exclusively used, the function succeeds and returns TRUE; otherwise, the function fails and returns FALSE. The pbData parameter must be NULL and dwFlags must be zero when using this value.

Note The PP_KEYSET_SEC_DESCR flag is not supported under Windows 95.

pbData
[in] Data buffer to contain a value to be set as a provider parameter. The required value is set in this buffer before calling CryptSetProvParam. The form of this data varies depending on the dwParam setting. For PP_USE_HARDWARE_RNG, this parameter must be NULL.
dwFlags
[in] If dwParam is PP_KEYSET_SEC_DESCR, dwFlags contains the SECURITY_INFORMATION applicable bit flags, as defined in the Win32 Programmer's Reference. For Windows 2000 and later, key-container security is handled with SetFileSecurity and GetFileSecurity. The documentation on the RegGetKeySecurity and RegSetKeySecurity Win32 functions provides additional information for platforms earlier than Windows 2000.

These bit flags can be combined with a bitwise-OR operation. For additional details, see CryptGetProvParam.

If dwParam is PP_USE_HARDWARE_RNG, dwFlags must be set to zero.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

The error codes prefaced by "NTE" are generated by the particular CSP being used. Error codes include the following.

Value | Meaning
ERROR_BUSY | The CSP context is currently being used by another process.
ERROR_INVALID_HANDLE | One of the parameters specifies an invalid handle.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
NTE_BAD_FLAGS | The dwFlags parameter is nonzero or the pbData buffer contains an invalid value.
NTE_BAD_TYPE | The dwParam parameter specifies an unknown parameter.
NTE_BAD_UID | The CSP context that was specified when the hKey key was created cannot be found.
NTE_FAIL | The function failed in some unexpected way.

Remarks

If dwParam is PP_CLIENT_HWND, pbData buffer contains a DWORD value specifying the window handle that the provider uses when interacting directly with the user. CryptSetProvParam must be called before calling CryptAcquireContext because many CSPs display a user interface during the CryptAcquireContext function. Use zero (0) for the hProv parameter in the call to CryptSetProvParam. If this is done. the parameter is set for all cryptographic contexts subsequently acquired within this process.

Examples

See Example C Program: Enumerating CSP Providers and Provider Types.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.

See Also

Service Provider Functions, CryptAcquireContext, CryptGetProvParam, CryptSetKeyParam


CryptUninstallDefaultContext

The CryptUninstallDefaultContext function removes a default context previously installed by CryptInstallDefaultContext. This function will block until any threads currently using this context finish, if the default context was installed with CRYPT_DEFAULT_CONTEXT_PROCESS_FLAG set.

BOOL WINAPI CryptUninstallDefaultContext(
  HCRYPTDEFAULTCONTEXT hDefaultContext,
  DWORD dwFlags,
  void *pvReserved
);

Parameters

hDefaultContext
[in] Handle of the context to be released.
dwFlags
[in] Reserved for future use.
pvReserved
[in] Reserved for future use.

Return Values

If the function succeeds, the return value is nonzero (TRUE) .If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on all platforms.


Key Generation and Exchange Functions

Key generation functions create, configure, and destroy cryptographic keys. They are also used to exchange keys with other users. The following table briefly describes each function.

Function | Description
CryptAcquireCertificatePrivateKey | Acquires an HCRYPTPROV handle and dwKeySpec for a specified certificate context.
CryptDeriveKey | Creates a key derived from a password.
CryptDestroyKey | Destroys a key.
CryptDuplicateKey | Makes an exact copy of a key and the state the key is in.
CryptExportKey | Transfers a key from the CSP to a key BLOB in the application's memory space.
CryptGenKey | Creates a random key.
CryptGenRandom | Generates random data.
CryptGetKeyParam | Retrieves a key's parameters.
CryptGetUserKey | Gets a handle to the key exchange or signature key.
CryptImportKey | Transfers a key from a key BLOB to a CSP.
CryptSetKeyParam | Specifies a key's parameters.


CryptAcquireCertificatePrivateKey

The CryptAcquireCertificatePrivateKey function acquires a HCRYPTPROV cryptographic service provider (CSP) handle including access to its related key container and the dwKeySpec for a user's specified certificate context. This function is used to get access to a user's private key when the user's certificate is available and the handle of a CSP with the user's key container is not available. This function can be used by the owner of a private key and not by any other user.

If a CSP handle and the key container containing a user's private key are available, the CryptGetUserKey function can be used.

BOOL WINAPI CryptAcquireCertificatePrivateKey(
  PCCERT_CONTEXT pCert,
  DWORD dwFlags,
  void *pvReserved,
  HCRYPTPROV *phCryptProv,
  DWORD *pdwKeySpec,
  BOOL *pfCallerFreeProv
);

Parameters

pCert
[in] Pointer to a CERT_CONTEXT structure containing the specified certificate context. This is the certificate context for which a private key will be acquired.
dwFlags
[in] The following flag values are defined.
Flag name | Meaning
CRYPT_ACQUIRE_CACHE_FLAG An HCRYPTPROV value is returned as phCryptProv. If an HCRYPTPROV value is already acquired and cached, that HCRYPTPROV value is returned. Otherwise, a new HCRYPTROV value is acquired and cached by using the certificate's CERT_KEY_CONTEXT_PROP_ID.

In any case, when this flag is set, pfCallerFreeProv returns FALSE and the calling application must not free the cached HCRYPTPROV value.
CRYPT_ACQUIRE_USE_PROV_INFO_FLAG Uses the certificate's property CERT_KEY_PROV_INFO_PROP_ID to determine if caching should be accomplished. For more information on CERT_KEY_PROV_INFO_PROP_ID, see CertSetCertificateContextProperty.

Uses caching, but only if during a previous call the dwFlags of the CRYPT_KEY_PROV_INFO structure was CERT_SET_KEY_CONTEXT_PROP.

CRYPT_ACQUIRE_COMPARE_KEY_FLAG | The public key in the certificate is compared with the public key returned by the CSP. If the keys do not match, the acquisition operation fails and the last error code is set to NTE_BAD_PUBLIC_KEY. If a cached HCRYPTPROV value is returned, no comparison is made.
CRYPT_ACQUIRE_SILENT_FLAG | The application requests that the CSP not display any user interface (UI) for this context. If the CSP must display the UI to operate, the call fails and the NTE_SILENT_CONTEXT error code is set as the last error.

pvReserved
[in] Reserved for future use and must be NULL.
phCryptProv
[out] Pointer to the returned HCRYPTPROV value. Depending on the dwFlags value, the HCRYPTPROV value must be freed by the calling application or explicitly freed on the last free action of the certificate context.
pdwKeySpec
[out] Pointer to a DWORD value identifying the private key to use from the acquired provider's key container. It can be AT_KEYEXCHANGE or AT_SIGNATURE.
pfCallerFreeProv
[out] Pointer to a BOOL flag. The flag is returned set to FALSE if:
  • Public key acquisition or comparison fails.
  • CRYPT_ACQUIRE_CACHE_FLAG is set.
  • CRYPT_ACQUIRE_USE_PROV_INFO_FLAG is set, the certificate context property is set to CERT_KEY_PROV_INFO_PROP_ID with the CRYPT_KEY_PROV_INFO structure, and the dwFlags parameter is set to CERT_SET_KEY_CONTEXT_PROP_ID.

If fCallerFreeProv flag is returned FALSE, the calling application must not release the returned HCRYPTPROV value. The returned HCRYPTPROV value is released on the last free action of the certificate context.

When the fCallerFreeProv flag is set to TRUE, the returned HCRYPTPROV value must be released by calling CryptReleaseContext.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. One possible error code is the following.

Value | Meaning
NTE_BAD_PUBLIC_KEY | The public key in the certificate does not match the public key returned by the CSP. This error code is returned if the CRYPT_ACQUIRE_COMPARE_KEY_FLAG is set and the public key in the certificate does not match the public key returned by the cryptographic provider.

Examples

See Example C Program: Sending and Receiving a Signed and Encrypted Message.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Key Generation and Exchange Functions, CRYPT_KEY_PROV_INFO, CryptReleaseContext, CertSetCertificateContextProperty


CryptDeriveKey

The CryptDeriveKey function generates cryptographic session keys derived from a base data value. This function guarantees that when the same CSP and algorithms are used, the keys generated from the same base data are identical. The base data can be a password or any other user data.

This function is the same as CryptGenKey, except that the generated session keys are derived from base data instead of being random. CryptDeriveKey can only be used to generate session keys. It cannot generate public/private key pairs.

A handle to the session key is returned in the phKey parameter. This handle can be used with any CryptoAPI function that requires a key handle.

BOOL WINAPI CryptDeriveKey(
  HCRYPTPROV hProv,
  ALG_ID Algid,
  HCRYPTHASH hBaseData,
  DWORD dwFlags,
  HCRYPTKEY *phKey
);

Parameters

hProv
[in] HCRYPTPROV handle of a cryptographic service provider (CSP) created by a call to CryptAcquireContext.
Algid
[in] ALG_ID structure identifying the symmetric encryption algorithm for which the key is to be generated. The algorithms available will most likely be different for each CSP. For more information on which algorithm identifier is used by the different providers for the key specs AT_KEYEXCHANGE and AT_SIGNATURE, see ALG_ID.

For more information on ALG_ID values to use with the Microsoft Base Cryptographic Provider, see Base Provider Algorithms. For more information on ALG_ID values to use with the Microsoft Strong Cryptographic Provider or the Microsoft Enhanced Cryptographic Provider, see Enhanced Provider Algorithms.

hBaseData
[in] Handle to a hash object that has been fed the exact base data.

To obtain this handle, an application must first create a hash object with CryptCreateHash and then add the base data to the hash object with CryptHashData. This process is described in detail in Hashes and Digital Signatures.

dwFlags
[in] Specifies the type of key generated.

The sizes of a session key can be set when the key is generated. The key size, representing the length of the key modulus in bits, is set with the upper 16 bits of this parameter. Thus, if a 128-bit RC4 session key is to be generated, the value 0x00800000 is combined with any other dwFlags predefined value with a bitwise-OR operation. Due to changing export control restrictions, the default CSP and default key length may change between operating system releases. It is important that both the encryption and decryption use the same CSP and that the key length be explicitly set using the dwFlags parameter to ensure interoperability on different operating system platforms.

The lower 16 bits of this parameter can be zero or you can specify one or more of the following flags by using the bitwise-OR operator to combine them.
Value | Meaning
CRYPT_CREATE_SALT Typically, when a session key is made from a hash value, there are a number of leftover bits. For example, if the hash value is 128 bits and the session key is forty bits, there will be eighty-eight bits left over.

If this flag is set, then the key is assigned a salt value based on the unused hash value bits. You can retrieve this salt value by using the CryptGetKeyParam function with the dwParam parameter set to KP_SALT.

If this flag is not set, then the key is given a salt value of zero.

When keys with nonzero salt values are exported (by using CryptExportKey), the salt value must also be obtained and kept with the key BLOB.
CRYPT_EXPORTABLE If this flag is set, the session key can be transferred out of the CSP into a key BLOB through the CryptExportKey function. Because keys generally must be exportable, this flag should usually be set.

If this flag is not set, then the session key is not exportable. This means the key is available only within the current session and only the application that created it is able to use it.

This flag does not apply to public/private key pairs.
CRYPT_NO_SALT | This flag specifies that a no salt value gets allocated for a forty-bit symmetric key. For more information, see New Salt Value Functionality.
CRYPT_UPDATE_KEY Some CSPs use session keys that are derived from multiple hash values. When this is the case, CryptDeriveKey must be called multiple times.

If this flag is set, a new session key is not generated. Instead, the key specified by phKey is modified. The precise behavior of this flag is dependent on the type of key being generated and on the particular CSP being used.

The Microsoft cryptographic service providers ignore this flag.

phKey
[in/out] Address to which the function copies the handle of the newly generated key.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes are listed in the following table.

Value | Meaning
ERROR_INVALID_HANDLE | One of the parameters specifies an invalid handle.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
NTE_BAD_ALGID | The Algid parameter specifies an algorithm that this CSP does not support.
NTE_BAD_FLAGS | The dwFlags parameter contains an invalid value.
NTE_BAD_HASH | The hBaseData parameter does not contain a valid handle to a hash object.
NTE_BAD_HASH_STATE | An attempt was made to add data to a hash object that is already marked "finished."
NTE_BAD_UID | The hProv parameter does not contain a valid context handle.
NTE_FAIL | The function failed in some unexpected way.
NTE_SILENT_CONTEXT | The provider could not perform the action because the context was acquired as silent.

Remarks

When keys are generated for symmetric block ciphers, the key by default is set up in cipher block chaining (CBC) mode with an initialization vector of zero. This cipher mode provides a good default method for bulk-encrypting data. To change these parameters, use the CryptSetKeyParam function.

The CryptDeriveKey function completes the hash. After CryptDeriveKey has been called, no more data can be added to the hash. Additional calls to CryptHashData or CryptHashSessionKey fail. After the application is done with the hash, CryptDestroyHash must be called to destroy the hash object.

To choose an appropriate key length, the following methods are recommended.

  • Enumerate the algorithms which the CSP supports and to get maximum and minimum key lengths for each algorithm. When using Internet Explorer 4.0 or later or Windows NT 4.0 with Service Pack 4 or later, call CryptGetProvParam with the PP_ENUMALGS_EX.
  • Use the minimum and maximum lengths to choose an appropriate key length. It is not always advisable to choose the maximum length since this can lead to performance issues.
  • After the desired key length has been chosen, use the upper 16 bits of the dwFlags parameter to specify the key length.

The following table lists minimum, default, and maximum key lengths for session key by algorithm and provider.

Provider | Algorithms | Minimum Key Length | Default Key Length | Maximum Key Length
MS Base | RC4 and RC2 | 40 | 40 | 56
MS Base | DES | 56 | 56 | 56
MS Enhanced | RC4 and RC2 | 40 | 128 | 128
MS Enhanced | DES | 56 | 56 | 56
MS Enhanced | 3DES 112 | 112 | '112 | 112
MS Enhanced | 3DES | 168 | 168 | 168
MS Strong | RC4 and RC2 | 40 | 40 | 128
MS Strong | DES | 56 | 56 | 56
MS Strong | 3DES 112 | 112 | 112 | 112
MS Strong | 3DES | 168 | 168 | 168
DSS/DH Base | RC4 and RC2 | 40 | 40 | 56
DSS/DH Base | Cylink MEK | 40 | 40 | 40
DSS/DH Base | DES | 56 | 56 | 56
DSS/DH Enh | RC4 and RC2 | 40 | 40 | 128
DSS/DH Enh | Cylink MEK | 40 | 40 | 40
DSS/DH Enh | DES | 56 | 56 | 56
DSS/DH Enh | 3DES 112 | 112 | 112 | 112
DSS/DH Enh | 3DES | 168 | 168 | 168

Examples

See Example C Program: Deriving a Session Key from a Password.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.

See Also

Key Generation and Exchange Functions, CryptAcquireContext, CryptCreateHash, CryptDestroyHash, CryptDestroyKey, CryptExportKey, CryptGenKey, CryptGetKeyParam, CryptHashData, CryptHashSessionKey, CryptSetKeyParam


CryptDestroyKey

The CryptDestroyKey function releases the handle referenced by the hKey parameter. After a key handle has been released, it becomes invalid and cannot be used again.

If the handle refers to a session key, or to a public key that has been imported into the CSP through CryptImportKey, this function destroys the key and frees the memory that the key occupied. Many CSPs scrub the memory where the key was held before freeing it. However, the underlying public/private key pair is not destroyed by this function. Only the handle is destroyed.

BOOL WINAPI CryptDestroyKey(
  HCRYPTKEY hKey
);

Parameters

hKey
[in] Handle of the key to be destroyed.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes are listed in the following table.

Value | Meaning
ERROR_BUSY | The key object specified by hKey is currently being used and cannot be destroyed.
ERROR_INVALID_HANDLE | The hKey parameter specifies an invalid handle.
ERROR_INVALID_PARAMETER | The hKey parameter contains an invalid value.
NTE_BAD_KEY | The hKey parameter does not contain a valid handle to a key.
NTE_BAD_UID | The CSP context that was specified when the key was created cannot be found.

Remarks

Keys take up both operating system's memory space and the CSP's memory space. Some CSPs are implemented in hardware with limited memory resources. Applications must destroy all keys with the CryptDestroyKey function when they are finished with them.

Examples

See Example C Program: Creating and Hashing a Session Key.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.

See Also

Key Generation and Exchange Functions, CryptDeriveKey, CryptGenKey, CryptGetUserKey, CryptImportKey


CryptDuplicateKey

The CryptDuplicateKey function makes an exact copy of a key and the key's state.

BOOL WINAPI CryptDuplicateKey(
  HCRYPTKEY hKey,
  DWORD *pdwReserved,
  DWORD dwFlags,
  HCRYPTKEY *phKey
);

Parameters

hKey
[in] Handle to the key to be duplicated.
pdwReserved
[in] Reserved for future use and must be NULL.
dwFlags
[in] Reserved for future use and must be zero.
phKey
[out] Address of the handle to the duplicated key.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

The error code prefaced by "NTE" is generated by the particular CSP being used. Some possible error codes are listed in the following table.

Value | Meaning
ERROR_CALL_NOT_IMPLEMENTED | Because this is a new function, existing CSPs might not implement it. This error is returned if the CSP does not support this function.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
NTE_BAD_KEY | The handle to the original key is not valid.

Remarks

CryptDuplicateKey makes a copy of a key and the exact state of the key. This function might be used if an application needs to encrypt two separate messages with the same key but with different salt values. The key would be generated, a duplicate made with the CryptDuplicateKey function, and then the appropriate salt value would be set on each key with the CryptSetKeyParam function.

CryptDestroyKey must be called to destroy any keys that are created with CryptDuplicateKey. Destroying the original key does not cause the duplicate key to be destroyed. Once a duplicate key is made, it is separate from the original key. There is no shared state between the two keys.

Examples

See Example C Program: Duplicating a Session Key.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 98 or later.
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.

See Also

Key Generation and Exchange Functions, CryptDestroyKey, CryptSetKeyParam


CryptExportKey

The CryptExportKey function exports a cryptographic key or a key pair from a cryptographic service provider (CSP) in a secure manner.

A handle to the key to be exported is passed to the function, and the function returns key BLOB This key BLOB can be sent over a non-secure transport or stored in a non-secure storage location. This function can export an Schannel session key, regular session key, public key, or public/private key pair. The key BLOB to export is useless until the intended recipient uses the CryptImportKey function on it to import the key or key pair into a recipient's CSP.

BOOL WINAPI CryptExportKey(
  HCRYPTKEY hKey,
  HCRYPTKEY hExpKey,
  DWORD dwBlobType,
  DWORD dwFlags,
  BYTE *pbData,
  DWORD *pdwDataLen
);

Parameters

hKey
[in] Handle to the key to be exported.
hExpKey
[in] Handle to a cryptographic key of the destination user. The key data within the exported key BLOB is encrypted using this key. This ensures that only the destination user is able to make use of the key BLOB.

Most often, this is the key exchange public key of the destination user. However, certain protocols in some CSPs require that a session key belonging to the destination user be used for this purpose.

Windows 2000 introduces support for Symmetric Key Wrap; however, the use of a session key is not currently supported on any earlier platform by either the Microsoft Base Cryptographic Provider or the Microsoft Enhanced Cryptographic Provider.

If the key BLOB type specified by dwBlobType is PUBLICKEYBLOB, this parameter is unused and must be set to zero.

If the key BLOB type specified by dwBlobType is PRIVATEKEYBLOB, this is typically a handle to a session key that is to be used to encrypt the key BLOB. Some CSPs allow this parameter to be zero, in which case the application must encrypt the private key BLOB manually so as to protect it.

To determine how Microsoft cryptographic service providers respond to this parameter, see the private-key BLOB sections of Microsoft Cryptographic Service Providers.

dwBlobType
[in] Specifies the type of key BLOB to be exported in pbData. This must be one of the following constants as discussed in Storage and Exchange of Cryptographic Keys.
Value | Meaning
OPAQUEKEYBLOB | Used to store session keys in an Schannel CSP. OPAQUEKEYBLOBs are nontransferable and must be used within the CSP that generated the BLOB.
PRIVATEKEYBLOB | Used to transport public/private key pairs.
PUBLICKEYBLOB | Used to transport public keys.
SIMPLEBLOB | Used to transport session keys.
SYMMETRICWRAPKEYBLOB | Used to export and import a symmetric key wrapped with another symmetric key. The actual wrapped key is in the format specified in the IETF SMIME X9.42 standard.

dwFlags
[in] The following flag values are defined.
Value | Meaning
CRYPT_DESTROYKEY | This flag destroys the original key in the OPAQUEKEYBLOB. This flag is available in Schannel CSPs only.
CRYPT_SSL2_FALLBACK | The first eight bytes of the RSA encryption block padding must be set to 0x03 rather than to random data. This prevents version rollback attacks and is discussed in the SSL3 specification. This flag is available for Schannel CSPs only.
CRYPT_OAEP | This flag causes PKCS #1 version 2 formatting to be created with the RSA encryption and decryption when exporting SIMPLEBLOBs.

pbData
[out] Pointer to a buffer to receive the key BLOB data. The format of this BLOB varies depending on the BLOB type requested in the dwBlobType parameter. For the format for PRIVATEKEYBLOBs, PUBLICKEYBLOBs, and SIMPLEBLOBs, see Base Provider Key BLOBs.

This parameter can be NULL to acquire the size of the buffer needed to hold the BLOB. For more information, see Retrieving Data of Unknown Length,

pdwDataLen
[in/out] Pointer to a DWORD value specifying the size, in bytes, of the buffer pointed to by the pbData parameter. When the function returns, the DWORD value contains the number of bytes stored in the buffer.

Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. On input, buffer sizes are usually specified large enough to ensure that the largest possible output data fits in the buffer. On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes are listed in the following table.

Value | Meaning
ERROR_INVALID_HANDLE | One of the parameters specifies an invalid handle.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
ERROR_MORE_DATA | If the buffer specified by the pbData parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code and stores the required buffer size, in bytes, in the variable pointed to by pdwcbDataLen.
NTE_BAD_FLAGS | The dwFlags parameter is nonzero.
NTE_BAD_KEY | One or both of the keys specified by hKey and hExpKey are invalid.
NTE_BAD_KEY_STATE | You do not have permission to export the key. That is, when the hKey key was created, the CRYPT_EXPORTABLE flag was not specified.
NTE_BAD_PUBLIC_KEY | The key BLOB type specified by dwBlobType is PUBLICKEYBLOB, but hExpKey does not contain a public key handle.
NTE_BAD_TYPE | The dwBlobType parameter specifies an unknown BLOB type.
NTE_BAD_UID | The CSP context that was specified when the hKey key was created cannot be found.
NTE_NO_KEY | A session key is being exported, and the hExpKey parameter does not specify a public key.

Examples

See Example C Program: Signing a Hash and Verifying the Hash Signature and Example C Program: Exporting a Session Key.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.

See Also

Key Generation and Exchange Functions, CryptImportKey


CryptGenKey

The CryptGenKey function generates a random cryptographic session key or a public/private key pair. A handle to the key or key pair is returned in phKey. This handle can then be used as needed with any CryptoAPI function requiring a key handle.

The calling application must specify the algorithm when calling this function. Because this algorithm type is kept bundled with the key, the application does not need to specify the algorithm later when the actual cryptographic operations are performed.

BOOL WINAPI CryptGenKey(
  HCRYPTPROV hProv,
  ALG_ID Algid,
  DWORD dwFlags,
  HCRYPTKEY *phKey
);

Parameters

hProv
[in] HCRYPTPROV handle of a cryptographic service provider (CSP) created by a call to CryptAcquireContext.
Algid
[in] ALG_ID structure identifying the algorithm for which the key is to be generated. Values for this parameter vary depending on the CSP used.

For ALG_ID values to use with the Microsoft Base Cryptographic Provider, see Base Provider Algorithms.

For ALG_ID values to use with the Microsoft Strong Cryptographic Provider or the Microsoft Enhanced Cryptographic Provider, see Enhanced Provider Algorithms.

For a Diffie-Hellman CSP, use one of the following values.
Value | Meaning
CALG_DH_EPHEM | Specifies an "Ephemeral" Diffie-Hellman key.
CALG_DH_SF | Specifies a "Store and Forward" Diffie-Hellman key.

In addition to generating session keys for symmetric algorithms, this function can also generate public/private key pairs. Each CryptoAPI client generally possesses two public/private key pairs. To generate one of these key pairs, set the Algid parameter to one of the following values.
Value | Meaning
AT_KEYEXCHANGE | Key exchange
AT_SIGNATURE | Digital signature

Note When key specifications AT_KEYEXCHANGE and AT_SIGNATURE are specified, the algorithm identifiers that are used to generate the key depend on the provider used. As a result, for these key specifications, the values returned from CryptGetKeyParam (when the KP_ALGID parameter is specified) depend on the provider used. To determine which algorithm identifier is used by the different providers for the key specs AT_KEYEXCHANGE and AT_SIGNATURE, see ALG_ID.

dwFlags
[in] Specifies the type of key generated. The sizes of a session key, RSA signature key, and RSA key exchange keys can be set when the key is generated. The key size, representing the length of the key modulus in bits, is set with the upper 16 bits of this parameter. Thus, if a 2,048-bit RSA signature key is to be generated, the value 0x08000000 is combined with any other dwFlags predefined value with a bitwise-OR operation. The upper 16 bits of 0x08000000 is 0x0800, or decimal 2048.

Due to changing export control restrictions, the default CSP and default key length may change between operating system releases. It is important that both the encryption and decryption use the same CSP and that the key length be explicitly set using the dwFlags parameter to ensure interoperability on different operating system platforms.

If the upper 16 bits is zero, the default key size is generated. If a key larger than the maximum or smaller than the minimum is specified, the call fails with the ERROR_INVALID_PARAMETER code.

The following table lists current minimum, default, and maximum signature and exchange key lengths. For current session key lengths, see CryptDeriveKey
Key Type and Provider | Minimum Length | Default Length | Maximum Length
Signature Keys / RSA Base and Strong providers | 384 | 512 | 16
Signature Keys / RSA Enhanced provider | 384 | 1024 | 16
Exchange Keys / Base and Strong providers | 384 | 512 | 1024
Exchange Keys / Enhanced provider | 384 | 1024 | 16

For more information about keys generated using Microsoft providers, see Microsoft Cryptographic Service Providers.

This parameter can be zero, or you can specify one or more of the following flags by using the bitwise-OR operator to combine them.
Value | Meaning
CRYPT_CREATE_SALT If this flag is set, then the key is assigned a random salt value automatically. You can retrieve this salt value by using the CryptGetKeyParam function with the dwParam parameter set to KP_SALT.

If this flag is not set, then the key is given a salt value of zero.

When keys with nonzero salt values are exported (through CryptExportKey), then the salt value must also be obtained and kept with the key BLOB.
CRYPT_EXPORTABLE If this flag is set, then the key can be transferred out of the CSP into a key BLOB by using the CryptExportKey function. Because session keys generally must be exportable, this flag should usually be set when they are created.

If this flag is not set, then the key is not exportable. For a session key, this means that the key is available only within the current session and only the application that created it will be able to use it. For a public/private key pair, this means that the private key cannot be transported or backed up.

This flag applies only to session key and private key BLOBs. It does not apply to public keys, which are always exportable.
CRYPT_NO_SALT | This flag specifies that a no salt value gets allocated for a forty-bit symmetric key. For more information, see New Salt Value Functionality.
CRYPT_PREGEN | This flag specifies an initial Diffie-Hellman or DSS key generation. This flag is useful only with Diffie-Hellman and DSS CSPs. When used, a default key length will be used unless a key length is specified in the upper 16 bits of the dwFlags parameter. If parameters that involve key lengths are set on a PREGEN Diffie-Hellman or DSS key using CryptSetKeyParam, the key lengths must be compatible with the key length set here.
CRYPT_USER_PROTECTED | If this flag is set, the user is notified through a dialog box or another method when certain actions are attempting to use this key. The precise behavior is specified by the CSP being used. Prior to Internet Explorer 4.0, Microsoft cryptographic service providers ignored this flag. Starting with Internet Explorer 4.0, Microsoft providers support this flag value. Windows 98, Windows NT 4.0 with Service Pack 4, and Windows 2000 support this flag value. If the provider context was opened with the CRYPT_SILENT flag set, using this flag causes a failure and the last error is set to NTE_SILENT_CONTEXT.
CRYPT_ARCHIVABLE | If this flag is set, the key can be exported until its handle is closed by a call to CryptDestroyKey. This allows newly generated keys to be exported upon creation for archiving or key recovery. After the handle is closed, the key is no longer exportable

phKey
[out] Address to which the function copies the handle of the newly generated key.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes are listed in the following table.

Value | Meaning
ERROR_INVALID_HANDLE | One of the parameters specifies an invalid handle.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
NTE_BAD_ALGID | The Algid parameter specifies an algorithm that this CSP does not support.
NTE_BAD_FLAGS | The dwFlags parameter contains an invalid value.
NTE_BAD_UID | The hProv parameter does not contain a valid context handle.
NTE_FAIL | The function failed in some unexpected way.
NTE_SILENT_CONTEXT | The provider could not perform the action because the context was acquired as silent.

Remarks

If keys are generated for symmetric block ciphers, the key by default is set up in cipher block chaining (CBC) mode with an initialization vector of zero. This cipher mode provides a good default method for bulk encrypting data. To change these parameters, use the CryptSetKeyParam function.

To choose an appropriate key length, the following methods are recommended:

  • Enumerate the algorithms which the CSP supports and get maximum and minimum key lengths for each algorithm. When using Internet Explorer 4.0 or later or Windows NT 4.0 with Service Pack 4 or later, call CryptGetProvParam with the PP_ENUMALGS_EX.
  • Use the minimum and maximum lengths to choose an appropriate key length. It is not always advisable to choose the maximum length since this can lead to performance issues.
  • After the desired key length has been chosen, use the upper 16 bits of the dwFlags parameter to specify the key length.

Examples

See Example C Program: Encrypting a File and Example C Program: Decrypting a File.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.

See Also

Key Generation and Exchange Functions, CryptAcquireContext, CryptDestroyKey, CryptExportKey, CryptGetKeyParam, CryptImportKey, CryptSetKeyParam


CryptGenRandom

The CryptGenRandom function fills a buffer with cryptographically random bytes.

BOOL WINAPI CryptGenRandom(
  HCRYPTPROV hProv,
  DWORD dwLen,
  BYTE *pbBuffer
);

Parameters

hProv
[in] HCRYPTPROV handle of a cryptographic service provider (CSP) created by a call to CryptAcquireContext.
dwLen
[in] Number of bytes of random data to be generated.
pbBuffer
[in/out] Buffer to receive the returned data. This buffer must be at least dwLen bytes in length.

Optionally, the application can fill this buffer with data to use as an auxiliary random seed.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes are listed in the following table.

Value | Meaning
ERROR_INVALID_HANDLE | One of the parameters specifies an invalid handle.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
NTE_BAD_UID | The hProv parameter does not contain a valid context handle.
NTE_FAIL | The function failed in some unexpected way.

Remarks

The data produced by this function is cryptographically random. It is far more random than the data generated by the typical random number generator such as the one shipped with your C compiler.

This function is often used to generate random initialization vectors and salt values.

All software random number generators work in fundamentally the same way. They start with a random number, known as the seed, and then use an algorithm to generate a pseudo-random sequence of bits based on it. The most difficult part of this process is to get a seed that is truly random. This is usually based on user input latency, or the jitter from one or more hardware components.

If an application has access to a good random source, it can fill the pbBuffer buffer with some random data before calling CryptGenRandom. The CSP then uses this data to further randomize its internal seed. It is acceptable to omit the step of initialize the pbBuffer buffer before calling CryptGenRandom.

Examples

See Example C Program: Duplicating a Session Key.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.

See Also

Key Generation and Exchange Functions, CryptAcquireContext, CryptGenKey, CryptSetKeyParam


CryptGetKeyParam

The CryptGetKeyParam function retrieves data that governs the operations of a key. If the Microsoft Cryptographic Service Provider is used, the base symmetric keying material is not obtainable by this function or any other function.

BOOL WINAPI CryptGetKeyParam(
  HCRYPTKEY hKey,
  DWORD dwParam,
  BYTE *pbData,
  DWORD *pdwDataLen,
  DWORD dwFlags
);

Parameters

hKey
[in] Handle to the key being queried.
dwParam
[in] Specifies the query being made. For all key types, dwParam can be set to one of the following key value types:
Key type | Description
KP_ALGID | The key algorithm. pbData contains an ALG_ID value indicating the algorithm that was specified when the key was created. Note that when key specifications AT_KEYEXCHANGE and AT_SIGNATURE are specified for the Algid parameter, the algorithm identifiers that are used to generate the key depend on the provider used. As a result, for these key specifications the values returned from CryptGetKeyParam (when the KP_ALGID value is specified) depend on the provider used. To determine which algorithm identifier is used by the different providers for the key specifications AT_KEYEXCHANGE and AT_SIGNATURE, see ALG_ID.
KP_BLOCKLEN If a session key is specified by hKey, returns the key cipher's block length, in bits. pbData is a DWORD value indicating the block length. For stream ciphers, this value is always be zero.

If a public/private key pair is specified by hKey, this parameter returns a BLOB containing the key pair's encryption granularity in bits. For example, the Microsoft Base Cryptographic Provider generates 512-bit RSA key pairs, so a value of 512 is returned for these keys. If the public-key algorithm does not support encryption, the value returned by this parameter is undefined
KP_KEYLEN A value used to get the actual length of a key in bits. The length of the key is located in the DWORD value pointed to by pbData. This value can be used to get the length of any key type. Microsoft CSPs return a key length of sixty-four bits for CALG_DES, 128 bits for CALG_3DES_112, and 192 bits for CALG_3DES. These lengths are different from the lengths returned when enumerating algorithms with the dwParam value of CryptGetProvParam set to PP_ENUMALGS. The length returned by this call is the actual size of the key including the parity bits included in the key.

Microsoft CSPs that support the ALG_ID CALG_CYLINK_MEK return sixty-four bits for that algorithm. CALG_CYLINK_MEK is a forty-bit key but has parity and zeroed key bits to make the key length sixty-four bits.
KP_SALT | The salt value. pbData contains a BYTE array indicating the current salt value. The size of the salt value varies depending on the CSP and algorithm being used. Salt values do not apply to public/private key pairs.
KP_PERMISSIONS | Key permissions. pbData contains a DWORD value with zero or more bit permission flags set. For a description of each of these flags, refer to the permission flag table at the end of this Remarks section.

If a DSS key is specified by hKey, the dwParam value can also be set to one of the following value types.
Key type | Description
KP_P | pbData contains the prime modulus P from the DSS key BLOB. The length of the data is returned in the pdwDataLen parameter.
KP_Q | pbData contains the prime Q from the DSS key BLOB. The length of the data is returned in the pdwDataLen parameter.
KP_G | pbData contains the generator G from the DSS key BLOB. The length of the data is returned in the pdwDataLen parameter.

If a block cipher session key is specified by hKey, the dwParam value can also be set to one of the following value types.
Key type | Description
KP_EFFECTIVE_KEYLEN | Query the effective key length of an RC2 key. pbData contains a DWORD value equal to the effective key length.
KP_IV | The initialization vector. pbData contains a BYTE array indicating the current initialization vector. This array contains block_length/8 elements. For example, if the block length is sixty-four bits, the initialization vector consists of eight bytes.
KP_PADDING | The padding mode. pbData buffer contains a DWORD value indicating the padding method used by the cipher. The padding method currently defined is PKCS5_PADDING—PKCS 5 (sec 6.2).
KP_MODE | The cipher mode. pbData contains a DWORD value indicating the mode of the cipher. For a list of valid cipher modes, refer to the table in the Remarks section.
KP_MODE_BITS | The number of bits to feed back. pbData contains a DWORD value indicating the number of bits that are processed per cycle when the OFB or CFB cipher modes are used.

pbData
[out] Pointer to a sequence of BYTES to receive the data. The function returns the specified data in this buffer. The form of this data depends on the value of dwParam.

This parameter can be NULL to retrieve the size of the buffer needed. For more information, see Retrieving Data of Unknown Length.

pdwDataLen
[in/out] Pointer to a DWORD value specifying the size, in bytes, of the buffer pointed to by the pbData parameter. When the function returns, the DWORD value contains the number of bytes stored in the buffer.

Note When processing the data returned in the buffer, applications must the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. On input, buffer sizes are usually specified large enough to ensure that the largest possible output data fits in the buffer. On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

dwFlags
[in] Reserved for future use and must be zero.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes follow.

Value | Meaning
ERROR_INVALID_HANDLE | One of the parameters specifies an invalid handle.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
ERROR_MORE_DATA | If the buffer specified by the pbData parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code and stores the required buffer size, in bytes, in the variable pointed to by pdwDataLen.
NTE_BAD_FLAGS | The dwFlags parameter is nonzero.
NTE_BAD_KEY or NTE_NO_KEY | The key specified by the hKey parameter is invalid.
NTE_BAD_TYPE | The dwParam parameter specifies an unknown value number.
NTE_BAD_UID | The CSP context that was specified when the key was created cannot be found.

Remarks

The following table lists the possible return value when dwParam is KP_MODE. These cipher modes are discussed in Data Encryption and Decryption.

Cipher Mode | Description
CRYPT_MODE_CBC | cipher block chaining
CRYPT_MODE_CFB | cipher feedback
CRYPT_MODE_ECB | electronic codebook
CRYPT_MODE_OFB | output feedback

The following table lists the flags in the bit field that are returned when dwParam is set to KP_PERMISSIONS. These bit flags can be combined using bitwise-OR operations. All permission flags are ignored in Windows 95 Windows 98, Windows NT 4.0 and earlier when using any Microsoft CSP. Windows 2000 using any Microsoft CSP recognizes and uses the CRYPT_EXPORT flag bit. None of the permission flags except the CRYPT_EXPORT flag bit when using Windows 2000 should be relied upon. A custom CSP, however, can use these flag values to restrict operations on keys.

Value | Meaning
CRYPT_ARCHIVE | Allows export during the lifetime of its handle. This bit can be set only if it is already set in the key's internal permissions field. Attempts to clear this bit are ignored.
CRYPT_DECRYPT | Allows decryption.
CRYPT_ENCRYPT | Allows encryption.
CRYPT_EXPORT | Allows key to be exported.
CRYPT_MAC | Allows MACs to be used with key.
CRYPT_READ | Allows values to be read.
CRYPT_WRITE | Allows values to be set.

Examples

See Example C Program: Setting and Getting Session Key Parameters.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.

See Also

Key Generation and Exchange Functions, CryptSetKeyParam


CryptGetUserKey

The CryptGetUserKey function retrieves a handle of one of a user's two public/private key pairs. This function is used only by the owner of the public/private key pairs and only when the handle of a cryptographic service provider (CSP) and its associated key container is available. If the CSP handle is not available and the user's certificate is, use CryptAcquireCertificatePrivateKey.

BOOL WINAPI CryptGetUserKey(
  HCRYPTPROV hProv,
  DWORD dwKeySpec,
  HCRYPTKEY *phUserKey
);

Parameters

hProv
[in] HCRYPTPROV handle of a cryptographic service provider (CSP) created by a call to CryptAcquireContext.
dwKeySpec
[in] Identifies the private key to use from the key container. It can be AT_KEYEXCHANGE or AT_SIGNATURE.

Additionally, some providers allow access to other user-specific keys through this function. For details, see the documentation on the specific provider.

phUserKey
[out] Pointer to the HCRYPTKEY handle of the retrieved keys.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes follow.

Value | Meaning
ERROR_INVALID_HANDLE | One of the parameters specifies an invalid handle.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
NTE_BAD_KEY | The dwKeySpec parameter contains an invalid value.
NTE_BAD_UID | The hProv parameter does not contain a valid context handle.
NTE_NO_KEY | The key requested by the dwKeySpec parameter does not exist.

Examples

See Example C Program: Signing a Hash and Verifying the Hash Signature and Example C Program: Exporting a Session Key.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.

See Also

Key Generation and Exchange Functions, CryptAcquireContext, CryptDestroyKey, CryptGenKey


CryptImportKey

The CryptImportKey function transfers a cryptographic key from a key BLOB into a cryptographic service provider (CSP).This function can be used to import an Schannel session key, regular session key, public key, or public/private key pair. For all but the public key, the key or key pair is encrypted.

BOOL WINAPI CryptImportKey(
  HCRYPTPROV hProv,
  BYTE *pbData,
  DWORD dwDataLen,
  HCRYPTKEY hPubKey,
  DWORD dwFlags,
  HCRYPTKEY *phKey
);

Parameters

hProv
[in] HCRYPTPROV handle of a cryptographic service provider (CSP) created by a call to CryptAcquireContext.
pbData
[in] BYTE sequence containing the key CRYPTOAPI_BLOB. This key BLOB was generated by the CryptExportKey function, either in this application or by another application possibly running on a different computer.

The key BLOB's pbData member is a byte sequence with a PUBLICKEYSTRUC BLOB header followed by the encrypted key.

dwDataLen
[in] Length, in bytes, of the key BLOB.
hPubKey
[in] The meaning of this parameter differs depending on the CSP type and the type of key BLOB being imported.

If the key BLOB is encrypted with the key exchange key pair, for example, a SIMPLEBLOB, this parameter can be the handle to the key exchange key.

If the key BLOB is encrypted with a session key, for example, an encrypted PRIVATEKEYBLOB, this parameter contains the handle of this session key.

If the key BLOB is not encrypted, for example, a PUBLICKEYBLOB, this parameter is not used and must be zero.

If the key BLOB is encrypted with a session key in an Schannel CSP, for example, an encrypted OPAQUEKEYBLOB, this parameter is not used and must be set to zero.

dwFlags
[in] Currently used only when a public/private key pair in the form of a PRIVATEKEYBLOB is imported into the CSP.

The following flag values are defined.
Value | Meaning
CRYPT_EXPORTABLE | The key being imported is eventually to be re-exported. If this flag is not used, then calls to CryptExportKey with the key handle fail.
CRYPT_OAEP | This flag causes PKCS #1 version 2 formatting to be checked with the RSA encryption and decryption when importing SIMPLEBLOBs.
CRYPT_NO_SALT | A no-salt value gets allocated for a 40-bit symmetric key. For more information, see New Salt Value Functionality.

phKey
[out] Pointer to the handle of the imported key.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes follow.

Value | Meaning
ERROR_BUSY | Some CSPs set this error if a private key is imported into a container while another thread or process is using this key.
ERROR_INVALID_HANDLE | One of the parameters specifies an invalid handle.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
NTE_BAD_ALGID | The simple key BLOB you are trying to import is not encrypted with the expected key exchange algorithm.
NTE_BAD_DATA | Either the algorithm that works with the public key you are trying to import is not supported by this CSP, or an attempt was made to import a session key that was encrypted with something other than one of your public keys.
NTE_BAD_FLAGS | The dwFlags parameter specified is invalid.
NTE_BAD_TYPE | The key BLOB type is not supported by this CSP and is possibly invalid.
NTE_BAD_UID | The hProv parameter does not contain a valid context handle.
NTE_BAD_VER | The key BLOB's version number does not match the CSP version. This usually indicates that the CSP needs to be upgraded.

Examples

See Example C Program: Signing a Hash and Verifying the Hash Signature and Example C Program: Decrypting a File.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.

See Also

Key Generation and Exchange Functions, CryptAcquireContext, CryptDestroyKey, CryptExportKey


CryptSetKeyParam

The CryptSetKeyParam function customizes various aspects of a session key's operations. The values set by this function are not persisted to memory and can only be used with in a single session.

The Microsoft Base Cryptographic Provider does not permit setting values for key exchange or signature keys; however, custom providers can define values that can be set for its keys.

BOOL WINAPI CryptSetKeyParam(
  HCRYPTKEY hKey,
  DWORD dwParam,
  BYTE *pbData,
  DWORD dwFlags
);

Parameters

hKey
[in] Handle to the key for which values are to be set.
dwParam
[in] The following tables contain predefined values that can be used.

For all session key types, the dwParam value can be set to one of the following key value types.
Session key types | Flag value | Description
All key types | KP_SALT | pbData points to a BYTE array specifying a new salt value to be made part of the session key. The size of the salt value varies depending on the CSP being used. Before setting this value, determine the size of the salt value by calling CryptGetKeyParam. Salt values are used to make the session keys more unique making dictionary attacks more difficult. The salt value is zero by default for Microsoft Base Cryptographic Provider.
KP_SALT_EX | pbData points to a CRYPTOAPI_BLOB structure containing the salt. For more information, see Specifying a Salt Value.
KP_PERMISSIONS | pbData points to a DWORD value specifying zero or more permission flags. For a description of these flags, see CryptGetKeyParam.
KP_ALGID | pbData points to an appropriate ALG_ID This is used when exchanging session keys with the Microsoft Base DSS, Diffie-Hellman Cryptographic Provider or compatible CSPs. Once a key is agreed on with the CryptImportKey function, the session key is enabled for use by setting its algorithm type.
DSS keys | KP_P | pbData points to the prime modulus P of a DSS key BLOB. The data is in the form of a CRYPTOAPI_BLOB structure. The pbData member is the value and the cbData member is the length of the value. The value is expected with no header information and in little-endian form.
KP_Q | pbData points to the prime Q of a DSS key BLOB. The data is in the form of a BLOB structure where the pbData member is the value and the cbData member is the length of the value. The value is expected with no header information and in little-endian form.
KP_G | pbData points to the generator G from the DSS key BLOB. The data is in the form of a CRYPTOAPI_BLOB structure, where the pbData member is the value and the cbData member is the length of the value. The value is expected with no header information and in little-endian form.
KP_X | After the P, Q, and G values have been set, a call can be made to CryptSetKeyParam specifying the KP_X value for dwParam and NULL for the pbData parameter. This causes the X and Y values to be generated.
DSS or Diffie-Hellman keys | KP_PUB_PARAMS | Sets the public parameters (P, Q, G, and so on) of a DSS or Diffie-Hellman key. The key handle for this key must be in the PREGEN state, generated with the CRYPT_PREGEN flag. The pbData parameter must be a pointer to a DATA_BLOB structure where the data in this structure is a DHPUBKEY_VER3 or DSSPUBKEY_VER3 BLOB. The function copies the public parameters from this CRYPTOAPI_BLOB structure to the key handle. After this call is made, the KP_X parameter value should be used with CryptSetKeyParam to create the actual private key. The KP_PUB_PARAMS parameter is used as one call rather than multiple calls with the parameter values KP_P, KP_Q and KP_G.
Block cipher
session keys 		KP_EFFECTIVE_KEYLEN This value type can be used only with RC2 keys and has been added because of the previous implementation of CryptSetKeyParam in the Windows NT 4.0 Service Pack 2 Microsoft Enhanced Cryptographic Provider. In that implementation, the RC2 keys in the Enhanced Provider were 128 bits in strength, but the effective key length used to expand keys into the key table was only forty bits. This reduced the strength of the algorithm to forty bits. To maintain backward compatibility, the previous implementation will remain as is. However, the effective key length can be set to be greater than forty bits by using KP_EFFECTIVE_KEYLEN in the CryptSetKeyParam call. The effective key length is passed in the pbData parameter as a pointer to a DWORD value with the effective key length value. The minimum effective key length on the Microsoft Base Cryptographic Provider is one, and the maximum is forty. In the Microsoft Enhanced Cryptographic Provider, the minimum is one and the maximum is 1,024. The key length must be set prior to encrypting or decrypting with the key.
KP_IV pbData points to a BYTE array specifying the initialization vector. This array must contain block_length/8 elements. For example, if the block length is sixty-four bits, the initialization vector consists of eight bytes.

The initialization vector is set to zero by default for the Microsoft Base Cryptographic Provider.
KP_PADDING | pbData points to a DWORD value specifying the padding method to be used by the cipher. The only padding method currently defined is PKCS5_PADDING.
KP_MODE | pbData points to a DWORD value specifying the cipher mode to be used. For a list of the defined cipher modes, see CryptGetKeyParam. The cipher mode is set to CRYPT_MODE_CBC by default for the Microsoft Base Cryptographic Provider.
KP_MODE_BITS | pbData point to a DWORD value indicating the number of bits processed per cycle when the OFB or CFB cipher mode is used. The number of bits processed per cycle is set to eight by default for the Microsoft Base Cryptographic Provider.

pbData
[in] Pointer to a buffer initialized with the value to be set before calling CryptSetKeyParam. The form of this data varies depending on the value of dwParam.
dwFlags
[in] Used only when dwParam is KP_ALGID. The dwFlags parameter is used to pass in flag values for the enabled key. The dwFlags parameter can hold values such as the key size and the other flag values allowed when generating the same type of key with CryptGenKey. For information on allowable flag values, see CryptGenKey.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes follow.

Value | Meaning
ERROR_BUSY | The CSP context is currently being used by another process.
ERROR_INVALID_HANDLE | One of the parameters specifies an invalid handle.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
NTE_BAD_FLAGS | The dwFlags parameter is nonzero, or the pbData buffer contains an invalid value.
NTE_BAD_TYPE | The dwParam parameter specifies an unknown parameter.
NTE_BAD_UID | The CSP context that was specified when the hKey key was created cannot be found.
NTE_FAIL | The function failed in some unexpected way.
NTE_FIXEDPARAMETERS | Some CSPs have hard-coded P, Q, and G values. If this is the case, then using KP_P, KP_Q, and KP_G for the value of dwParam causes this error.

Remarks

If the KP_Q, KP_P, or KP_X parameters are set on a PREGEN Diffie-Hellman or DSS key, the key lengths must be compatible with the key length set using the upper 16 bits of the dwFlags parameter when the key was created using CryptGenKey. If no key length was set in CryptGenKey, the default key length was used. This will create an error if a non-default key length is used to set P, Q, or X.

Examples

See Example C Program: Duplicating a Session Key and Example C Program: Setting and Getting Session Key Parameters.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.

See Also

Key Generation and Exchange Functions, ALG_ID, CryptGenKey, CryptGetKeyParam, CryptImportKey


CryptEncodeObject/CryptDecodeObject Functions

These are generalized encoding and decoding functions. They are used to encode and decode certificates, certificate revocation lists (CRLs), certificate requests, and certificate extensions.

The following functions are included in this category.

Function | Description
CryptDecodeObject | Decodes a structure of type lpszStructType.
CryptDecodeObjectEx | Decodes a structure of type lpszStructType. CryptDecodeObjectEx supports the one-pass memory allocation option.
CryptEncodeObject | Encodes a structure of type lpszStructType.
CryptEncodeObjectEx | Encodes a structure of type lpszStructType. CryptEncodeObjectEx supports the one-pass memory allocation option.


CryptDecodeObject

The CryptDecodeObject function decodes a structure of the type indicated by the lpszStructType parameter. The use of CryptDecodeObjectEx is recommended as an API that performs the same function with significant performance improvements.

BOOL WINAPI CryptDecodeObject(
  DWORD dwCertEncodingType,
  LPCSTR lpszStructType,
  const BYTE *pbEncoded,
  DWORD cbEncoded,
  DWORD dwFlags,
  void *pvStructInfo,
  DWORD *pcbStructInfo
);

Parameters

dwCertEncodingType
[in] Type of encoding used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

Note Either a certificate or message encoding type is required. X509_ASN_ENCODING is the default. If that type is indicated, it is used. Otherwise, if the PKCS7_ASN_ENCODING type is indicated, it is used.

lpszStructType
[in] Pointer to an OID defining the structure type. If the high-order word of the lpszStructType parameter is zero, the low-order word specifies the integer identifier for the type of the specified structure. Otherwise, this parameter is a long pointer to a NULL-terminated string.

For more details about object identifier strings, their predefined constants and corresponding structures, see Constants for CryptEncodeObject and CryptDecodeObject.

pbEncoded
[in] Pointer to the encoded structure to be decoded.
cbEncoded
[in] Number of bytes pointed to by pbEncoded.
dwFlags
[in] The following flags are defined. They can be combined with a bitwise-OR operation.
Value | Meaning
CRYPT_DECODE_NOCOPY_FLAG | This flag can be set to indicate that "no copy" optimization is enabled. This optimization, where applicable, updates the pvStructInfo members to point to content residing within pbEncoded instead of making a copy of the content and appending it to pvStructInfo. For applicable cases, less memory needs to be allocated by the calling application and execution is faster because a copy is not being made. Note that the tradeoff when performing a "no copy" decoding is that pbEncoded cannot be freed until pvStructInfo is freed.
CRYPT_UNICODE_NAME_DECODE_DISABLE_IE4_UTF8_FLAG | This flag is applicable when decoding X509_UNICODE_NAME, X509_UNICODE_NAME_VALUE, or X509_UNICODE_ANY_STRING. By default, CERT_RDN_T61_STRING encoded values are initially decoded as UTF8. If the UTF8 decoding fails, then the value is decoded as eight-bit characters. If this flag is set, it skips the initial attempt to decode the value as UTF8 and decodes the value as eight-bit characters.
CRYPT_DECODE_TO_BE_SIGNED_FLAG | By default, the contents of the buffer pointed to by pbEncoded included the signed content and the signature. If this flag is set, the buffer includes only the "to be signed" content. This flag is applicable to X509_CERT_TO_BE_SIGNED, X509_CERT_CRL_TO_BE_SIGNED, X509_CRT_REQUEST_TO_BE_SIGNED, and X509_KEYGEN_REQUEST_TO_BE_SIGNED objects.
CRYPT_DECODE_SHARE_0ID_STING_FLAG | When this flag is set, the OID stings are allocated in Crypt32.dll and shared instead of being copied into the returned data structure. This flag can be set if Crypt32.dll is not unloaded before the caller is unloaded.
CRYPT_DECODE_NO_SINGATURE_BYTE_REVERSAL_FLAG | By default, the signature bytes are reversed. If this flag is set, this byte reversal is inhibited.

pvStructInfo
[out] Pointer to a buffer to receive the decoded structure. When the buffer that is specified is not large enough to receive the decoded structure, the function sets the ERROR_MORE_DATA code and stores the required buffer size, in bytes, in the variable pointed to by pcbStructInfo.

This parameter can be NULL to retrieve the size of this information for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.

pcbStructInfo
[in/out] Pointer to a DWORD value specifying the size, in bytes, of the buffer pointed to by the pvStructInfo parameter. When the function returns, this DWORD value contains the size of the decoded data copied to *pvStructInfo. The size contained in the variable pointed to by pcbStructInfo can indicate a size larger than the decoded structure, as the decoded structure can include pointers to other structures. This size is the sum of the size needed by the decoded structure and other structures pointed to.

Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. Some possible error codes are listed in the following table.

Value | Meaning
CRYPT_E_BAD_ENCODE | An error was encountered while decoding.
ERROR_FILE_NOT_FOUND | A decoding function could not be found for the specified dwCertEncodingType and lpszStructType.
ERROR_MORE_DATA | If the buffer specified by the pvStructInfo parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code and stores the required buffer size, in bytes, in the variable pointed to by pcbStructInfo.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN1 Encoding/Decoding Error Codes.

Examples

See Example C Program: ASN1 Encoding and Decoding.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

CryptEncodeObject/CryptDecodeObject Functions, CryptDecodeObjectEx, CryptEncodeObject


CryptDecodeObjectEx

The CryptDecodeObjectEx function decodes a structure of the type indicated by the lpszStructType parameter. CryptDecodeObjectEx offers a significant performance improvement over CryptDecodeObject by supporting memory allocation with the CRYPT_DECODE_ALLOC_FLAG value.

BOOL WINAPI CryptDecodeObjectEx(
  DWORD dwCertEncodingType,
  LPCSTR lpszStructType,
  const BYTE *pbEncoded,
  DWORD cbEncoded,
  DWORD dwFlags,
  PCRYPT_DECODE_PARA pDecodePara,
  void *pvStructInfo,
  DWORD *pcbStructInfo
);

Parameters

dwCertEncodingType
[in] Type of encoding used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

Note Either a certificate or message encoding type is required. X509_ASN_ENCODING is the default. If that type is indicated, it is used. Otherwise, if the PKCS7_ASN_ENCODING type is indicated, it is used.

lpszStructType
[in] Pointer to an OID defining the structure type. If the high-order word of the lpszStructType parameter is zero, the low-order word specifies the integer identifier for the type of the specified structure. Otherwise, this parameter is a long pointer to a NULL-terminated string.

For more details about object identifier strings, their predefined constants and corresponding structures, see Constants for CryptEncodeObject and CryptDecodeObject.

pbEncoded
[in] Pointer to the data to be decoded. The structure must be of the type specified by lpszStructType.
cbEncoded
[in] Number of bytes pointed to by pbEncoded. This is the number of bytes to be decoded.
dwFlags
[in] The following flags are defined. They can be combined with bitwise-OR operations.
Value | Meaning
CRYPT_DECODE_ALLOC_FLAG The called decoding function allocates memory for the decoded structure. A pointer to the allocated structure is returned in pvStructInfo.

If pDecodePara or pDecodePara->pfnAlloc is NULL, then LocalAlloc is called for the allocation and LocalFree must be called to free the memory.

If pDecodePara and pDecodePara->pfnAlloc are non-NULL, then pDecodePara->pfnAlloc is called for the allocation and the function pointed to by pDecodePara->pfnFree must be called to free the memory.
CRYPT_DECODE_NOCOPY_FLAG | This flag can be set to enable a "no copy" optimization. This optimization updates the pvStructInfo members to point to content residing within pbEncoded instead of making a copy of the content and appending it to pvStructInfo. The calling application needs to allocate less memory and execution is faster because a copy is not made. Note that when performing "no copy" decoding, pbEncoded cannot be freed until pvStructInfo is freed.
CRYPT_UNICODE_NAME_DECODE_DISABLE_IE4_UTF8_FLAG | This flag is applicable when decoding X509_UNICODE_NAME, X509_UNICODE_NAME_VALUE, or X509_UNICODE_ANY_STRING. By default, CERT_RDN_T61_STRING encoded values are initially decoded as UTF8. If the UTF8 decoding fails, then the value is decoded as eight-bit characters. If this flag is set, it skips the initial attempt to decode the value as UTF8 and decodes the value as eight-bit characters.
CRYPT_DECODE_TO_BE_SIGNED_FLAG | By default, the contents of the buffer pointed to by pbEncoded included the signed content and the signature. If this flag is set, the buffer includes only the "to be signed" content. This flag is applicable to X509_CERT_TO_BE_SIGNED, X509_CERT_CRL_TO_BE_SIGNED, X509_CRT_REQUEST_TO_BE_SIGNED, and X509_KEYGEN_REQUEST_TO_BE_SIGNED objects.
CRYPT_DECODE_SHARE_0ID_STING_FLAG | When this flag is set, the OID strings are allocated in Crypt32.dll and shared instead of being copied into the returned data structure. This flag can be set if Crypt32.dll is not unloaded before the caller is unloaded.
CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG | By default, the signature bytes are reversed. If this flag is set, this byte reversal is inhibited.

pDecodePara
[in] Pointer to a CRYPT_DECODE_PARA structure containing decoding paragraph information. If pDecodePara is set to NULL, then LocalAlloc and LocalFree are used to allocate and free memory. If pDecodePara points to a CRYPT_DECODE_PARA structure that the structure passes in callback functions to allocate and free memory. These callback functions override the default memory allocation of LocalAlloc and LocalFree.
pvStructInfo
[out] If the dwFlags CRYPT_ENCODE_ALLOC_FLAG is set, pvStructInfo is not a pointer to a buffer but is the address of a pointer to the buffer. Because memory is allocated inside the function and the pointer is stored at *pvStructInfo , pvStructInfo must always be non-NULL.

If CRYPT_ENCODE_ALLOC_FLAG is not set, pvStructInfo is a pointer to a buffer that receives the decoded structure. When the buffer that is specified is not large enough to receive the decoded structure, the function sets the ERROR_MORE_DATA code and stores the required buffer size, in bytes, in the variable pointed to by pcbStructInfo.

This parameter can be NULL to retrieve the size of this information for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.

pcbStructInfo
[in/out] Pointer to a DWORD value that contains the size, in bytes, of the buffer pointed to by the pvStructInfo parameter. When the function returns, the DWORD value contains the number of bytes stored in the buffer. The size contained in the variable pointed to by pcbStructInfo can indicate a size larger than the decoded structure, as the decoded structure can include pointers to auxiliary data. This size is the sum of the size needed by the decoded structure and the auxiliary data.

When CRYPT_DECODE_ALLOC_FLAG is set, pcbStructInfo is the address of a pointer to the DWORD value that is updated.

Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. Some possible error codes are listed in the following table.

Value | Meaning
CRYPT_E_BAD_ENCODE | An error was encountered while decoding.
ERROR_FILE_NOT_FOUND | A decoding function could not be found for the specified dwCertEncodingType and lpszStructType.
ERROR_MORE_DATA | If the buffer specified by the pvStructInfo parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code and stores the required buffer size, in bytes, in the variable pointed to by pcbStructInfo.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN1 Encoding/Decoding Error Codes.

Examples

See Example C Program: ASN1 Encoding and Decoding.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

CryptEncodeObject/CryptDecodeObject Functions, CryptDecodeObject, CryptEncodeObject, CryptEncodeObjectEx


CryptEncodeObject

The CryptEncodeObject function encodes a structure of the type indicated by the value of the lpszStructType parameter. The use of CryptEncodeObjectEx is recommended as an API that performs the same function with significant performance improvements.

BOOL WINAPI CryptEncodeObject(
  DWORD dwCertEncodingType,
  LPCSTR lpszStructType,
  const void *pvStructInfo,
  BYTE *pbEncoded,
  DWORD *pcbEncoded
);

Parameters

dwCertEncodingType
[in] Type of encoding used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

Note Either a certificate or message encoding type is required. X509_ASN_ENCODING is the default. If that type is indicated, it is used. Otherwise, if the PKCS7_ASN_ENCODING type is indicated, it is used.

lpszStructType
[in] Pointer to an OID defining the structure type. If the high-order word of the lpszStructType parameter is zero, the low-order word specifies the integer identifier for the type of the specified structure. Otherwise, this parameter is a long pointer to a NULL terminated string.

For more details about object identifier strings, their predefined constants and corresponding structures, see Constants for CryptEncodeObject and CryptDecodeObject.

pvStructInfo
[in] Pointer to the structure to be encoded. The structure must be of a type specified by lpszStructType.
pbEncoded
[out] Pointer to a buffer to receive the encoded structure. When the buffer that is specified is not large enough to receive the decoded structure, the function sets the ERROR_MORE_DATA code and stores the required buffer size, in bytes, in the variable pointed to by pcbEncoded.

This parameter can be NULL to retrieve the size of this information for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.

pcbEncoded
[in/out] Pointer to a DWORD value that contains the size, in bytes, of the buffer pointed to by the pbEncoded parameter. When the function returns, the DWORD value contains the number of allocated encoded bytes stored in the buffer.

Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. Some possible error codes are listed in the following table.

Value | Meaning
CRYPT_E_BAD_ENCODE | An error was encountered while encoding.
ERROR_FILE_NOT_FOUND | An encoding function could not be found for the specified dwCertEncodingType and lpszStructType.
ERROR_MORE_DATA | If the buffer specified by the pbEncoded parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code and stores the required buffer size, in bytes, in the variable pointed to by pcbEncoded.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN1 Encoding/Decoding Error Codes.

Examples

See Example C Program: Making a Certificate Request and Example C Program: ASN1 Encoding and Decoding.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

CryptEncodeObject/CryptDecodeObject Functions, CryptEncodeObjectEx, CryptDecodeObject


CryptEncodeObjectEx

The CryptEncodeObjectEx function encodes a structure of the type indicated by the value of the lpszStructType parameter This function offers a significant performance improvement over CryptEncodeObject by supporting memory allocation with the CRYPT_ENCODE_ALLOC_FLAG value.

BOOL WINAPI CryptEncodeObjectEx(
  DWORD dwCertEncodingType,
  LPCSTR lpszStructType,
  const void *pvStructInfo,
  DWORD dwFlags,
  PCRYPT_ENCODE_PARA pEncodePara,
  void *pvEncoded,
  DWORD *pcbEncoded
);

Parameters

dwCertEncodingType
[in] Type of encoding used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

Note Either a certificate or message encoding type is required. X509_ASN_ENCODING is the default. If that type is indicated, it is used. Otherwise, if the PKCS7_ASN_ENCODING type is indicated, it is used.

lpszStructType
[in] Pointer to an OID defining the structure type. If the high-order word of the lpszStructType parameter is zero, the low-order word specifies an integer identifier for the type of the specified structure. Otherwise, this parameter is a long pointer to a NULL terminated string.

For more details about object identifier strings, their predefined constants and corresponding structures, see Constants for CryptEncodeObject and CryptDecodeObject.

pvStructInfo
[in] Pointer to the structure to be encoded. The structure must be of the type specified by lpszStructType.
dwFlags
[in] The following flag values are defined. They can be combined with bitwise-OR operations.
Value | Meaning
CRYPT_ENCODE_ALLOC_FLAG The called encoding function allocates memory for the encoded bytes. A pointer to the allocated bytes is returned in pvEncoded.

If pEncodePara or pEncodePara->pfnAlloc is NULL, then LocalAlloc is called for the allocation and LocalFree must be called to free the memory.

If pEncodePara and pEncodePara->pfnAlloc are non-NULL, then pEncodePara->pfnAlloc is called for the allocation and the function pointed to by pEncodePara->pfnFree must be called to free the memory.
CRYPT_UNICODE_NAME_ENCODE_ENABLE_T61_UNICODE_FLAG | This flag is applicable when encoding X509_UNICODE_NAME. If this flag is set and all the Unicode characters are <= 0xFF, the CERT_RDN_T61_STRING is selected instead of the CERT_RDN_UNICODE_STRING.
CRYPT_UNICODE_NAME_ENCODE_DISABLE_CHECK_TYPE_FLAG | This flag is applicable when encoding X509_UNICODE_NAME, X509_UNICODE_NAME_VALUE, or X509_UNICODE_ANY_STRING. If this flag is set, the characters are not checked to see if they are valid for the specified value type.
CRYPT_UNICODE_NAME_ENCODE_ENABLE_UTF8_UNICODE_FLAG | This flag is applicable when encoding an X509_UNICODE_NAME. When set, CERT_RDN_UTF8_STRING is selected instead of CERT_RDN_UNICODE_STRING.

pEncodePara
[in] Optional pointer to a CRYPT_ENCODE_PARA structure containing encoding information. If pEncodePara is set to NULL, LocalAlloc and LocalFree are used to allocate and free memory. If pEncodePara points to a CRYPT_ENCODE_PARA structure, that structure passes in callback functions to allocate and free memory. These function override the default memory allocation of LocalAlloc and LocalFree.
pvEncoded
[out] Pointer to a buffer to receive the encoded structure. When the buffer that is specified is not large enough to receive the decoded structure, the function sets the ERROR_MORE_DATA code and stores the required buffer size, in bytes, in the variable pointed to by pcbEncoded.

This parameter can be NULL to retrieve the size of the buffer for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.

If dwFlags is set to CRYPT_ENCODE_ALLOC_FLAG , pvEncoded not a pointer to a buffer but is the address of a pointer to the buffer. Because memory is allocated inside the function and the pointer is stored at *pvEncoded, pvEncoded must always be non-NULL.

pcbEncoded
[in/out] Pointer to a DWORD value that contains the size, in bytes, of the buffer pointed to by the pvEncoded parameter. When the function returns, the variable pointed to by the pcbEncoded parameter contains the number of allocated, encoded bytes stored in the buffer.

When CRYPT_ENCODE_ALLOC_FLAG is set, pcbEncoded is the address of a pointer to the DWORD value that is updated.

Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. Some possible error codes are listed in the following table.

Value | Meaning
CRYPT_E_BAD_ENCODE | An error was encountered while encoding.
ERROR_FILE_NOT_FOUND | An encoding function could not be found for the specified dwCertEncodingType and lpszStructType.
ERROR_MORE_DATA | If the buffer specified by the pbEncoded parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code and stores the required buffer size, in bytes, in the variable pointed to by pcbEncoded.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN1 Encoding/Decoding Error Codes.

Remarks

CryptEncodeObjectEx first looks for an installable extended encoding function. If no extended encoding function is found, the old, non-extended, installable function is located.

Examples

See Example C Program: ASN1 Encoding and Decoding.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

CryptEncodeObject/CryptDecodeObject Functions, CryptDecodeObject, CryptDecodeObjectEx, CryptEncodeObject


Data Encryption/Decryption Functions

The functions in this section support encryption and decryption operations. CryptEncrypt and CryptDecrypt require a cryptographic key before being called. This is done by using the function CryptGenKey, CryptDeriveKey, or CryptImportKey. The encryption algorithm is specified when the key is created. the CryptSetKeyParam can set additional encryption parameters.

Function | Description
CryptDecrypt | Decrypts a section of ciphertext by using the specified encryption key.
CryptEncrypt | Encrypts a section of plaintext by using the specified encryption key.
CryptProtectData | Performs encryption on the data in a DATA_BLOB structure.
CryptUnprotectData | Performs a decryption and integrity check of the data in a DATA_BLOB.


CryptDecrypt

The CryptDecrypt function decrypts data previously encrypted using CryptEncrypt function.

Important changes to support S/MIME e-mail interoperability have been made to CryptoAPI that affect the handling of enveloped messages. For details, see the Remarks section for CryptMsgOpenToEncode.

Under some circumstances, Microsoft cryptographic service providers may not allow encryption when used in France, in which case this function fails with the error code NTE_PERM. This may occur on down-level platforms such as Windows 95, Windows 98, and Windows NT 4.0, depending on the system's configuration and the version of the CSPs. When executing on these platforms, an application should check for this condition and behave accordingly.

BOOL WINAPI CryptDecrypt(
  HCRYPTKEY hKey,
  HCRYPTHASH hHash,
  BOOL Final,
  DWORD dwFlags,
  BYTE *pbData,
  DWORD *pdwDataLen
);

Parameters

hKey
[in] Handle to the key to use for the decryption. An application obtains this handle by using either the CryptGenKey or CryptImportKey function.

This key specifies the decryption algorithm to be used.

hHash
[in] Handle to a hash object. If data is to be decrypted and hashed simultaneously, a handle to a hash object is passed in this parameter. The hash value is updated with the decrypted plaintext. This option is useful when simultaneously decrypting and verifying a signature.

Before calling CryptDecrypt, the application must obtain a handle to the hash object by calling the CryptCreateHash function. After the decryption is complete, the hash value can be obtained through CryptGetHashParam, it can be signed using CryptSignHash, or it can be used to verify a digital signature using CryptVerifySignature.

If no hash is to be done, this parameter must be zero.

Final
[in] Specifies whether this is the last section in a series being decrypted. This value is TRUE if this is the last or only block. If it is not the last block, it is FALSE. For more information, see the Remarks section later in this topic.
dwFlags
[in] The following dwFlags value is defined but reserved for a future release:
dwFlag | Description
CRYPT_OAEP | When set with the MS Enhanced Provider and RSA encryption/decryption causes PKCS #1 version 2 formatting to be used.

pbData
[in/out] Buffer holding the data to be decrypted. After the decryption has been performed, the plaintext is placed back in this same buffer.

The number of encrypted bytes in this buffer is specified by pdwDataLen.

pdwDataLen
[in/out] Pointer to a DWORD value indicating the length of the pbData buffer. Before calling this function, the calling application sets the DWORD value to the number of bytes to be decrypted. Upon return, the DWORD value contains the number of bytes of the decrypted plaintext.

When a block cipher is used, this data length must be a multiple of the block size unless this is the final section of data to be decrypted and the Final parameter is TRUE.

Return Values

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes follow.

Value | Meaning
ERROR_INVALID_HANDLE | One of the parameters specifies an invalid handle.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
NTE_BAD_ALGID | The hKey session key specifies an algorithm that this CSP does not support.
NTE_BAD_DATA | The data to be decrypted is invalid. For example, when a block cipher is used and the Final flag is FALSE, the value specified by pdwDataLen must be a multiple of the block size. This error can also be returned when the padding is found to be invalid.
NTE_BAD_FLAGS | The dwFlags parameter is nonzero.
NTE_BAD_HASH | The hHash parameter contains an invalid handle.
NTE_BAD_KEY | The hKey parameter does not contain a valid handle to a key.
NTE_BAD_LEN | The size of the output buffer is too small to hold the generated plaintext.
NTE_BAD_UID | The CSP context that was specified when the key was created cannot be found.
NTE_DOUBLE_ENCRYPT | The application attempted to decrypt the same data twice.
NTE_FAIL | The function failed in some unexpected way.

Remarks

If a large amount of data is to be decrypted, it can be done in sections. This is done by calling CryptDecrypt repeatedly. The Final parameter must be set to TRUE only on the last call to CryptDecrypt, so the decryption engine can properly finish the decryption process. The following extra actions are performed when Final is TRUE:

  • If the key is a block cipher key, the data is padded to a multiple of the block size of the cipher. To find the block size of a cipher, use CryptGetKeyParam to get the KP_BLOCKLEN value of the key.
  • If the cipher is operating in a chaining mode, the next CryptDecrypt operation resets the cipher's feedback register to the KP_IV value of the key.
  • If the cipher is a stream cipher, the next CryptDecrypt call resets the cipher to its initial state.

In Windows 2000, the Microsoft Enhanced RSA Provider supports direct encryption with RSA public keys and decryption with RSA private keys. The encryption uses PKCS #1 Type 2 padding, On decryption, this padding is verified. The length of ciphertext data to be decrypted must be the same length as the modulus of the RSA key used to decrypt the data. If the ciphertext has zeros in the most significant bytes, these bytes must be included in the input data buffer and in the input buffer length. The ciphertext must be in little-endian format.

Examples

See Example C Program: Encrypting a File and Example C Program: Decrypting a File.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.

See Also

Data Encryption/Decryption Functions, CryptCreateHash, CryptEncrypt, CryptGenKey, CryptGetHashParam, CryptGetKeyParam, CryptImportKey, CryptMsgOpenToEncode, CryptSignHash, CryptVerifySignature


CryptEncrypt

The CryptEncrypt function encrypts data. The algorithm used to encrypt the data is designated by the key held by the CSP module and is referenced by the hKey parameter.

Important changes to support S/MIME e-mail interoperability have been made to the CryptoAPI that affect the handling of enveloped messages. For details, see the Remarks section for CryptMsgOpenToEncode.

Under some circumstances, Microsoft cryptographic service providers may not allow encryption when used in France, in which case this function fails with the error code NTE_PERM. This may occur on down-level platforms such as Windows 95, Windows 98, and Windows NT 4.0, depending on the system's configuration and the version of the CSPs. When executing on these platforms, an application should check for this condition and behave accordingly.

BOOL WINAPI CryptEncrypt(
  HCRYPTKEY hKey,
  HCRYPTHASH hHash,
  BOOL Final,
  DWORD dwFlags,
  BYTE *pbData,
  DWORD *pdwDataLen,
  DWORD dwBufLen
);

Parameters

hKey
[in] Handle to the encryption key. An application obtains this handle by using either the CryptGenKey or the CryptImportKey function.

The key specifies the encryption algorithm used.

hHash
[in] Handle to a hash object. If data is to be hashed and encrypted simultaneously, a handle to a hash object can be passed in the hHash parameter. The hash value is updated with the plaintext passed in. This option is useful when generating signed and encrypted text.

Before calling CryptEncrypt, the application must obtain a handle to the hash object by calling the CryptCreateHash function. After the encryption is complete, the hash value can be obtained through the CryptGetHashParam function or the hash can be signed using the CryptSignHash function.

If no hash is to be done, this parameter must be zero.

Final
[in] Specifying whether this is the last section in a series being encrypted. Final is set TRUE for the last or only block and FALSE if there are more blocks to be encrypted. For more information, see the Remarks section later in this topic.
dwFlags
[in] The following dwFlags value is defined but reserved for a future release:
dwFlag | Description
CRYPT_OAEP | When set with the MS Enhanced Provider and RSA encryption/decryption causes PKCS #1 version 2 formatting to be used.

pbData
[in/out] Pointer to a buffer holding the data to be encrypted. The encrypted data overwrites the data to be encrypted in this buffer.

The size of this buffer is specified by dwBufLen. The number of bytes of data to be encrypted is specified by pdwDataLen.

This parameter is set to NULL to determine the number of bytes required for the returned data.

pdwDataLen
[in/out] Pointer to a DWORD value holding the length of the data buffer. Before calling this function, the DWORD value is set to the number of bytes to be encrypted. Upon return, the DWORD value contains the number of bytes needed to hold the encrypted data.

If the buffer allocated for pbData is not large enough to hold the data, GetLastError returns ERROR_MORE_DATA and stores the required buffer size, in bytes, in the DWORD value pointed to by pdwDataLen.

If pbData is NULL, no error is returned, and the function stores the size of the data, in bytes, in the DWORD value pointed to be pdwDataLen. This lets an application unambiguously determine the correct buffer size.

If a block cipher is used, this data length must be a multiple of the block size unless this is the final section of data to be encrypted and the Final parameter is set to TRUE.

dwBufLen
[in] The length in bytes of the input pbData buffer.

Note that, depending on the algorithm used, the encrypted text can be larger than the original plaintext. In this case, the pbData buffer needs to be sized accordingly.

As a rule, if a stream cipher is used the ciphertext is the same size as the plaintext. If a block cipher is used, the ciphertext is up to a "block length" larger than the plaintext.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError.

The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes follow.

Value | Meaning
ERROR_INVALID_HANDLE | One of the parameters specifies an invalid handle.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
NTE_BAD_ALGID | The hKey session key specifies an algorithm that this CSP does not support.
NTE_BAD_DATA | The data to be encrypted is invalid. For example, when a block cipher is used and the Final flag is FALSE, the value specified by pdwDataLen must be a multiple of the block size.
NTE_BAD_FLAGS | The dwFlags parameter is nonzero.
NTE_BAD_HASH | The hHash parameter contains an invalid handle.
NTE_BAD_HASH_STATE | An attempt was made to add data to a hash object that is already marked "finished."
NTE_BAD_KEY | The hKey parameter does not contain a valid handle to a key.
NTE_BAD_LEN | The size of the output buffer is too small to hold the generated ciphertext.
NTE_BAD_UID | The CSP context that was specified when the key was created cannot be found.
NTE_DOUBLE_ENCRYPT | The application attempted to encrypt the same data twice.
NTE_FAIL | The function failed in some unexpected way.
NTE_NO_MEMORY | The CSP ran out of memory during the operation.

Remarks

If a large amount of data is to be encrypted, it can be done in sections by calling CryptEncrypt repeatedly. The Final parameter is set to TRUE on the last call to CryptEncrypt so that the encryption engine can properly finish the encryption process. The following extra actions are performed when Final is TRUE:

  • If the key is a block cipher key, the data is padded to a multiple of the block size of the cipher. To find the block size of a cipher, use CryptGetKeyParam to get the KP_BLOCKLEN value of the key.
  • If the cipher is operating in a chaining mode, the next CryptEncrypt operation resets the cipher's feedback register to the KP_IV value of the key.
  • If the cipher is a stream cipher, the next CryptEncrypt resets the cipher to its initial state.

In Windows 2000, the Microsoft Enhanced RSA Provider supports direct encryption with RSA public keys and decryption with RSA private keys. The encryption uses PKCS #1 Type 2 padding. On decryption, this padding is verified. The length of plaintext data that can be encrypted with a call to CryptEncrypt with an RSA key is the length of the key modulus minus eleven bytes. The eleven bytes is the chosen minimum for PKCS #1 padding. The ciphertext is returned in little-endian format.

Examples

See Example C Program: Encrypting a File and Example C Program: Decrypting a File.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.

See Also

Data Encryption/Decryption Functions, CryptCreateHash, CryptDecrypt, CryptGenKey, CryptGetHashParam, CryptGetKeyParam, CryptImportKey, CryptMsgOpenToEncode, CryptSignHash


CryptProtectData

The CryptProtectData function performs encryption on the data in a DATA_BLOB structure. Typically, only a user with the same logon credential as the encrypter can decrypt the data. In addition, the encryption and decryption usually must be done on the same computer. For information about exceptions, see the Remarks section.

BOOL WINAPI CryptProtectData(
  DATA_BLOB *pDataIn,
  LPCWSTR szDataDescr,
  DATA_BLOB *pOptionalEntropy,
  PVOID pvReserved,
  CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct,
  DWORD dwFlags,
  DATA_BLOB *pDataOut
);

Parameters

pDataIn
[in] Pointer to a DATA_BLOB containing the plaintext to be encrypted.
szDataDescr
[in] String with a readable description of the data to be encrypted. This description string is included with the encrypted data. This parameter is required and cannot be set to NULL.
pOptionalEntropy
[in] Pointer to a BLOB containing a password or other additional entropy used to encrypted the data. The BLOB used in the encryption phase must also be used in the decryption phase. This parameter can be set to NULL for no additional entropy.
pvReserved
[in] Reserved for future use and must be set to NULL.
pPromptStruct
[in] Pointer to a CRYPTPROTECT_PROMPTSTRUCT structure that provides information about where and when prompts are to be displayed and what the content of those prompts should be. The parameter is optional and can be set to NULL in both the encryption and decryption phases.
dwFlags
[in] The following flag values are defined.
Value | Meaning
CRYPTPROTECT_LOCAL_MACHINE | When this flag is set, it associates the data encrypted with the current computer instead of with an individual user. Any user on the computer on which CryptProtectData is called can use CryptUnprotectData to decrypt the data.
CRYPTPROTECT_UI_FORBIDDEN | This flag is used for remote situations where presenting a user interface (UI) is not an option. When this flag is set and UI is specified for either the protect or unprotect operation, the operation fails and GetLastError returns the ERROR_PASSWORD_RESTRICTION code.
CRYPTPROTECT_AUDIT | This flag generates an audit on protect and unprotect operations.
CRYPTPROTECT_NO_RECOVERY | This flag protects data with a non-recoverable key.
CRYPTPROTECT_VERIFY_PROTECTION | This flag verifies the protection of a protected BLOB.

pDataOut
[out] Pointer to a DATA_BLOB that receives the encrypted data.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError.

Remarks

Typically, only a user with logon credentials matching those of the encrypter can decrypt the data. In addition, decryption usually can only be done on the computer where the data was encrypted. However, a user with a roaming profile can decrypt the data from another computer on the network.

If the CRYPTPROTECT_LOCAL_MACHINE flag is set when the data is encrypted, any user on the computer where the encryption was done can decrypt the data.

The function creates a session key to perform the encryption. The session key is re-derived when the data is to be decrypted.

The function also adds a MAC (keyed integrity check) to the encrypted data to guard against data tampering.

Under some circumstances, Microsoft cryptographic service providers may not allow encryption when used in France, in which case this function fails with the error code NTE_PERM. This may occur on down-level platforms such as Windows 95, Windows 98, and Windows NT 4.0, depending on the system's configuration and the version of the CSPs. When executing on these platforms, an application should check for this condition and behave accordingly.

Examples

See Example C Program: Using CryptProtectData.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Encryption/Decryption Functions, CryptUnprotectData


CryptUnprotectData

The CryptUnprotectData function decrypts and does an integrity check of the data in a DATA_BLOB structure. Usually, only a user with the same logon credentials as the encrypter can decrypt the data. In addition, the encryption and decryption must be done on the same computer. For information about exceptions, see the Remarks section for CryptProtectData.

BOOL WINAPI CryptUnprotectData(
  DATA_BLOB *pDataIn,
  LPWSTR *ppszDataDescr,
  DATA_BLOB *pOptionalEntropy,
  PVOID pvReserved,
  CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct,
  DWORD dwFlags,
  DATA_BLOB *pDataOut
);

Parameters

pDataIn
[in] Pointer to a DATA_BLOB structure that holds the encrypted data. The DATA_BLOB structure's cbData member holds the length of the pbData member's byte string that contains the text to be encrypted.
ppszDataDescr
[out/optional] Pointer to a string readable description of the encrypted data included with the encrypted data is placed. This parameter is optional and can be set to NULL.
pOptionalEntropy
[in/optional] Pointer to a BLOB containing a password or other additional entropy used when the data was encrypted. This parameter is optional and can be set to NULL; however, if optional entropy BLOB was used in the encryption phase, that same BLOB must be used for the decryption phase.
pvReserved
[in] Reserved for future use and must be set to NULL.
pPromptStruct
[in/optional] Pointer to a CRYPTPROTECT_PROMPTSTRUCT structure that provides information about where and when prompts are to be displayed and what the content of those prompts should be. This parameter is optional and can be set to NULL.
dwFlags
[in] The following flag value is defined.
Value | Meaning
CRYPTPROTECT_UI_FORBIDDEN | This flag is used for remote situations where the user interface (UI) is not an option. When this flag is set and UI is specified for either the protect or unprotect operation, the operation fails and GetLastError returns the ERROR_PASSWORD_RESTRICTION code.

pDataOut
[out] Pointer to a DATA_BLOB structure where the function stores the decrypted data.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE.

Remarks

The CryptProtectData function creates a session key when the data is encrypted. That key is re-derived and used to decrypt the data BLOB.

The MAC hash added to the encrypted data can be used to determine whether the encrypted data was altered in any way. Any tampering results in the return of the ERROR_INVALID_DATA code.

The pbData member of the DATA_BLOB allocated and any non-NULL ppszDataDescr must be freed using LocalFree.

Examples

See Example C Program: Using CryptProtectData.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Encryption/Decryption Functions, Microsoft Base Cryptographic Provider, CryptProtectData


Hash and Digital Signature Functions

The functions described in this section are used in applications to compute hashes, and to create and verify digital signatures. Hashes are also known as message digests.

The following table describes each function.

Function | Description
CryptCreateHash | Creates an empty hash object.
CryptDestroyHash | Destroys a hash object.
CryptDuplicateHash | Duplicates a hash object.
CryptGetHashParam | Retrieves a hash object parameter.
CryptHashData | Hashes a block of data, adding it to the specified hash object.
CryptHashSessionKey | Hashes a session key, adding it to the specified hash object.
CryptSetHashParam | Sets a hash object parameter.
CryptSignHash | Signs the specified hash object.
CryptVerifySignature | Verifies a digital signature, given a handle to the hash object.


CryptCreateHash

The CryptCreateHash function initiates the hashing of a stream of data. It creates and returns to the calling application a handle to a CSP hash object. This handle is used in subsequent calls to CryptHashData and CryptHashSessionKey to hash session keys and other streams of data.

BOOL WINAPI CryptCreateHash(
  HCRYPTPROV hProv,
  ALG_ID Algid,
  HCRYPTKEY hKey,
  DWORD dwFlags,
  HCRYPTHASH *phHash
);

Parameters

hProv
[in] HCRYPTPROV handle of a cryptographic service provider (CSP) created by a call to CryptAcquireContext.
Algid
[in] ALG_ID structure containing the identifier and necessary additional parameters of the hash algorithm.

Valid values for this parameter vary, depending on the CSP that is used. For the list of default algorithms, see the Remarks section later in this topic.

hKey
[in] If the type of hash algorithm is a keyed hash, such as the HMAC or MAC algorithm, the key for the hash is passed in this parameter. For nonkeyed algorithms, this parameter must be set to zero.

For keyed algorithms, the key must be to a block cipher key, such as RC2, that has a cipher mode of CBC.

dwFlags
[in] Reserved for future use and must be zero.
phHash
[out] Address to which the function copies a handle to the new hash object.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError.

The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow.

Value | Meaning
ERROR_INVALID_HANDLE | One of the parameters specifies an invalid handle.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
ERROR_NOT_ENOUGH_MEMORY | The operating system ran out of memory during the operation.
NTE_BAD_ALGID | The Algid parameter specifies an algorithm that this CSP does not support.
NTE_BAD_FLAGS | The dwFlags parameter is nonzero.
NTE_BAD_KEY | A keyed hash algorithm (such as CALG_MAC) is specified by Algid, and the hKey parameter is either zero or it specifies an invalid key handle. This error code is also returned if the key is to a stream cipher, or if the cipher mode is anything other than CBC.
NTE_NO_MEMORY | The CSP ran out of memory during the operation.

Remarks

The cryptographic service provider defines the following hashing algorithms.

Value | Meaning
CALG_HMAC | HMAC, a keyed hash algorithm
CALG_MAC | Message Authentication Code
CALG_MD2 | MD2
CALG_MD5 | MD5
CALG_SHA | US DSA Secure Hash Algorithm
CALG_SHA1 | Same as CALG_SHA
CALG_SSL3_SHAMD5 | SSL3 client authentication

For more information on hashing algorithms, see Hash and Signature Algorithms.

The computation of the actual hash is done with the CryptHashData and CryptHashSessionKey functions. These require a handle to the hash object. After all the data has been added to the hash object, any of the following operations can be performed:

  • The hash value can be retrieved by using CryptGetHashParam.
  • A session key can be derived by using CryptDeriveKey.
  • The hash can be signed by using CryptSignHash.
  • A signature can be verified by using CryptVerifySignature.

After one of the functions from this list has been called, CryptHashData and CryptHashSessionKey cannot be called.

Examples

See Example C Program: Creating and Hashing a Session Key and Example C Program: Signing a Hash and Verifying the Hash Signature.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.

See Also

Hash and Digital Signature Functions, CryptAcquireContext, CryptDeriveKey, CryptDestroyHash, CryptGetHashParam, CryptHashData, CryptHashSessionKey, CryptSetHashParam, CryptSignHash, CryptVerifySignature


CryptDestroyHash

The CryptDestroyHash function destroys the hash object referenced by the hHash parameter. After a hash object has been destroyed, it can no longer be used.

The destruction of hash objects after their use is finished is recommended for security reasons.

BOOL WINAPI CryptDestroyHash(
  HCRYPTHASH hHash
);

Parameters

hHash
[in] Handle of the hash object to be destroyed.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError.

The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow.

Value | Meaning
ERROR_BUSY | The hash object specified by hHash is currently being used and cannot be destroyed.
ERROR_INVALID_HANDLE | The hHash parameter specifies an invalid handle.
ERROR_INVALID_PARAMETER | The hHash parameter contains an invalid value.
NTE_BAD_ALGID | The hHash handle specifies an algorithm that this CSP does not support.
NTE_BAD_HASH | The hash object specified by the hHash parameter is invalid.
NTE_BAD_UID | The CSP context that was specified when the hash object was created cannot be found.

Remarks

When a hash object is destroyed, many CSPs scrub the memory in the CSP where the hash object was held. The CSP memory is then freed.

There should be a one-to-one correspondence between calls to CryptCreateHash and CryptDestroyHash.

Examples

See Example C Program: Creating and Hashing a Session Key.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.

See Also

Hash and Digital Signature Functions, CryptCreateHash, CryptHashData, CryptSignHash


CryptDuplicateHash

The CryptDuplicateHash function is used to make an exact copy of a hash to the point when the duplication is done. The duplicate hash includes the hash's state.

A hash can be created in a piece-by-piece way. CryptDuplicateHash can be used to create separate hashes of two different contents that begin with the same content.

BOOL WINAPI CryptDuplicateHash(
  HCRYPTHASH hHash,
  DWORD *pdwReserved,
  DWORD dwFlags,
  HCRYPTHASH *phHash
);

Parameters

hHash
[in] Handle of the hash to be duplicated.
pdwReserved
[in] Reserved for future use and must be zero.
dwFlags
[in] Reserved for future use and must be zero.
phHash
[out] Address of the handle of the duplicated hash.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError.

The error code prefaced by "NTE" is generated by the particular CSP you are using. Some possible error codes follow.

Value | Meaning
ERROR_CALL_NOT_IMPLEMENTED | Because this is a new function, existing CSPs cannot implement it. This error is returned if the CSP does not support this function.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
NTE_BAD_HASH | The handle to the original hash is not valid.

Remarks

CryptDuplicateHash makes a copy of a hash and the exact state of the hash. This function might be used if a calling application needed to generate two hashes, but both hashes had to start with some common data hashed. A hash might be created, the common data hashed, a duplicate made with the CryptDuplicateHash function, and then the data unique to each hash would be added.

CryptDestroyHash must be called to destroy any hashes that are created with CryptDuplicateHash. Destroying the original hash does not cause the duplicate hash to be destroyed. Once a duplicate hash is made, it is separate from the original hash. There is no shared state between the two hashes.

Examples

See Example C Program: Duplicating a Hash.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 98 or later.
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.

See Also

Hash and Digital Signature Functions, CryptDestroyHash


CryptGetHashParam

The CryptGetHashParam function retrieves data that governs the operations of a hash object. The actual hash value can be retrieved by using this function.

BOOL WINAPI CryptGetHashParam(
  HCRYPTHASH hHash,
  DWORD dwParam,
  BYTE *pbData,
  DWORD *pdwDataLen,
  DWORD dwFlags
);

Parameters

hHash
[in] Handle of the hash object to be queried.
dwParam
[in] Query type. This parameter can be set to one of the following queries.
Query type | Description | pbData contents
HP_ALGID | Hash algorithm | An ALG_ID structure indicating the algorithm specified when the hash object was created. For a list of hash algorithms, see CryptCreateHash.
HP_HASHSIZE | Hash value size | DWORD value indicating the number of bytes in the hash value. This value will usually be 16 or 20, depending on the hash algorithm. Applications must retrieve this value just before the HP_HASHVAL value so the correct amount of memory can be allocated.
HP_HASHVAL Hash value The hash value or message hash for the hash object specified by hHash. This value is generated based on the data supplied to the hash object earlier through the CryptHashData and CryptHashSessionKey functions.
The CryptGetHashParam function completes the hash. After CryptGetHashParam has been called, no more data can be added to the hash. Additional calls to CryptHashData or CryptHashSessionKey fail. After the application is done with the hash, CryptDestroyHash should be called to destroy the hash object.

Note CSPs can add additional values this function can query.

pbData
[out] Pointer to a buffer that receives the specified value data. The form of this data varies, depending on the value number.

This parameter can be NULL to set the size of this information for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.

pdwDataLen
[in/out] Pointer to a DWORD value specifying the size, in bytes, of the pbdata buffer. When the function returns, the DWORD value contains the number of bytes stored in the buffer.

Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

dwFlags
[in] Reserved for future use and must be zero.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError.

The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow.

Value | Meaning
ERROR_INVALID_HANDLE | One of the parameters specifies an invalid handle.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
ERROR_MORE_DATA | If the buffer specified by the pbData parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code and stores the required buffer size, in bytes, in the variable pointed to by pdwDataLen.
NTE_BAD_FLAGS | The dwFlags parameter is nonzero.
NTE_BAD_HASH | The hash object specified by the hHash parameter is invalid.
NTE_BAD_TYPE | The dwParam parameter specifies an unknown value number.
NTE_BAD_UID | The CSP context that was specified when the hash was created cannot be found.

Examples

See Example C Program: Duplicating a Hash.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.

See Also

Hash and Digital Signature Functions, ALG_ID, CryptCreateHash, CryptDestroyHash, CryptGetKeyParam, CryptHashData, CryptHashSessionKey, CryptSetHashParam


CryptHashData

The CryptHashData function adds data to a specified hash object. This function and CryptHashSessionKey can be called multiple times to compute the hash of long or discontinuous data streams.

Before calling this function, CryptCreateHash must be called to create a handle of a hash object.

BOOL WINAPI CryptHashData(
  HCRYPTHASH hHash,
  BYTE *pbData,
  DWORD dwDataLen,
  DWORD dwFlags
);

Parameters

hHash
[in] Handle of the hash object.
pbData
[in] Pointer to a buffer containing the data to be added to the hash object.
dwDataLen
[in] Number of bytes of data to be added. This must be zero if the CRYPT_USERDATA flag is set.
dwFlags
[in] The following flag value is defined.
Value | Meaning
CRYPT_USERDATA | All Microsoft Cryptographic Providers ignore this parameter. For any CSP that does not ignore this parameter, if this flag is set, the CSP prompts the user to input data directly. This data is added to the hash. The application is not allowed access to the data. This flag can be used to allow the user to enter a PIN into the system.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError.

The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow.

Value | Meaning
ERROR_INVALID_HANDLE | One of the parameters specifies an invalid handle.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
NTE_BAD_ALGID | The hHash handle specifies an algorithm that this CSP does not support.
NTE_BAD_FLAGS | The dwFlags parameter contains an invalid value.
NTE_BAD_HASH | The hash object specified by the hHash parameter is invalid.
NTE_BAD_HASH_STATE | An attempt was made to add data to a hash object that is already marked "finished."
NTE_BAD_KEY | A keyed hash algorithm is being used, but the session key is no longer valid. This error is generated if the session key is destroyed before the hashing operation is complete.
NTE_BAD_LEN | The CSP does not ignore the CRYPT_USERDATA flag, the flag is set, and the dwDataLen parameter has a nonzero value.
NTE_BAD_UID | The CSP context that was specified when the hash object was created cannot be found.
NTE_FAIL | The function failed in some unexpected way.
NTE_NO_MEMORY | The CSP ran out of memory during the operation.

Examples

See Example C Program: Signing a Hash and Verifying the Hash Signature and Example C Program: Deriving a Session Key from a Password.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.

See Also

Hash and Digital Signature Functions, CryptCreateHash, CryptHashSessionKey, CryptSignHash


CryptHashSessionKey

The CryptHashSessionKey function computes the cryptographic hash of a session key object. This function can be called multiple times with the same hash handle to compute the hash of multiple keys. Calls to CryptHashSessionKey can be interspersed with calls to CryptHashData.

Before calling this function, CryptCreateHash must be called to create the handle of a hash object.

BOOL WINAPI CryptHashSessionKey(
  HCRYPTHASH hHash,
  HCRYPTKEY hKey,
  DWORD dwFlags
);

Parameters

hHash
[in] Handle to the hash object.
hKey
[in] Handle to the key object to be hashed.
dwFlags
[in] The following flag value is defined.
Value Meaning
CRYPT_LITTLE_ENDIAN When this flag is set, the bytes of the key are hashed in little-endian form. Note that by default (when dwFlags is zero), the bytes of the key are hashed in big-endian form.

This dwFlags value is supported with Internet Explorer 4.0 or later, Windows 98, or Windows 2000 or later.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError.

The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow.

Value | Meaning
ERROR_INVALID_HANDLE | One of the parameters specifies an invalid handle.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
NTE_BAD_ALGID | The hHash handle specifies an algorithm that this CSP does not support.
NTE_BAD_FLAGS | The dwFlags parameter is nonzero.
NTE_BAD_HASH | The hash object specified by the hHash parameter is invalid.
NTE_BAD_HASH_STATE | An attempt was made to add data to a hash object that is already marked "finished."
NTE_BAD_KEY | A keyed hash algorithm is being used, but the session key is no longer valid. This error is generated if the session key is destroyed before the hashing operation is complete.
NTE_BAD_UID | The CSP context that was specified when the hash object was created cannot be found.
NTE_FAIL | The function failed in some unexpected way.

Examples

See Example C Program: Creating and Hashing a Session Key.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.

See Also

Hash and Digital Signature Functions, CryptCreateHash, CryptGenKey, CryptHashData


CryptSetHashParam

The CryptSetHashParam function customizes the operations of a hash object including setting up initial hash contents and selecting a specific hashing algorithm.

BOOL WINAPI CryptSetHashParam(
  HCRYPTHASH hHash,
  DWORD dwParam,
  BYTE *pbData,
  DWORD dwFlags
);

Parameters

hHash
[in] Handle to the hash object on which to set parameters.
dwParam
[in] The following values are defined values.
Value | Contents of pbData
HP_HMAC_INFO. | Pointer to an HMAC_INFO structure that specifies the cryptographic hash algorithm and the inner and outer strings to be used.
HP_HASHVAL. Byte array containing a hash value to place directly into the hash object. Before setting this value, the size of the hash value must be determined by reading the HP_HASHSIZE value with the CryptGetHashParam function.
Some CSPs do not support this capability.

Note Some CSP types can add additional values that can be set with this function.

pbData
[in] Value data buffer. Place the value data in this buffer before calling CryptSetHashParam. The form of this data varies, depending on the value number.
dwFlags
[in] Reserved for future use and must be zero.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError.

The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow.

Value | Meaning
ERROR_INVALID_HANDLE | One of the parameters specifies an invalid handle.
ERROR_BUSY | The CSP context is currently being used by another process.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
NTE_BAD_FLAGS | The dwFlags parameter is nonzero or the pbData buffer contains an invalid value.
NTE_BAD_HASH | The hash object specified by the hHash parameter is invalid.
NTE_BAD_TYPE | The dwParam parameter specifies an unknown value.
NTE_BAD_UID | The CSP context that was specified when the hKey key was created cannot be found.
NTE_FAIL | The function failed in some unexpected way.

Remarks

Occasionally, a hash value that has been generated elsewhere must be signed. This can be done using the following sequence of operations.

  1. Create a hash object with CryptCreateHash.
  2. Set the HP_HASHVAL value.
  3. Sign the hash value by using CryptSignHash, obtaining a digital signature block.
  4. Destroy the hash object by using CryptDestroyHash.

Examples

See Example C Program: Duplicating a Hash.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.

See Also

Hash and Digital Signature Functions, CryptCreateHash, CryptDestroyHash, CryptGetHashParam, CryptSetKeyParam, CryptSignHash, HMAC_INFO


CryptSignHash

The CryptSignHash function signs data. Because all signature algorithms are asymmetric and thus slow, the CryptoAPI does not allow data be signed directly. Instead, data is first hashed and CryptSignHash is used to sign the hash.

BOOL WINAPI CryptSignHash(
  HCRYPTHASH hHash,
  DWORD dwKeySpec,
  LPCTSTR sDescription,
  DWORD dwFlags,
  BYTE *pbSignature,
  DWORD *pdwSigLen
);

Parameters

hHash
[in] Handle of the hash object to be signed.
dwKeySpec
[in] Identifies the private key to use from the provider's container. It can be AT_KEYEXCHANGE or AT_SIGNATURE.

The signature algorithm used is specified when the key pair is originally created.

The only signature algorithm that the Microsoft Base Cryptographic Provider supports is the RSA Public-Key algorithm.

sDescription
[in] This parameter is no longer used, and must be set to NULL to prevent security vulnerabilities. However, it is still supported for backward compatibility in the Microsoft Base Cryptographic Provider.
dwFlags
[in] The following flag value is defined.
Value Meaning
CRYPT_NOHASHOID Used with RSA providers. The hash object identifier (OID) is not placed in the RSA public key encryption. If this flag is not set, the hash OID in the default signature is as specified in the definition of DigestInfo in PKCS #7.

This dwFlags value is supported with Windows 2000 or later. It is not supported in Windows 98 or Internet Explorer 5.0.

pbSignature
[out] Pointer to a buffer receiving the signature data.

This parameter can be NULL to set the buffer size for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.

pdwSigLen
[in/out] Pointer to a DWORD value that specifies the size, in bytes, of the pdwSigLen buffer. When the function returns, the DWORD value contains the number of bytes stored in the buffer.

Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE.

The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow.

Value | Meaning
ERROR_INVALID_HANDLE | One of the parameters specifies an invalid handle.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
ERROR_MORE_DATA | The buffer specified by the pbSignature parameter is not large enough to hold the returned data. The required buffer size, in bytes, is in the pdwSigLen DWORD value.
NTE_BAD_ALGID | The hHash handle specifies an algorithm that this CSP does not support.
NTE_BAD_FLAGS | The dwFlags parameter is nonzero.
NTE_BAD_HASH | The hash object specified by the hHash parameter is invalid.
NTE_BAD_UID | The CSP context that was specified when the hash object was created cannot be found.
NTE_NO_KEY | The private key specified by dwKeySpec does not exist.
NTE_NO_MEMORY | The CSP ran out of memory during the operation.

Remarks

Before calling this function, the CryptCreateHash function must be called to get a handle to a hash object. The CryptHashData or CryptHashSessionKey function is then used to add the data or session keys to the hash object. The CryptSignHash function completes the hash.

While the DSS CSP supports hashing with both the MD5 and the SHA hash algorithms, the DSS CSP only supports signing SHA hashes.

After this function is called, no more data can be added to the hash. Additional calls to CryptHashData or CryptHashSessionKey fail.

After the application finishes using the hash, CryptDestroyHash should be called to destroy the hash object.

The UNICODE version of this function, CryptSignHashW, is not supported on Windows 9x platforms.

Examples

See Example C Program: Signing a Hash and Verifying the Hash Signature.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.
Unicode: Implemented as Unicode and ANSI versions on all platforms.

See Also

Hash and Digital Signature Functions, CryptCreateHash, CryptDestroyHash, CryptHashData, CryptHashSessionKey, CryptVerifySignature


CryptVerifySignature

The CryptVerifySignature function verifies the signature of a hash object.

Before calling this function, CryptCreateHash must be called to create the handle of a hash object. CryptHashData or CryptHashSessionKey is then used to add data or session keys to the hash object.

After CryptVerifySignature has been completed, only CryptDestroyHash can be called using the hHash handle.

BOOL WINAPI CryptVerifySignature(
  HCRYPTHASH hHash,
  BYTE *pbSignature,
  DWORD dwSigLen,
  HCRYPTKEY hPubKey,
  LPCTSTR sDescription,
  DWORD dwFlags
);

Parameters

hHash
[in] Handle of the hash object to verify.
pbSignature
[in] Address of the signature data to be verified.
dwSigLen
[in] Number of bytes in the pbSignature signature data.
hPubKey
[in] Handle to the public key to use to authenticate the signature. This public key must belong to the key pair that was originally used to create the digital signature.
sDescription
[in] This parameter should no longer be used and must be set to NULL to prevent security vulnerabilities. However, it is still supported for backward compatibility in the Microsoft Base Cryptographic Provider.
dwFlags
[in] The following value is defined.
Value Meaning
CRYPT_NOHASHOID This flag is used with RSA providers. When verifying the signature, the hash obejct identifier (OID) is not expected to be present or checked. If this flag is not set, the hash OID in the default signature is verified as specified in the definition of DigestInfo in PKCS #7.

This dwFlags value is supported with Windows 2000 or later. It is not supported in Windows 98 or Internet Explorer 5.0.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError.

The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow.

Value | Meaning
ERROR_INVALID_HANDLE | One of the parameters specifies an invalid handle.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an invalid pointer.
NTE_BAD_FLAGS | The dwFlags parameter is nonzero.
NTE_BAD_HASH | The hash object specified by the hHash parameter is invalid.
NTE_BAD_KEY | The hPubKey parameter does not contain a handle to a valid public key.
NTE_BAD_SIGNATURE | The signature was not verified. This might be because the data itself has changed, the description string did not match, or the wrong public key was specified by hPubKey. This error can also be returned if the hashing or signature algorithms do not match the ones used to create the signature.
NTE_BAD_UID | The CSP context that was specified when the hash object was created cannot be found.
NTE_NO_MEMORY | The CSP ran out of memory during the operation.

Remarks

The CryptVerifySignature function completes the hash. After this call, no more data can be added to the hash. Additional calls to CryptHashData or CryptHashSessionKey fail. After the application is done with the hash, CryptDestroyHash should be called to destroy the hash object.

The UNICODE version of this function, CryptVerifySignature, is not supported on Windows 9x platforms.

Examples

See Example C Program: Signing a Hash and Verifying the Hash Signature.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.
Unicode: Implemented as Unicode and ANSI versions on all platforms.

See Also

Hash and Digital Signature Functions, CryptCreateHash, CryptDestroyHash, CryptHashData, CryptHashSessionKey, CryptSignHash


Certificate and Certificate Store Functions

This group of Win32 functions manage the use, storage, and retrieval of certificates, certificate revocation lists (CRLs), and certificate trust lists (CTLs). These functions can be divided into the following groups of functions:

  • Certificate Store Functions
  • General Maintenance Functions
  • Certificate Functions
  • Certificate Revocation List Functions
  • Certificate Trust List Functions
  • Extended Property Functions


Certificate Store Functions

A user site can, over time, collect many certificates. Typically, a site has certificates for the user of the site, and other certificates describing those individuals and entities with whom the user communicates. For each entity, there can be more than one certificate. For each individual certificate, there should be a chain of verifying certificates that provides a trail back to a trusted root certificate. Certificate stores and their related functions provide functionality to store, retrieve, enumerate, verify, and use the information stored in the certificates.

The following functions are used to work with the certificate stores, themselves.

Function | Description
CertAddStoreToCollection | Adds a sibling certificate store to a collection certificate store.
CertCloseStore | Closes a certificate store handle.
CertControlStore | Allows an application to be notified when there is a difference between the contents of a cached store and the contents of the store that is persisted to storage. It also provides resynchronization of the cached store if necessary and provides a means to commit changes made in the cached store to persisted storage.
CertDuplicateStore | Duplicates a store handle by incrementing the reference count.
CertEnumPhysicalStore | Enumerates the physical stores for a specified system store.
CertEnumSystemStore | Enumerates all available system stores.
CertEnumSystemStoreLocation | Enumerates all of the locations that have an available system store.
CertGetStoreProperty | Gets a store property.
CertOpenStore | Opens a certificate store using a specified store provider type.
CertOpenSystemStore | Opens a system certificate store based on a subsystem protocol.
CertRegisterPhysicalStore | Adds a physical store to a registry system store collection.
CertRegisterSystemStore | Registers a system store.
CertRemoveStoreFromCollection | Removes a sibling certificate store from a collection store.
CertSaveStore | Saves the certificate store.
CertSetStoreProperty | Sets a store property.
CertUnregisterPhysicalStore | Removes a physical store from a specified system store collection.
CertUnregisterSystemStore | Unregisters a specified system store.


CertAddStoreToCollection

The CertAddStoreToCollection function adds a sibling certificate store to a collection certificate store. When a certificate store has been added to a collection store, all of the certificates, CRLs, and CTLs in the store that has been added to the collection store can be retrieved by find or enumerate function calls using the collection store.

BOOL WINAPI CertAddStoreToCollection(
  HCERTSTORE hCollectionStore,
  HCERTSTORE hSiblingStore,
  DWORD dwUpdateFlag,
  DWORD dwPriority
);

Parameters

hCollectionStore
[in] Handle of a certificate store.
hSiblingStore
[in/optional] Handle of a sibling store to be added to the collection store. For more information, see the Remarks section later in this topic.
dwUpdateFlag
[in] Indicates whether certificates, CRLs, and CTLs can be added to the new sibling store member of the collection store. Set dwUpdateFlag to CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG to enable addition or to zero to disable additions.
dwPriority
[in] Sets a priority level of the new store in the collection, with zero being the lowest priority. If zero is passed for this parameter, the specified store is appended as the last store in the collection. The priority levels of the stores in a collection determine the order in which the stores are enumerated, and the search order of the stores when attempting to retrieve a certificate, CRL, or CTL. Priority levels also determine to which store of a collection a new certificate, CRL, or CTL is added. For further information, see the Remarks section later in this topic.

Return Values

If the function succeeds, a new store is added to the collection of stores and the return value is TRUE.

If the function fails, the store was not added and the return value is FALSE.

Remarks

A collection store has the same HCERTSTORE handle as a single store; thus, almost all functions that apply to any certificate store also apply to any collection store. Enumeration and search processes span all of the stores in a collection store; however, functions such as CertAddCertificateLinkToStore that add links to stores cannot be used with collection stores.

When a certificate, CRL, or CTL is added to a collection store, the list of sibling stores in the collection is searched in priority order to find the first store that allows adding. Adding is enabled if CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG was set in the CertAddStoreToCollection call. With any function that adds elements to a store, if a store that allows adding does not return success, the addition function continues on to the next store without providing notification.

When a collection store and its sibling stores are closed with CertCloseStore using CERT_CLOSE_STORE_FORCE_FLAG, the collection store must be closed before its sibling stores. If CERT_CLOSE_STORE_FORCE_FLAG is not used, the stores can be closed in any order.

Examples

See Example C Program: Collection and Sibling Certificate Store Operations.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Functions, CertRemoveStoreFromCollection


CertCloseStore

The CertCloseStore function closes a certificate store handle and reduces the reference count on the store. There needs to be a corresponding call to CertCloseStore for each successful call to the CertOpenStore or CertDuplicateStore functions.

BOOL WINAPI CertCloseStore(
  HCERTSTORE hCertStore,
  DWORD dwFlags
);

Parameters

hCertStore
[in] Handle of the certificate store to be closed.
dwFlags
[in] Typically, this parameter uses the default value zero. The default is to close the store with memory remaining allocated for contexts that have not been freed. In this case, no check is made to determine whether memory for contexts remains allocated.

Set flags can force the freeing of memory for all of a store's certificate, CRL, and CTL contexts when the store is closed. Flags can also be set that check whether all of the store's certificate, CRL, and CTL contexts have been freed. The following values are defined.
Value | Meaning
CERT_CLOSE_STORE_CHECK_FLAG | Checks for nonfreed certificate, CRL, and CTL contexts. A returned error code indicates that one or more store elements is still in use. This flag should only be used as a diagnostic tool in the development of applications.
CERT_CLOSE_STORE_FORCE_FLAG | Forces the freeing of memory for all contexts associated with the store. This flag can be safely used only when the store is opened in a function and neither the store handle nor any of its contexts are passed to any called functions. For details, see the Remarks section later in this topic.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError.

If CERT_CLOSE_STORE_CHECK_FLAG is not set or if it is set and all contexts associated with the store have been freed, the return value is TRUE.

If CERT_CLOSE_STORE_CHECK_FLAG is set and memory for one or more contexts associated with the store remains allocated, the return value is FALSE. The store is always closed even when the function returns FALSE. For details, see the Remarks section later in this topic.

GetLastError is set to CRYPT_E_PENDING_CLOSE if memory for contexts associated with the store remains allocated. Any existing value returned by GetLastError is preserved unless CERT_CLOSE_STORE_CHECK_FLAG is set.

Remarks

While a certificate store is open, contexts from that store can be retrieved or duplicated. When a context is retrieved or duplicated, its reference count is incremented. When a context is freed by passing it to a search or enumeration function as a previous context or by using CertFreeCertificateContext, CertFreeCRLContext, or CertFreeCTLContext, its reference count is decremented. When a context's reference count reaches zero, memory allocated for that context is automatically freed. When the memory allocated for a context has been freed, any pointers to that context become invalid.

By default, memory used to store contexts with reference count greater than zero is not freed when a certificate store is closed. References to those contexts remain valid; however, this can cause "memory leaks." Also, any changes made to the properties of a context after the store has been closed are not persisted.

To force the freeing of memory for all contexts associated with a store, set CERT_STORE_CLOSE_FORCE_FLAG. With this flag set, memory for all contexts associated with the store is freed and all pointers to certificate, CRL, or CTL contexts associated with the store become invalid. This flag should only be set when the store is opened in a function and neither the store handle nor any of its contexts were ever passed to any called functions.

The status of reference counts on contexts associated with a store can be checked when the store is closed by using CERT_CLOSE_STORE_CHECK_FLAG. When this flag is set, and all certificate, CRL, or CTL contexts have not been released, the function returns FALSE and GetLastError returns CRYPT_E_PENDING_CLOSE. Note that the store is still closed when FALSE is returned and the memory for any active contexts is not freed.

If CERT_STORE_NO_CRYPT_RELEASE_FLAG was not set when the store was opened, closing a store releases its CSP handle.

Examples

See Example C Program: Certificate Store Operations and Example C Program: Collection and Sibling Certificate Store Operations.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Functions, CertOpenStore, CertDuplicateStore, CertFreeCertificateContext, CertFreeCRLContext, CertFreeCTLContext, CryptReleaseContext


CertControlStore

[This is preliminary documentation and subject to change.]

The CertControlStore function allows an application to be notified when there is a difference between the contents of a cached store in use and the contents of that store as it is persisted to storage. Differences can occur as another process makes a change that affects the store as it is persisted.

The CertControlStore function can be used to synchronize a cached store if necessary, and provides a means to commit changes made in the cached store to persisted storage. Additional functionality is planned.

BOOL WINAPI CertControlStore(
  HCERTSTORE hCertStore,
  DWORD dwFlags,
  DWORD dwCtrlType,
  void const *pvCtrlPara
);

Parameters

hCertStore
[in] Handle of the certificate store.
dwFlags
[in] If the dwCtrlType parameter is set to CERT_STORE_CTRL_COMMIT, the following dwFlags are defined:
Value | Meaning
CERT_STORE_CTRL_COMMIT_FORCE_FLAG | Forces the contents of the cache memory store to be copied to permanent storage even if the cache has not been changed.
CERT_STORE_CTRL_COMMIT_CLEAR_FLAG | Inhibits the copying the contents of the cache memory store to permanent storage even when the store is closed.
CERT_STORE_CTRL_INHIBIT_DUPLICATE_HANDLE_FLAG | Inhibits a duplicate handle of the event HANDLE. If this flag is set, CertControlStore with CERT_STORE_CTRL_CANCEL_NOTIFY passed must be called for this event HANDLE before closing the hCertStore handle.

If dwCtrlType is set to CERT_STORE_CTRL_NOTIFY_CHANGE or CERT_STORE_CTRL_RESYNC, the dwFlags parameter is not used and must be set to zero.

dwCtrlType
[in] Control action to be taken by CertControlStore. The interpretations of pvCtrlPara and dwFlags depend on the value of dwCtrlType. Currently, the following three actions are defined:
Value | Meaning
CERT_STORE_CTRL_RESYNC | The cached store is resynchronized and made to match the persisted store.
CERT_STORE_CTRL_NOTIFY_CHANGE | A signal is returned in the space pointed to by pvCtrlPara to indicate that the current contents of the cached store differ from the store's persisted state.
CERT_STORE_CTRL_COMMIT | Any changes made to the cached store are copied to persisted storage. If no changes were made since the cached store was opened or since the last commit, the call is ignored. The call is also ignored if the store provider is a provider that automatically persists changes immediately.
CERT_STORE_CTRL_AUTO_RESYNC At the start of every enumeration or find store call, a check is made to determine whether or not a change has been made in the store. If the store has changed, a re-synchronization is done. This check is only done on first enumeration or find calls, when the pPrevContext is NULL.
The pvCtrPara member is not used and must be set to NULL.
CERT_STORE_CTRL_CANCEL_NOTIFY | Cancels notification signaling of the event HANDLE passed in a previous CERT_STORE_CTRL_NOTIFY_CHANGE or CERT_STORE_CTRL_RESYNC. The pvCtrlPara parameter points to the event HANDLE to be canceled.

pvCtrlPara
[in] If dwCtrlType is CERT_STORE_NOTIFY_CHANGE, pvCtrlPara is set to the address of a handle where the system signals the notification change event when a change from the persisted state of the store is detected. The handle must be initialized with a call to the function CreateEvent. The pvCtrlPara parameter can be set to NULL for registry-based stores. If pvCrtlPara is NULL, an internal notification change event is created and registered to be signaled. Using the internal notification change event allows resyncronization operations only if the store was changed.

If dwCtrlType is CERT_STORE_CTRL_RESYNC, set pvCtrlPara to the address of the event handle to be signaled on the next change in the persisted store. Typically, this address is the address of the event handle passed with CERT_STORE_CTRL_NOTIFY_CHANGE during initialization. The event handle passed is rearmed. If pvCtrlPara is set to NULL, no event is rearmed.

If dwCtrlType CERT_STORE_CTRL_COMMIT, pvCtrlPara is not used and must be set to NULL.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError.

If dwCtrlType is CERT_STORE_NOTIFY_CHANGE, the function returns TRUE if a handle for the event signal was successfully set up. The function returns FALSE if the event handle was not set up.

If dwCtrlType is CERT_STORE_CTRL_RESYNC, the function returns TRUE if the resynchronization succeeded and FALSE if the resynchronization failed.

If dwCtrlType is CERT_STORE_CTRL_COMMIT, the function returns TRUE to indicate the successful completion of the commit to persisted storage and FALSE if the commit failed.

Some providers might not support specific control types. In these cases, CertControlStore returns FALSE and GetLastError is set to the ERROR_NOT_SUPPORTED code.

Remarks

Resynchronization of a store can be done at any time. It need not follow a signaled notification change event.

CERT_STORE_CTRL_NOTIFY_CHANGE is supported on registry based store providers by using the RegNotifyChangeKeyValue function.

CertControlStore using CERT_STORE_CTRL_NOTIFY_CHANGE is called once for each event handle to be passed with CERT_STORE_CTRL_RESYNC. These calls using CERT_STORE_CTRL_NOTIFY_CHANGE must be made after each event is created and not after an event has been signaled.

Examples

See Example C Program: Setting and Getting Certificate Store Properties.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Functions, CreateEvent, WaitForSingleObjectEx


CertDuplicateStore

The CertDuplicateStore function duplicates a store handle by incrementing the store's reference count.

HCERTSTORE WINAPI CertDuplicateStore(
  HCERTSTORE hCertStore
);

Parameters

hCertStore
[in] Handle of the certificate store for which the reference count is being incremented.

Return Values

Currently, a copy is not made of the handle, and the returned handle is the same as the handle that was input. If NULL is passed in, the called function will raise an access violation (AV) exception.

Examples

See Example C Program: Certificate Store Operations.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Functions


CertEnumPhysicalStore

The CertEnumPhysicalStore function retrieves the first or next physical store on a computer. Used in a loop, this function can retrieve in sequence all of the physical stores available on a computer.

BOOL WINAPI CertEnumPhysicalStore(
  const void *pvSystemStore,
  DWORD dwFlags,
  void *pvArg,
  PFN_CERT_ENUM_PHYSICAL_STORE pfnEnum
);

Parameters

pvSystemStore
[in] If CERT_SYSTEM_STORE_RELOCATE_FLAG is set in dwFlags, pvSystemStore points to a CERT_SYSTEM_STORE_RELOCATE_PARA structure that indicates both the name and the location of the system store to be enumerated. Otherwise, pvSystemStore is a pointer to a Unicode string that names the system store whose physical stores are to be enumerated. For details on prefixing a ServiceName or ComputerName to the system store name, see CertRegisterSystemStore.
dwFlags
[in] Specifies the location of the system store. The following flag values are defined.

CERT_SYSTEM_STORE_CURRENT_USER
CERT_SYSTEM_STORE_CURRENT_SERVICE
CERT_SYSTEM_STORE_LOCAL_MACHINE
CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
CERT_SYSTEM_STORE_SERVICES
CERT_SYSTEM_STORE_USERS
CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE

In addition, CERT_SYSTEM_STORE_RELOCATE_FLAG can be combined using a bitwise-OR operation with any of the high-word location flags.

pvArg
[in] Pointer to a void that allows the application to declare, define, and initialize a structure to hold any information to be passed to the callback enumeration function.
pfnEnum
[in] Pointer to the callback function used to show the details for each physical store. This callback function determines the content and format for the presentation of information on each physical store. The application must provide the callback function and declare the following signature:
BOOL WINAPI CertEnumPhysicalStoreCallback(
  const void *pvSystemStore,
  DWORD dwFlags,
  LPCWSTR pwszStoreName,
  PCERT_SYSTEM_STORE_INFO pStoreInfo,
  void *pvReserved,
  void *pvArg
);

The pvArg parameter passed to the callback function is the pvArg pointer passed to CertEnumPhysicalStore.

Return Values

If the function succeeds and another physical store was found, the return value is TRUE.

If the function fails and another physical store was not found, the return value is FALSE. For extended error information, call GetLastError.

If the system store location only supports system stores and does not support physical stores, the function returns FALSE and GetLastError returns the ERROR_NOT_SUPPORTED code.

Remarks

To use CertEnumPhysicalStore, an application must declare and define the ENUM_ARG structure and an enumeration callback function.

To access a remote store, the security permissions in the registry keys on that remote computer must be set to allow access. For more information on setting security permissions in a Windows NT/Windows 2000 registry, see MSDN Article ID Q155363.

Examples

See Example C Program: Listing System and Physical Stores.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Functions, CERT_SYSTEM_STORE_RELOCATE_PARA, CertEnumSystemStore, CertEnumSystemStoreLocation, CertRegisterPhysicalStore, CertRegisterSystemStore, CertUnregisterPhysicalStore, CertUnregisterSystemStore


CertEnumSystemStore

The CertEnumSystemStore function retrieves the first or next system store available. Used in a loop, this function can retrieve in sequence all of the system stores available on a computer.

BOOL WINAPI CertEnumSystemStore(
  DWORD dwFlags,
  void *pvSystemStoreLocationPara,
  void *pvArg,
  PFN_CERT_ENUM_SYSTEM_STORE pfnEnum
);

Parameters

dwFlags
[in] Specifies the location of the system store. The following flag values are defined.

CERT_SYSTEM_STORE_CURRENT_USER
CERT_SYSTEM_STORE_CURRENT_SERVICE
CERT_SYSTEM_STORE_LOCAL_MACHINE
CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
CERT_SYSTEM_STORE_SERVICES
CERT_SYSTEM_STORE_USERS
CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE

In addition, CERT_SYSTEM_STORE_RELOCATE_FLAG can be combined using a bitwise-OR operation with any of the high-word location flags.

pvSystemStoreLocationPara
[in/optional] If CERT_SYSTEM_STORE_RELOCATE_FLAG is set in the dwFlags parameter, pvSystemStoreLocationPara points to a CERT_SYSTEM_STORE_RELOCATE_PARA structure that indicates both the name and the location of the system store. Otherwise, pvSystemStoreLocationPara is a pointer to a Unicode string that names the system store.

For CERT_SYSTEM_STORE_LOCAL_MACHINE or CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY, pvSystemStoreLocationPara can optionally be set to a Unicode computer name for enumerating local computer stores on a remote computer, for example "\\ComputerName" or "ComputerName". The leading "\\" backslashes are optional in the ComputerName.

For CERT_SYSTEM_STORE_SERVICES or CERT_SYSTEM_STORE_USERS, if pvSystemStoreLocationPara is NULL, the function enumerates both the service/user names and the stores for each service/user name. Otherwise, pvSystemStoreLocationPara is a Unicode string specifying a remote computer name and/or service/user name, for example "ServiceName,""\\ComputerName," or "ComputerName\."

If only the ComputerName is specified, it must have either the leading "\\" backslashes or a trailing backslash. Otherwise, it is interpreted as the ServiceName or UserName.

pvArg
[in] Pointer to a void allowing the application to declare, define, and initialize a structure to hold any information to be passed to the callback enumeration function.
pfnEnum
[in] Pointer to the callback function used to show the details for each system store. This callback function determines the content and format for the presentation of information on each system store. The application must provide the callback function and must declare it with the following signature:
BOOL WINAPI CertEnumSystemStoreCallback(
  const void *pvSystemStore,
  DWORD dwFlags,
  PCERT_SYSTEM_STORE_INFO pStoreInfo,
  void *pvReserved,
  void *pvArg
);

The pvArg parameter passed by CertEnumSystemStore to the callback function is the pvArg pointer passed to CertEnumSystemStore.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE.

Remarks

To use CertEnumSystemStore, the application must declare and define the ENUM_ARG structure and an enumeration callback function.

To access a remote store, the security permissions in the registry keys on that remote computer must be set to allow access. For more information on setting security permissions in a Windows NT/Windows 2000 registry, see MSDN Article ID Q155363.

Examples

See Example C Program: Listing System and Physical Stores.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Functions, CERT_SYSTEM_STORE_RELOCATE_PARA, CertEnumPhysicalStore, CertEnumSystemStoreLocation, CertRegisterPhysicalStore, CertRegisterSystemStore, CertUnregisterPhysicalStore, CertUnregisterSystemStore


CertEnumSystemStoreLocation

The CertEnumSystemStoreLocation function retrieves the first or next system store location. Used in a loop, this function can retrieve in sequence all system store locations.

BOOL WINAPI CertEnumSystemStoreLocation(
  DWORD dwFlags,
  void *pvArg,
  PFN_CERT_ENUM_SYSTEM_STORE_LOCATION pfnEnum
);

Parameters

dwFlags
[in] Reserved for future use and must be zero.
pvArg
[in] Pointer to a void allowing the application to declare, define, and initialize a structure to hold any information to be passed to the callback enumeration function.
pfnEnum
[in] Pointer to the callback function used to show the details for each store location. This callback function determines the content and format for the presentation of information on each store location. The callback function must be provided by the application and must be declared with the following signature:
BOOL WINAPI CertEnumStoreLocationCallback(
  LPCWSTR pvszStoreLoocations
  DWORD dwFlags,
  void *pvReserved,
  void *pvArg
);

The pvArg parameter passed to the callback function is the pvArg pointer passed to CertEnumSystemStoreLocation.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE.

Remarks

To use CertEnumSystemStoreLocation, an application must declare and define the ENUM_ARG structure and an enumeration callback function.

Examples

See Example C Program: Listing System and Physical Stores.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Functions, CertEnumPhysicalStore, CertEnumSystemStore, CertRegisterPhysicalStore, CertRegisterSystemStore, CertUnregisterPhysicalStore, CertUnregisterSystemStore


CertGetStoreProperty

The CertGetStoreProperty function retrieves a store property.

BOOL CertGetStoreProperty(
  HCERTSTORE hCertStore,
  DWORD dwPropId,
  void *pvData,
  DWORD *pcbData
);

Parameters

hCertStore
[in] Handle of an open certificate store.
dwPropId
[in] Indicates one of a range of store properties. There is one predefined store property, CERT_STORE_LOCALIZED_NAME_PROP_ID, the localized name of the store.

User defined properties must be outside the current range of values for predefined context properties. Currently, user-defined dwPropId values begin at 4,096.

pvData
[out] Pointer to a buffer that receives the data as determined by dwPropId. For CERT_STORE_LOCALIZED_NAME_PROP_ID, this is the localized name of the store, and pvData points to a NULL terminated Unicode, wide-character string. For other dwPropIds, pvData points to an array of bytes.

This parameter can be NULL to set the size of this information for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.

pcbData
[in/out] Pointer to a DWORD value that specifies the size, in bytes, of the pvData buffer. When the function returns, the DWORD value contains the number of bytes stored in the buffer.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE.

If the store property is found, the function returns TRUE, pvData points to the property, and pcbData points to the length of the string. If the store property is not found, the function returns FALSE and GetLastError returns CRYPT_E_NOT_FOUND.

Remarks

Store property identifiers are properties applicable to an entire store. They are not properties on an individual certificate, CRL, or CTL context. Currently, no store properties are persisted.

Examples

See Example C Program: Setting and Getting Certificate Store Properties.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Functions, CertSetStoreProperty


CertOpenStore

The CertOpenStore function opens a certificate store using a specified store provider type. While this function can open a certificate store for ordinary purposes, CertOpenSystemStore is recommended to open the most common certificate stores. CertOpenStore is required for more complex options and special cases.

HCERTSTORE WINAPI CertOpenStore(
  LPCSTR lpszStoreProvider,
  DWORD dwMsgAndCertEncodingType,
  HCRYPTPROV hCryptProv,
  DWORD dwFlags,
  const void *pvPara
);

Parameters

lpszStoreProvider
[in] Specifies the store provider type. The following predefined store provider types furnish most common application needs.

CERT_STORE_PROV_MEMORY
CERT_STORE_PROV_FILE
CERT_STORE_PROV_FILENAME
CERT_STORE_PROV_COLLECTION
CERT_STORE_PROV_REG
CERT_STORE_PROV_SYSTEM
CERT_STORE_PROV_SYSTEM_REGISTRY
CERT_STORE_PROV_PHYSICAL
CERT_STORE_PROV_MSG
CERT_STORE_PROV_PKCS7
CERT_STORE_PROV_SERIALIZED
CERT_STORE_PROV_LDAP

Most of the provider names passed to lpszStoreProvider can be prefixed with "sz_" as in sz_CERT_STORE_PROV_FILE. Calling a provider with a name prefixed by "sz_" does not change that provider in any way.

Provider types that pass a string to pvPara have alternate forms: one that passes the string as Unicode (an LPCWSTR variable) and another that passes the string as ASCII (an LPCSTR variable). The names of providers that pass ASCII strings must be suffixed with "_A" as in CERT_STORE_PROV_FILENAME_A. The names of providers that pass Unicode strings can be suffixed with "_W" as in sz_CERT_STORE_PROV_REG_W. The names of providers without either the "_A" or "_W" use the default, Unicode form.

The store provider type passed in lpszStoreProvider determines the type of the parameter passed in pvPara and the use and meaning of the high word of the dwFlags parameter.

The predefined store provider types are defined as follows:
Store provider | Description | pvPara use | Comments
CERT_STORE_PROV_MEMORY | Creates a certificate store in cached memory. No certificates, CRLs, or CTLs are initially loaded into the store Typically used to create a temporary store. | Not used. | Any addition of certificates, CRLs, or CTLs or changes in properties of certificates, CRLs, or CTLs in a memory store are not automatically saved. They can be saved to a file or to a memory BLOB using CertSaveStore.
CERT_STORE_PROV_FILE | Initializes the store with certificates, CRLs, and CTLs read from a specified open file. This provider expects the file to contain only a serialized store and not either PKCS #7 signed messages or a single encoded certificate. | The handle of a file opened using CreateFile | The file pointer must be positioned at the beginning of the serialized store information. After the data in the serialized store has been loaded into the certificate store, the file pointer is positioned at the beginning of any data that can follow the serialized store data in the file. If CERT_FILE_STORE_COMMIT_ENABLE is set in dwFlags, the file handle is duplicated and the store is always committed as a serialized store. The file is not closed when the store is closed.
CERT_STORE_PROV_FILENAME Initializes the store with certificates, CRLs, and CTLs from a file. The provider opens the file and first attempts to read the file as a serialized store, then as a PKCS #7 signed message, and finally as a single encoded certificate. The name of an existing, unopened file is passed in pvPara as a Unicode or ASCII string. The dwEncodingType parameter must contain the encoding types to be used with both messages and certificates. If the file contains an X.509 encoded certificate, the open operation fails with GetLastError returning ERROR_ACCESS_DENIED.
If the CERT_FILE_STORE_COMMIT_ENABLE flag is set in dwFlags, the dwCreationDisposition value passed to CreateFile is as follows:
If the CERT_STORE_CREATE_NEW_FLAG flag is set,
CreateFile uses CREATE_NEW.
If the CERT_STORE_OPEN_EXISTING_FLAG flag is set, CreateFile uses OPEN_EXISTING.
For all other settings of dwFlags, CreateFile uses OPEN_ALWAYS.
If dwFlags includes CERT_FILE_STORE_COMMIT_ENABLE, the file is committed as either a PKCS #7 or a serialized store depending on the file type opened. If the file was empty or if the file name has either a .p7c or .spc extension, the file is committed as a PKCS #7. Otherwise, the file is committed as a serialized store.
CERT_STORE_PROV_COLLECTION | Opens a store that will be a collection of other stores. Stores are added to or removed from the collection using CertAddStoreToCollection and CertRemoveStoreFromCollection. When a store is added to a collection, all certificates, CRLs, and CTLs in that store become available to searches or enumerations of the collection store. | Set to NULL | The high word of dwFlags is set to zero.
CERT_STORE_PROV_REG | Initializes the store with certificates, CRLs, and CTLs from a registry subkey. | The handle of an open registry key, named with the prefix HKEY | This provider opens or creates the registry subkeys Certificates, CRLs, and CTLs under the key passed in pvPara. The input key is not closed by the provider. Before returning, the provider opens its own copy of the key passed in pvPara. If CERT_STORE_READONLY_FLAG is set in the low word of dwFlags, registry subkeys are opened using the RegOpenKey with KEY_READ_ACCESS. Otherwise, registry subkeys are created using RegCreateKey with KEY_ALL_ACCESS. Any changes to the contents of the opened store are immediately persisted to the registry. However, if CERT_STORE_READONLY_FLAG is set in the low word of dwFlags, any attempt to add to the contents of the store or to change a context's property results in an error with GetLastError returning the E_ACCESSDENIED code.
CERT_STORE_PROV_SYSTEM | Initializes the store with certificates, CRLs, and CTLs from the specified system store. | A system store name passed as a Unicode or ASCII string, such as "MY," or "Root,". | The system store is a logical, collection store consisting of one or more physical stores. A physical store associated with a system store is registered with the CertRegisterPhysicalStore function. After the system store is opened, all of the physical stores that are associated with it are also opened by calls to CertOpenStore and are added to the system store collection using CertAddStoreToCollection.The high word of dwFlags indicates the system store location, usually set to CERT_SYSTEM_STORE_CURRENT_USER. For details about registry locations, see the section on dwFlags later in this topic and System Store Locations. Some system store locations can be open remotely. For details, see System Store Locations.
CERT_STORE_PROV_SYSTEM_REGISTRY | Initializes the store with certificates, CRLs, and CTLs from a physical registry store. The physical store is not opened as a collection store. Enumerations and searches go through only the certificates, CRLs, and CTLs in that one physical store. The implementation of this provider is the same as the CERT_STORE_PROV_SYSTEM provider implemented in Windows NT 4.0. | A system store name, passed as a Unicode or ASCII string, such as "MY," or "Root," | The high word of dwFlags indicates the system store location, usually set to CERT_SYSTEM_STORE_CURRENT_USER. For more information, see the section on dwFlags later in this topic. Some system store locations can be open remotely. For details, see System Store Locations.
CERT_STORE_PROV_PHYSICAL | Initializes the store with certificates, CRLs, and CTLs from a specified physical store that is a member of a logical system store. | Both the system store name and physical names. | Two names are separated with an intervening backslash (\), for example "Root\.LocalMachine." Here, Root is the name of the system store and .LocalMachine is the name of the physical store. The system and physical store names are Unicode strings and cannot contain any backslashes. The high word of dwFlags indicates the system store location, usually CERT_SYSTEM_STORE_CURRENT_USER. For more information, see the section on dwFlags later in this topic. Some physical store locations can be opened remotely.
CERT_STORE_PROV_MSG | Initializes the store with certificates, CRLs, and CTLs from the specified cryptographic message. The dwEncodingType parameter must contain the encoding types used with both messages and certificates. | The HCRYPTMSG handle of the encoded message, returned by a call to CryptMsgOpenToDecode.
CERT_STORE_PROV_PKCS7 | Initializes the store with certificates, CRLs, and CTLs from an encoded PKCS #7 signed message. The dwtEncodingType parameter must specify the encoding types to be used with both messages and certificates. | Pointer to the encoded message's CRYPT_DATA_BLOB.
CERT_STORE_PROV_SERIALIZED | Initializes the store with certificates, CRLs, and CTLs from a memory location containing a serialized store. | Pointer to a CRYPT_DATA_BLOB serialized memory BLOB.
CERT_STORE_PROV_LDAP | Initializes the store with certificates, CRLs, and CTLs from the results of the query specified by a LDAP URL. | A query is passed in pvPara as a Unicode string. | In order to perform write operations on the store, the URL must specify a BASE query with no filter and a single attribute.

Additional store providers can be installed or registered by using CryptInstallOIDFunctionAddress or CryptRegisterOIDFunction. For additional information, see Extending CertOpenStore Functionality.

dwMsgAndCertEncodingType
[in] Applicable only to the CERT_STORE_PROV_MSG, CERT_STORE_PROV_PKCS7, or CERT_STORE_PROV_FILENAME provider types. For all other provider types, this parameter is unused and should be set to 0.

Both a certificate and a message encoding type are required for the CERT_STORE_PROV_MSG, CERT_STORE_PROV_PKCS7, and CERT_STORE_PROV_FILENAME provider types. The LOWORD specifies the encoding type of certificates, CRLs, and CTLs in the cryptographic message. The HIWORD specifies the encoding type of the message. Encoding types are specified by combining the two encoding types with a bitwise-OR operation.

The most common encoding types are used by passing

    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING.
hCryptProv
[in] HCRYPTPROV handle to a cryptographic provider. Passing NULL in this parameter causes an appropriate, default provider to be used. Using the default provider is recommended. The default or specified cryptographic provider is used for all store APIs that verify the signature of a subject certificate or CRL.
dwFlags
[in] These values consist of high-word and low-word values combined using a bitwise-OR operation.

The low-word portion of dwFlags controls a variety of general characteristics of the certificate store opened. This portion can be used with all store provider types. Currently defined low-word values are listed in the following table.
Value | Meaning
CERT_STORE_CREATE_NEW_FLAG A new store is created if one did not exist. The function fails if the store already exists.

If neither CERT_STORE_OPEN_EXISTING_FLAG nor CERT_STORE_CREATE_NEW_FLAG is set, a store is opened if it exists or is created and opened if it did not already exist.
CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG The closing of a store's provider cannot be done when CertCloseStore is called but will be deferred if certificates, CRLs, or CTLs obtained from the store are still in use. The store is actually closed when the last certificate, CRL, or CTL obtained from the store is freed. Any changes made to properties of these certificates, CRLs, and CTLs, even after the call to CertCloseStore, are persisted.

If this flag is not set and certificates, CRLs, or CTLs obtained from the store are still in use, the properties of those certificates, CRLs, and CTLs can be changed, but those changes are not persisted. Setting this flag causes those changes to be persisted.

Note that setting this flag causes extra overhead in doing context duplications and free operations.

If CertCloseStore is called with CERT_CLOSE_STORE_FORCE_FLAG, CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG is ignored.

When this flag is set and a non-NULL HCRYPTPROV value is passed, that provider will continue to be used even after the call to CertCloseStore.

CERT_STORE_DELETE_FLAG | The store is deleted instead of being opened. CertOpenStore returns NULL for both success and failure of the deletion. To determine the success of the deletion, call GetLastError, which returns zero if the store was deleted and a nonzero value if it was not deleted.
CERT_STORE_ENUM_ARCHIVED_FLAG | Overrides the default procedure of skipping in enumerations all certificates with the CERT_ARCHIVED_PROP_ID property set. If this flag is set, an enumeration of the certificates in the store lists all of the certificates in the store, including those that have the CERT_ARCHIVED_PROP_ID property.
CERT_STORE_MANIFOLD_FLAG | Certificates are checked for their manifold extension. When certificates are found with the same manifold extension, the "older" certificates are archived by setting their CERT_ARCHIVED_PROP_ID properties.
CERT_STORE_NO_CRYPT_RELEASE_FLAG | This flag is not used when the NULL is passed in the hCryptProv parameter and the default CSP is used. The flag is valid when a non-NULL CSP handle is passed as the hCryptProv parameter. Setting this flag prevents the automatic release of a non-default CSP when the certificate store is closed.
CERT_STORE_OPEN_EXISTING_FLAG | Only an existing store can be opened. If the store does not exist, the function fails.
CERT_STORE_READONLY_FLAG | Any attempt to change the contents of the store results in an error. When this flag is set and a registry based store provider is being used, the registry subkeys are opened by using RegOpenKey with KEY_READ_ACCESS. Otherwise, the registry subkeys are created by using RegCreateKey with KEY_ALL_ACCESS.
CERT_STORE_SET_LOCALIZED_NAME_FLAG | If this flag is supported, the provider sets the store's CERT_STORE_LOCALIZED_NAME_PROP_ID property. The localized name can be retrieved by calling CertGetStoreProperty with dwPropID set to CERT_STORE_LOCALIZED_NAME_PROP_ID. This flag is supported for providers of types CERT_STORE_PROV_FILENAME, CERT_STORE_PROV_SYSTEM, CERT_STORE_PROV_SYSTEM_REGISTRY, and CERT_STORE_PROV_PHYSICAL_W.
CERT_STORE_UPDATE_KEYID_FLAG | Within CurrentUser and LocalMachine, lists of key identifiers exist. These key identifiers have properties much like the properties of certificates. If the CERT_STORE_UPDATE_KEYID_FLAG is set, then for every key identifier in the store's location that has a CERT_KEY_PROV_INFO_PROP_ID property, that property is automatically updated from the key identifier property CERT_KEY_PROV_INFO_PROP_ID or the CERT_KEY_IDENTIFIER_PROP_ID of the certificate related to that key identifier.
CERT_STORE_BACKUP_RESTORE_FLAG | Uses the thread's SE_BACKUP_NAME and SE_RESTORE_NAME privileges to open registry or file-based system stores. If the thread does not have these privileges, CertOpenStore fails with an access denied error.

The high word of dwFlags is used to specify system store registry locations for the system store provider types CERT_STORE_PROV_SYSTEM, CERT_STORE_PROV_SYSTEM_REGISTER, and CERT_STORE_PROV_PHYSICAL. The following are defined high-word values associated with system store providers:

  • CERT_SYSTEM_STORE_CURRENT_SERVICE
  • CERT_SYSTEM_STORE_CURRENT_USER
  • CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY
  • CERT_SYSTEM_STORE_LOCAL_MACHINE
  • CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
  • CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
  • CERT_SYSTEM_STORE_SERVICES
  • CERT_SYSTEM_STORE_USERS

Each system store location opens, by default, relative to the HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, or HKEY_USERS predefined registry key. For additional details, see System Store Locations.

Two additional system store flags can be set in the high word of dwFlags, as listed in the following table.
Value | Meaning
CERT_SYSTEM_STORE_RELOCATE_FLAG | Overrides the default location of a system store. When it is set, pvPara must pass a pointer to a CERT_SYSTEM_STORE_RELOCATE_PARA structure rather than a string. The structure indicates both the name of the store and its location in the registry.
CERT_SYSTEM_STORE_UNPROTECTED_FLAG | By default, when the CurrentUser "Root" store is opened, any SystemRegistry roots not on the protected root list are deleted from the cache before CertOpenStore returns. When this flag is set, this default is overridden and all of the roots in the SystemRegistry are returned and no check of the protected root list is made.

Two additional high-word flags have been added for the CERT_STORE_PROV_REGISTRY provider.
Value | Meaning
CERT_REGISTRY_STORE_SERIALIZED_FLAG The CERT_STORE_PROV_REG provider saves certificates, CRLs, and CTLs in a single, serialized store subkey instead of performing the default save operation. The default is that each certificate, CRL, or CTL is saved as a separate registry subkey under the appropriate subkey.

This flag is mainly used for stores downloaded from the GPT, such as the CurrentUserGroupPolicy and LocalMachineGroupPolicy stores.

When CERT_REGISTRY_STORE_SERIALIZED_FLAG is set, store additions, deletions, or property changes are not persisted until there is a call to either CertCloseStore or CertControlStore using CERT_STORE_CTRL_COMMIT.
CERT_REGISTRY_STORE_REMOTE_FLAG | The key passed in pvPara points to a registry key on a remote computer. To access a registry key on a remote computer, security permissions on the remote computer must be set to allow access. For further details, see the Remarks section later in this topic.

One high-word flag, CERT_FILE_STORE_COMMIT_ENABLE, has been added for the file provider types CERT_STORE_PROV_FILE and CERT_STORE_PROV_FILENAME.

When this flag is set, any additions to the store or any changes made to properties of contexts in the store are committed to the file store either when CertCloseStore is called or when CertControlStore is called with CERT_STORE_CONTROL_COMMIT.

CertOpenStore fails with E_INVALIDARG if both CERT_FILE_STORE_COMMIT_ENABLE and CERT_STORE_READONLY_FLAG are set in dwFlags.

pvPara
[in] Pointer to a VOID that can point to data of different data types depending on the provider being used. Detailed information about the type and content to be passed in pvPara is specified in the descriptions of the available providers.

Return Values

If the function succeeds, the return value is a handle to the certificate store.

If the function fails, the return value is NULL.

Note that CreateFile, ReadFile, or registry errors might be propagated and their error codes returned. CertOpenStore has a single error code of its own, the ERROR_FILE_NOT_FOUND code, which indicates that the function was unable to find the provider specified by the lpszStoreProvider parameter.

Remarks

A system store is a collection consisting of one or more physical sibling stores. For each system store, there are predefined physical sibling stores. After opening a system store such as MY at CERT_SYSTEM_STORE_CURRENT_USER, CertOpenStore is called to open of all of the physical stores in the system store collection. Each of these physical stores is added to the system store collection using CertAddStoreToCollection. All certificates, CRLs, and CTLs in those physical stores are available through the logical system store collection.

The following system store locations can be opened remotely:

  • CERT_SYSTEM_STORE_LOCAL_MACHINE
  • CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
  • CERT_SYSTEM_STORE_SERVICES
  • CERT_SYSTEM_STORE_USERS

System store locations are opened remotely by prefixing the store name in the string passed to pvPara with the computer name. Examples of remote system store names are:

  • ComputerName\CA
  • \\ComputerName\CA
  • ComputerName\ServiceName\Trust
  • \\ComputerName\ServiceName\Trust

For additional information on system stores, see System Store Locations.

To access a remote store, the security permissions in the registry keys on the remote computer must be set to allow access. For more information on setting security permissions in a Windows registry, see MSDN Article ID Q155363.

Examples

See Example C Code for Opening Certificate Stores.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Functions, CERT_SYSTEM_STORE_RELOCATE_PARA, CertAddStoreToCollection, CertCloseStore, CertControlStore, CertGetCertificateContextProperty, CertGetCRLContextProperty, CertGetCTLContextProperty, CertGetStoreProperty, CertRegisterPhysicalStore, CertRemoveStoreFromCollection. CertSaveStore, CryptInstallOIDFunctionAddress, CryptMsgOpenToDecode, CryptRegisterOIDFunction


CertOpenSystemStore

The CertOpenSystemStore function is a simplified function used to open the most common system certificate store. To open certificate stores with more complex requirements, such as file-based or memory-based stores, use CertOpenStore.

HCERTSTORE WINAPI CertOpenSystemStore(
  HCRYPTPROV hProv,
  LPCTSTR szSubsystemProtocol
);

Parameters

hProv
[in] HCRYPTPROV handle of a cryptographic service provider (CSP). Set hProv to NULL to use the default CSP. If hProv is not NULL, it must be a CSP handle created using CryptAcquireContext.
szSubsystemProtocol
[in] String naming a system store. Some example system stores are listed in the following table.
Predefined system store name | Meaning
"CA" | Certification authority certificates.
"MY" | A certificate store holding "My" certificates with their associated private keys.
"ROOT" | Root certificates.
"SPC" | Software publisher certificates.

Note If the system store name provided in this parameter is not the name of an existing system store, a new system store will be created and used. CertEnumSystemStore can be used to list the names of existing system stores.

Return Values

If the function succeeds, the return value is a handle to the certificate store.

If the function fails, the return value is NULL. For extended error information, call GetLastError. Note that errors from the called function CertOpenStore are propagated to this function.

Remarks

After the system store is opened, all the standard certificate store functions can be used to manipulate the certificates.

After use, the store should be closed by using CertCloseStore.

Examples

See Example C Program: Certificate Store Operations.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

Certificate Store Functions, CertAddEncodedCertificateToStore, CertCloseStore, CertGetCertificateContextProperty, CertGetCRLContextProperty, CertOpenStore, CertSaveStore


CertRegisterPhysicalStore

The CertRegisterPhysicalStore function adds a physical store to a registry system store collection.

BOOL WINAPI CertRegisterPhysicalStore(
  const void *pvSystemStore,
  DWORD dwFlags,
  LPCWSTR pwszStoreName,
  PCERT_PHYSICAL_STORE_INFO pStoreInfo,
  void *pvReserved
);

Parameters

pvSystemStore
[in] System store collection to which the physical store is added. This parameter points either to a NULL terminated Unicode string or to a CERT_SYSTEM_STORE_RELOCATE_PARA structure. For details on using the structure and on adding a ServiceName or ComputerName before the system store name string, see CertRegisterSystemStore.
dwFlags
[in] The high word of the dwFlags parameter specifies the location of the system store. For details on defined high-word flags and prepending ServiceName, UserNames, and ComputerNames to the system store name, see CertRegisterSystemStore.

The following low-word flags are also defined and can be combined with high-word flags using a bitwise-OR operation.
Value | Meaning
CERT_SYSTEM_STORE_RELOCATE_FLAG | The system store is not in its default registry location and the pvSystemStore parameter must be a pointer to a CERT_SYSTEM_STORE_RELOCATE_PARA structure.
CERT_STORE_CREATE_NEW_FLAG | The function fails if the physical store already exists in the store location.

pwszStoreName
[in] Pointer to a Unicode string naming the physical store to be added to the system store collection.
pStoreInfo
[in] Pointer to a CERT_PHYSICAL_STORE_INFO structure providing basic information about the physical store.
pvReserved
[in] Reserved for future use and must be set to NULL.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE.

Remarks

To access a remote store, the security permissions in the registry keys on that remote computer must be set to allow access. For more information on setting security permissions in a Windows registry, see MSDN Article ID Q155363.

Examples

See Example C Program: Listing System and Physical Stores.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Functions, CERT_PHYSICAL_STORE_INFO, CertEnumPhysicalStore, CertEnumSystemStore, CertEnumSystemStoreLocation, CertRegisterSystemStore, CertUnregisterPhysicalStore


CertRegisterSystemStore

The CertRegisterSystemStore function registers a system store.

BOOL WINAPI CertRegisterSystemStore(
  const void *pvSystemStore,
  DWORD dwFlags,
  PCERT_SYSTEM_STORE_INFO pStoreInfo,
  void *pvReserved
);

Parameters

pvSystemStore
[in] Identifies the system store to be registered. If CERT_SYSTEM_STORE_RELOCATE_FLAG is set in the dwFlags parameter, pvSystemStore points to a CERT_SYSTEM_STORE_RELOCATE_PARA structure. Otherwise, it points to a NULL terminated Unicode string naming the system store.

With appropriate settings in dwFlags, the identified store can be a system store on a remote local computer. Stores on remote computers can be registered with the computer name as a prefix to the name of the system store. For example, a remote local computer store can be registered with pvSystemStore pointing to the string "\\ComputerName\Trust" or "ComputerName\Trust".

Leading "\\" backslashes are optional before a ComputerName.

dwFlags
[in] The high word of the dwFlags parameter is used to specify the location of the system store.

The following high-word values are defined.
Value | Meaning
CERT_SYSTEM_STORE_CURRENT_SERVICE | pvSystemStore can be a system store name that is prefixed with the ServiceName.
CERT_SYSTEM_STORE_CURRENT_USER | pvSystemStore can be a system store name that is prefixed with the UserName.
CERT_SYSTEM_STORE_LOCAL_MACHINE | pvSystemStore can be a system store that is on a remote computer.
CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY | pvSystemStore is a group policy store and can be on a remote computer.
CERT_SYSTEM_STORE_SERVICES | pvSystemStore must be a system store name prefixed with the ServiceName.
CERT_SYSTEM_STORE_USERS | pvSystemStore must be a system store name that is prefixed with the UserName.

Stores on remote computers can be registered for CERT_SYSTEM_STORE_LOCAL_MACHINE, CERT_SYSTEM_STORE_SERVICES, CERT_SYSTEM_STORE_USERS, or CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY.

The following low-word values are also defined and can be combined using a bitwise-OR operation with high-word values.
Value | Meaning
CERT_SYSTEM_STORE_RELOCATE_FLAG | The system store is not in its default register location and pvSystemStore must be a pointer to a CERT_SYSTEM_STORE_RELOCATE_PARA structure.
CERT_STORE_CREATE_NEW_FLAG | The function fails if the system store already exists in the store location.

pStoreInfo
[in] Reserved for future use and must be set to NULL.
pvReserved
[in] Reserved for future use and must be set to NULL.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE.

Remarks

To access a remote store, the security permissions in the registry keys on that remote computer must be set to allow access. For more information on setting security permissions in a Windows registry, see MSDN Article ID Q155363.

Examples

See Example C Program: Listing System and Physical Stores.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Functions, CertEnumPhysicalStore, CertEnumSystemStore, CertEnumSystemStoreLocation, CertRegisterPhysicalStore, CertUnregisterPhysicalStore, CertUnregisterSystemStore


CertRemoveStoreFromCollection

The CertRemoveStoreFromCollection function removes a sibling certificate store from a collection store.

void WINAPI CertRemoveStoreFromCollection(
  HCERTSTORE hCollectionStore,
  HCERTSTORE hSiblingStore
);

Parameters

hCollectionStore
[in] Handle of the collection certificate store.
hSiblingStore
[in] Handle of the sibling certificate store to be removed from the collection store.

Return Values

None.

Examples

See Example C Program: Collection and Sibling Certificate Store Operations.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Functions, CertAddStoreToCollection, CertOpenStore


CertSaveStore

The CertSaveStore function saves the certificate store to a file or to a memory BLOB.

BOOL WINAPI CertSaveStore(
  HCERTSTORE hCertStore,
  DWORD dwMsgAndCertEncodingType,
  DWORD dwSaveAs,
  DWORD dwSaveTo,
  void *pvSaveToPara,
  DWORD dwFlags
);

Parameters

hCertStore
[in] Handle of the certificate store to be saved.
dwMsgAndCertEncodingType
[in] Specifies the certificate and message encoding types. Encoding is used only when dwSaveAs is CERT_STORE_SAVE_AS_PKCS7. Otherwise, the dwMsgAndCertEncodingType parameter is not used.

Note When needed, both a certificate and message encoding type are required and are specified by combining them with a bitwise-OR operation, as shown in the following example:

    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
dwSaveAs
[in] Specifies whether the store can be saved as a serialized store containing properties in addition to encoded certificates, CRL, and CTLs (CERT_STORE_SAVE_AS_STORE), or as a PKCS #7 signed message that does not include additional properties (CERT_STORE_SAVE_AS_PKCS7).

Note that the CERT_KEY_CONTEXT_PROP_ID property and the related CERT_KEY_PROV_HANDLE_PROP_ID and CERT_KEY_SPEC_PROP_ID values are not saved to a serialized store.

The dwEncodingType parameter specifies the message encoding type when dwSaveAs is set to CERT_STORE_SAVE_AS_PKCS7.

dwSaveTo
[in] Along with the pvSaveToPara parameter, specifies where to save the store as follows.

When dwSaveTo is set to CERT_STORE_SAVE_TO_FILE, the function saves the store to the specified file. The file's handle is passed in the pvSaveToPara parameter. After a successful save operation, the file pointer is positioned after the last write operation.

When dwSaveTo is set to CERT_STORE_SAVE_TO_MEMORY, the function saves the store to the memory BLOB passed in pvSaveToPara. Before use, the memory BLOB's pbData and cbData members must be initialized. Upon return, cbData is updated with the actual length. For a length-only calculation, pbData must be set to NULL. If pbData is non-NULL and cbData is not large enough, the function returns FALSE with a last error code of ERROR_MORE_DATA.

When dwSaveTo is set to CERT_STORE_SAVE_TO_FILENAME_A, CERT_STORE_SAVE_TO_FILENAME_W, or CERT_STORE_SAVE_TO_FILENAME, the function opens the file, saves to it, and closes it. The file name is passed in pvSaveToPara. The "_W" suffix indicates a Unicode file name; the "_A" suffix indicates an ASCII file name.

For the "_W" option, given LPCWSTR pwszFilename; pvSaveToPara = (void *) pwszFilename;

For the "_A" option, given LPCSTR pszFilename; pvSaveToPara = (void *) pszFilename;

Note The default option, without "_A" or "_W" suffixed to the value name, is Unicode.

pvSaveToPara
[in/out] Pointer used to save the store. May be a file handle or a pointer to a MEMORY_BLOB structure.
dwFlags
[in] Reserved for future use and must be zero.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError.

Note that CreateFile or WriteFile errors can be propagated to this function. One possible error code is CRYPT_E_FILE_ERROR which indicates that an error occurred while writing to the file.

Examples

See Example C Program: Collection and Sibling Certificate Store Operations, Example C Program: Certificate Store Operations and Example C Program: Setting and Getting Certificate Store Properties.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Functions, CertOpenStore, CertCloseStore


CertSetStoreProperty

The CertSetStoreProperty function sets a store property.

BOOL CertSetStoreProperty(
  HCERTSTORE hCertStore,
  DWORD dwPropId,
  DWORD dwFlags,
  const void *pvData
);

Parameters

hCertStore
[in] Handle for the certificate store .
dwPropId
[in] Indicates one of a range of store properties. Values for user-defined properties must be outside the current range of predefined context property values. Currently, user-defined pwPropId values begin at 4,096. There is one predefined store property, CERT_STORE_LOCALIZED_NAME_PROP_ID, the localized name of the store.
dwFlags
[in] Reserved for future use and must be zero.
pvData
[in] The type definition for pvData depends on the dwPropId value. If dwPropId is CERT_STORE_LOCALIZED_NAME_PROP_ID, pvData points to a CRYPT_DATA_BLOB structure. The pbData member of that structure is a pointer to a NULL terminated Unicode character string. The cbData member of that structure is a DWORD value holding the length of the string.

For user-defined dwPropId values, pvData is a pointer to an encoded PCRYPT_DATA_BLOB.

If a value already exists for the selected property, the old value is replaced.

Calling this function with pvData set to NULL deletes a property.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE.

Remarks

Store property identifiers are properties applicable to an entire store. They are not properties for an individual certificate, CRL, or CTL context. Currently, no store properties are persisted.

Examples

See Example C Program: Setting and Getting Certificate Store Properties.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Functions, CertGetStoreProperty


CertUnregisterPhysicalStore

The CertUnregisterPhysicalStore function removes a physical store from a specified system store collection. CertUnregisterPhysicalStore can also be used to delete the physical store.

BOOL WINAPI CertUnregisterPhysicalStore(
  const void *pvSystemStore,
  DWORD dwFlags,
  LPCWSTR pwszStoreName
);

Parameters

pvSystemStore
[in] Pointer to an identifier of the system store collection from which the physical store is to be removed. It is either to a NULL terminated Unicode string or to a CERT_SYSTEM_STORE_RELOCATE_PARA structure. For details on using the structure and on prepending a ServiceName or ComputerName to the system store name string, see CertRegisterSystemStore.
dwFlags
[in] The high word of the dwFlags parameter specifies the location of the system store. For details on defined high-word flags and on prepending ServiceName, UserNames, and ComputerNames to the system store name, see CertRegisterSystemStore.

The following low-word values are also defined. They can be combined using bitwise-OR operations with high-word values.
Value | Meaning
CERT_SYSTEM_STORE_RELOCATE_FLAG | The system store is not in its default registry location and pvSystemStore must be a pointer to a CERT_SYSTEM_STORE_RELOCATE_PARA structure.
CERT_STORE_DELETE_FLAG | The physical store is first removed from the system store collection and is then deleted.

pwszStoreName
[in] NULL terminated Unicode string naming the physical store.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE.

Remarks

To access a remote store, the security permissions in the registry keys on that remote computer must be set to allow access. For more information on setting security permissions in a Windows registry, see MSDSN Article ID Q155363.

Examples

See Example C Program: Listing System and Physical Stores.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Functions, CertEnumPhysicalStore, CertEnumSystemStore, CertEnumSystemStoreLocation, CertRegisterPhysicalStore, CertRegisterSystemStore


CertUnregisterSystemStore

The CertUnregisterSystemStore function unregisters a specified system store.

BOOL WINAPI CertUnregisterSystemStore(
  const void *pvSystemStore,
  DWORD dwFlags
);

Parameters

pvSystemStore
[in] Identifies the system store to be unregistered. It points either to a NULL terminated Unicode string or to a CERT_SYSTEM_STORE_RELOCATE_PARA structure. For details on using the structure and on prepending a ServiceName or ComputerName to the system store name string, see CertRegisterSystemStore.
dwFlags
[in] The high word of the dwFlags parameter specifies the location of the system store. For details on defined high-word flags and on prepending ServiceName, UserNames, and ComputerNames to the system store name, see CertRegisterSystemStore.

The following low-word values are also defined and can be combined with high-word values using a bitwise-OR operation .
Value | Meaning
CERT_SYSTEM_STORE_RELOCATE_FLAG | The system store is not in its default registry location and pvSystemStore must be a pointer to a CERT_SYSTEM_STORE_RELOCATE_PARA structure.
CERT_STORE_DELETE_FLAG | The system store is deleted after it has been unregistered.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE.

Remarks

To access a remote store, the security permissions in the registry keys on that remote computer must be set to allow access. For more information on setting security permissions in a Windows registry, see MSDN Article ID Q155363.

Examples

See Example C Program: Listing System and Physical Stores.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Functions, CertEnumPhysicalStore, CertEnumSystemStore, CertEnumSystemStoreLocation, CertRegisterPhysicalStore, CertRegisterSystemStore, CertUnregisterPhysicalStore


General Maintenance Functions

The CryptoAPI provides a set of general certificate and certificate store functions. The following table briefly describes each function.

Function | Description
CertAddSerializedElementToStore | Adds the serialized certificate or CRL element to the store.
CertCreateContext | Creates the specified context from the encoded bytes. The new context is not put into a store.
CertEnumSubjectInSortedCTL | Enumerates the TrustedSubjects in a sorted CTL context.
CertFindSubjectInCTL | Finds the specified subject in a CTL.
CertFindSubjectInSortedCTL | Finds the specified subject in a sorted CTL.


CertAddSerializedElementToStore

The CertAddSerializedElementToStore function adds a serialized certificate, CRL, or CTL element to the store. The serialized element contains the encoded certificate, CRL, or CTL and its extended properties. Extended properties are associated with a certificate and are not part of a certificate as issued by a certification authority (CA). Extended properties are not available on a certificate when it is used on a non-Microsoft platform.

BOOL WINAPI CertAddSerializedElementToStore(
  HCERTSTORE hCertStore,
  const BYTE *pbElement,
  DWORD cbElement,
  DWORD dwAddDisposition,
  DWORD dwFlags,
  DWORD dwContextTypeFlags,
  DWORD *pdwContextType,
  const void **ppvContext
);

Parameters

hCertStore
[in] Handle of a certificate store where the created certificate will be stored. If hCertStore is NULL, the function creates a copy of a certificate, CRL, or CTL context with its extended properties, but the certificate, CRL, or CTL is not persisted in any store.
pbElement
[in] Pointer to a buffer containing the certificate, CRL, or CTL information to be serialized and added to the certificate store.
cbElement
[in] Size, in bytes, of the pbElement buffer.
dwAddDisposition
[in] Specifies the action to take if the certificate, CRL, or CTL already exists in the store. Currently defined disposition values are shown in the following table.
Disposition | Meaning
CERT_STORE_ADD_NEW | If the certificate, CRL, or CTL is new, it is created and persisted to the store. The operation fails if an identical certificate, CRL, or CTL already exists in the store. The last error code is set to CRYPT_E_EXISTS.
CERT_STORE_ADD_USE_EXISTING | If the certificate, CRL, or CTL is new, it is added to the store. If an identical certificate, CRL, or CTL already exists, the existing element is used. If ppvContext is not NULL, the existing context is duplicated. The function only adds properties that do not already exist. The SHA1 and MD5 hash properties are not copied.
CERT_STORE_ADD_REPLACE_EXISTING | If an identical certificate, CRL, or CTL already exists in the store, the existing certificate, CRL, or CTL context is deleted before creating and adding the new context.
CERT_STORE_ADD_ALWAYS | No check is made to see if an identical certificate, CRL, or CTL already exists. A new element is always created. This can lead to duplicates in the store. To determine if the element already exists in the store, call CertGetCRLFromStore or CertGetSubjectCertificateFromStore.
CERT_STORE_ADD_NEWER If a matching certificate or a link to a matching certificate exists, the function compares the NotBefore times on the certificates. If the existing certificate has a NotBefore time less than the NotBefore time on the new certificate, the old certificate or link is replaced just as with CERT_STORE_ADD_REPLACE_EXISTING. If the existing certificate has a NotBefore time greater than or equal to the NotBefore time on the certificate to be added, the function fails with GetLastError returning the CRYPT_E_EXISTS code.

If a matching certificate or a link to a matching certificate is not found in the store, a new certificate is added to the store.
CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES | The action is the same as for CERT_STORE_ADD_NEWER. However, if an older certificate is replaced, the properties of the older certificate are incorporated into the replacement certificate.
CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES | If a matching certificate exists in the store, the existing context is deleted before creating and adding the new context. The new added context inherits properties from the existing certificate.

dwFlags
[in] Reserved for future use. Must be zero.
dwContextTypeFlags
[in] Specifics the contexts that can be added. For example, to add either a certificate, CRL, or CTL, set dwContextTypeFlags to:
CERT_STORE_CERTIFICATE_CONTEXT_FLAG | CERT_STORE_CRL_CONTEXT_FLAG

Currently defined context type flags are shown in the following table.
Context type flag | Meaning
CERT_STORE_ALL_CONTEXT_FLAG | Adds any context.
CERT_STORE_CERTIFICATE_CONTEXT_FLAG | Adds only a certificate context.
CERT_STORE_CRL_CONTEXT_FLAG | Adds only a CRL context.
CERT_STORE_CTL_CONTEXT_FLAG | Adds only a CTL context.

pdwContextType
[out] Pointer to the context type of the added serialized element. This is an optional parameter and can be NULL indicating that the calling application does not require the context type.

Currently defined context types are shown in the following table.
Context type | Meaning
CERT_STORE_CERTIFICATE_CONTEXT | Certificates
CERT_STORE_CRL_CONTEXT | CRLs
CERT_STORE_CTL_CONTEXT | CTLs

ppvContext
[out] Pointer to a pointer to the decoded certificate, CRL, or CTL context. This is an optional parameter and can be NULL indicating that the calling application does not require the context of the added or existing certificate, CRL, or CTL.

If ppvContext is not NULL, it must be the address of a pointer to a CERT_CONTEXT, CRL_CONTEXT or CTL_CONTEXT. When the application is finished with the context, the context must be freed by using CertFreeCertificateContext for a certificate, CertFreeCRLContext for a CRL or CertFreeCTLContext for a CTL.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError. Some possible error codes follow.

Value | Meaning
CRYPT_E_EXISTS | If the dwAddDisposition parameter is set to CERT_STORE_ADD_NEW, the certificate, CRL, or CTL already exists in the store.
E_INVALIDARG | An invalid disposition value was specified in the dwAddDisposition parameter.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN1 Encoding/Decoding Error Codes.

Examples

See Example C Program: Serializing Certificates and Adding Serialized Elements to Stores.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

General Maintenance Functions, CertSerializeCertificateStoreElement, CertSerializeCRLStoreElement


CertCreateContext

The CertCreateContext function creates the specified context from the encoded bytes. The context created does not include any extended properties.

const void * WINAPI CertCreateContext(
  DWORD dwContextType,
  DWORD dwEncodingType,
  const BYTE *pbEncoded,
  DWORD cbEncoded,
  DWORD dwFlags,
  PCERT_CREATE_CONTEXT_PARA pCreatePara
);

Parameters

dwContextType
[in] Specifies the contexts that can be created. For example, to create either a certificate context, CRL, or CTL, set dwContextType to:
CERT_STORE_CERTIFICATE_CONTEXT_FLAG | CERT_STORE_CRL_CONTEXT_FLAG

Currently defined context type flags are shown in the following table.
Context type | Meaning
CERT_STORE_ALL_CONTEXT_FLAG | Any context.
CERT_STORE_CERTIFICATE_CONTEXT_FLAG | Certificate context.
CERT_STORE_CRL_CONTEXT_FLAG | CRL context.
CERT_STORE_CTL_CONTEXT_FLAG | CTL context.

dwEncodingType
[in] Specifies the encoding type used. Currently, only X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are being used; however, additional encoding types may be added in the future. For either current encoding type, use:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
pbEncoded
[in] Pointer to a buffer containing the existing encoded context content to be copied.
cbEncoded
[in] Size, in bytes, of the pbEncoded buffer.
dwFlags
[in] The following flag values are defined and can be combined with a bitwise-OR operation.
Value | Meaning
CERT_CREATE_CONTEXT_NOCOPY_FLAG | The created context points directly to the content pointed to by pbEncoded instead of an allocated copy.
CERT_CREATE_CONTEXT_SORTED_FLAG The function creates a context with sorted entries. Currently, this flag only applies to a CTL context.

For CTLs, the cCTLEntry member of the returned CTL_INFO structure is always zero. CertFindSubjectInSortedCTL and CertEnumSubjectInSortedCTL must be called to find or enumerate the CTL entries.
CERT_CREATE_CONTEXT_NO_HCRYPTMSG_FLAG | By default, when a CTL context is created, a HCRYTPMSG handle to its SignedData message is created. This flag can be set to improve performance by not creating this handle. This flag can only be used when dwContextType is CERT_STORE_CTL_CONTEXT.
CERT_CREATE_CONTEXT_NO_ENTRY_FLAG | By default, when a CTL context is created, its entries are decoded. When this flag is set, the entries are not decoded and performance is improved. This flag can only be used when dwContextType is CERT_STORE_CTL_CONTEXT.

pCreatePara
[in] Pointer to a CERT_CREATE_CONTEXT_PARA structure.

If pCreatePara and its pfnFree member are both non-NULL, the pfnFree member is used to free the pbEncoded pointer.

If the pvFree member pCreatePara is non-NULL, it is freed by the pfnFree member function.

If pCreatePara or its pfnFree member is NULL, no attempt is made to free pbEncoded.

Return Values

If the function succeeds, the return value is a pointer to the newly created context. The function member, pvFree of pCreatePara must be called to free the created context.

If the function fails, the return value is NULL.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

General Maintenance Functions, CTL_INFO, CertEnumSubjectInSortedCTL, CertFindSubjectInSortedCTL


CertEnumSubjectInSortedCTL

The CertEnumSubjectInSortedCTL function retrieves the first or next TrustedSubject in a sorted certificate trust list (CTL). A sorted CTL is a CTL created with the CERT_CREATE_CONTEXT_SORTED_FLAG set. Used in a loop, this function can retrieve in sequence all TrustedSubjects in a sorted CTL.

BOOL WINAPI CertEnumSubjectInSortedCTL(
  PCCTL_CONTEXT pCtlContext,
  void **ppvNextSubject,
  PCRYPT_DER_BLOB pSubjectIdentifier,
  PCRYPT_DER_BLOB pEncodedAttributes
);

Parameters

pCtlContext
[in] Pointer to the CTL_CONTEXT structure to be searched.
ppvNextSubject
[in/out] Pointer to the address of the last TrustedSubject found. To start the enumeration, ppvNextSubject must point to a pointer with set to NULL. Upon return, the pointer addressed by ppvNextSubject is updated to point to the next TrustedSubject in the encoded sequence.
pSubjectIdentifier
[out] Pointer to a CRYPT_DER_BLOB structure, uniquely identifying a TrustedSubject. The information in this structure can be a hash or any unique byte sequence.
pEncodedAttributes
[out] Pointer to a CRYPT_DER_BLOB structure containing a byte count and a pointer to the TrustedSubject's encoded attributes.

Return Values

If the function succeeds, the return value is TRUE, with ppvNextSubject updated to point to the next TrustedSubject in the encoded sequence.

If the function fails, the return value is FALSE. The return value is FALSE if there are no more subjects or there is an invalid argument.

Remarks

The pbData members of CRYPT_DER_BLOB structures .point directly to the encoded bytes. The CRYPT_DER_BLOB structures, themselves, must be allocated and freed by the application, but the memory addressed by the pbData members of these structures is not allocated by the application and must not be freed by the application.

If the CTL is not sorted with the CERT_CREATE_CONTEXT_SORTED_FLAG flag set, an error results.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

General Maintenance Functions, CertFindSubjectInSortedCTL, CTL_CONTEXT


CertFindSubjectInCTL

The CertFindSubjectInCTL function attempts to find the specified subject in a certificate trust list (CTL). A subject can be identified either by the certificate's whole context or by any unique identifier of the certificate's subject such as the SHA1 hash of the certificate's issuer and serial number.

PCTL_ENTRY WINAPI CertFindSubjectInCTL(
  DWORD dwEncodingType,
  DWORD dwSubjectType,
  void *pvSubject,
  PCCTL_CONTEXT pCtlContext,
  DWORD dwFlags
);

Parameters

dwEncodingType
[in] Specifies the encoding type used. Currently, only X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are being used; however, additional encoding types may be added in the future. For either current encoding type, use:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
dwSubjectType
[in] Specifies the type of subject to be searched for in the CTL. May be NULL for a default search.
Subject code | Type pointed to by pvSubject | Comments
CTL_CERT_SUBJECT_TYPE | CERT_CONTEXT structure. | The structure's SubjectAlgorithm member is examined to determine the representation of the subject's identity. Initially, only SHA1 and MD5 hashes are supported as values for SubjectAlgorithm. The appropriate hash property is obtained from the CERT_CONTEXT structure.
CTL_ANY_SUBJECT_TYPE | CTL_ANY_SUBJECT_INFO structure. | The SubjectAlgorithm member of this structure must match the algorithm type of the CTL, and the SubjectIdentifer member must match one of the CTL entries.

The certificate's hash or the SubjectIdentifier member of the CTL_ANY_SUBJECT_INFO structure is used as the key in searching the subject entries. A binary memory comparison is done between the key and the entry's SubjectIdentifer.

If dwSubjectType is set to either preceding value, dwEncodingType is not used.

pvSubject
[in] Pointer used in conjunction with the dwSubjectType parameter.
pCtlContext
[in] Pointer to the CTL_CONTEXT structure being searched.
dwFlags
[in] Reserved for future use and must be zero.

Return Values

If the function succeeds, the return value is the entry, if it is found.

If the function fails, the return value is NULL. For extended error information, call GetLastError. Some possible error codes follow.

Value | Meaning
CRYPT_E_NOT_FOUND | The subject was not found in the CTL.
E_INVALIDARG | The dwSubjectType parameter was not either CTL_CERT_SUBJECT_TYPE or CTL_ANY_SUBJECT_TYPE.
NTE_BAD_ALGID | The CTL's SubjectAlgorithm member did not map to either SHA1 or MD5.

Remarks

The certificate's hash or the SubjectIdentifier member of the CTL_ANY_SUBJECT_INFO structure is used as the key in searching the subject entries. A binary memory comparison is done between the key and the entry's SubjectIdentifer.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

General Maintenance Functions, CERT_CONTEXT, CertFindCTLInStore, CTL_ANY_SUBJECT_INFO, CTL_CONTEXT


CertFindSubjectInSortedCTL

The CertFindSubjectInSortedCTL function attempts to find the specified subject in a sorted certificate trust list (CTL). A subject can be identified either by the certificate's whole context or by any unique identifier of the certificate's subject, such as the SHA1 hash of the certificate's issuer and serial number.

BOOL WINAPI CertFindSubjectInSortedCTL(
  PCRYPT_DATA_BLOB pSubjectIdentifier,
  PCCTL_CONTEXT pCtlContext,
  DWORD dwFlags,
  void *pvReserved,
  PCRYPT_DER_BLOB pEncodedAttributes
);

Parameters

pSubjectIdentifier
[in] Pointer to a CRYPT_DATA_BLOB structure uniquely identifying the subject. The information in this structure can be a hash or any unique byte sequence.
pCtlContext
[in] Pointer to the CTL_CONTEXT structure to be searched.
dwFlags
[in] Reserved for future use and must be NULL.
pvReserved
[in] Reserved for future use and must be NULL.
pEncodedAttributes
[out] Pointer to a CRYPT_DER_BLOB structure containing a byte count and a pointer to the subject's encoded attributes.

Return Values

If the function succeeds and the subject identifier exists in the CTL, the return value is TRUE.

If the function fails and does not locate a matching subject identifier, the return value is FALSE.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

General Maintenance Functions, CertEnumSubjectInSortedCTL, CTL_CONTEXT


Certificate Functions

The following functions works with certificates. Most of these functions have related functions to deal with CRLs and CTLs. For more information on related CRL and CTL functions, see Certificate Revocation List Functions and Certificate Trust List Functions.

Function | Description
CertAddCertificateContextToStore | Adds a certificate context to the certificate store.
CertAddCertificateLinkToStore | Adds a link in a certificate store to a certificate context in a different store.
CertAddEncodedCertificateToStore | Converts the encoded certificate to a certificate context and then adds the context to the certificate store.
CertCreateCertificateContext | Creates a certificate context from an encoded certificate. The created context is not put in a certificate store.
CertCreateSelfSignCertificate | Creates a self-signed certificate.
CertDeleteCertificateFromStore | Deletes a certificate from the certificate store.
CertDuplicateCertificateContext | Duplicates a certificate context by incrementing its reference count.
CertEnumCertificatesInStore | Enumerates the certificate contexts in the certificate store.
CertFindCertificateInStore | Finds the first, or next, certificate context in the certificate store meeting a search criterion.
CertFreeCertificateContext | Frees a certificate context.
CertGetIssuerCertificateFromStore | Gets a certificate context from the certificate store for the first, or next, issuer of the specified subject certificate.
CertGetSubjectCertificateFromStore | Gets the subject certificate context, uniquely identified by its issuer and serial number, from the certificate store.
CertGetValidUsages | Returns an array of usages consisting of the intersection of the valid usages for all certificates in an array of certificates.
CertSerializeCertificateStoreElement | Serializes a certificate context's encoded certificate and an encoded representation of its properties.
CertVerifySubjectCertificateContext | Performs the enabled verification checks on the subject certificate using the issuer.


CertAddCertificateContextToStore

The CertAddCertificateContextToStore function adds a certificate context to the certificate store.

BOOL WINAPI CertAddCertificateContextToStore(
  HCERTSTORE hCertStore,
  PCCERT_CONTEXT pCertContext,
  DWORD dwAddDisposition,
  PCCERT_CONTEXT *ppStoreContext
);

Parameters

hCertStore
[in] Handle of a certificate store.
pCertContext
[in] Pointer to the CERT_CONTEXT structure to be added to the store.
dwAddDisposition
[in] Specifies the action to take if a matching certificate or a link to a matching certificate already exists in the store. Currently defined disposition values and their uses are as follows.
Value | Meaning
CERT_STORE_ADD_ALWAYS | The function makes no check for an existing matching certificate or link to a matching certificate. A new certificate is always added to the store. This can lead to duplicates in a store.
CERT_STORE_ADD_NEW | If a matching certificate or a link to a matching certificate exists, the operation fails. GetLastError returns the CRYPT_E_EXISTS code.
CERT_STORE_ADD_NEWER If a matching certificate or a link to a matching certificate exists, the function compares the NotBefore times on the certificates. If the existing certificate has a NotBefore time less than the NotBefore time on the new certificate, the old certificate or link is replaced just as with CERT_STORE_ADD_REPLACE_EXISTING. If the existing certificate has a NotBefore time greater than or equal to the NotBefore time on the certificate to be added, the function fails with GetLastError returning the CRYPT_E_EXISTS code.

If a matching certificate or a link to a matching certificate is not found in the store, a new certificate is added to the store.
CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES | The action is the same as for CERT_STORE_ADD_NEWER. However, if an older certificate is replaced, the properties of the older certificate are incorporated into the replacement certificate.
CERT_STORE_ADD_REPLACE_EXISTING | If a link to a matching certificate exists, that existing certificate or link is deleted and a new certificate is created and added to the store. If a matching certificate or a link to a matching certificate does not exist, a new link is added.
CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES | If a matching certificate exists in the store, the existing context is deleted before creating and adding the new context. The new added context inherits properties from the existing certificate.
CERT_STORE_ADD_USE_EXISTING If a matching certificate or a link to a matching certificate exists, that existing certificate or link is used and properties from the new certificate are added. The function does not fail, but it does not add a new context. If ppCertContext is not NULL, the existing context is duplicated.

If a matching certificate or a link to a matching certificate does not exist, a new certificate is added.

ppStoreContext
[out/optional] Pointer to a pointer to the copy to be made of the certificate that was added to the store.

The ppStoreContext parameter can be NULL, indicating that the calling application does not require a copy of the added certificate. If a copy is made, it must be freed by using CertFreeCertificateContext.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError. Some possible error codes follow.

Value | Meaning
CRYPT_E_EXISTS | This value is returned if CERT_STORE_ADD_NEW is set and the certificate already exists in the store, or if CERT_STORE_ADD_NEWER is set and a certificate exists in the store with a NotBefore date greater than or equal to the NotBefore date on the certificate to be added.
E_INVALIDARG | An invalid disposition value was specified in the dwAddDisposition parameter.

Errors from the called functions, CertAddEncodedCertificateToStore and CertSetCertificateContextProperty, can be propagated to this function.

Remarks

The certificate context is not duplicated using CertDuplicateCertContext. Instead, the function creates a new copy of the context and adds it to the store.

In addition to the encoded certificate, CertDuplicateCertContext also copies the context's properties, with the exception of the CERT_KEY_PROV_HANDLE_PROP_ID and CERT_KEY_CONTEXT_PROP_ID properties.

Examples

See Example C Program: Certificate Store Operations.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Functions, CertAddEncodedCertificateToStore, CertSetCertificateContextProperty


CertAddCertificateLinkToStore

The CertAddCertificateLinkToStore function adds a link in a certificate store to a certificate context in a different store. Instead of creating and adding a duplicate of the certificate context, this function adds a link to the original certificate.

BOOL WINAPI CertAddCertificateLinkToStore(
  HCERTSTORE hCertStore,
  PCCERT_CONTEXT pCertContext,
  DWORD dwAddDisposition,
  PCCERT_CONTEXT *ppStoreContext
);

Parameters

hCertStore
[in] Handle to the certificate store where the link is to be added.
pCertContext
[in] Pointer to the CERT_CONTEXT structure to be linked.
dwAddDisposition
[in] Specifies the action if a matching certificate or a link to a matching certificate already exists in the store. Currently defined disposition values and their uses are as follows.
Value | Meaning
CERT_STORE_ADD_ALWAYS | The function makes no check for an existing matching certificate or link to a matching certificate. A new certificate is always added to the store. This can lead to duplicates in a store.
CERT_STORE_ADD_NEW | If a matching certificate or a link to a matching certificate exists, the operation fails. GetLastError returns the CRYPT_E_EXISTS code.
CERT_STORE_ADD_NEWER If a matching certificate or a link to a matching certificate exists, the function compares the NotBefore times on the certificates. If the existing certificate has a NotBefore time less than the NotBefore time on the new certificate, the old certificate or link is replaced just as with CERT_STORE_ADD_REPLACE_EXISTING. If the existing certificate has a NotBefore time greater than or equal to the NotBefore time on the certificate to be added, the function fails with GetLastError returning the CRYPT_E_EXISTS code.

If a matching certificate or a link to a matching certificate is not found in the store, a new certificate is added to the store.
CERT_STORE_ADD_REPLACE_EXISTING | If a link to a matching certificate exists, that existing link is deleted and a new link is created and added to the store. If no matching certificate or link to a matching certificate exists, one is added.
CERT_STORE_ADD_USE_EXISTING | If a matching certificate or a link to a matching certificate exists, the existing certificate is used. The function does not fail, but no new link is added. If no matching certificate or link to a matching certificate exists, a new link is added.

ppStoreContext
[out/optional] Pointer to a pointer to a copy of the link created. The ppStoreContext parameter can be NULL to indicate that a copy of the link is not needed. If a copy of the link is created, that copy must be freed using CertFreeCertificateContext.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError. Some possible error codes follow.

Value | Meaning
CRYPT_E_EXISTS | For a dwAddDisposition parameter of CERT_STORE_ADD_NEW, the certificate already exists in the store.
E_INVALIDARG | An invalid disposition value was specified in the dwAddDisposition parameter.

Remarks

Because the link provides access to the original certificate context, setting an extended property in the linked certificate context changes that extended property in the certificate's original location and in any other links to that certificate.

Links cannot be added to a store opened as a collection. Stores opened as collections include all stores opened with CertOpenSystemStore or CertOpenStore using CERT_STORE_PROV_SYSTEM or CERT_STORE_PROV_COLLECTION. For additional information, see CertAddStoreToCollection.

If links are used and CertCloseStore is called with CERT_CLOSE_STORE_FORCE_FLAG, the store using links must be closed before the store containing the original contexts is closed. If CERT_CLOSE_STORE_FORCE_FLAG is not used, the two stores can be closed in either order.

Examples

See Example C Program: Certificate Store Operations.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Functions, CertAddCRLLinkToStore, CertAddCTLLinkToStore, CertAddStoreToCollection, CertCloseStore, CertFreeCertificateContext, CertOpenStore, CertOpenSystemStore


CertAddEncodedCertificateToStore

The CertAddEncodedCertificateToStore function creates a certificate context from an encoded certificate and adds it to the certificate store. The context created does not include any extended properties.

The CertAddEncodedCertificateToStore function also makes a copy of the encoded certificate before adding the certificate to the store.

BOOL WINAPI CertAddEncodedCertificateToStore(
  HCERTSTORE hCertStore,
  DWORD dwCertEncodingType,
  const BYTE *pbCertEncoded,
  DWORD cbCertEncoded,
  DWORD dwAddDisposition,
  PCCERT_CONTEXT *ppCertContext
);

Parameters

hCertStore
[in] Handle to the certificate store.
dwCertEncodingType
[in] Specifies the type of encoding used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pbCertEncoded
[in] Pointer to a buffer containing the encoded certificate that is to be added to the certificate store.
cbCertEncoded
[in] Size, in bytes, of the pbCertEncoded buffer.
dwAddDisposition
[in] Specifies the action to take if a matching certificate or link to a matching certificate exists in the store. Currently defined disposition values and their uses are as follows.
Value | Meaning
CERT_STORE_ADD_ALWAYS | The function makes no check for an existing matching certificate or link to a matching certificate. A new certificate is always added to the store. This can lead to duplicates in a store.
CERT_STORE_ADD_NEW | If a matching certificate or a link to a matching certificate exists in the store, the operation fails. GetLastError returns the CRYPT_E_EXISTS code.
CERT_STORE_ADD_NEWER If a matching certificate or a link to a matching certificate exists, the function compares the NotBefore times on the certificates. If the existing certificate has a NotBefore time less than the NotBefore time on the new certificate, the old certificate or link is replaced just as with CERT_STORE_ADD_REPLACE_EXISTING. If the existing certificate has a NotBefore time greater than or equal to the NotBefore time on the certificate to be added, the function fails with GetLastError returning the CRYPT_E_EXISTS code.

If a matching certificate or a link to a matching certificate is not found in the store, a new certificate is added to the store.
CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES | The action is the same as for CERT_STORE_ADD_NEWER, except that if an older certificate is replaced, the properties of the older certificate are incorporated into the replacement certificate.
CERT_STORE_ADD_REPLACE_EXISTING | If a matching certificate or link to a matching certificate exists in the store, the existing certificate or link is deleted and a new certificate is created and added to the store. If a matching certificate or link to a matching certificate does not exist, a new certificate is created and added to the store.
CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES | If a matching certificate exists in the store, that existing context is deleted before creating and adding the new context. The new context inherits properties from the existing certificate.
CERT_STORE_ADD_USE_EXISTING If a matching certificate or a link to a matching certificate exists, that existing certificate or link is used and properties from the new certificate are added. The function does not fail, but it does not add a new context. If ppCertContext is not NULL, the existing context is duplicated.

If a matching certificate or link to a matching certificate does not exist, a new certificate is added.

ppCertContext
[out/optional] Pointer to a pointer to the decoded certificate context. This is an optional parameter that can be NULL, indicating that the calling application does not require a copy of the new or existing certificate. When a copy is made, its context must be freed by using CertFreeCertificateContext.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError. Some possible error codes follow.

Value | Meaning
CRYPT_E_EXISTS | This code is returned if CERT_STORE_ADD_NEW is set and the certificate already exists in the store, or if CERT_STORE_ADD_NEWER is set and there is a certificate in the store with a NotBefore date greater than or equal to the NotBefore date on the certificate to be added.
E_INVALIDARG | An invalid disposition value was specified in the dwAddDisposition parameter, or an invalid certificate encoding type was specified. Currently, only the X509_ASN_ENCODING type is supported.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN1 Encoding/Decoding Error Codes.

Examples

See Example C Program: Serializing Certificates and Adding Serialized Elements to Stores.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Functions, CertAddCertificateContextToStore, CertFreeCertificateContext


CertCreateCertificateContext

The CertCreateCertificateContext function creates a certificate context from an encoded certificate. The created context is not persisted to a certificate store. The function makes a copy of the encoded certificate within the created context.

PCCERT_CONTEXT WINAPI CertCreateCertificateContext(
  DWORD dwCertEncodingType,
  const BYTE *pbCertEncoded,
  DWORD cbCertEncoded
);

Parameters

dwCertEncodingType
[in] Specifies the type of encoding used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pbCertEncoded
[in] Pointer to a buffer containing the encoded certificate from which the context is to be created.
cbCertEncoded
[in] Size, in bytes, of the pbCertEncoded buffer.

Return Values

If the function succeeds, the return value is a pointer to a read-only CERT_CONTEXT.

If the function is unable to decode and create the certificate context, the return value is NULL. For extended error information, call GetLastError. Some possible error codes follow.

Value | Meaning
E_INVALIDARG | An invalid certificate encoding type was specified. Currently, only the X509_ASN_ENCODING type is supported.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN1 Encoding/Decoding Error Codes.

Remarks

The CERT_CONTEXT must be freed by calling CertFreeCertificateContext. CertDuplicateCertificateContext can be called to make a duplicate. CertSetCertificateContextProperty and CertGetCertificateContextProperty can be called to store and read properties for the certificate.

Examples

See Example C Program: Certificate Store Operations.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Functions, CERT_CONTEXT, CertCreateCRLContext, CertCreateCTLContext, CertDuplicateCertificateContext, CertFreeCertificateContext, CertGetCertificateContextProperty, CertSetCertificateContextProperty


CertCreateSelfSignCertificate

[This is preliminary documentation and subject to change.]

The CertCreateSelfSignCertificate function builds a self-signed certificate and returns a pointer to a CCERT_CONTEXT representing the certificate.

WINCRYPT32API PCCERT_CONTEXT WINAPI CertCreateSelfSignCertificate(
  HCRYPTPROV hProv,
  PCERT_NAME_BLOB pSubjectIssuerBlob,
  DWORD dwFlags,
  PCRYPT_KEY_PROV_INFO pKeyProvInfo,
  PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm,
  PSYSTEMTIME pStartTime,
  PSYSTEMTIME pEndTime,
  PCERT_EXTENSIONS pExtensions
);

Parameters

hProv
[in] [optional] Handle of a cryptographic provider use to sign the certificate created. If NULL, information from the pKeyProvInfo parameter is used to acquire the needed handle. If pKeyProvInfo is also NULL, the default provider type, PROV_RSA_FULL provider type, the default key specification, AT_SIGNATURE, and a newly-created key container with a unique container name are used.
pSubjectIssuerBlob
[in] Pointer to a BLOB containing the distinguished name (DN) for the certificate subject. The parameter can not be NULL. Minimally, a pointer to an empty DN must be provided. This BLOB is normally created using the CertStrToName function. It can also be created using the CryptEncodeObject function specifying either the X509_NAME or X509_UNICODE_NAME StructType.
dwFlags
[in] Flags set to override default function behavior. Either or both of the following dwFlags values can be set.
Defined constant | Value | Meaning
CERT_CREATE_SELFSIGN_NO_KEY_INFO | 2 | By default, the returned PCCERT_CONTEXT references the private keys by setting the CERT_KEY_PROV_INFO_PROP_ID. If this property is not desired, specify CERT_CREATE_SELFSIGN_NO_KEY_INFO.
CERT_CREATE_SELFSIGN_NO_SIGN | 1 | By default, the certificate being created is signed. If the certificate being created is only a dummy placeholder, the certificate might not need to be signed. Signing of the certificate is skipped if CERT_CREATE_SELFSIGN_NO_SIGN is specified.
pKeyProvInfo
[optional] Before a certificate is created, the CSP is queried for the key provider, key provider type, and the key container name. If the CSP queried does not support these queries, the function fails. If the default provider does not support these queries, a pKeyProvInfo value must be specified. The RSA BASE does support these queries.
pSignatureAlgorithm
[optional] Pointer to a CRYPT_ALGORITHM_IDENTIFIER structure. If NULL, the default algorithm, SHA1RSA, is used.
pStartTime
[optional] Pointer to a SYSTEMTIME structure. If NULL, the system current time is used by default.
pEndTime
[optional] Pointer to a SYSTEMTIME structure. If NULL, the pStartTime value plus one year will be used by default.
pExtensions
[optional] Pointer to a CERT_EXTENSIONS array of CERT_EXTENSION structures. By default, the array is empty. An alternate subject name, if desired, can be specified as one of these extensions.

Return Values

If the function succeeds, a PCCERT_CONTEXT pointing to the created certificate is returned. If the function fails. it returns NULL. For extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.
Library: Use Crypt32.lib.


CertDeleteCertificateFromStore

The CertDeleteCertificateFromStore function deletes the specified certificate context from the certificate store.

BOOL WINAPI CertDeleteCertificateFromStore(
  PCCERT_CONTEXT pCertContext
);

Parameters

pCertContext
[in] Pointer to the CERT_CONTEXT structure to be deleted.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError. One possible error code is the following.

Value | Meaning
E_ACCESSDENIED | Indicates the store was opened as read-only and a delete operation is not allowed.

Remarks

After a certificate is deleted from a store all subsequent attempts to get or find that certificate in that store will fail. However, memory allocated for the certificate is not freed until all duplicated contexts have also been freed.

The pCertContext is always freed for this function by using CertFreeCertificateContext, even for an error. Freeing the context reduces its reference count by one. If the reference count reaches zero, memory allocated for the certificate is freed.

Examples

See Example C Program: Deleting Certificates from a Certificate Store.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Functions, CertDeleteCRLFromStore, CertFreeCertificateContext


CertDuplicateCertificateContext

The CertDuplicateCertificateContext function duplicates a certificate context by incrementing its reference count.

PCCERT_CONTEXT WINAPI CertDuplicateCertificateContext(
  PCCERT_CONTEXT pCertContext
);

Parameters

pCertContext
[in] Pointer to the CERT_CONTEXT structure for which the reference count is incremented.

Return Values

Currently, a copy is not made of the context, and the returned pointer to a context has the same value as the pointer to a context that was input. If the pointer passed into this function is NULL, NULL is returned.

Examples

See Example C Program: Deleting Certificates from a Certificate Store.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Functions, CertDuplicateCRLContext


CertEnumCertificatesInStore

The CertEnumCertificatesInStore function retrieves the first or next certificate in a certificate store. Used in a loop, this function can retrieve in sequence all certificates in a certificate store.

PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(
  HCERTSTORE hCertStore,
  PCCERT_CONTEXT pPrevCertContext
);

Parameters

hCertStore
[in] Handle of a certificate store.
pPrevCertContext
[in] Pointer to the CERT_CONTEXT of the previous certificate context found.

This parameter must be NULL to begin the enumeration and get the first certificate in the store. Successive certificates are enumerated by setting pPrevCertContext to the pointer returned by a previous call to the function.

For logical stores including collection stores under Windows 2000, Windows NT 4.0 with Service Pack 4 or Internet Explorer 5.0, and Windows 98 running Internet Explorer 5.0, a duplicate of the pCertContext returned by this function cannot be used to begin a new sub-sequence of enumerations because the duplicated certificate loses the initial enumeration state. The enumeration skips any certificate previously deleted by CertDeleteCertificateFromStore.

Return Values

If the function succeeds, the return value is a pointer to the next CERT_CONTEXT in the store. If no more certificates exist in the store, the function returns NULL.

For extended error information, call GetLastError. Some possible error codes follow.

Value | Meaning
E_INVALIDARG | The handle in the hCertStore parameter is not the same as that in the certificate context pointed to by pPrevCertContext.
CRYPT_E_NOT_FOUND | No certificates were found. This happens if the store is empty or if the function reached the end of the store's list.

Remarks

The returned pointer is freed when passed as the pPrevCertContext parameter on a subsequent call. Otherwise, the pointer must be freed by calling CertFreeCertificateContext. A pPrevCertContext that is not NULL is always freed by CertFreeCertificateContext, even for an error.

A duplicate of the currently enumerated certificate can be made by calling CertDuplicateCertificateContext.

Examples

See Example C Program: Deleting Certificates from a Certificate Store.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Functions, CERT_CONTEXT, CertDeleteCertificateFromStore, CertDuplicateCertificateContext, CertFindCertificateInStore, CertFindCRLInStore, CertFindCTLInStore, CertFreeCertificateContext


CertFindCertificateInStore

[This is preliminary documentation and subject to change.]

The CertFindCertificateInStore function finds the first or next certificate context in a certificate store that matches a search criteria established by the dwFindType and its associated pvFindPara. This function can be used in a loop to find all of the certificates in a certificate store that match the specified find criteria.

PCCERT_CONTEXT WINAPI CertFindCertificateInStore(
  HCERTSTORE hCertStore,
  DWORD dwCertEncodingType,
  DWORD dwFindFlags,
  DWORD dwFindType,
  const void *pvFindPara,
  PCCERT_CONTEXT pPrevCertContext
);

Parameters

hCertStore
[in] Handle of the certificate store to be searched.
dwCertEncodingType
[in] Specifies the type of encoding used. Both the certificate and message encoding types must be specified by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

dwFindFlags
[in] Used with some dwFindType values to modify the search criteria. For most dwFindType values, dwFindFlags is not used and should be set to zero. For detailed information, see the Remarks section later in this topic.
dwFindType
[in] Specifies the type of search being made. The search type determines the data type, contents, and the use of pvFindPara. Currently defined dwFindType values and the data type each requires for pvFindPara are as follows.
Value of dwFindType | Value of pvFindPara | Search Criteria
CERT_FIND_ANY | NULL; pvFindPara not used | No search criteria used. Returns the next certificate in the store.
CERT_FIND_CERT_ID | CERT_ID structure | Find the certificate identified by the specified CERT_ID.
CERT_FIND_CTL_USAGE | CTL_USAGE structure | Searches for a certificate having a szOID_ENHANCED_KEY_USAGE extension or a CERT_CTL_PROP_ID that matches the pszUsageIdentifier member of the CTL_USAGE structure
CERT_FIND_ENHKEY_USAGE CERT_ENHKEY_USAGE structure Searches for a certificate in the store having either an enhanced key usage extension or an enhanced key usage property and a usage identifier that matches the pszUsageIdentifier member in the CERT_ENHKEY_USAGE structure.

A certificate has an enhanced key usage extension if it has a CERT_EXTENSION structure with the pszObjId member set to szOID_ENHANCED_KEY_USAGE. A certificate has an enhanced key usage property if its CERT_ENHKEY_USAGE_PROP_ID identifier is set.

If pvFindPara is NULL or the cUsageIdentifier member of CERT_ENHKEY_USAGE is zero, any certificate that has either the enhanced key usage extension or the enhanced key usage property meets the selection criteria.

If pvFindPara is NULL or the cUsageIdentifier member of the CERT_ENHKEY_USAGE structure is zero, any certificate having enhanced key usage is a match.

If CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG is set in dwFindFlags, certificates without the key usage extension or property are also matches. Setting this flag takes precedence over passing NULL in pvFindPara.

If CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG is set, a match is done only on the key usage extension.

For details on flag modifications to search criteria, see the Remarks section later in this topic.
CERT_FIND_EXISTING | CERT_CONTEXT structure | Searches for a certificate that is an exact match of the specified certificate context .
CERT_FIND_HASH | CRYPT_HASH_BLOB structure | Searches for a certificate with a SHA1 hash that matches the hash in the CRYPT_HASH_BLOB structure
CERT_FIND_ISSUER_ATTR CERT_RDN structure Search for a certificate with specified issuer attributes that match attributes in the CERT_RDN structure. If these values are set, the function compares attributes of the issuer in a certificate with elements of the CERT_RDN_ATTR array in this CERT_RDN structure. Comparisons iterate through the CERT_RDN_ATTR attributes looking for a match with the certificate's issuer attributes.

If the pszObjId member of CERT_RDN_ATTR is NULL, the attribute object identifier is ignored.

If the dwValueType member of CERT_RDN_ATTR is CERT_RDN_ANY_TYPE, the value type is ignored.

If the pbData member of CERT_RDN_VALUE_BLOB is NULL, any value is a match.

Currently only an exact, case-sensitive match is supported. For details on Unicode options, see the Remarks section later in this topic. When these values are set, the search is restricted to certificates whose encoding type matches dwCertEncodingType.
CERT_FIND_ISSUER_NAME | CERT_NAME_BLOB structure | Search for a certificate with an exact match of the entire issuer name with the name in CERT_NAME_BLOB. The search is restricted to certificates that match the dwCertEncodingType.
CERT_FIND_ISSUER_OF CERT_CONTEXT structure Searches for a certificate with an issuer that matches the issuer in CERT_CONTEXT.

Instead of using CertFindCertificateInStore with this value, use the CertGetCertificateChain function.
CERT_FIND_ISSUER_STR | Null-terminated wide (Unicode) string | Search for a certificate containing the specified issuer name string. The certificate's issuer member is converted to a name string of the appropriate type using the appropriate form of CertNameToStr formatted as CERT_SIMPLE_NAME_STR. Then a case-insensitive substring-within-a-string match is performed. When this value is set, the search is restricted to certificates whose encoding type matches dwCertEncodingType.
CERT_FIND_KEY_IDENTIFIER | CRYPT_HASH_BLOB structure | Searches for a certificate with a CERT_KEY_IDENTIFIER_PROP_ID property matching the key identifier in CRYPT_HASH_BLOB.
CERT_FIND_KEY_SPEC | DWORD value containing a key specification | Searches for a certificate having a CERT_KEY_SPEC_PROP_ID property matching the key specification in pvFindPara.
CERT_FIND_MD5_HASH | CRYPT_HASH_BLOB structure | Searches for a certificate with an MD5 hash that matches the hash in CRYPT_HASH_BLOB.
CERT_FIND_PROPERTY | DWORD value containing a property identifier | Searches for a certificate with a property that matches the property identifier specified by the DWORD value in pvFindPara.
CERT_FIND_PUBLIC_KEY | CERT_PUBLIC_KEY_INFO structure | Searches for a certificate with a public key that matches the public key in the CERT_PUBLIC_KEY_INFO structure.
CERT_FIND_SHA1_HASH | CRYPT_HASH_BLOB structure | Searches for a certificate with a SHA1 hash that matches the hash in the CRYPT_HASH_BLOB structure.
CERT_FIND_SIGNATURE_HASH | CRYPT_HASH_BLOB structure | Searches for a certificate with a signature hash that matches the signature hash in the CRYPT_HASH_BLOB structure.
CERT_FIND_SUBJECT_ATTR CERT_RDN structure Searches for a certificate with specified subject attributes that match attributes in the CERT_RDN structure. If RDN values are set, the function compares attributes of the subject in a certificate with elements of the CERT_RDN_ATTR array in this CERT_RDN structure. Comparisons iterate through the CERT_RDN_ATTR attributes looking for a match with the certificate's subject's attributes.

If the pszObjId member of CERT_RDN_ATTR is NULL, the attribute object identifier is ignored.

If the dwValueType member of CERT_RDN_ATTR is CERT_RDN_ANY_TYPE, the value type is ignored.

If the pbData member of CERT_RDN_VALUE_BLOB is NULL, any value is a match.

Currently only an exact, case-sensitive match is supported.

For details on Unicode options, see the Remarks section later in this topic. When these values are set, the search is restricted to certificates whose encoding type matches dwCertEncodingType.
CERT_FIND_SUBJECT_CERT | CERT_INFO structure | Searches for a certificate with both an issuer and a serial number that match the issuer and serial number in the CERT_INFO structure.
CERT_FIND_SUBJECT_NAME | CERT_NAME_BLOB structure | Searches for a certificate with an exact match of the entire subject name with the name in the CERT_NAME_BLOB structure. The search is restricted to certificates that match the value of dwCertEncodingType.
CERT_FIND_SUBJECT_STR | NULL terminated wide (Unicode) string | Searches for a certificate containing the specified subject name string. The certificate's subject member is converted to a name string of the appropriate type using the appropriate form of CertNameToStr formatted as CERT_SIMPLE_NAME_STR. Then a case-insensitive substring-within-a-string match is performed. When this value is set, the search is restricted to certificates whose encoding type matches dwCertEncodingType.
CERT_FIND_CROSS_CERT_DIST_POINTS | not used | Find a certificate having either a cross certificate distribution point extension or property.
CERT_FIND_PUBKEY_MD5_HASH | CRYPT_HASH_BLOB | Find a certificate whose MD5-hashed public key matches the specified hash.

Note There are alternate forms of dwFindType value that pass a string in pvFindPara. One form uses a Unicode string, and the other an ASCII string. Values that end in "_W" or without a suffix use Unicode. Values that end with "_A" use ASCII strings.

Note The CERT_FIND_CROSS_CERT_DIST_POINTS value for dwFindType can only be used with Windows Whistler and later.

pvFindPara
[in] Points to a data item or structure used with dwFindType.
pPrevCertContext
[in] Pointer to the last CERT_CONTEXT structure returned by this function. This parameter must be NULL on the first call of the function. A pPrevCertContext parameter that is not NULL is always freed by this function, even if the function causes an error.

Return Values

If the function succeeds, the return value is a pointer to a read-only CERT_CONTEXT structure.

If the function fails and a certificate that matches the search criteria is not found, the return value is NULL.

A non-NULL CERT_CONTEXT that CertFindCertificateInStore returns must be freed by CertFreeCertificateContext or by being passed as the pPrevCertContext parameter on a subsequent call to CertFindCertificateInStore.

For extended error information, call GetLastError. Some possible error codes follow.

Value | Meaning
CRYPT_E_NOT_FOUND | No certificate was found matching the search criteria. This can happen if the store is empty or the end of the store's list is reached.
E_INVALIDARG | The handle in the hCertStore parameter is not the same as that in the certificate context pointed to by the pPrevCertContext parameter, or an invalid value was specified in the dwFindType parameter.

Remarks

The dwFindFlags parameter is used to modify the criteria of some search types.

The CERT_UNICODE_IS_RDN_ATTRS_FLAG dwFindFlags value is used only with the CERT_FIND_SUBJECT_ATTR and CERT_FIND_ISSUER_ATTR values for dwFindType. CERT_UNICODE_IS_RDN_ATTRS_FLAG must be set if the CERT_RDN_ATTR structure pointed to by pvFindPara was initialized with Unicode strings. Before any comparison is made, the string to be matched is converted by using X509_UNICODE_NAME to provide for Unicode comparisons.

The following dwFindFlags values are used only with the CERT_FIND_ENKEY_USAGE value for dwFindType:

CERT_FIND_OR_ENHKEY_USAGE_FLAG
The search criteria can be altered by setting one or more flags. By default, if the pszUsageIdentifer member of the CERT_ENHKEY_USAGE structure pointed to by pvFindPara is to be matched, each identifier must be matched to satisfy the search criteria. However, if CERT_FIND_OR_ENHKEY_USAGE_FLAG is set, a match can be made to all identifiers combined by using a bitwise-OR operation; thus, matching any one of the identifiers is sufficient.
CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG
When this flag is set, in addition to usual matches, any certificate that has neither the enhanced key usage extension nor the enhanced key usage property meets the search criteria.
CERT_FIND_NO_ENHKEY_USAGE_FLAG
When this flag is set, only those certificates that have neither an enhanced key usage nor the enhanced key usage property are matches. This flag setting takes precedence over pvFindPara being NULL.
CERT_FIND_VALID_ENHKEY_USAGE_FLAG
When this flag is set, the function only matches those certificates that are valid for the specified usage. By default, in order to match, a certificate must be valid for all usages.

CERT_FIND_OR_ENHKEY_USAGE_FLAG can also be set if the certificate only needs to be valid for one of the specified usages. Note that CertGetValidUsages is called to get the certificate's list of valid usages. Only CERT_FIND_OR_ENHKEY_USAGE_FLAG can also apply when CERT_FIND_VALID_ENHKEY_USAGE_FLAG is set.

CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG
When this flag is set, the matching process involves only the extension usage identifiers. If pvFindPara is NULL or the cUsageIdentifier member of the CERT_ENHKEY_USAGE structure pointed to by pvFindPara is zero, any certificate having an enhanced key usage extension is a match. If CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG is also set, any certificate without the enhanced key usage extension is also a match. If CERT_FIND_NO_ENHKEY_USAGE_FLAG is also set, only certificates without the enhanced key usage extension are matches.
CERT_FIND_EXT_PROP_ENHKEY_USAGE_FLAG
When this flag is set, the matching process involves only usage identifiers that are properties. If pvFindPara is NULL or cUsageIdentifier is set to zero, any certificate having an enhanced key usage property is a match. If CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG is also set, any certificate without the enhanced key usage property is also a match. If CERT_FIND_NO_ENHKEY_USAGE_FLAG is set, only certificates without the enhanced key usage property are matches.
CERT_CASE_INSENSITIVE_IS_RDN_ATTRS_FLAG
Used only with CERT_FIND_SUBJECT_ATTR and CERT_FIND_ISSUER-ATTR values of dwFindType. By default, a case-sensitive, exact match is made. If this flag is set, the match is case-insensitive.

CertDuplicateCertificateContext can be called to make a duplicate of the returned context. The returned context can be added to a different certificate store using CertAddCertificateContextToStore, or a link to that certificate context can be added to a store that is not a collection store using CertAddCertificateLinkToStore.

Examples

See Example C Program: Certificate Store Operations and Example C Program: Collection and Sibling Certificate Store Operations.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Functions, CERT_CONTEXT, CertAddCertificateContextToStore, CertAddCertificateLinkToStore, CertDuplicateCertificateContext, CertEnumCertificatesInStore, CertFreeCertificateContext, CertGetCertificateChain, CertNameToStr


CertFreeCertificateContext

The CertFreeCertificateContext function frees a certificate context by decrementing its reference count. When the reference count goes to zero, CertFreeCertificateContext frees the memory occupied by a certificate context. Each context obtained by a get, find, enumerate, duplicate, or create operation must be freed by the appropriate free operation.

BOOL WINAPI CertFreeCertificateContext(
  PCCERT_CONTEXT pCertContext
);

Parameters

pCertContext
[in] Pointer to the CERT_CONTEXT to be freed.

Return Values

The function always returns TRUE.

Examples

See Example C Program: Certificate Store Operations.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Functions, CertFreeCRLContext


CertGetIssuerCertificateFromStore

The CertGetIssuerCertificateFromStore function retrieves the certificate context from the certificate store for the first or next issuer of the specified subject certificate. The new Certificate Chain Verification Functions are recommended instead of the use of this function.

PCCERT_CONTEXT WINAPI CertGetIssuerCertificateFromStore(
  HCERTSTORE hCertStore,
  PCCERT_CONTEXT pSubjectContext,
  PCCERT_CONTEXT pPrevIssuerContext,
  DWORD *pdwFlags
);

Parameters

hCertStore
[in] Handle of a certificate store.
pSubjectContext
[in] Pointer to a CERT_CONTEXT structure containing the subject information. This parameter can be obtained from any certificate store or can be created by the calling application using the CertCreateCertificateContext function.
pPrevIssuerContext
[in/optional] Pointer to a CERT_CONTEXT structure containing the issuer information. An issuer can have multiple certificates, especially when a validity period is about to change. This parameter must be NULL on the call to get the first issuer certificate. To get the next certificate for the issuer, set pPrevIssuerContext to the CERT_CONTEXT structure returned by the previous call.

A pPrevIssuerContext that is not NULL is always freed by CertGetIssuerCertificateFromStore by using CertFreeCertificateContext, even for an error.

pdwFlags
[in/out]The following flags enable verification checks on the returned certificate. They can be combined using a bitwise-OR operation to enable multiple verifications.
Value | Meaning
CERT_STORE_NO_CRL_FLAG | Indicates no matching CRL was found.
CERT_STORE_NO_ISSUER_FLAG | Indicates no issuer certificate was found.
CERT_STORE_REVOCATION_FLAG | Checks whether the subject certificate is on the issuer's revocation list.
CERT_STORE_SIGNATURE_FLAG | Uses the public key in the issuer's certificate to verify the signature on the subject certificate.
CERT_STORE_TIME_VALIDITY_FLAG | Gets the current time and verifies that it is within the subject certificate's validity period.

If a verification check of an enabled type succeeds, its flag is set to zero. If it fails, its flag remains set upon return. For CERT_STORE_REVOCATION_FLAG, the verification succeeds if the function does not find a CRL related to the subject certificate.

If CERT_STORE_REVOCATION_FLAG is set and the issuer does not have a CRL in the store, CERT_STORE_NO_CRL_FLAG is set and CERT_STORE_REVOCATION_FLAG remains set.

If CERT_STORE_SIGNATURE_FLAG or CERT_STORE_REVOCATION_FLAG is set, CERT_STORE_NO_ISSUER_FLAG is set if the function does not find an issuer certificate in the store. For more details, see the Remarks section later in this topic.

In the case of a verification check failure, a pointer to the issuer's CERT_CONTEXT is still returned and GetLastError is not updated.

Return Values

If the function succeeds, the return value is a pointer to a read-only issuer CERT_CONTEXT.

If the function fails and the first or next issuer certificate is not found, the return value is NULL.

Only the last returned CERT_CONTEXT structure must be freed by calling CertFreeCertificateContext. When the returned CERT_CONTEXT from one call to the function is supplied as the pPrevIssuerContext parameter on a subsequent call, the context is freed as part of the action of the function.

For extended error information, call GetLastError. Some possible error codes follow.

Value | Meaning
CRYPT_E_NOT_FOUND | No issuer was found for the subject certificate.
CRYPT_E_SELF_SIGNED | The issuer certificate is the same as the subject certificate. It is a self-signed root certificate.
E_INVALIDARG | The handle in the hCertStore parameter is not the same as that of the certificate context pointed to by the pPrevIssuerContext parameter, or an unsupported flag was set in pdwFlags.

Remarks

CertDuplicateCertificateContext can be called to make a duplicate of the issuer certificate.

The hexadecimal values for dwFlags can be combined using a bitwise-OR operation to enable multiple verifications. For example, to enable both signature and time validity, the value 0x00000003 is passed in dwFlags on input. In this case, if CERT_STORE_SIGNATURE_FLAG verification succeeds but CERT_STORE_TIME_VALIDITY_FLAG verification fails, dwFlags returns as 0x00000002 on output.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Functions


CertGetSubjectCertificateFromStore

The CertGetSubjectCertificateFromStore function returns from a certificate store a subject certificate context uniquely identified by its issuer and serial number.

PCCERT_CONTEXT WINAPI CertGetSubjectCertificateFromStore(
  HCERTSTORE hCertStore,
  DWORD dwCertEncodingType,
  PCERT_INFO pCertId
);

Parameters

hCertStore
[in] Handle of a certificate store.
dwCertEncodingType
[in] Specifies the type of encoding used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pCertId
[in] Pointer to a CERT_INFO structure. Only the Issuer and SerialNumber members are used.

Return Values

If the function succeeds, the return value is a pointer to a read-only CERT_CONTEXT. The CERT_CONTEXT must be freed by calling CertFreeCertificateContext.

The returned certificate might not be valid. Usually, it is verified when getting its issuer certificate (CertGetIssuerCertificateFromStore).

For extended error information, call GetLastError. One possible error code is the following.

Value | Meaning
CRYPT_E_NOT_FOUND | The subject certificate was not found in the store.

Remarks

CertDuplicateCertificateContext can be called to make a duplicate certificate.

Examples

See Example C Program: Signing, Encoding,Decoding, and Verifying a Message.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Functions, CertDuplicateCertificateContext, CertFreeCertificateContext, CertGetIssuerCertificateFromStore


CertGetValidUsages

The CertGetValidUsages function returns an array of usages consisting of the intersection of the valid usages for all certificates in an array of certificates.

BOOL WINAPI CertGetValidUsages(
  DWORD cCerts,
  PCCERT_CONTEXT *rghCerts,
  int *cNumOIDs,
  LPSTR *rghOIDs,
  DWORD *pcbOIDs
);

Parameters

cCerts
[in] Number of certificates in the array to be checked.
rghCerts
[in] Array of certificates to be checked for valid usage.
cNumOIDs
[out] Number of valid usages found as the intersection of the valid usages of all certificates in the array. If all of the certificates are valid for all usages, cNumOIDS is set to negative one ( -1).
rghOIDs
[out] Array of the OIDs of the valid usages that are shared by all of the certificates in the rghCerts array. This parameter can be NULL to set the size of this structure for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.
pcbOIDs
[in out] Pointer to a DWORD value that specifies the size, in bytes, of the rghOIDs array and the strings pointed to. When the function returns, the DWORD value contains the number of bytes needed for the array.

Return Values

If the function succeeds, the return value is nonzero (TRUE) .If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 98 or later.
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.


CertSerializeCertificateStoreElement

The CertSerializeCertificateStoreElement function serializes a certificate context's encoded certificate and its encoded properties. The result can be persisted to storage so that the certificate and properties can be retrieved at a later time.

BOOL WINAPI CertSerializeCertificateStoreElement(
  PCCERT_CONTEXT pCertContext,
  DWORD dwFlags,
  BYTE *pbElement,
  DWORD *pcbElement
);

Parameters

pCertContext
[in] Pointer to the CERT_CONTEXT to be serialized.
dwFlags
[in] Reserved for future use and must be zero.
pbElement
[out] Pointer to a buffer that receives the serialized output, including the encoded certificate and possibly its properties.

This parameter can be NULL to set the size of this information for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.

pcbElement
[in/out] Pointer to a DWORD value specifying the size, in bytes, of the buffer pointed to by the pbElement parameter. When the function returns, DWORD value contains the number of bytes stored in the buffer.

Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError.

Examples

See Example C Program: Serializing Certificates and Adding Serialized Elements to Stores.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Functions, CertAddSerializedElementToStore


CertVerifySubjectCertificateContext

The CertVerifySubjectCertificateContext function performs the enabled verification checks on a certificate by checking the validity of the certificate's issuer. The new Certificate Chain Verification Functions are recommended instead this function.

BOOL WINAPI CertVerifySubjectCertificateContext(
  PCCERT_CONTEXT pSubject,
  PCCERT_CONTEXT pIssuer,
  DWORD *pdwFlags
);

Parameters

pSubject
[in] Pointer to a CERT_CONTEXT structure containing the subject's certificate.
pIssuer
[in/optional] Pointer to a CERT_CONTEXT containing the issuer's certificate. When checking just CERT_STORE_TIME_VALIDITY_FLAG, pIssuer can be NULL.
pdwFlags
[in/out] Pointer to a DWORD value contain verification check flags. The following flags can be set to enable verification checks on the subject certificate. They can be combined using a bitwise-OR operation to enable multiple verifications.
Value | Meaning
CERT_STORE_REVOCATION_FLAG | Checks whether the subject certificate is on the issuer's revocation list.
CERT_STORE_SIGNATURE_FLAG | Uses the public key in the issuer's certificate to verify the signature on the subject certificate.
CERT_STORE_TIME_VALIDITY_FLAG | Gets the current time and verifies that it is within the subject certificate's validity period.

If an enabled verification check succeeds, its flag is set to zero. If it fails, then its flag is set upon return.

If CERT_STORE_REVOCATION_FLAG was enabled and the issuer does not have a CRL in the store, then CERT_STORE_NO_CRL_FLAG is set in addition to CERT_STORE_REVOCATION_FLAG.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE.

For a verification check failure, TRUE is still returned. FALSE is returned only when a bad parameter is passed in.

For extended error information, call GetLastError. One possible error code is the following.

Value | Meaning
E_INVALIDARG | An unsupported bit was set in pdwFlags. Any combination of CERT_STORE_SIGNATURE_FLAG, CERT_STORE_TIME_VALIDITY_FLAG, and CERT_STORE_REVOCATION_FLAG can be set. If pIssuer is NULL, only CERT_STORE_TIME_VALIDITY_FLAG can be set.

Remarks

The hexadecimal value of the flags can be combined using bitwise-OR operations to enable multiple verifications. For example, to enable both signature and time validity, the value

CERT_STORE_SIGNATURE_FLAG | CERT_STORE_TIME_VALIDITY_FLAG

is placed in the pdwFlags DWORD value as an input parameter. If CERT_STORE_SIGNATURE_FLAG verification succeeds, but CERT_STORE_TIME_VALIDITY_FLAG verification fails, pdwFlags is set to CERT_STORE_TIME_VALIDITY_FLAG when the function returns.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Functions, CertGetIssuerCertificateFromStore


Certificate Revocation List Functions

These Win32 functions manage the storage and retrieval of certificate revocation lists.

Function | Description
CertAddCRLContextToStore | Adds a CRL context to the certificate store.
CertAddCRLLinkToStore | Adds a link in a store to a CRL context in a different store.
CertAddEncodedCRLToStore | Converts the encoded CRL to a CRL context and then adds the context to the certificate store.
CertCreateCRLContext | Creates a CRL context from an encoded CRL. The created context is not put in a certificate store.
CertDeleteCRLFromStore | Deletes a CRL from the certificate store.
CertDuplicateCRLContext | Duplicates a CRL context by incrementing the reference count.
CertEnumCRLsInStore | Enumerates the CRL contexts in a store.
CertFindCertificateInCRL | Search a CRL's list of entries for a specified certificate.
CertFindCRLInStore | Finds the first, or next, CRL context in the certificate store that matches a specific criterion.
CertFreeCRLContext | Frees a CRL context.
CertGetCRLFromStore | Gets the first, or next, CRL context from the certificate store for the specified issuer certificate.
CertSerializeCRLStoreElement | Serializes the CRL context's encoded CRL and its properties.


CertAddCRLContextToStore

The CertAddCRLContextToStore function adds a certificate revocation list (CRL) context to the certificate store.

BOOL WINAPI CertAddCRLContextToStore(
  HCERTSTORE hCertStore,
  PCCRL_CONTEXT pCrlContext,
  DWORD dwAddDisposition,
  PCCRL_CONTEXT *ppStoreContext
);

Parameters

hCertStore
[in] Handle of a certificate store.
pCrlContext
[in] Pointer to the CRL_CONTEXT structure to be added.
dwAddDisposition
[in] Specifies the action to take if a matching CRL or a link to a matching CRL already exists in the store. Currently defined disposition values and their uses are as follows.
Value | Meaning
CERT_STORE_ADD_ALWAYS | Makes no check for an existing matching CRL or link to a matching CRL. A new CRL is always added to the store. This can lead to duplicates in a store.
CERT_STORE_ADD_NEW | If a matching CRL or a link to a matching CRL exists, the operation fails. GetLastError returns the CRYPT_E_EXISTS code.
CERT_STORE_ADD_NEWER If a matching CRL or a link to a matching CRL exists, the function compares the ThisUpdate times on the CRLs. If the existing CRL has a ThisUpdate time less than the ThisUpdate time on the new CRL, the old CRL or link is replaced just as with CERT_STORE_ADD_REPLACE_EXISTING. If the existing CRL has a ThisUpdate time greater than or equal to the ThisUpdate time on the CRL to be added, the function fails with GetLastError returning the CRYPT_E_EXISTS code.

If a matching CRL or a link to a matching CRL is not found in the store, a new CRL is added to the store.
CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES | The action is the same as for CERT_STORE_ADD_NEWER, except that if an older CRL is replaced, the properties of the older CRL are incorporated into the replacement CRL.
CERT_STORE_ADD_REPLACE_EXISTING | If a matching CRL or a link to a matching CRL exists, the existing CRL or link is deleted and a new CRL is created and added to the store. If a matching CRL or a link to a matching CRL does not exist, one is added.
CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES | If a matching CRL exists in the store, the existing context is deleted before creating and adding the new context. The added context inherits properties from the existing CRL.
CERT_STORE_ADD_USE_EXISTING If a matching CRL or a link to a matching CRL exists, that existing CRL is used and properties from the new CRL are added. The function does not fail, but no new CRL is added. If ppCertContext is not NULL, the existing context is duplicated.

If a matching CRL or a link to a matching CRL does not exist, a new CRL is added.

ppStoreContext
[out/optional] Pointer to a pointer to the decoded CRL context. This is an optional parameter and can be NULL, indicating that the calling application does not require a copy of the added or existing CRL. If a copy is made, that context must be freed by using CertFreeCRLContext.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError. Some possible error codes follow.

Value | Meaning
CRYPT_E_EXISTS | This error is returned if CERT_STORE_ADD_NEW is set and the CRL already exists in the store or if CERT_STORE_ADD_NEWER is set and a CRL exists in the store with a ThisUpdate date greater than or equal to the ThisUpdate date on the CRL to be added.
E_INVALIDARG | The dwAddDisposition parameter specified an invalid disposition value.

Errors from the called functions CertAddEncodedCRLToStore and CertSetCRLContextProperty can be propagated to this function.

Remarks

The CRL context is not duplicated using CertDuplicateCRLContext. Instead, a new copy is created and added to the store. In addition to copying the encoded CRL, the function copies the context's properties.

Examples

See Example C Program: Certificate Store Operations. In that example, change all references to "certificate" to "CRL."

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Revocation List Functions, CertAddEncodedCRLToStore, CertDuplicateCRLContext, CertFreeCRLContext, CertSetCRLContextProperty


CertAddCRLLinkToStore

The CertAddCRLLinkToStore function adds a link in a store to a certificate revocation list (CRL) context in a different store. Instead of creating and adding a duplicate of the CRL, this function adds a link to the original CRL context.

BOOL WINAPI CertAddCRLLinkToStore(
  HCERTSTORE hCertStore,
  PCCRL_CONTEXT pCrlContext,
  DWORD dwAddDisposition,
  PCCRL_CONTEXT *ppStoreContext
);

Parameters

hCertStore
[in] Handle of a certificate store where the link is to be added.
pCrlContext
[in] Pointer to the CRL_CONTEXT structure to be linked.
dwAddDisposition
[in] Specifies the action to take if a matching CRL or a link to a matching CRL exists in the store. Currently defined disposition values and their uses are as follows.
Value | Meaning
CERT_STORE_ADD_ALWAYS | Makes no check for an existing matching CRL or link to a matching CRL. A new link is always added to the store. This can lead to duplicates in a store.
CERT_STORE_ADD_NEW | If a matching CRL or a link to a matching CRL exists, the operation fails. GetLastError returns the CRYPT_E_EXISTS code.
CERT_STORE_ADD_NEWER If a matching CRL or a link to a matching CRL exists, the ThisUpdate times on the CRLs are compared. If the existing CRL has a ThisUpdate time less than the ThisUpdate time on the new CRL, the old link is replaced just as with CERT_STORE_ADD_REPLACE_EXISTING. If the existing CRL has a ThisUpdate time greater than or equal to the ThisUpdate time on the CRL to be added, the function fails with GetLastError returning the CRYPT_E_EXISTS code.

If a matching CRL or a link to a matching CRL is not found in the store, a new link is added to the store.
CERT_STORE_ADD_REPLACE_EXISTING | If a link to the matching CRL exists, that existing link is deleted and a new link is created and added to the store. If a matching CRL or a link to a matching CRL does not exist, a new link is added.
CERT_STORE_ADD_USE_EXISTING | If a matching CRL or a link to a matching CRL exists, that existing link is used. The function does not fail, but no new link is added. If a matching CRL or link to a CRL does not exist, a new link is added.

ppStoreContext
[out/optional] Pointer to a pointer of a copy of the link created. The ppStoreContext parameter can be NULL to indicate that a copy of the link is not needed. If a copy of the link is created, that copy must be freed using CertFreeCRLContext.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError. Some possible error codes follow.

Value | Meaning
CRYPT_E_EXISTS | For a dwAddDisposition of CERT_STORE_ADD_NEW, the CTL already exists in the store.
E_INVALIDARG | An invalid disposition value was specified in the dwAddDisposition parameter.

Remarks

Because the link provides access to an original CRL context, setting an extended property in the linked CRL context changes that extended property in the CRL's original location and in any other links to that CRL.

Links cannot be added to a store that is opened as a collection. Stores opened as collections include all stores opened with CertOpenSystemStore or CertOpenStore using CERT_STORE_PROV_SYSTEM or CERT_STORE_PROV_COLLECTION. For more information, see CertAddStoreToCollection.

If links are used and CertCloseStore is called with CERT_CLOSE_STORE_FORCE_FLAG, the store using links must be closed before the store containing the original contexts can be closed. If CERT_CLOSE_STORE_FORCE_FLAG is not used, the two stores can be closed in either order.

Examples

See Example C Program: Certificate Store Operations. In that example, change all references to "certificate" to "CRL."

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Revocation List Functions, CertAddCertificateLinkToStore, CertAddCTLLinkToStore, CertAddStoreToCollection, CertCloseStore, CertFreeCRLContext, CertOpenStore, CertOpenSystemStore


CertAddEncodedCRLToStore

The CertAddEncodedCRLToStore function creates a certificate revocation list (CRL) context from an encoded CRL and adds it to the certificate store. The function makes a copy of the CRL context before adding it to the store.

BOOL WINAPI CertAddEncodedCRLToStore(
  HCERTSTORE hCertStore,
  DWORD dwCertEncodingType,
  const BYTE *pbCrlEncoded,
  DWORD cbCrlEncoded,
  DWORD dwAddDisposition,
  PCCRL_CONTEXT *ppCrlContext
);

Parameters

hCertStore
[in] Handle of a certificate store.
dwCertEncodingType
[in] Specifies the type of encoding used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING

PKCS_7_ASN_ENCODING

pbCrlEncoded
[in] Pointer to a buffer containing the encoded CRL to be added to the certificate store.
cbCrlEncoded
[in] Size, in bytes, of the pbCrlEncoded buffer.
dwAddDisposition
[in] Specifies the action to take if a matching CRL or a link to a matching CRL already exists in the store. Currently defined disposition values and their uses are as follows.
Value | Meaning
CERT_STORE_ADD_ALWAYS | Makes no check for an existing matching CRL or link to a matching CRL. A new CRL is always added to the store. This can lead to duplicates in a store.
CERT_STORE_ADD_NEW | If a matching CRL or a link to a matching CRL exists, the operation fails. GetLastError returns the CRYPT_E_EXISTS code.
CERT_STORE_ADD_NEWER If a matching CRL or a link to a matching CRL exists, the ThisUpdate times on the CRLs are compared. If the existing CRL has a ThisUpdate time less than the ThisUpdate time on the new CRL, the old CRL or link is replaced just as with CERT_STORE_ADD_REPLACE_EXISTING. If the existing CRL has a ThisUpdate time greater than or equal to the ThisUpdate time on the CRL to be added, the function fails with GetLastError returning the CRYPT_E_EXISTS code.

If a matching CRL or a link to a matching CRL is not found in the store, a new CRL is added to the store.
CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES | The action is the same as for CERT_STORE_ADD_NEWER, except that if an older CRL is replaced, the properties of the older CRL are incorporated into the replacement CRL.
CERT_STORE_ADD_REPLACE_EXISTING | If a matching CRL or a link to a matching CRL exists, that existing CRL or link is deleted and a new CRL is created and added to the store. If a matching CRL or a link to a matching CRL does not exist, one is added.
CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES | If a matching CRL exists in the store, that existing context is deleted before creating and adding the new context. The new context inherits properties from the existing CRL.
CERT_STORE_ADD_USE_EXISTING If a matching CRL or a link to a matching CRL exists, that existing CRL is used and properties from the new CRL are added. The function does not fail, but no new CRL is added. If ppCertContext is not NULL, the existing context is duplicated.

If a matching CRL or a link to a matching CRL does not exist, a new CRL is added.

ppCrlContext
[out/optional] Pointer to a pointer to the decoded CRL_CONTEXT structure. This is an optional parameter that can be NULL, indicating that the calling application does not require a copy of the new or existing CRL. If a copy is made, that context must be freed using CertFreeCRLContext.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError. Some possible error codes follow.

Value | Meaning
CRYPT_E_EXISTS | This error is returned if CERT_STORE_ADD_NEW is set and the CRL already exists in the store, or if CERT_STORE_ADD_NEWER is set and there is a CRL in the store with a ThisUpdate time greater than or equal to the ThisUpdate time for the CRL to be added.
E_INVALIDARG | An invalid disposition value was specified in the dwAddDisposition parameter, or an invalid encoding type was specified. Currently, only the encoding type X509_ASN_ENCODING is supported.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN1 Encoding/Decoding Error Codes.

Examples

See Example C Program: Serializing Certificates and Adding Serialized Elements to Stores. In that example, change all references to "certificate" to "CRL."

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Revocation List Functions, CertAddCRLContextToStore, CertFreeCRLContext


CertCreateCRLContext

The CertCreateCRLContext function creates a certificate revocation list (CRL) context from an encoded CRL. The created context is not persisted to a certificate store. It makes a copy of the encoded CRL within the created context.

PCCRL_CONTEXT WINAPI CertCreateCRLContext(
  DWORD dwCertEncodingType,
  const BYTE *pbCrlEncoded,
  DWORD cbCrlEncoded
);

Parameters

dwCertEncodingType
[in] Specifies the type of encoding used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pbCrlEncoded
[in] Pointer to a buffer containing the encoded CRL from which the context is to be created.
cbCrlEncoded
[in] Size, in bytes, of the pbCrlEncoded buffer.

Return Values

If the function succeeds, the return value is a pointer to a read-only CRL_CONTEXT.

If the function fails and is unable to decode and create the CRL_CONTEXT, the return value is NULL. For extended error information, call GetLastError. Some possible error codes follow.

Value | Meaning
E_INVALIDARG | Invalid certificate encoding type. Currently, only the encoding type X509_ASN_ENCODING is supported.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN1 Encoding/Decoding Error Codes.

Remarks

The CRL_CONTEXT must be freed by calling CertFreeCRLContext. CertDuplicateCRLContext can be called to make a duplicate. CertSetCRLContextProperty and CertGetCRLContextProperty can be called to store and read properties for the CRL.

Examples

See Example C Program: Certificate Store Operations. In that example, change all references to "certificate" to "CRL."

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Revocation List Functions, CertCreateCertificateContext, CertCreateCTLContext, CertDuplicateCRLContext, CertFreeCRLContext, CertGetCRLContextProperty, CertSetCRLContextProperty, CRL_CONTEXT


CertDeleteCRLFromStore

The CertDeleteCRLFromStore function deletes the specified certificate revocation list (CRL) context from the certificate store.

BOOL WINAPI CertDeleteCRLFromStore(
  PCCRL_CONTEXT pCrlContext
);

Parameters

pCrlContext
[in] Pointer to the CRL_CONTEXT structure to be deleted.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError. One possible error code is the following.

Value | Meaning
E_ACCESSDENIED | The store was opened read-only, and a delete operation is not allowed.

Remarks

All subsequent get or find operations for the CRL in this store fail. However, memory allocated for the CRL is not freed until all duplicated contexts have also been freed.

The pCrlContext parameter is always freed by this function by using CertFreeCRLContext, even for an error.

Examples

See Example C Program: Deleting Certificates from a Certificate Store. In that example, change all references to "certificate" to "CRL."

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Revocation List Functions, CertFreeCRLContext


CertDuplicateCRLContext

The CertDuplicateCRLContext function duplicates a certificate revocation list (CRL) context by incrementing its reference count.

PCCRL_CONTEXT WINAPI CertDuplicateCRLContext(
  PCCRL_CONTEXT pCrlContext
);

Parameters

pCrlContext
[in] Pointer to the CRL_CONTEXT structure for which the reference count is being incremented.

Return Values

Currently, a copy is not made of the context, and the returned context is the same as the context that was input. If the pointer passed into this function is NULL, NULL is returned.

Examples

See Example C Program: Deleting Certificates from a Certificate Store. In that example, change all references to "certificate" to "CRL."

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Revocation List Functions


CertEnumCRLsInStore

The CertEnumCRLsInStore function retrieves the first or next certificate revocation list (CRL) context in a certificate store. Used in a loop, this function can retrieve in sequence all CRL contexts in a certificate store.

PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(
  HCERTSTORE hCertStore,
  PCCRL_CONTEXT pPrevCrlContext
);

Parameters

hCertStore
[in] Handle of a certificate store.
pPrevCrlContext
[in] Pointer to the previous CRL_CONTEXT structure found. The pPrevCrlContext parameter must be NULL to get the first CRL in the store. Successive CRLs are enumerated by setting pPrevCRlContext to the pointer returned by a previous call to the function. The enumeration skips any CRLs previously deleted by CertDeleteCRLFromStore.

Return Values

If the function succeeds, the return value is a pointer to the next CRL_CONTEXT in the store.

NULL is returned if the function fails. For extended error information, call GetLastError. Some possible error codes follow.

Value | Meaning
E_INVALIDARG | The handle in the hCertStore parameter is not the same as that in the certificate context pointed to by pPrevCertContext.
CRYPT_E_NOT_FOUND | No CRL was found. This happens if the store is empty or the end of the store's list is reached.

Remarks

The returned pointer is freed when it is passed as the pPrevCrlContext on a subsequent call to the function. Otherwise, the pointer must explicitly be freed by calling CertFreeCRLContext. A pPrevCrlContext that is not NULL is always freed when passed to this function through a call to CertFreeCRLContext, even if the function itself returns an error.

A duplicate of the CRL context returned by this function can be made by calling CertDuplicateCRLContext.

Examples

See Example C Program: Deleting Certificates from a Certificate Store. In the example, change all references to "certificate" to "CRL."

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Revocation List Functions, CertDeleteCRLFromStore, CertDuplicateCRLContext, CertFindCRLInStore, CertFreeCRLContext


CertFindCertificateInCRL

The CertFindCertificateInCRL function search the CRL's list of entries for the specified certificate.

BOOL WINAPI CertFindCertificateInCRL(
  PCCERT_CONTEXT pCert,
  PCCRL_CONTEXT pCrlContext,
  DWORD dwFlags,
  OPTIONAL void *pvReserved,
  PCRL_ENTRY *ppCrlEntry
);

Parameters

pCert
[in] Pointer to a CERT_CONTEXT of the certificate to be searched for in the CRL.
pCrlContext
[in] Pointer to the CRL_CONTEXT to be searched.
dwFlags
[in] Reserved for future use. Must be set to zero (0).
pvReserved
[in] Reserved for future use. Must be set to zero (0).
ppCrlEntry
[out] If the certificate is found in the CRL, this pointer is updated with a pointer to the entry. Otherwise, it is set to NULL. The returned entry is not allocated and must not be freed.

Return Values

TRUE is returned if the list was searched, whether a matching certificate was found or not. If the list was not searched, FALSE is returned.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.


CertFindCRLInStore

[This is preliminary documentation and subject to change.]

The CertFindCRLInStore function finds the first or next certificate revocation list (CRL) context in a certificate store that matches a search criterion established by the dwFindType parameter and the associated pvFindPara parameter. This function can be used in a loop to find all of the CRL contexts in a certificate store that match the specified find criteria.

PCCRL_CONTEXT WINAPI CertFindCRLInStore(
  HCERTSTORE hCertStore,
  DWORD dwEncodingType,
  DWORD dwFindFlags,
  DWORD dwFindType,
  const void *pvFindPara,
  PCCRL_CONTEXT pPrevCrlContext
);

Parameters

hCertStore
[in] Handle of the certificate store to be searched.
dwEncodingType
[in] Not currently used and must be set to zero.
dwFindFlags
[in] If dwFindType is CRL_FIND_ISSUED_BY, by default, only issuer name matching is done. The following flags can be used to do additional filtering.
Value | Meaning
CRL_FIND_ISSUED_BY_AKI_FLAG | Checks for a CRL that has an Authority Key Identifier (AKI) extension. If the CRL has an AKI, only a CRL whose AKI matches the issuer is returned. Note: the AKI extension has the following OID and szOID_AUTHORITY_KEY_IDENTIFIER2 and its corresponding data structure.
CRL_FIND_ISSUED_BY_SIGNATURE_FLAG | Use the public key in the issuer's certificate to verify the signature on the CRL. Only returns a CRL having a valid signature.
CRL_FIND_ISSUED_BY_DELTA_FLAG | Finds and returns a delta CRL.
CRL_FIND_ISSUED_BY_BASE_FLAG | Finds and returns a base CRL.

Note The CRL_FIND_ISSUED_BY_DELTA_FLAG, and CRL_FIND_ISSUED_BY_BASE_FLAG values for dwFindFlags can only be used with Windows Whistler and later.

dwFindType
[in] Specifies the type of search being made. The value of dwFindType determines the data type, contents, and use of the pvFindPara parameter. Currently defined search types and their pvFindPara requirements are as follows.
Find Type | pvFindPara | Search criteria
CRL_FIND_ANY | Not used; must be set to NULL | No search criteria. The next CRL in the store is returned.
CRL_FIND_ISSUED_BY | Pointer to a CERT_CONTEXT | Searches for the next CRL in the store matching the issuer in the CERT_CONTEXT.
CRL_FIND_EXISTING Pointer to a CRL_CONTEXT Searches for the next CRL that matches the CRL_CONTEXT in the following ways::
1. Both are base or delta CRLs
2. The issuer-name BLOBs for both are identical

3. If they exist, the Authority/KeyIdentificer and IssuingDistributionPoint encoded extension BLOBs match.

pvFindPara
[in] Determined by the value of dwFindType. See the above table for details.
pPrevCrlContext
[in] Pointer to the last CRL_CONTEXT returned by this function. Must be NULL to get the first CRL in the store meeting the search criteria. Successive CRLs meeting the search criteria can be found by setting pPrevCrlContext to the PCCRL_CONTEXT pointer returned by a previous call to the function. The search process skips any CRLs that do not match the search criteria or that have been previously deleted from the store by CertDeleteCRLFromStore.

A pPrevCrlContext that is not NULL is always freed by this function, even if the function causes an error.

Return Values

If the function succeeds, the return value is a pointer to a read-only CRL context. The returned CRL context must be freed by calling CertFreeCRLContext or implicitly be freed when passed as the pPrevCrlContext parameter on a subsequent call to CertFindCRLInStore.

If the function fails and a CRL that matches the search criteria is not found, the return value is NULL. For extended error information, call GetLastError. Some possible error codes follow.

Value | Meaning
E_INVALIDARG | The handle in the hCertStore parameter is not the same as that in the CRL context pointed to by the pPrevCrlContext parameter, or an invalid search type was specified in the dwFindType parameter.
CRYPT_E_NOT_FOUND | No CRLs are in the store, no CRL was found matching the search criteria, or reached the end of the store's list.

Remarks

The returned pointer is freed when passed as the pPrevCrlContext parameter on a subsequent call to the function. Otherwise, the pointer must be explicitly freed by calling CertFreeCRLContext. A pPrevCrlContext that is not NULL is always freed by CertFindCRLInStore using a call to CertFreeCRLContext, even if there is an error in the function.

CertDuplicateCRLContext can be called to make a duplicate of the returned context. The returned CRL context can be added to a different certificate store using CertAddCRLContextToStore, or a link to that CRL context can be added to a noncollection store using CertAddCRLLinkToStore.

Examples

See Example C Program: Certificate Store Operations. In that example, change all references to "certificate" to "CRL."

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Revocation List Functions, CertAddCRLContextToStore, CertAddCRLLinkToStore, CertDeleteCRLFromStore, CertDuplicateCRLContext, CertFreeCRLContext, CRL_CONTEXT


CertFreeCRLContext

The CertFreeCRLContext function frees a certificate revocation list (CRL) context by decrementing its reference count. When the reference count goes to zero, CertFreeCRLContext frees the memory occupied by a CRL context. Each context obtained by a get, find, enumerate, duplicate, or create operation must be freed using the appropriate free operation.

BOOL WINAPI CertFreeCRLContext(
  PCCRL_CONTEXT pCrlContext
);

Parameters

pCrlContext
[in] Pointer to the CRL_CONTEXT to be freed.

Return Values

The function always returns TRUE.

Examples

See Example C Program: Certificate Store Operations.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Revocation List Functions, CertFreeCertificateContext, CRL_CONTEXT


CertGetCRLFromStore

[This is preliminary documentation and subject to change.]

The CertGetCRLFromStore function gets the first or next certificate revocation list (CRL) context from the certificate store for the specified issuer. The function also performs the enabled verification checks on the CRL. The new Certificate Chain Verification Functions are recommended instead of this function.

PCCRL_CONTEXT WINAPI CertGetCRLFromStore(
  HCERTSTORE hCertStore,
  PCCERT_CONTEXT pIssuerContext,
  PCCRL_CONTEXT pPrevCrlContext,
  DWORD *pdwFlags
);

Parameters

hCertStore
[in] Handle of a certificate store.
pIssuerContext
[in/optional] Pointer to an issuer CERT_CONTEXT. The pIssuerContext pointer can come from this store or another store, or could have been created by the calling CertCreateCertificateContext. If NULL is passed for this parameter, all the CRLs in the store are found.
pPrevCrlContext
[in] Pointer to a CRL_CONTEXT. An issuer can have multiple CRLs. For example, it can generate delta CRLs by using an X.509 version 3 extension. This parameter must be NULL on the first call to get the CRL. To get the next CRL for the issuer, the parameter is set to the CRL_CONTEXT returned by a previous call. A non-NULL pPrevCrlContext is always freed by this function using a call to CertFreeCRLContext, even for an error.
pdwFlags
[in/out] The following flag values are defined to enable verification checks on the returned CRL. These flags can be combined using a bitwise-OR operation.
Value | Meaning
CERT_STORE_SIGNATURE_FLAG | Uses the public key in the issuer's certificate to verify the signature on the returned CRL.
CERT_STORE_TIME_VALIDITY_FLAG | Gets the current time and verifies that it is within the time between the CRL's ThisUpdate and NextUpdate.
CERT_STORE_BASE_CRL_FLAG | Gets a base CRL.
CERT_STORE_DELTA_CRL_FLAG | Gets a delta CRL.

If an enabled verification check succeeds, its flag is set to zero. If an enabled verification check fails, its flag remains set upon return. If pIssuerContext is NULL, then an enabled CERT_STORE_SIGNATURE_FLAG always fails and the CERT_STORE_NO_ISSUER_FLAG is also set. For more details, see the Remarks section later in this topic.

If only one of CERT_STORE_BASE_CRL_FLAG or CERT_STORE_DELTA_CRL_FLAG is set, this function returns either a base or delta CRL and the appropriate base or delta flag will be cleared on return. If both flags are set, only one of the flags will be cleared.

For a verification check failure, a pointer to the first or next CRL_CONTEXT is still returned and GetLastError is not updated.

Note The CERT_STORE_BASE_CRL_FLAG and CERT_STORE_DELTA_CRL_FLAG values for pdwFlags can only be used with Windows Whistler and later.

Return Values

If the function succeeds, the return value is a pointer to a read-only CRL_CONTEXT.

If the function fails and the first or next CRL is not found, the return value is NULL.

The returned CRL_CONTEXT must be freed by calling CertFreeCRLContext. However, when the returned CRL_CONTEXT is supplied for pPrevCrlContext on a subsequent call, the function frees it.

For extended error information, call GetLastError. Some possible error codes follow.

Value | Meaning
E_INVALIDARG | The handle in the hCertStore parameter is not the same as that in the CRL context pointed to by the pPrevCrlContext parameter, or an unsupported flag was set in pdwFlags.
CRYPT_E_NOT_FOUND | Either no CRLs existed in the store for the issuer, or the function reached the end of the store's list.

Remarks

CertDuplicateCRLContext can be called to make a duplicate CRL.

The hexadecimal values of the flags can be combined using a bitwise-OR operation in order to enable both verifications. For example, to enable both verifications, the DWORD value pointed to by pdwFlags is set to value CERT_STORE_SIGNATURE_FLAG | CERT_STORE_TIME_VALIDITY_FLAG. If the CERT_STORE_SIGNATURE_FLAG verification succeeded, but CERT_STORE_TIME_VALIDITY_FLAG verification failed, the DWORD value pointed to by pdwFlags is set to CERT_STORE_TIME_VALIDITY_FLAG when the function returns.

Examples

See Example C Program: Listing the Certificates in a Store. In that example, change all references to "certificate" to "CRL."

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Revocation List Functions, CertCreateCertificateContext, CertDuplicateCRLContext, CertFreeCRLContext, CertGetCRLContextProperty, CRL_CONTEXT


CertSerializeCRLStoreElement

The CertSerializeCRLStoreElement function serializes an encoded certificate revocation list (CRL) context and the encoded representation of its properties. The result can be persisted to storage so that the CRL and properties can be retrieved at a later time.

BOOL WINAPI CertSerializeCRLStoreElement(
  PCCRL_CONTEXT pCrlContext,
  DWORD dwFlags,
  BYTE *pbElement,
  DWORD *pcbElement
);

Parameters

pCrlContext
[in] Pointer to the CRL_CONTEXT structure being serialized.
dwFlags
[in] Reserved for future use and must be zero.
pbElement
[out] Pointer to a buffer to receive the serialized output, including the encoded CRL, and possibly its properties.

This parameter can be NULL to set the size of this information for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.

pcbElement
[in/out] Pointer to a DWORD value specifying the size, in bytes, of the buffer pointed to by the pbElement parameter. When the function returns, the DWORD value contains the number of bytes stored in the buffer.

Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError.

Examples

See Example C Program: Serializing Certificates and Adding Serialized Elements to Stores.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Revocation List Functions, CertAddSerializedElementToStore


Certificate Trust List Functions

These Win32 functions manage the storage and retrieval of certificate trust lists (CTL).

Function | Description
CertAddCTLContextToStore | Adds a CTL context to the certificate store.
CertAddCTLLinkToStore | Adds a link in a store to a CRL context in a different store.
CertAddEncodedCTLToStore | Converts the encoded CTL to a CTL context and then adds the context to the certificate store.
CertCreateCTLContext | Creates a CTL context from an encoded certificate trust list. The created context is not put in a certificate store.
CertDeleteCTLFromStore | Deletes a CTL from the certificate store.
CertDuplicateCTLContext | Duplicates a CTL context by incrementing the reference count.
CertEnumCTLsInStore | Enumerates the CTL contexts in the certificate store.
CertFindCTLInStore | Finds the first, or next, CTL context in the certificate store that matches a specific criteria.
CertFreeCTLContext | Frees a CTL context.
CertSerializeCTLStoreElement | Serializes the CTL context's encoded CTL and its properties.


CertAddCTLContextToStore

The CertAddCTLContextToStore function adds a certificate trust list (CTL) context to a certificate store.

BOOL WINAPI CertAddCTLContextToStore(
  HCERTSTORE hCertStore,
  PCCTL_CONTEXT pCtlContext,
  DWORD dwAddDisposition,
  PCCTL_CONTEXT *ppStoreContext
);

Parameters

hCertStore
[in] Handle of a certificate store.
pCtlContext
[in] Pointer to the CTL_CONTEXT structure to be added to the store.
dwAddDisposition
[in] Specifies the action to take if a matching CTL or a link to a matching CTL already exists in the store. Currently defined disposition values and their uses are as follows.
Value | Meaning
CERT_STORE_ADD_ALWAYS | Makes no check for an existing matching CTL or link to a matching CTL. A new CTL is always added to the store. This can lead to duplicates in a store.
CERT_STORE_ADD_NEW | If a matching CTL or a link to a matching CTL exists, the operation fails. GetLastError returns the CRYPT_E_EXISTS code.
CERT_STORE_ADD_NEWER If a matching CTL or a link to a matching CTL exists, the ThisUpdate times on the CTLs are compared. If the existing CTL has a ThisUpdate time less than the ThisUpdate time on the new CTL, the old CTL or link is replaced just as with CERT_STORE_ADD_REPLACE_EXISTING. If the existing CTL has a ThisUpdate time greater than or equal to the ThisUpdate time on the CTL to be added, the function fails with GetLastError returning the CRYPT_E_EXISTS code.

If a matching CTL or a link to a matching CTL is not found in the store, a new CTL is added to the store.
CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES | The action is the same as for CERT_STORE_ADD_NEWER, except that if an older CTL is replaced, the properties of the older CTL are incorporated into the replacement CTL.
CERT_STORE_ADD_REPLACE_EXISTING | If a matching CTL or a link to a matching CTL exists, the existing CTL or link is deleted and a new CTL is created and added to the store. If a matching CTL or a link to a matching CTL does not exist, one is added.
CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES | If a matching CTL exists in the store, that existing context is deleted before creating and adding the new context. The added context inherits properties from the existing CTL.
CERT_STORE_ADD_USE_EXISTING If a matching CTL or a link to a matching CTL exists, that existing CTL is used and properties from the new CTL are added. The function does not fail, but no new CTL is added. If ppCertContext is not NULL, the existing context is duplicated.

If a matching CTL or a link to a matching CTL does not exist, a new CTL is added.

ppStoreContext
[out/optional] Pointer to a pointer to the decoded CTL context. This optional parameter can be NULL indicating that the calling application does not require a copy of the added or existing CTL. If a copy is made, that context must be freed using CertFreeCTLContext.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError. Some possible error codes follow.

Value | Meaning
CRYPT_E_EXISTS | This error is returned if CERT_STORE_ADD_NEW is set and the CTL exists in the store or if CERT_STORE_ADD_NEWER is set and a CTL exists in the store with a ThisUpdate date greater than or equal to the ThisUpdate date on the CTL to be added.
E_INVALIDARG | An invalid add disposition was specified by the dwAddDisposition parameter.

Errors from the called functions CertAddEncodedCRLToStore and CertSetCRLContextProperty can be propagated to this function.

Remarks

The CTL context is not duplicated using CertDuplicateCTLContext. Instead, a new copy is created and added to the store. In addition to the encoded CTL, the context's properties are copied.

Examples

See Example C Program: Certificate Store Operations. In that example, change all references to "certificate" to "CRL."

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Trust List Functions, CertAddEncodedCTLToStore, CertSetCTLContextProperty


CertAddCTLLinkToStore

The CertAddCTLLinkToStore function adds a link in a store to a certificate trust list (CTL) context in a different store. Instead of creating and adding a duplicate of a CTL context, this function adds a link to the original CTL context.

BOOL WINAPI CertAddCTLLinkToStore(
  HCERTSTORE hCertStore,
  PCCTL_CONTEXT pCtlContext,
  DWORD dwAddDisposition,
  PCCTL_CONTEXT *ppStoreContext
);

Parameters

hCertStore
[in] Handle of the certificate store where the link is to be added.
pCtlContext
[in] Pointer to the CTL_CONTEXT structure to be linked.
dwAddDisposition
[in] Specifies the action to take if a matching CTL or a link to a matching CTL already exists in the store. Currently defined disposition values and their uses are as follows.
Value | Meaning
CERT_STORE_ADD_ALWAYS | Makes no check for an existing matching CTL or link to a matching CTL. A new CTL is always added to the store. This can lead to duplicates in a store.
CERT_STORE_ADD_NEW | If a matching CTL or a link to a matching CTL exists, the operation fails. GetLastError returns the CRYPT_E_EXISTS code.
CERT_STORE_ADD_NEWER If a matching CTL or a link to a matching CTL exists, the ThisUpdate times on the CTLs are compared. If the existing CTL has a ThisUpdate time less than the ThisUpdate time on the new CTL, the old CTL or link is replaced just as with CERT_STORE_ADD_REPLACE_EXISTING. If the existing CTL has a ThisUpdate time greater than or equal to the ThisUpdate time on the CTL to be added, the function fails with GetLastError returning the CRYPT_E_EXISTS code.

If a matching CTL or a link to a matching CTL is not found in the store, a new CTL is added to the store.
CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES | The action is the same as for CERT_STORE_ADD_NEWER, except that if an older CTL is replaced, the properties of the older CTL are incorporated into the replacement CTL.
CERT_STORE_ADD_REPLACE_EXISTING | If a matching CTL or a link to a matching CTL exists, the existing CTL or link is deleted and a new CTL is created and added to the store. If a matching CTL or a link to a matching CTL does not exist, one is added.
CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES | If a matching CTL exists in the store, that existing context is deleted before creating and adding the new context. The added context inherits properties from the existing CTL.
CERT_STORE_ADD_USE_EXISTING If a matching CTL or a link to a matching CTL exists, that existing CTL is used and properties from the new CTL are added. The function does not fail, but no new CTL is added. If ppCertContext is not NULL, the existing context is duplicated.

If a matching CTL or a link to a matching CTL does not exist, a new CTL is added.

ppStoreContext
[out/optional] Pointer to a pointer to a copy of the link created. ppStoreContext can be NULL to indicate that a copy of the link is not needed. If a copy of the link is created, that copy must be freed using CertFreeCTLContext.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError. Some possible error codes follow.

Value | Meaning
CRYPT_E_EXISTS | For a dwAddDisposition of CERT_STORE_ADD_NEW, the CTL already exists in the store.
E_INVALIDARG | Invalid add disposition specified by the dwAddDisposition parameter.

Remarks

Because the link provides access to the original CTL context, setting an extended property in the linked CTL context changes that extended property in the original CTL's location and in any other links to that CTL.

Links cannot be added to a store that is opened as a collection. Stores opened as collections include all stores opened with CertOpenSystemStore or CertOpenStore using CERT_STORE_PROV_SYSTEM or CERT_STORE_PROV_COLLECTION. Also see CertAddStoreToCollection.

When links are used and CertCloseStore is called with CERT_CLOSE_STORE_FORCE_FLAG, the store using links must be closed before the store containing the original contexts is closed. If CERT_CLOSE_STORE_FORCE_FLAG is not used, the two stores can be closed in either order.

Examples

See Example C Program: Certificate Store Operations. In that example, change all references to "certificate" to "CRL."

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Trust List Functions, CertOpenSystemStore, CertAddStoreToCollection, CertAddCRLLinkToStore, CertAddCertificateLinkToStore, CertFreeCTLContext


CertAddEncodedCTLToStore

The CertAddEncodedCTLToStore function creates a certificate trust list (CTL) context from an encoded CTL and adds it to the certificate store. The function makes a copy of the CTL context before adding it to the store.

BOOL WINAPI CertAddEncodedCTLToStore(
  HCERTSTORE hCertStore,
  DWORD dwMsgAndCertEncodingType,
  const BYTE *pbCtlEncoded,
  DWORD cbCtlEncoded,
  DWORD dwAddDisposition,
  PCCTL_CONTEXT *ppCtlContext
);

Parameters

hCertStore
[in] Handle of a certificate store.
dwMsgAndCertEncodingType
[in] Specifies the type of encoding used. Both the certificate and message encoding types must be specified by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pbCtlEncoded
[in] Pointer to a buffer containing the encoded CTL to be added to the certificate store.
cbCtlEncoded
[in] Size, in bytes, of the pbCtlEncoded buffer.
dwAddDisposition
[in] Specifies the action to take if a matching CTL or a link to a matching CTL already exists in the store. Currently defined disposition values and their uses are as follows
Value | Meaning
CERT_STORE_ADD_ALWAYS | Makes no check for an existing matching CTL or link to a matching CTL. A new CTL is always added to the store. This can lead to duplicates in a store.
CERT_STORE_ADD_NEW | If a matching CTL or a link to a matching CTL exists, the operation fails. GetLastError returns the CRYPT_E_EXISTS code.
CERT_STORE_ADD_NEWER If a matching CTL or a link to a matching CTL exists, the ThisUpdate times on the CTLs are compared. If the existing CTL has a ThisUpdate time less than the ThisUpdate time on the new CTL, the old CTL or link is replaced just as with CERT_STORE_ADD_REPLACE_EXISTING. If the existing CTL has a ThisUpdate time greater than or equal to the ThisUpdate time on the CTL to be added, the function fails with GetLastError returning the CRYPT_E_EXISTS code.

If a matching CTL or a link to a matching CTL is not found in the store, a new CTL is added to the store.
CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES | The action is the same as for CERT_STORE_ADD_NEWER, except that if an older CTL is replaced, the properties of the older CTL are incorporated into the replacement CTL.
CERT_STORE_ADD_REPLACE_EXISTING | If a matching CTL or a link to a matching CTL exists, the existing CTL or link is deleted and a new CTL is created and added to the store. If a matching CTL or a link to a matching CTL does not exist, one is added.
CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES | If a matching CTL exists in the store, that existing context is deleted before creating and adding the new context. The added context inherits properties from the existing CTL.
CERT_STORE_ADD_USE_EXISTING If a matching CTL or a link to a matching CTL exists, that existing CTL is used and properties from the new CTL are added. The function does not fail, but no new CTL is added. If ppCertContext is not NULL, the existing context is duplicated.

If a matching CTL or a link to a matching CTL does not exist, a new CTL is added.

ppCtlContext
[out/optional] Pointer to a pointer to the decoded CTL_CONTEXT structure. Can be NULL indicating that the calling application does not require a copy of the added or existing CTL. If a copy is made, it must be freed by using CertFreeCTLContext.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError. Some possible error codes follow.

Value | Meaning
CRYPT_E_EXISTS | This error code is returned if CERT_STORE_ADD_NEW is set and the CTL already exists in the store, or if CERT_STORE_ADD_NEWER is set and there is a CTL in the store with a ThisUpdate time greater than or equal to the ThisUpdate time on the CTL to be added.
E_INVALIDARG | An invalid disposition value was specified in the dwAddDisposition parameter, or an invalid encoding type was specified. Currently, only the encoding types X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are supported.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN1 Encoding/Decoding Error Codes.

Examples

See Example C Program: Serializing Certificates and Adding Serialized Elements to Stores. In that example, change all references to "certificate" to "CTL."

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Trust List Functions, CertAddCTLContextToStore, CertFreeCTLContext


CertCreateCTLContext

The CertCreateCTLContext function creates a certificate trust list (CTL) context from an encoded CTL. The created context is not persisted to a certificate store. The function makes a copy of the encoded CTL within the created context.

PCCTL_CONTEXT WINAPI CertCreateCTLContext(
  DWORD dwMsgAndCertEncodingType,
  const BYTE *pbCtlEncoded,
  DWORD cbCtlEncoded
);

Parameters

dwMsgAndCertEncodingType
[in] Specifies the type of encoding used. Both the certificate and message encoding types must be specified by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pbCtlEncoded
[in] Pointer to a buffer containing the encoded CTL from which the context is to be created.
cbCtlEncoded
[in] Size, in bytes, of the pbCtlEncoded buffer.

Return Values

If the function succeeds, the return value is a pointer to a read-only CTL_CONTEXT.

If the function fails and is unable to decode and create the CTL_CONTEXT, the return value is NULL. For extended error information, call GetLastError. Some possible error codes follow.

Value | Meaning
E_INVALIDARG | Invalid certificate encoding type. Only PKCS_7_ASN_ENCODING and X509_ASN_ENCODING are supported.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN1 Encoding/Decoding Error Codes.

Remarks

The CTL_CONTEXT must be freed by calling CertFreeCTLContext. CertDuplicateCTLContext can be called to make a duplicate. CertSetCTLContextProperty and CertGetCTLContextProperty can be called to store and read properties for the CTL.

Examples

See Example C Program: Certificate Store Operations. In that example, change all references to "certificate" to "CTL."

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Trust List Functions, CertCreateCertificateContext, CertCreateCRLContext, CertDuplicateCTLContext, CertFreeCTLContext, CertGetCTLContextProperty, CertSetCTLContextProperty, CTL_CONTEXT


CertDeleteCTLFromStore

The CertDeleteCTLFromStore function deletes the specified certificate trust list (CTL) context from a certificate store.

BOOL WINAPI CertDeleteCTLFromStore(
  PCCTL_CONTEXT pCtlContext
);

Parameters

pCtlContext
[in] Pointer to the CTL_CONTEXT structure to be deleted.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError. One possible error code is the following.

Value | Meaning
E_ACCESSDENIED | The store was opened read-only, and a delete operation is not allowed.

Remarks

All subsequent get or find operations for the CTL in this store fail. However, memory allocated for the CTL is not freed until all duplicated contexts have also been freed.

The pCtlContext parameter is always freed by this function by using CertFreeCTLContext, even for an error.

Examples

See Example C Program: Deleting Certificates from a Certificate Store. In that example, change all references to "certificate" to "CTL."

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Trust List Functions, CertFreeCTLContext


CertDuplicateCTLContext

The CertDuplicateCTLContext function duplicates a certificate trust list (CTL) context by incrementing its reference count.

PCCTL_CONTEXT WINAPI CertDuplicateCTLContext(
  PCCTL_CONTEXT pCtlContext
);

Parameters

pCtlContext
[in] Pointer to the CTL_CONTEXT structure for which the reference count is being incremented.

Return Values

Currently, a copy is not made of the context, and the returned pointer to CTL_CONTEXT is the same as pointer input. If the pointer passed into this function is NULL, NULL is returned.

Examples

See Example C Program: Deleting Certificates from a Certificate Store. In that example, change all references to "certificate" to "CTL."

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Trust List Functions


CertEnumCTLsInStore

The CertEnumCTLsInStore function retrieves the first or next certificate trust list (CTL) context in a certificate store. Used in a loop, this function can retrieve in sequence all CTL contexts in a certificate store.

PCCTL_CONTEXT WINAPI CertEnumCTLsInStore(
  HCERTSTORE hCertStore,
  PCCTL_CONTEXT pPrevCtlContext
);

Parameters

hCertStore
[in] Handle of a certificate store.
pPrevCtlContext
[in] Pointer to the previous CTL_CONTEXT structure found. It must be NULL to get the first CTL in the store. Successive CTLs are enumerated by setting pPrevCtlContext to the pointer returned by a previous call. The enumeration skips any CTLs previously deleted by CertDeleteCTLFromStore.

Return Values

If the function succeeds, the return value is a pointer to a read-only CTL_CONTEXT.

If the function fails and a CTL is not found, the return value is NULL. For extended error information, call GetLastError. Some possible error codes follow.

Value | Meaning
CRYPT_E_NOT_FOUND | Either no CTLs exist in the store, or the function reached the end of the store's list.
E_INVALIDARG | The handle in the hCertStore parameter is not the same as that in the CTL context pointed to by the pPrevCtlContext parameter.

Remarks

The returned pointer is freed when passed as the pPrevCtlContext on a subsequent call. Otherwise, the pointer must be explicitly freed by calling CertFreeCTLContext. A pPrevCtlContext that is not NULL is always freed by this function (through a call to CertFreeCTLContext), even for an error.

A duplicate can be made by calling CertDuplicateCTLContext.

Examples

See Example C Program: Deleting Certificates from a Certificate Store. In that example, change all references to "certificate" to "CTL."

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Trust List Functions, CertDeleteCTLFromStore, CertDuplicateCTLContext, CertFindCTLInStore, CertFreeCTLContext, CTL_CONTEXT


CertFindCTLInStore

The CertFindCTLInStore function finds the first or next certificate trust list (CTL) context that matches search criteria established by the dwFindType and its associated pvFindPara. This function can be used in a loop to find all of the CTL contexts in a certificate store that match the specified find criteria.

PCCTL_CONTEXT WINAPI CertFindCTLInStore(
  HCERTSTORE hCertStore,
  DWORD dwMsgAndCertEncodingType,
  DWORD dwFindFlags,
  DWORD dwFindType,
  const void *pvFindPara,
  PCCTL_CONTEXT pPrevCtlContext
);

Parameters

hCertStore
[in] Handle of the certificate store to be searched.
dwMsgAndCertEncodingType
[in] Specifies the type of encoding used on the CTL. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

This parameter is used only when the dwFindType parameter is set to CTL_FIND_USAGE.

dwFindFlags
[in] Can be set when dwFindType is set to CTL_FIND_USAGE. For details, see the comments under CTL_FIND_USAGE, following.
dwFindType
[in] Specifies the search type. The value of dwFindType determines the data type, contents, and use of the pvFindPara parameter. Currently defined values and their pvFindPara requirements are as follows.
Value | pvFindPara type | Meaning
CTL_FIND_ANY | NULL | Any CTL is a match.
CTL_FIND_SHA1_HASH | CRYPT_HASH_BLOB structure | A CTL with a hash matching the hash in the CRYPT_HASH_BLOB structure is found.
CTL_FIND_MD5_HASH | CRYPT_HASH_BLOB structure | A CTL with a hash matching the hash in the CRYPT_HASH_BLOB structure is found.
CTL_FIND_USAGE CTL_FIND_USAGE_PARA structure Any CTL is found that has a usage identifier, list identifier, or signer matching the usage identifier, list identifier, or signer in the CTL_FIND_USAGE_PARA structure.

If the cUsageIdentifier member of SubjectUsage size, any CTL is a match.

If the cbData member of ListIdentifier member is zero, any list identifier is a match. If the cbData member of ListIdentifier is CTL_FIND_NO_LIST_ID_CBDATA, only a CTL without a list identifier is a match.

If the pSigner member in the CTL_FIND_USAGE_PARA structure is NULL, any CTL signer is a match, and only the Issuer and SerialNumber members in the pSigner CERT_INFO structure are used. If pSigner is CTL_FIND_NO_SIGNER_PTR, only a CTL without a signer is a match.
CTL_FIND_SAME_USAGE_FLAG | CTL_FIND_USAGE_PARA structure | Only CTLs with exactly the same usage identifiers are matched. CTLs having additional usage identifiers are not matched. For example, if only "1.2.3" is specified in the CTL_FIND_USAGE_PARA structure, then for a match, the CTL must only contain "1.2.3" and no additional usage identifiers.
CTL_FIND_EXISTING | Pointer to a CTL_CONTEXT | Searches for the next CRL that is an exact match of the CTL_CONTEXT.
CTL_FIND_SUBJECT | CTL_FIND_SUBJECT_PARA structure | A CTL having the specified subject is found. CertFindSubjectInCTL can be called to get a pointer to the subject's entry in the CTL. The pUsagePara member in CTL_FIND_SUBJECT_PARA can optionally be set to enable the matching described preceding under CTL_FIND_USAGE.

pvFindPara
[in] Pointer to the search value associated with the dwFindType parameter.
pPrevCtlContext
[in] Pointer to the last CTL_CONTEXT returned by this function. It must be NULL to get the first CTL in the store. Successive CTLs are retrieved by setting pPrevCtlContext to the pointer to the CTL_CONTEXT returned by a previous function call. Any certificates that do not meet the search criteria or that have been previously deleted by CertDeleteCTLFromStore are skipped.

Return Values

If the function succeeds, the return value is a pointer to a read-only CTL context.

For extended error information, call GetLastError. Some possible error codes follow.

Value | Meaning
CRYPT_E_NOT_FOUND | Either no CTLs were found in the store, no CTL was found matching the search criteria, or the function reached the end of the store's list.
E_INVALIDARG | The handle in the hCertStore parameter is not the same as that in the CTL context pointed to by the pPrevCtlContext parameter, or an invalid value was specified in the dwFindType parameter.

Remarks

A returned pointer is freed when passed as the pPrevCtlContext on a subsequent call to the function. Otherwise, the pointer must be freed by calling CertFreeCTLContext. A non-NULL pPrevCtlContext passed to the function is always freed with a call to CertFreeCTLContext, even if the function generates an error.

CertDuplicateCTLContext can be called to make a duplicate of the returned context. The returned CTL context can be added to a different certificate store using CertAddCTLContextToStore, or a link to that CTL context can be added to a noncollection store using CertAddCTLLinkToStore. If a CTL matching the search criteria is not found, NULL is returned.

Examples

See Example C Program: Certificate Store Operations. In that example, change all references to "certificate" to "CRL."

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Trust List Functions, CertAddCTLContextToStore, CertAddCTLLinkToStore, CertDeleteCTLFromStore, CertDuplicateCTLContext, CertEnumCTLsInStore, CertFindSubjectInCTL, CertFreeCTLContext, CTL_CONTEXT, CTL_FIND_USAGE_PARA


CertFreeCTLContext

The CertFreeCTLContext function frees a certificate trust list (CTL) context by decrementing its reference count. When the reference count goes to zero, CertFreeCTLContext frees the memory occupied by a CTL context. Each context obtained by a get, find, enumerate, duplicate, or create operation must be freed using the appropriate free operation.

BOOL WINAPI CertFreeCTLContext(
  PCCTL_CONTEXT pCtlContext
);

Parameters

pCtlContext
[in] Pointer to the CTL_CONTEXT to be freed.

Return Values

The function always returns TRUE.

Examples

See Example C Program: Certificate Store Operations.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Trust List Functions, CertFreeCRLContext, CTL_CONTEXT


CertSerializeCTLStoreElement

The CertSerializeCTLStoreElement function serializes an encoded certificate trust list (CTL) context and the encoded representation of its properties. The result can be persisted to storage so that the CTL and properties can be retrieved later.

BOOL WINAPI CertSerializeCTLStoreElement(
  PCCTL_CONTEXT pCtlContext,
  DWORD dwFlags,
  BYTE *pbElement,
  DWORD *pcbElement
);

Parameters

pCtlContext
[in] Pointer to the CTL_CONTEXT structure being serialized.
dwFlags
[in] Reserved for future use and must be zero.
pbElement
[out] Pointer to a buffer that receives the serialized output, including the encoded CTL and, possibly, its properties.

This parameter can be NULL to set the size of this information for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.

pcbElement
[in/out] Pointer to a DWORD value that specifies the size, in bytes, of the buffer that is pointed to by the pbElement parameter. When the function returns the DWORD value contains the number of bytes stored in the buffer.

Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError.

Examples

See Example C Program: Serializing Certificates and Adding Serialized Elements to Stores.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Trust List Functions, CertAddSerializedElementToStore


Extended Property Functions

The following functions work with extended properties of certificates, CRLs, and CTLs.

Function | Description
CertEnumCertificateContextProperties | Enumerates the properties for the specified certificate context.
CertEnumCRLContextProperties | Enumerates the properties for the specified CRL context.
CertEnumCTLContextProperties | Enumerates the properties for the specified CTL context.
CertGetCertificateContextProperty | Retrieves certificate properties.
CertGetCRLContextProperty | Retrieves CRL properties.
CertGetCTLContextProperty | Retrieves CTL properties.
CertSetCertificateContextProperty | Sets certificate properties.
CertSetCRLContextProperty | Sets CRL properties.
CertSetCTLContextProperty | Sets CTL properties.


CertEnumCertificateContextProperties

The CertEnumCertificateContextProperties function retrieves the first or next extended property associated with a certificate context. Used in a loop, this function can retrieve in sequence all of the extended properties associated with a certificate context.

DWORD WINAPI CertEnumCertificateContextProperties(
  PCCERT_CONTEXT pCertContext,
  DWORD dwPropId
);

Parameters

pCertContext
[in] Pointer to the CERT_CONTEXT structure of the certificate containing the properties to be enumerated.
dwPropId
[in] Property number of the last property enumerated. To get the first property, dwPropId is zero. To retrieve subsequent properties, dwPropId is set to the property number returned by the last call to the function. To enumerate all the properties, function calls continue until the function returns zero.

Applications can call CertGetCertificateContextProperty with the dwPropId returned by this function to retrieve that property's data.

Return Values

The return value is a DWORD value that identifies a certificate context's property. The DWORD value returned by one call of the function can be supplied as the dwPropId in a subsequent call to the function. If there are no more properties to be enumerated or if the function fails, zero is returned.

Remarks

CERT_KEY_PROV_HANDLE_PROP_ID and CERT_KEY_SPEC_PROP_ID properties are stored as members of the CERT_KEY_CONTEXT_PROP_ID property. They are not enumerated individually.

Examples

See Example C Program: Listing the Certificates in a Store.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Extended Property Functions, CertGetCertificateContextProperty


CertEnumCRLContextProperties

The CertEnumCRLContextProperties function retrieves the first or next extended property associated with a certificate revocation list (CRL) context. Used in a loop, this function can retrieve in sequence all extended properties associated with a CRL context.

DWORD WINAPI CertEnumCRLContextProperties(
  PCCRL_CONTEXT pCrlContext,
  DWORD dwPropId
);

Parameters

pCrlContext
[in] Pointer to a CRL_CONTEXT structure.
dwPropId
[in] Property number of the last property enumerated. To get the first property, dwPropId is zero. To retrieve subsequent properties, dwPropId is set to the property number returned by the last call to the function. To enumerate all the properties, function calls continue until the function returns zero.

Applications can call CertGetCRLContextProperty with the dwPropId returned by this function to retrieve that property's data.

Return Values

The return value is a DWORD value that identifies a CRL context's property. The DWORD value returned by one call of the function can be supplied as the dwPropId in a subsequent call to the function. If there are no more properties to be enumerated or if the function fails, zero is returned.

Examples

See Example C Program: Certificate Store Operations.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Extended Property Functions, CertGetCRLContextProperty


CertEnumCTLContextProperties

The CertEnumCTLContextProperties function retrieves the first or next extended property associated with a certificate trust list (CTL) context. Used in a loop, this function can retrieve in sequence all extended properties associated with a CTL context.

DWORD WINAPI CertEnumCTLContextProperties(
  PCCTL_CONTEXT pCtlContext,
  DWORD dwPropId
);

Parameters

pCtlContext
[in] Pointer to a CTL_CONTEXT structure.
dwPropId
[in] Property number of the last property enumerated. To get the first property, dwPropId is zero. To retrieve subsequent properties, dwPropId is set to the property number returned by the last call to the function. To enumerate all the properties, function calls continue until the function returns zero.

Applications can call CertGetCTLContextProperty with the dwPropId returned by this function to retrieved that property's data.

Return Values

The return value is a DWORD value that identifies a CTL context's property. The DWORD value returned by one call of the function can be supplied as the dwPropId in a subsequent call to the function. If there are no more properties to be enumerated or if the function fails, zero is returned.

Examples

See Example C Program: Certificate Store Operations.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Extended Property Functions, CertGetCTLContextProperty


CertGetCertificateContextProperty

[This is preliminary documentation and subject to change.]

The CertGetCertificateContextProperty function retrieves the information contained in an extended property of a certificate context.

BOOL WINAPI CertGetCertificateContextProperty(
  PCCERT_CONTEXT pCertContext,
  DWORD dwPropId,
  void *pvData,
  DWORD *pcbData
);

Parameters

pCertContext
[in] Pointer to the CERT_CONTEXT of the certificate containing the property to be retrieved.
dwPropId
[in] Identifies the property to be retrieved. Currently defined identifiers and the data type to be returned in pvData are listed in the following table.
Property identifier | pvData type | Meaning
CERT_ACCESS_STATE_PROP_ID | DWORD | Returns a DWORD value indicating whether write operations to the certificate are persisted. The DWORD value is not set if the certificate is in a memory store or in a registry-based store that is opened as read-only.
CERT_ARCHIVED_PROP_ID | NULL | Indicates the certificate is skipped during enumerations. A certificate with this property set is found with explicit search operations, such as those used to find a certificate with a specific hash or a serial number. No data in pvData is associated with this property.
CERT_AUTO_ENROLL_PROP_ID | Array of BYTEs | Returns a NULL-terminated Unicode string naming the certificate type for which the certificate has been auto enrolled.
CERT_CTL_USAGE_PROP_ID | Array of BYTEs | Returns an array of bytes containing an ASN.1 encoded CTL_USAGE structure.
CERT_DESCRIPTION_PROP_ID | Array of BYTEs | Returns the property displayed by the certificate UI. This property allows the user to describe the certificate's use.
CERT_ENHKEY_USAGE_PROP_ID | Array of BYTEs | Returns an array of bytes containing an ASN.1 encoded CERT_ENHKEY_USAGE structure. This structure contains an array of Enhanced Key Usage object identifiers (OIDs), each specifying a valid use of the certificate.
CERT_FRIENDLY_NAME_PROP_ID | Array of BYTEs | Returns a NULL-terminated Unicode character string specifying the friendly name for the certificate.
CERT_HASH_PROP_ID | Array of BYTEs | Returns the SHA1 hash. If the hash does not exist, it is computed using CryptHashCertificate.
CERT_KEY_CONTEXT_PROP_ID CERT_KEY
_CONTEXT 		Returns a CERT_KEY_CONTEXT structure.
CERT_KEY_IDENTIFIER_PROP_ID | Array of BYTEs | If nonexistent, searches for the szOID_SUBJECT_KEY_IDENTIFIER extension. If that fails, a SHA1 hash is done on the certificate's SubjectPublicKeyInfo to produce the identifier values.
CERT_KEY_PROV_HANDLE_PROP_ID | HCRYPTPROV | Returns the provider handle obtained from CERT_KEY_CONTEXT_PROP_ID.
CERT_KEY_PROV_INFO_PROP_ID CRYPT_KEY
_PROV_INFO 		Returns a pointer to CRYPT_KEY_PROV_INFO.
CERT_KEY_SPEC_PROP_ID | DWORD | Returns a DWORD value specifying the private key obtained from CERT_KEY_CONTEXT_PROP_ID if it exists. Otherwise, if CERT_KEY_PROV_INFO_PROP_ID exists, it is the source of the dwKeySpec.
CERT_MD5_HASH_PROP_ID | Array of BYTEs | Returns the MD5 hash. If the hash does not exist, it is computed using CryptHashCertificate.
CERT_NEXT_UPDATE_LOCATION_PROP_ID Array of BYTEs Returns the ASN.1 encoded CERT_ALT_NAME_INFO structure.

CERT_NEXT_UPDATE_LOCATION_PROP_ID is currently used only with CTLs.
CERT_PUBKEY_ALG_PROP_ID | Array of BYTES | Returns the ASN.1 encoded PublicKey Algorithm Parameters. This property will only be set for public keys supporting algorithm parameter inheritance and when the parameters have been omitted for the encoded and signed certificate.
CERT_PVK_FILE_PROP_ID | Array of BYTEs | Returns a NULL-terminated Unicode, wide character string specifying the file name containing the private key associated with the certificate's public key.
CERT_SHA1_HASH_PROP_ID | Array of BYTEs | Returns the SHA1 hash. If the hash does not exist, it is computed using CryptHashCertificate.
CERT_SIGNATURE_HASH_PROP_ID | Array of BYTEs | Returns the signature hash. If the hash does not exist, it is computed with CryptHashToBeSigned. The length of the hash is 20 bytes for SHA and 16 for MD5.
CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID | CRYPT_DATA_BLOB | MD5 hash of the public key associated with the private key used to sign this certificate.
CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID | CRYPT_DATA_BLOB | MD5 hash of this certificate's public key
CERT_ENROLLMENT_PROP_ID | CRYPT_DATA_BLOB | Enrollment information of the pending request containing RequestID, CADNSName, CAName, and FriendlyName. The data format is defined as: the first 4 bytes, pending request ID; next 4 bytes, CADNSName size in characters including null-terminator followed by CADNSName string with null-terminator; next 4 bytes CAName size in characters including null-terminator followed by CAName string with null-terminator; next 4 bytes, FriendlyName size in characters including null-terminator followed by FriendlyName string with null-terminator.
CERT_CROSS_CERT_DIST_POINTS_PROP_ID | CRYPT_DATA_BLOB | Location of the cross certificates. Currently, this value is only applicable to certificates and not to CRLs or CTLs.The CRYPT_DATA_BLOB structure contains an ASN.1 encoded CROSS_CERT_DIST_POINTS_INFO structure encoded using CryptEncodeObject with a X509_CROSS_CERT_DIST_POINTS value for the lpszStuctType parameter.
CERT_DATE_STAMP_PROP_ID | FILETIME | Time when the certificate was added to the store.

For all other property identifiers, pvData points to an array of bytes and not a CRYPT_DATA_BLOB as pointed to by the pvData parameter in CertSetCertificateContextProperty.

For more details about each property identifier, see the documentation on the dwPropId parameter in CertSetCertificateContextProperty.

Note The CERT_CROSS_CERT_DIST_POINTS_PROP_ID, CERT_ENROLLMENT_PROP_ID, and CERT_DATE_STAMP_PROP_ID values for dwPropId can only be used with Windows Whistler and later.

pvData
[out] Pointer to a buffer to receive the data as determined by dwPropId. Structures pointed to by members of a structure returned are also returned following the base structure. Therefore, the size contained in pcbData often exceed the size of the base structure.

This parameter can be NULL to set the size of the information for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.

pcbData
[in/out] Pointer to a DWORD value specifying the size, in bytes, of the buffer pointed to by the pvData parameter. When the function returns, the DWORD value contains the number of bytes to be stored in the buffer.

Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError. Some possible error codes follow.

Value | Meaning
CRYPT_E_NOT_FOUND | The certificate does not have the specified property.
ERROR_MORE_DATA | If the buffer specified by the pvData parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code and stores the required buffer size, in bytes, in the variable pointed to by pcbData.

Errors from the called function CryptHashCertificate can be propagated to this function.

Examples

See Example C Program: Getting and Setting Certificate Properties and Example C Program: Listing the Certificates in a Store.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Extended Property Functions, CERT_KEY_CONTEXT, CertCreateCertificateContext, CertSetCertificateContextProperty, CryptHashCertificate, CryptHashToBeSigned


CertGetCRLContextProperty

The CertGetCRLContextProperty function gets an extended property for the specified certificate revocation list (CRL) context.

BOOL WINAPI CertGetCRLContextProperty(
  PCCRL_CONTEXT pCrlContext,
  DWORD dwPropId,
  void *pvData,
  DWORD *pcbData
);

Parameters

pCrlContext
[in] Pointer to the CRL_CONTEXT structure.
dwPropId
[in] Identifies the property to be retrieved. Currently defined identifiers and the data type to be returned in pvData are listed in the following table.
Property identifier | pvData type | Meaning
CERT_ACCESS_STATE_PROP_ID | DWORD | Returns a DWORD value indicating whether write operations to the certificate are persisted. The DWORD value is not set if the certificate is in a memory store or in a registry-based store that is opened as read-only.
CERT_ARCHIVED_PROP_ID | NULL | Indicates the certificate is skipped during enumerations. A certificate with this property set is found with explicit search operations, such as those used to find a certificate with a specific hash or a serial number. No data in pvData is associated with this property.
CERT_AUTO_ENROLL_PROP_ID | Array of BYTEs | Returns a NULL-terminated Unicode string naming the certificate type for which the certificate has been auto enrolled.
CERT_CTL_USAGE_PROP_ID | Array of BYTEs | Returns an array of bytes containing an ASN.1 encoded CTL_USAGE structure.
CERT_DESCRIPTION_PROP_ID | Array of BYTEs | Returns the property displayed by the certificate UI. This property allows the user to describe the certificate's use.
CERT_ENHKEY_USAGE_PROP_ID | Array of BYTEs | Returns an array of bytes containing an ASN.1 encoded CERT_ENHKEY_USAGE structure.
CERT_FRIENDLY_NAME_PROP_ID | Array of BYTEs | Returns a NULL terminated Unicode character string specifying the friendly name for the CRL.
CERT_SHA1_HASH_PROP_ID | Array of BYTEs | Returns the SHA1 hash. If the hash does not exist, it is computed using CryptHashCertificate.
CERT_KEY_CONTEXT_PROP_ID CERT_KEY
_CONTEXT 		Returns a CERT_KEY_CONTEXT structure.
CERT_KEY_IDENTIFIER_PROP_ID | Array of BYTEs | If nonexistent, searches for the szOID_SUBJECT_KEY_IDENTIFIER extension. If that fails, a SHA1 hash is done on the certificate's SubjectPublicKeyInfo to produce the identifier values.
CERT_KEY_PROV_HANDLE_PROP_ID | HCRYPTPROV | Returns the provider handle obtained from the CERT_KEY_CONTEXT_PROP_ID.
CERT_KEY_PROV_INFO_PROP_ID CRYPT_KEY
_PROV_INFO 		Returns a pointer to a CRYPT_KEY_PROV_INFO.
CERT_KEY_SPEC_PROP_ID | DWORD | Returns a DWORD value specifying the private key obtained from CERT_KEY_CONTEXT_PROP_ID if it exists. Otherwise, if CERT_KEY_PROV_INFO_PROP_ID exists, it is the source of the dwKeySpec.
CERT_MD5_HASH_PROP_ID | Array of BYTEs | Returns the MD5 hash. If the hash does not exist, it is computed using CryptHashCertificate.
CERT_NEXT_UPDATE_LOCATION_PROP_ID Array of BYTEs Returns the ASN.1 encoded CERT_ALT_NAME_INFO structure.

CERT_NEXT_UPDATE
_LOCATION_PROP_ID is currently used only with CTLs.
CERT_PVK_FILE_PROP_ID | Array of BYTEs | Returns a NULL-terminated Unicode, wide character string specifying the file name containing the private key associated with the certificate's public key.
CERT_SHA1_HASH_PROP_ID | Array of BYTEs | Returns the SHA1 hash. If the hash does not exist, it is computed using CryptHashCertificate.
CERT_SIGNATURE_HASH_PROP_ID | Array of BYTEs | Returns the signature hash. If the hash does not exist, it is computed with CryptHashToBeSigned. The length of the hash is 20 bytes for SHA and 16 for MD5.

For many property identifiers, pvData points to an array of bytes and not a CRYPT_DATA_BLOB as pointed to by the pvData parameter in CertSetCRLContextProperty.

For more details about each property identifier, see the documentation on the dwPropId parameter in CertSetCertificateContextProperty.

pvData
[out] Pointer to a buffer to receive the data as determined by dwPropId. Structures pointed to by members of a structure returned are also returned following the base structure. Therefore, the size contained in pcbData often exceed the size of the base structure.

This parameter can be NULL to set the size of the information for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.

pcbData
[in/out] Pointer to a DWORD value specifying the size, in bytes, of the buffer pointed to by the pvData parameter. When the function returns, the DWORD value contains the number of bytes to be stored in the buffer.

Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError.

Note that errors from the called function CryptHashCertificate can be propagated to this function. Some possible error codes follow.

Value | Meaning
CRYPT_E_NOT_FOUND | The CRL does not have the specified property.
ERROR_MORE_DATA | If the buffer specified by the pvData parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code and stores the required buffer size, in bytes, in the variable pointed to by pcbData.

Examples

See Example C Program: Getting and Setting Certificate Properties and Example C Program: Listing the Certificates in a Store.

In those examples, extrapolate from a certificate to a CRL. In other words, PCCERT_CONTEXT becomes PCCRL_CONTEXT, pCertContext becomes pCrlContext, CertEnumCertificateContextProperties becomes CertEnumCRLContextProperties, and CertGetCertificateContextProperty becomes CertGetCRLContextProperty.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Extended Property Functions, CertEnumCRLContextProperties, CertGetCertificateContextProperty, CryptHashCertificate


CertGetCTLContextProperty

The CertGetCTLContextProperty function retrieves an extended property of a certificate trust list (CTL) context.

BOOL WINAPI CertGetCTLContextProperty(
  PCCTL_CONTEXT pCtlContext,
  DWORD dwPropId,
  void *pvData,
  DWORD *pcbData
);

Parameters

pCtlContext
[in] Pointer to the CTL_CONTEXT structure.
dwPropId
[in] Identifies the property to be retrieved. Currently defined identifiers and the data type to be returned in pvData are listed in the following table.
Property identifier | pvData type | Meaning
CERT_ACCESS_STATE_PROP_ID | DWORD | Returns a DWORD value indicating whether write operations to the certificate are persisted. The DWORD value is not set if the certificate is in a memory store or in a registry-based store that is opened as read-only.
CERT_ARCHIVED_PROP_ID | NULL | Indicates the certificate is skipped during enumerations. A certificate with this property set is found with explicit search operations, such as those used to find a certificate with a specific hash or a serial number. No data in pvData is associated with this property.
CERT_AUTO_ENROLL_PROP_ID | Array of BYTEs | Returns a NULL-terminated Unicode string naming the certificate type for which the certificate has been auto enrolled.
CERT_CTL_USAGE_PROP_ID | Array of BYTEs | Returns an array of bytes containing an ASN.1 encoded CTL_USAGE structure.
CERT_DESCRIPTION_PROP_ID | Array of BYTEs | Returns the property displayed by the certificate UI. This property allows the user to describe the certificate's use.
CERT_ENHKEY_USAGE_PROP_ID | Array of BYTEs | Returns an array of bytes containing an ASN.1 encoded CERT_ENHKEY_USAGE structure.
CERT_FRIENDLY_NAME_PROP_ID | Array of BYTEs | Returns a NULL-terminated Unicode character string specifying the friendly name for the CTL.
CERT_HASH_PROP_ID | Array of BYTEs | Returns the SHA1 hash. If the hash does not exist, it is computed using CryptHashCertificate.
CERT_KEY_CONTEXT_PROP_ID CERT_KEY
_CONTEXT 		Returns a CERT_KEY_CONTEXT structure.
CERT_KEY_IDENTIFIER_PROP_ID | Array of BYTEs | If nonexistent, searches for the szOID_SUBJECT_KEY_IDENTIFIER extension. If that fails, a SHA1 hash is done on the certificate's SubjectPublicKeyInfo to produce the identifier values.
CERT_KEY_PROV_HANDLE_PROP_ID | HCRYPTPROV | Returns the provider handle obtained from the CERT_KEY_CONTEXT_PROP_ID.
CERT_KEY_PROV_INFO_PROP_ID CRYPT_KEY
_PROV_INFO 		Returns a pointer to a CRYPT_KEY_PROV_INFO.
CERT_KEY_SPEC_PROP_ID | DWORD | Returns a DWORD value specifying the private key obtained from CERT_KEY_CONTEXT_PROP_ID if it exists. Otherwise, if CERT_KEY_PROV_INFO_PROP_ID exists, it is the source of the dwKeySpec.
CERT_MD5_HASH_PROP_ID | Array of BYTEs | Returns the MD5 hash. If the hash does not exist, it is computed using CryptHashCertificate.
CERT_NEXT_UPDATE_LOCATION_PROP_ID Array of BYTEs Returns the ASN.1 encoded CERT_ALT_NAME_INFO structure.

CERT_NEXT_UPDATE_LOCATION_PROP_ID is currently used only with CTLs.
CERT_PVK_FILE_PROP_ID | Array of BYTEs | Returns a NULL-terminated Unicode, wide character string specifying the file name containing the private key associated with the certificate's public key.
CERT_SHA1_HASH_PROP_ID | Array of BYTEs | Returns the SHA1 hash. If the hash does not exist, it is computed using CryptHashCertificate.
CERT_SIGNATURE_HASH_PROP_ID | Array of BYTEs | Returns the signature hash. If the hash does not exist, it is computed with CryptHashToBeSigned. The length of the hash is 20 bytes for SHA and 16 for MD5.

For all other property identifiers, pvData points to an array of bytes and not a CRYPT_DATA_BLOB as pointed to by the pvData parameter in CertSetCertificateContextProperty.

For more details about each property identifier, see the documentation on the dwPropId parameter in CertSetCertificateContextProperty. CERT_SHA1_HASH_PROP_ID and CERT_NEXT_UPDATE_LOCATION_PROP_ID are the predefined properties of most interest.

pvData
[out] Pointer to a buffer to receive the data as determined by dwPropId. Structures pointed to by members of a structure returned are also returned following the base structure. Therefore, the size contained in pcbData often exceed the size of the base structure.

This parameter can be NULL to set the size of the information for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.

pcbData
[in/out] Pointer to a DWORD value specifying the size, in bytes, of the buffer pointed to by the pvData parameter. When the function returns, the DWORD value contains the number of bytes to be stored in the buffer.

Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError.

Note that errors from the called function CryptHashCertificate can be propagated to this function. Some possible error codes follow.

Value | Meaning
CRYPT_E_NOT_FOUND | The CTL does not have the specified property.
ERROR_MORE_DATA | If the buffer specified by the pvData parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code and stores the required buffer size, in bytes, in the variable pointed to by pcbData.

Examples

See Example C Program: Getting and Setting Certificate Properties and Example C Program: Listing the Certificates in a Store.

In those examples, extrapolate from a certificate to a CTL. In other words, PCCERT_CONTEXT becomes PCCTL_CONTEXT, pCertContext becomes pCtlContext, CertEnumCertificateContextProperties becomes CertEnumCTLContextProperties, and CertGetCertificateContextProperty becomes CertGetCTLContextProperty.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Extended Property Functions, CertEnumCTLContextProperties, CertGetCertificateContextProperty, CertSetCTLContextProperty, CryptHashCertificate


CertSetCertificateContextProperty

[This is preliminary documentation and subject to change.]

The CertSetCertificateContextProperty function sets an extended property for a specified certificate context.

BOOL WINAPI CertSetCertificateContextProperty(
  PCCERT_CONTEXT pCertContext,
  DWORD dwPropId,
  DWORD dwFlags,
  const void *pvData
);

Parameters

pCertContext
[in] Pointer to a CERT_CONTEXT structure.
dwPropId
[in] Identifies the property to be set. The value of dwPropId determines the type and content of the pvData parameter. Currently defined identifiers and their related pvData types are as follows.
Property identifier | pvData type | Comments
CERT_ARCHIVED_PROP_ID | NULL | Indicates the certificate is skipped during enumerations. A certificate with this property set is still found with explicit search operations—such as finding a certificate with a specific hash or a specific serial number
CERT_AUTO_ENROLL_PROP_ID | CRYPT_DATA_BLOB | Property set after a certificate has been enrolled using Auto Enroll. The CRYPT_DATA_BLOB structure pointed to by pvdata includes a NULL terminated, Unicode name of the certificate type for which the certificates has been auto enrolled. Any subsequent calls to Auto Enroll for the certificate checks for this property to determine whether the certificate has been enrolled.
CERT_CTL_USAGE_PROP_ID | CRYPT_DATA_BLOB | pvData points to a CRYPT_DATA_BLOB containing an ASN.1 encoded CTL_USAGE structure. This structure was encoded using CryptEncodeObject with X509_ENHANCED_KEY_USAGE value set.
CERT_DESCRIPTION_PROP_ID | CRYPT_DATA_BLOB | Property set and displayed by the certificate UI. This property allows the user to describe the certificate's use.
CERT_ENHKEY_USAGE_PROP_ID | CRYPT_DATA_BLOB | Property that indicates pvData points to a CRYPT_DATA_BLOB containing an ASN.1 encoded CERT_ENHKEY_USAGE structure. This structure was encoded using CryptEncodeObject with X509_ENHANCED_KEY_USAGE value set.
CERT_FRIENDLY_NAME_PROP_ID | CRYPT_DATA_BLOB | pvData points to a CRYPT_DATA_BLOB structure specifying the friendly name of the certificate.
CERT_HASH_PROP_ID | CRYPT_HASH_BLOB | This Property is implicitly set by a call to CertGetCertificateContextProperty
CERT_KEY_CONTEXT_PROP_ID | CERT_KEY_CONTEXT | CERT_KEY_CONTEXT structure specifying the certificate's private key. It contains both the HCRYPTPROV and key specification for the private key. For more information about the HCRYPTPROV member and dwFlags settings, see CERT_KEY_PROV_HANDLE_PROP_ID, following. Note that more CERT_KEY_CONTEXT structure members can be added for this property. If so, the cbSize member value will be adjusted accordingly. The cbSize member must be set to the size of the CERT_KEY_CONTEXT structure
CERT_KEY_IDENTIFIER_PROP_ID | CRYPT_DATA_BLOB | This property is typically implicitly set by a call to CertGetCertificateContextProperty.
CERT_KEY_PROV_HANDLE_PROP_ID | HCRYPTPROV | An HCRYPTPROV handle for the certificate's private key is passed. The hCryptProv member of the CERT_KEY_CONTEXT_PROP_ID structure is updated if it exists. If it does not exist, it is created with dwKeySpec initialized by CERT_KEY_PROV_INFO_PROP_ID. If CERT_STORE_NO_CRYPT_RELEASE_FLAG is not set, the HCRYPTPROV value is implicitly released either when the property is set to NULL or on the final freeing of the CERT_CONTEXT structure.
CERT_KEY_PROV_INFO_PROP_ID | CRYPT_KEY_PROV_INFO | The CRYPT_KEY_PROV_INFO structure specifies the certificate's private key.
CERT_KEY_SPEC_PROP_ID | DWORD | DWORD value specifying the private key. The dwKeySpec member of the CERT_KEY_CONTEXT_PROP_ID structure is updated if it exists. If it does not, it is created with hCryptProv set to zero.
CERT_MD5_HASH_PROP_ID | CRYPT_HASH_BLOB | This property is implicitly set by a call to CertGetCertificateContextProperty.
CERT_NEXT_UPDATE_LOCATION_PROP_ID | CRYPT_DATA_BLOB | The CRYPT_DATA_BLOB contains an ASN.1 encoded CERT_ALT_NAME_INFO structure encoded using CryptEncodeObject with the X509_ALTERNATE_NAME value set. CERT_NEXT_UPDATE_LOCATION_PROP_ID is currently used only with CTLs.
CERT_PUBKEY_ALG_PARA_PROP_ID | CRYPT_DATA_BLOB | Used with public keys supporting algorithm parameter inheritance. The data BLOB contains the ASN.1 encoded PublicKey Algorithm parameters. For DSS these are parameters encoded using CryptEncodeObject. This is used only if CMS_PKCS7 is defined.
CERT_PVK_FILE_PROP_ID | CRYPT_DATA_BLOB | The CRYPT_DATA_BLOB specifies the name of a file containing the private key associated with the certificate's public key. Inside the CRYPT_DATA_BLOB structure, the pbData member is a pointer to a NULL terminated Unicode, wide-character string, and the cbData member indicates the length of the string
CERT_SHA1_HASH_PROP_ID | CRYPT_HASH_BLOB | This Property is implicitly set by a call to CertGetCertificateContextProperty
CERT_SIGNATURE_HASH_PROP_ID | CRYPT_HASH_BLOB | If a signature hash does not exist, it is computed with CryptHashToBeSigned. pvData points to an existing or computed hash. Usually, the length of the hash is 20 bytes for SHA and 16 for MD5.
CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID | CRYPT_DATA_BLOB | MD5 hash of the public key associated with the private key used to sign this certificate.
CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID | CRYPT_DATA_BLOB | MD5 hash of this certificate's public key.
CERT_ENROLLMENT_PROP_ID | CRYPT_DATA_BLOB | Enrollment information of the pending request containing RequestID, CADNSName, CAName, and FriendlyName. The data format is defined as: the first 4 bytes, pending request ID; next 4 bytes, CADNSName size in characters including null-terminator followed by CADNSName string with null-terminator; next 4 bytes, CAName size in characters including null-terminator followed by CAName string with null-terminator; next 4 bytes, FriendlyName size in characters including null-terminator followed by FriendlyName string with null-terminator.
CERT_CROSS_CERT_DIST_POINTS_PROP_ID | CRYPT_DATA_BLOB | Location of the cross certificates. This value is only applicable to certificates and not to CRLs or CTLs.The CRYPT_DATA_BLOB structure contains an ASN.1 encoded CROSS_CERT_DIST_POINTS_INFO structure encoded using CryptEncodeObject with a X509_CROSS_CERT_DIST_POINTS value for the lpszStuctType parameter.
CERT_DATE_STAMP_PROP_ID - | FILETIME | Time when the certificate was added to the store.

Additional dwPropId types can be defined by the user using DWORD values from CERT_FIRST_USER_PROP_ID to CERT_LAST_USER_PROP_ID. For all user-defined dwPropId types, pvData points to an encoded CRYPT_DATA_BLOB.

Note The CERT_CROSS_CERT_DIST_POINTS_PROP_ID, CERT_ENROLLMENT_PROP_ID, and CERT_DATE_STAMP_PROP_ID dwPropId values can only be used with Windows Whistler and later.

dwFlags
[in] CERT_STORE_NO_CRYPT_RELEASE_FLAG can be set for the CERT_KEY_PROV_HANDLE_PROP_ID or CERT_KEY_CONTEXT_PROP_ID dwPropId properties.

If the CERT_SET_PROPERTY_IGNORE_PERSIST_ERROR_FLAG value is set, any provider-write errors are ignored and the cached context's properties are always set.

pvData
[in] Pointer to a data type determined by the value of dwPropId.

Note For any dwPropId, setting pvData to NULL deletes the property.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError. One possible error code is the following.

Value | Meaning
E_INVALIDARG | Invalid property. The identifier specified was greater than 0x0000FFFF, or, for the CERT_KEY_CONTEXT_PROP_ID property, an invalid cbSize member was specified in the CERT_KEY_CONTEXT structure.

Remarks

If a property already exists, its old value is replaced.

Examples

See Example C Program: Getting and Setting Certificate Properties.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Extended Property Functions, CERT_ALT_NAME_INFO, CERT_CONTEXT, CERT_KEY_CONTEXT, CertGetCertificateContextProperty, CertSetCRLContextProperty, CryptHashToBeSigned, CRYPT_KEY_PROV_INFO, CTL_USAGE, HCRYPTPROV


CertSetCRLContextProperty

The CertSetCRLContextProperty function sets an extended property for the specified certificate revocation list (CRL) context.

BOOL WINAPI CertSetCRLContextProperty(
  PCCRL_CONTEXT pCrlContext,
  DWORD dwPropId,
  DWORD dwFlags,
  const void *pvData
);

Parameters

pCrlContext
[in] Pointer to the CRL_CONTEXT structure.
dwPropId
[in] Identifies the property to be set. The value of dwPropId determines the type and content of the pvData parameter. Currently defined identifiers and their related pvData types are as follows.
Property identifier | pvData type | Comments
CERT_ARCHIVED_PROP_ID | NULL | Indicates the certificate is skipped during enumerations. A certificate with this property set is still found with explicit search operations—such as finding a certificate with a specific hash or a specific serial number.
CERT_AUTO_ENROLL_PROP_ID | CRYPT_DATA_BLOB | Property set after a certificate has been enrolled using Auto Enroll. The CRYPT_DATA_BLOB structure pointed to by pvdata includes a NULL terminated, Unicode name of the certificate type for which the certificates has been auto enrolled. Any subsequent calls to Auto Enroll for the certificate checks for this property to determine whether the certificate has been enrolled.
CERT_CTL_USAGE_PROP_ID | CRYPT_DATA_BLOB | pvData points to a CRYPT_DATA_BLOB containing an ASN.1 encoded CTL_USAGE structure. This structure was encoded using CryptEncodeObject with X509_ENHANCED_KEY_USAGE value set.
CERT_DESCRIPTION_PROP_ID | CRYPT_DATA_BLOB | Property set and displayed by the certificate UI. This property allows the user to describe the certificate's use.
CERT_ENHKEY_USAGE_PROP_ID | CRYPT_DATA_BLOB | Property that indicates pvData points to a CRYPT_DATA_BLOB containing an ASN.1 encoded CERT_ENHKEY_USAGE structure. This structure was encoded using CryptEncodeObject with X509_ENHANCED_KEY_USAGE value set.
CERT_FRIENDLY_NAME_PROP_ID | CRYPT_DATA_BLOB | pvData points to a CRYPT_DATA_BLOB structure specifying the friendly name of the CRL.
CERT_HASH_PROP_ID | CRYPT_HASH_BLOB | This property is implicitly set by a call to CertGetCertificateContextProperty.
CERT_KEY_CONTEXT_PROP_ID | CERT_KEY_CONTEXT | CERT_KEY_CONTEXT structure specifying the certificate's private key. It contains both the HCRYPTPROV and key specification for the private key. For more information about the HCRYPTPROV member and dwFlags settings, see CERT_KEY_PROV_HANDLE_PROP_ID, following. Note that more CERT_KEY_CONTEXT structure members can be added for this property. If so, the cbSize member value will be adjusted accordingly. The cbSize member must be set to the size of the CERT_KEY_CONTEXT structure.
CERT_KEY_IDENTIFIER_PROP_ID | CRYPT_DATA_BLOB | This property is typically implicitly set by a call to CertGetCertificateContextProperty.
CERT_KEY_PROV_HANDLE_PROP_ID | HCRYPTPROV | An HCRYPTPROV handle for the certificate's private key is passed. The hCryptProv member of the CERT_KEY_CONTEXT_PROP_ID structure is updated if it exists. If it does not exist, it is created with dwKeySpec initialized by CERT_KEY_PROV_INFO_PROP_ID. If CERT_STORE_NO_CRYPT_RELEASE_FLAG is not set, the HCRYPTPROV value is implicitly released either when the property is set to NULL or on the final freeing of the CERT_CONTEXT structure.
CERT_KEY_PROV_INFO_PROP_ID | CRYPT_KEY_PROV_INFO | The CRYPT_KEY_PROV_INFO structure specifies the certificate's private key.
CERT_KEY_SPEC_PROP_ID | DWORD | DWORD value specifying the private key. The dwKeySpec member of the CERT_KEY_CONTEXT_PROP_ID structure is updated if it exists. If it does not, it is created with hCryptProv set to zero.
CERT_MD5_HASH_PROP_ID | CRYPT_HASH_BLOB | This property is implicitly set by a call to CertGetCertificateContextProperty.
CERT_NEXT_UPDATE_LOCATION_PROP_ID | CRYPT_DATA_BLOB | The CRYPT_DATA_BLOB contains an ASN.1 encoded CERT_ALT_NAME_INFO structure encoded using CryptEncodeObject with the X509_ALTERNATE_NAME value set. CERT_NEXT_UPDATE_LOCATION_PROP_ID is currently used only with CTLs.
CERT_PVK_FILE_PROP_ID | CRYPT_DATA_BLOB | The CRYPT_DATA_BLOB specifies the name of a file containing the private key associated with the certificate's public key. Inside the CRYPT_DATA_BLOB structure, the pbData member is a pointer to a NULL terminated Unicode, wide-character string, and the cbData member indicates the length of the string.
CERT_SHA1_HASH_PROP_ID | CRYPT_HASH_BLOB | This property is implicitly set by a call to CertGetCertificateContextProperty.
CERT_SIGNATURE_HASH_PROP_ID | CRYPT_HASH_BLOB | If a signature hash does not exist, it is computed with CryptHashToBeSigned. pvData points to an existing or computed hash. Usually, the length of the hash is 20 bytes for SHA and 16 for MD5.

Usually, only the following properties are set.

CERT_HASH_PROP_ID
CERT_SHA1_HASH_PROP_ID
CERT_MD5_HASH_PROP_ID
CERT_SIGNATURE_HASH_PROP_ID

Additional dwPropId types can be defined by the user using DWORD values from CERT_FIRST_USER_PROP_ID to CERT_LAST_USER_PROP_ID. For all user-defined dwPropId types, pvData points to an encoded CRYPT_DATA_BLOB.

For all the other property identifiers, pvData points to an encoded CRYPT_DATA_BLOB structure.

dwFlags
[in] CERT_STORE_NO_CRYPT_RELEASE_FLAG can be set for the CERT_KEY_PROV_HANDLE_PROP_ID or CERT_KEY_CONTEXT_PROP_ID dwPropId properties.

If the CERT_SET_PROPERTY_IGNORE_PERSIST_ERROR_FLAG value is set, any provider-write errors are ignored and the cached context's properties are always set.

pvData
[in] Pointer to a data type that is determined by the value passed in dwPropId.

Note For any dwPropId, setting pvData to NULL deletes the property.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError. One possible error code is the following.

Value | Meaning
E_INVALIDARG | Invalid property. The identifier specified was greater than 0x0000FFFF, or, for the CERT_KEY_CONTEXT_PROP_ID property, an invalid cbSize member was specified in the CERT_KEY_CONTEXT structure.

Remarks

If a property already exists, its old value is replaced.

Examples

See Example C Program: Getting and Setting Certificate Properties.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Extended Property Functions, CertGetCRLContextProperty, CryptHashToBeSigned, CertSetCertificateContextProperty


CertSetCTLContextProperty

The CertSetCTLContextProperty function sets an extended property for the specified certificate trust list (CTL) context.

BOOL WINAPI CertSetCTLContextProperty(
  PCCTL_CONTEXT pCtlContext,
  DWORD dwPropId,
  DWORD dwFlags,
  const void *pvData
);

Parameters

pCtlContext
[in] Pointer to the CTL_CONTEXT structure.
dwPropId
[in] Identifies the property to be set. The value of dwPropId determines the type and content of the pvData parameter. Currently defined identifiers and their related pvData types are as follows.
Property identifier | pvData type | Comments
CERT_ARCHIVED_PROP_ID | NULL | Indicates the certificate is skipped during enumerations. A certificate with this property set is still found with explicit search operations—such as finding a certificate with a specific hash or a specific serial number.
CERT_AUTO_ENROLL_PROP_ID | CRYPT_DATA_BLOB | Property set after a certificate has been enrolled using Auto Enroll. The CRYPT_DATA_BLOB structure pointed to by pvData includes a NULL-terminated, Unicode name of the certificate type for which the certificates has been auto enrolled. Any subsequent calls to Auto Enroll for the certificate checks for this property to determine whether the certificate has been enrolled.
CERT_CTL_USAGE_PROP_ID | CRYPT_DATA_BLOB | pvData points to a CRYPT_DATA_BLOB structure containing an ASN.1 encoded CTL_USAGE structure. This structure was encoded using CryptEncodeObject with X509_ENHANCED_KEY_USAGE value set.
CERT_DESCRIPTION_PROP_ID | CRYPT_DATA_BLOB | Property set and displayed by the certificate UI. This property allows the user to describe the certificate's use.
CERT_ENHKEY_USAGE_PROP_ID | CRYPT_DATA_BLOB | Property that indicates pvData points to a CRYPT_DATA_BLOB structure containing an ASN.1 encoded CERT_ENHKEY_USAGE structure. This structure was encoded using CryptEncodeObject with X509_ENHANCED_KEY_USAGE value set.
CERT_FRIENDLY_NAME_PROP_ID | CRYPT_DATA_BLOB | pvData points to a CRYPT_DATA_BLOB structure specifying the friendly name of the certificate.
CERT_HASH_PROP_ID | CRYPT_HASH_BLOB | This property is implicitly set by a call to CertGetCertificateContextProperty.
CERT_KEY_CONTEXT_PROP_ID | CERT_KEY_CONTEXT | CERT_KEY_CONTEXT structure specifying the certificate's private key. It contains both the HCRYPTPROV value and the key specification for the private key. For more information about the HCRYPTPROV member and dwFlags settings, see CERT_KEY_PROV_HANDLE_PROP_ID, following. Note that more CERT_KEY_CONTEXT structure members can be added for this property. If so, the cbSize member value will be adjusted accordingly. The cbSize member must be set to the size of the CERT_KEY_CONTEXT structure
CERT_KEY_IDENTIFIER_PROP_ID | CRYPT_DATA_BLOB | This property is typically implicitly set by a call to CertGetCertificateContextProperty.
CERT_KEY_PROV_HANDLE_PROP_ID | HCRYPTPROV | An HCRYPTPROV handle for the certificate's private key is passed. The hCryptProv member of the CERT_KEY_CONTEXT_PROP_ID structure is updated if it exists. If it does not exist, it is created with dwKeySpec initialized by CERT_KEY_PROV_INFO_PROP_ID. If CERT_STORE_NO_CRYPT_RELEASE_FLAG is not set, the HCRYPTPROV value is implicitly released either when the property is set to NULL or on the final freeing of the CERT_CONTEXT structure.
CERT_KEY_PROV_INFO_PROP_ID | CRYPT_KEY_PROV_INFO | The CRYPT_KEY_PROV_INFO structure specifies the certificate's private key.
CERT_KEY_SPEC_PROP_ID | DWORD | DWORD value specifying the private key. The dwKeySpec member of the CERT_KEY_CONTEXT_PROP_ID structure is updated if it exists. If it does not, it is created with hCryptProv set to zero.
CERT_MD5_HASH_PROP_ID | CRYPT_HASH_BLOB | This property is implicitly set by a call to CertGetCertificateContextProperty.
CERT_NEXT_UPDATE_LOCATION_PROP_ID | CRYPT_DATA_BLOB | The CRYPT_DATA_BLOB structure contains an ASN.1 encoded CERT_ALT_NAME_INFO structure encoded using CryptEncodeObject with the X509_ALTERNATE_NAME value set. CERT_NEXT_UPDATE_LOCATION_PROP_ID is currently used only with CTLs.
CERT_PVK_FILE_PROP_ID | CRYPT_DATA_BLOB | The CRYPT_DATA_BLOB structure specifies the name of a file containing the private key associated with the certificate's public key. Inside the CRYPT_DATA_BLOB structure, the pbData member is a pointer to a NULL-terminated Unicode, wide-character string, and the cbData member indicates the length of the string.
CERT_SHA1_HASH_PROP_ID | CRYPT_HASH_BLOB | This property is implicitly set by a call to CertGetCertificateContextProperty.
CERT_SIGNATURE_HASH_PROP_ID | CRYPT_HASH_BLOB | If a signature hash does not exist, it is computed with CryptHashToBeSigned. pvData points to an existing or computed hash. Usually, the length of the hash is 20 bytes for SHA and 16 for MD5.

Typically, only the CERT_NEXT_UPDATE_LOCATION_PROP_ID property is set.

Additional dwPropId types can be defined by the user using DWORD values from CERT_FIRST_USER_PROP_ID to CERT_LAST_USER_PROP_ID. For all user-defined dwPropId types, pvData points to an encoded CRYPT_DATA_BLOB structure.

dwFlags
[in] CERT_STORE_NO_CRYPT_RELEASE_FLAG can be set for the CERT_KEY_PROV_HANDLE_PROP_ID or CERT_KEY_CONTEXT_PROP_ID dwPropId properties.

If the CERT_SET_PROPERTY_IGNORE_PERSIST_ERROR_FLAG value is set, any provider-write errors are ignored and the cached context's properties are always set.

pvData
[in] Pointer to a data type that is determined by the value passed in dwPropId.

Note For any dwPropId, setting pvData to NULL deletes the property.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError. One possible error code is the following.

Value | Meaning
E_INVALIDARG | Invalid property identifier. For details, see CertSetCertificateContextProperty.

Remarks

If a property already exists, its old value is replaced.

Examples

See Example C Program: Getting and Setting Certificate Properties.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Extended Property Functions, CertGetCTLContextProperty, CertSetCertificateContextProperty, CryptEncodeObject


Certificate Verification Functions

Certificate verification can be done using CTLs and certificate chains. Win32 functions are provided for both of these:

  • Functions Using CTLs
  • Certificate Chain Verification Functions


Functions Using CTLs

Several functions use CTLs in the verification process. Additional functions for working with CTLs can be found in Certificate Trust List Functions and Extended Property Functions.

The functions that use CTLs directly for verification are as follows.

Function | Description
CertVerifyCTLUsage | Verifies the usage of a CTL.
CryptMsgEncodeAndSignCTL | Encodes and signs a CTL as a message.
CryptMsgGetAndVerifySigner | Retrieves and verifies a CTL from a message.
CryptMsgSignCTL | Signs a message containing a CTL.


CertVerifyCTLUsage

The CertVerifyCTLUsage function verifies that a subject is trusted for a specified usage by finding a signed and time-valid CTL with the usage identifiers that contain the subject. A certificate's subject can be identified by either its certificate context or any unique identifier such as the SHA1 hash of the subject's certificate.

BOOL WINAPI CertVerifyCTLUsage(
  DWORD dwEncodingType,
  DWORD dwSubjectType,
  void *pvSubject,
  PCTL_USAGE pSubjectUsage,
  DWORD dwFlags,
  PCTL_VERIFY_USAGE_PARA pVerifyUsagePara,
  PCTL_VERIFY_USAGE_STATUS pVerifyUsageStatus
);

Parameters

dwEncodingType
[in] Specifies the encoding type used. Currently, only X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are being used; however, additional encoding types can be added in the future. For either current encoding type, use:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
dwSubjectType
[in] If the dwSubjectType parameter is set to CTL_CERT_SUBJECT_TYPE, pvSubject points to a CERT_CONTEXT structure. The structure's SubjectAlgorithm member is examined to determine the representation of the subject's identity. Initially, only SHA1 and MD5 hashes are supported as values for SubjectAlgorithm. The appropriate hash property is obtained from the CERT_CONTEXT structure.

If the dwSubjectType parameter is set to CTL_ANY_SUBJECT_TYPE, pvSubject points to the CTL_ANY_SUBJECT_INFO structure. The SubjectAlgorithm member of this structure must match the algorithm type of the CTL, and the SubjectIdentifer member must match one of the CTL entries.

If dwSubjectType is set to either preceding value, dwEncodingType is not used.

pvSubject
[in] Value used in conjunction with the dwSubjectType parameter.
pSubjectUsage
[in] Pointer to a CTL_USAGE structure used to specify the intended usage of the subject.
dwFlags
[in] If the CERT_VERIFY_INHIBIT_CTL_UPDATE_FLAG is not set, a time-invalid CTL in one of the stores specified by rghCtlStore in CTL_VERIFY_USAGE_PARA can be replaced. When replaced, the CERT_VERIFY_UPDATED_CTL_FLAG is set in dwFlags member of VerifyUsageStatus. If this flag is set, an update will not be made, even if a time-valid, updated CTL is received for a CTL that is currently time-invalid in the store.

If the CERT_VERIFY_TRUSTED_SIGNERS_FLAG is set, only the signer stores specified by rghSignerStore in CTL_VERIFY_USAGE_PARA are searched to find the signer. Otherwise, the signer stores provide additional sources to find the signer's certificate. See the Remarks section for more information.

If CERT_VERIFY_NO_TIME_CHECK_FLAG is set, the CTLs are not checked for time validity. Otherwise, they are.

If CERT_VERIFY_ALLOW_MORE_USAGE_FLAG is set, the CTL can contain usage identifiers in addition to those specified by pSubjectUsage. Otherwise, the found CTL will contain no additional usage identifiers.

pVerifyUsagePara
[in/optional] Pointer to a CTL_VERIFY_USAGE_PARA structure specifying the stores to be searched to find the CTL and the stores containing acceptable CTL signers. Setting the ListIdentifier member further limits the search.
pVerifyUsageStatus
[in/out] Pointer to a CTL_VERIFY_USAGE_STATUS structure. The cbSize member of the structure must to be set to the size in bytes of the structure and all other fields must be set to zero before CertVerifyCTLUsage is called. See CTL_VERIFY_USAGE_STATUS for more information.

Return Values

If the subject is trusted for the specified usage, TRUE is returned. Otherwise, FALSE is returned. GetLastError Call GetLastError can return one of the following error codes.

Error Code | Description
CRYPT_E_NO_VERIFY_USAGE_DLL | No DLL or exported function was found to verify subject usage.
CRYPT_E_NO_VERIFY_USAGE_CHECK | The called function wasn't able to do a usage check on the subject.
CRYPT_E_VERIFY_USAGE_OFFLINE | The server was off-line therefore the called function could not complete the usage check.
CRYPT_E_NOT_IN_CTL | The subject was not found in a CTL.
CRYPT_E_NO_TRUSTED_SIGNER | No trusted signer was found to verify the signature of the message or trust list.

The dwError member of the CTL_VERIFY_USAGE_PARA pointed to by pVerifyUsageStatus is set to the same error code.

Remarks

CertVerifyCTLUsage is a dispatcher to object identifier (OID) installable functions. First, it tries to find an OID function matching the first usage object identifier in the CLT_USAGE structure pointed to by pSubjectUsage. If this fails, it uses the default CertDllVerifyCTLUsage functions.

Microsoft has implemented an OID installable CertDllVerifyCTLUsage function residing in the Cryptnet.dll with the following properties:

  • If CTL stores are specified by rghCtlStore in pVerifyUsagePara, only those stores are searched to find a CTL. Otherwise, the Trust system store is searched to find a CTL.
  • If CERT_VERIFY_TRUSTED_SIGNERS_FLAG is set, only the signer stores specified by rghSignerStore in pVerifyUsagePara are searched to find the certificate corresponding to the signer's issuer and serial number. Otherwise, the CTL message's store, the signer stores specified by rghSignerStore in pVerifyUsagePara, the Trust system store, CA system store, ROOT and SPC system stores are searched to find the signer's certificate. In either case, the public key in the found certificate is used to verify the CTL's signature.
  • If the CTL has a set NextUpdate member and CERT_VERIFY_NO_TIME_CHECK is not set, it is verified for time validity.
  • If the CTL obtained from the store is time invalid, an attempt is made to get a time-valid version. The CertDllVerifyCTLUsage function uses the CTL's NextUpdateLocation property or CTL's NextUpdateLocation extension or it searches the signer's information for a NextUpdateLocation attribute.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Functions Using CTLs, CTL_VERIFY_USAGE_PARA, CTL_VERIFY_USAGE_STATUS, CertFindSubjectInCTL, CertFindCTLInStore


CryptMsgEncodeAndSignCTL

The CryptMsgEncodeAndSignCTL function encodes a CTL and creates a signed message containing the encoded CTL.

This function first encodes the CTL pointed to by pCtlInfo and then calls CryptMsgSignCTL to sign the encoded message.

BOOL WINAPI CryptMsgEncodeAndSignCTL(
  DWORD dwMsgEncodingType,
  PCTL_INFO pCtlInfo,
  PCMSG_SIGNED_ENCODE_INFO pSignInfo,
  DWORD dwFlags,
  BYTE *pbEncoded,
  DWORD *pcbEncoded
);

Parameters

dwMsgEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pCtlInfo
[in] Pointer to the CTL_INFO structure containing the CTL to be encoded and signed.
pSignInfo
[in] Pointer to a CMSG_SIGNED_ENCODE_INFO structure that contains an array of a CMSG_SIGNER_ENCODE_INFO structures.

The message can be encoded without signers if the cbSize member of the structure is set to the size of the structure and all of the other members are set to zero.

dwFlags
[in] CMSG_ENCODE_SORTED_CTL_FLAG is set if the CTL entries are to be sorted before encoding. This flag is set if the CertFindSubjectInSortedCTL or CertEnumSubjectInSortedCTL functions will be called.

CMSG_ENCODE_HASHED_SUBJECT_IDENTIFIER_FLAG is set if CMSG_ENCODE_SORTED_CTL_FLAG is set, and the identifier for the TrustedSubjects is a hash, such as MD5 or SHA1.

If CMS_PKCS7 is defined, dwFlags can be set to CMSG_CMS_ENCAPSULATED_CTL_FLAG to encode a CMS compatible V3 SignedData message.

pbEncoded
[out] Pointer to a buffer that receives the encoded, signed message created.

This parameter can be NULL to set the size of this information for memory allocation purposes. See Retrieving Data of Unknown Length.

pcbEncoded
[in/out] Pointer to a DWORD that specifies the size, in bytes, of the pbEncoded buffer. When the function returns, the DWORD contains the number of bytes stored or to be stored in the buffer.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). To get extended error information, call GetLastError. Errors can be propagated from calls to CryptMsgOpenToEncode and CryptMsgUpdate.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Functions Using CTLs, CMSG_SIGNED_ENCODE_INFO, CTL_INFO, CryptMsgOpenToEncode, CryptMsgSignCTL, CertFindSubjectInSortedCTL, CertEnumSubjectInSortedCTL


CryptMsgGetAndVerifySigner

The CryptMsgGetAndVerifySigner function verifies a cryptographic message's signature.

BOOL WINAPI CryptMsgGetAndVerifySigner(
  HCRYPTMSG hCryptMsg,
  DWORD cSignerStore,
  HCERTSTORE *rghSignerStore,
  DWORD dwFlags,
  PCCERT_CONTEXT *ppSigner,
  DWORD *pdwSignerIndex
);

Parameters

hCryptMsg
[in] Handle of a cryptographic message.
cSignerStore
[in] Number of stores in the rghSignerStore array.
rghSignerStore
[in/optional] Array of certificate store handles that can be searched for a signer's certificate.
dwFlags
[in] Indicates particular use of the function.
Flag | Meaning
CMSG_TRUSTED_SIGNER_FLAG | The stores in rghSignerStore are assumed trusted and they are the only stores searched to find the certificate corresponding to the signer's issuer and serial number. Otherwise, signer stores can be provided to supplement the message's store of certificates. If a signer certificate is found, its public key is used to verify the message signature.
CMSG_SIGNER_ONLY_FLAG | Return the signer without doing the signature verification.
CMSG_USE_SIGNER_INDEX_FLAG | Only the signer specified by *pdwSignerIndex is returned. Otherwise, iterate through all the signers until a signature is verified or there are no more signers.

ppSigner
[out/optional] If the signature is verified, *ppSigner is updated to point to the signer's certificate context. This parameter can be NULL if the application has no need for the signer's certificate.
pdwSignerIndex
[in/out/optional] If the signature is verified, pdwSigner is updated to point to the index of the signer in the array of signers. This parameter can be NULL if the application has no need for the index of the signer.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Functions Using CTLs, CERT_CONTEXT, CTL_CONTEXT, CryptMsgOpenToDecode, CryptMsgControl


CryptMsgSignCTL

The CryptMsgSignCTL function creates a signed message containing an encoded CTL.

BOOL WINAPI CryptMsgSignCTL(
  DWORD dwMsgEncodingType,
  BYTE *pbCtlContent,
  DWORD cbCtlContent,
  PCMSG_SIGNED_ENCODE_INFO pSignInfo,
  DWORD dwFlags,
  BYTE *pbEncoded,
  DWORD *pcbEncoded
);

Parameters

dwMsgEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pbCtlContent
[in] The encoded CTL_INFO that can be a member of a CTL_CONTEXT structure or can be created using the CryptEncodeObject function.
cbCtlContent
[in] Size, in bytes, of the content pointed to by pbCtlContent.
pSignInfo
[in] Pointer to a CMSG_SIGNED_ENCODE_INFO structure containing an array of a CMSG_SIGNER_ENCODE_INFO structures.

The message can be encoded without signers if the cbSize member of the structure is set to the size of the structure and all of the other members are set to zero.

dwFlags
[in] If CMS_PKCS7 is defined, can be set to CMSG_CMS_ENCAPSULATED_CTL_FLAG to encode a CMS compatible V3 SignedData message.
pbEncoded
[out] Pointer to a buffer to receives the encoded message.

This parameter can be NULL to get the size of this information for memory allocation purposes. See Retrieving Data of Unknown Length.

pcbEncoded
[in/out] Pointer to a DWORD specifying the size, in bytes, of the pbEncoded buffer. When the function returns, the DWORD contains the number of bytes stored or to be stored in the buffer.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. This function can return errors propagated from calls to CryptMsgOpenToEncode and CryptMsgUpdate.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Functions Using CTLs, CMSG_SIGNED_ENCODE_INFO, CryptMsgEncodeAndSignCTL, CryptMsgOpenToEncode


Certificate Chain Verification Functions

Certificate chains can be built to provide trust information about individual certificates. The following functions create and work with certificate chains.

Function Name | Description
CertCreateCertificateChainEngine | Creates a new, nondefault, chain engine for an application.
CertCreateCTLEntryFromCertificateContextProperties | Creates a CTL entry whose attributes are the certificate context's properties.
CertDuplicateCertificateChain | Duplicates a certificate chain by incrementing the chain's reference count and returning a pointer to the chain.
CertFindChainInStore | Finds the first or next certificate chain context in a store.
CertFreeCertificateChain | Frees a certificate chain by reducing its reference count.
CertFreeCertificateChainEngine | Frees a nondefault certificate chain engine.
CertGetCertificateChain | Builds a chain context starting from an end certificate and going back to a trusted root certificate, if possible.
CertSetCertificateContextPropertiesFromCTLEntry | Sets properties on the certificate context using the attributes in the CTL entry.
CertIsValidCRLForCertificate | Checks a CRL to find out if it is a CRL that would include a specific certificate if that certificate were revoked.
CertVerifyCertificateChainPolicy | Checks a certificate chain to verify its validity including its compliance with any specified validity policy criteria.


CertCreateCertificateChainEngine

The CertCreateCertificateChainEngine function creates a new, non-default chain engine for an application. A chain engine restricts the certificates in the root store that can be used for verification, restricts the certificate stores to be searched for certificates and CTLs, sets a time-out limit for searches that involve URLs, and limits the number of certificates checked between checking for a certificate cycle.

BOOL WINAPI CertCreateCertificateChainEngine(
  PCERT_CHAIN_ENGINE_CONFIG pConfig,
  HCERTCHAINENGINE *phChainEngine
);

Parameters

pConfig
[in] Pointer to a CERT_CHAIN_ENGINE_CONFIG data structure that specifies the parameters for the chain engine.
phChainEngine
[out] Pointer to the handle of the chain engine created.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

The hChainEngine parameter returns the chain engine handle.

Examples

See Example C Program: Creating a Certificate Chain.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Chain Verification Functions, CERT_CHAIN_ENGINE_CONFIG, CertFreeCertificateChainEngine


CertCreateCTLEntryFromCertificateContextProperties

[This is preliminary documentation and subject to change.]

The CertCreateCTLEntryFromCertificateContextProperties function creates a certificate trust list (CTL) entry whose attributes are the certificate context's properties. The SubjectIdentifier in the CTL entry is the SHA1 hash of the certificate.

The certificate properties are added as attributes. The property attribute OID is the decimal PROP_ID preceded by szOID_CERT_PROP_ID_PREFIX. Each property value is copied as a single attribute value.

Additional attributes can be included in the CTL entry using the cOptAttr and rgOptAttr parameters.

WINCRYPT32API BOOL WINAPI
CertCreateCTLEntryFromCertificateContextProperties(
  PCCERT_CONTEXT pCertContext,
  DWORD cOptAttr,
  PCRYPT_ATTRIBUTE rgOptAttr,
  DWORD dwFlags,
  void *pvReserved,
  PCTL_ENTRY pCtlEntry,
  DWORD *pcbCtlEntry
);

Parameters

pCertContext
[in] Pointer to the CERT_CONTEXT used to create the CTL.
cOptAttr
[in] DWORD. The number of additional attributes to be added.
rgOptAttr
[in] Pointer to any array of CRYPT_ATTRIBUTE attributes to be added to the CTL.
dwFlags
[in] DWORD. Can be set to CTL_ENTRY_FROM_PROP_CHAIN_FLAG to force the inclusion of the chain building hash properties as attributes.
pvReserved
[in] Pointer to a void. Reserved for future use.
pCtlEntry
[out] Pointer to memory allocated for the returned CTL_ENTRY structure. Set this parameter to NULL to obtain the number of bytes that must be allocated.
pcbCtlEntry
[in][out] Pointer to a DWORD. This parameter returns the number of bytes that must be allocated for the returned CTL_ENTRY.

Return Values

Returns TRUE (non-zero) if the function succeeds or FALSE (zero) if the function fails.For exended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.
Library: Use Crypt32.lib.


CertDuplicateCertificateChain

The CertDuplicateCertificateChain function duplicates a pointer to a certificate chain by incrementing the chain's reference count.

PCCERT_CHAIN_CONTEXT WINAPI CertDuplicateCertificateChain(
  PCCERT_CHAIN_CONTEXT pChainContext
);

Parameters

pChainContext
[in] Pointer to a CERT_CHAIN_CONTEXT chain context to be duplicated.

Return Values

If the function succeeds, a pointer is returned to the chain context. This pointer has the same value as the pChainContext passed into the function.

If the function fails, NULL is returned.

Examples

See Example C Program: Creating a Certificate Chain.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Chain Verification Functions, CertGetCertificateChain


CertFindChainInStore

The CertFindChainInStore function finds the first or next certificate in a store that meets specified criteria. It then builds and verifies a certificate chain context for that certificate. The certificate that is found and for which the chain is built is selected according to criteria established by the dwFindFlags, dwFindType, and pvFindPara parameters. This function can be used in a loop to find all of the certificates in a certificate store that match the specified find criteria and to build a certificate chain context for each certificate found.

PCCERT_CHAIN_CONTEXT WINAPI CertFindChainInStore(
  HCERTSTORE hCertStore,
  DWORD dwCertEncodingType,
  DWORD dwFindFlags,
  DWORD dwFindType,
  const void *pvFindPara,
  PCCERT_CHAIN_CONTEXT pPrevChainContext
);

Parameters

hCertStore
[in] Handle of the store to be searched for a certificate upon which a chain is built. This hCertStore is passed as an additional store to CertGetCertificateChain as the chain is built.
dwCertEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

dwFindFlags
[in] The following dwFindFlags are defined for dwFindType CERT_CHAIN_FIND_BY_ISSUER:
FindFlag | Meaning
CERT_CHAIN_FIND_BY_ISSUER_COMPARE_KEY_FLAG | Compares the public key in the end certificate with the cryptographic service provider's public key. This comparison is the last check made on the chain when it is built. As an issuer hCryptProv container of a private key might need to be checked several times in this process, dwAcquirePrivateKeyFlags can be set in the CERT_CHAIN_FIND_BY_ISSUER_PARA data structure to enable caching of that hCryptProv.
CERT_CHAIN_FIND_BY_ISSUER_COMPLEX_CHAIN_FLAG | By default, only the first simple chain is checked for issuer name matches. With this flag set, the default is overridden and subsequent simple chains are also checked for issuer name matches.
CERT_CHAIN_FIND_BY_ISSUER_CACHE_ONLY_FLAG | Improves the performance of this function by causing it to search only the cached system stores (root, my, ca, trust) to find issuer certificates. If this flag is not set, the hCertStore passed to CertFindChainInStore and passed along as the additional store to CertGetCertificateChain and that store is searched in addition to the cached system stores.
CERT_CHAIN_FIND_BY_ISSUER_CACHE_ONLY_URL_FLAG | Only the URL cache is search. The search does not hit the wire.
CERT_CHAIN_FIND_BY_ISSUER_LOCAL_MACHINE_FLAG | Only opens the Local Machine certificate stores. Current User's certificate stores are not opened.
CERT_CHAIN_FIND_BY_ISSUER_NO_KEY_FLAG | No check is made to see if the end certificate has an associated private key.

dwFindType
[in] The following dwFindType is defined:
CERT_CHAIN_FIND_BY_ISSUER
Builds a certificate chain for an end certificate with an available private key. A matching dwKeySpec and enhanced key usage can also be specified, and a callback function can be provided for even more caller-provided filtering before building the chain. By default, only the issuers in the first simple chain are compared in an issuer name match. If this flag is set, all of the chains are checked for an issuer certificate matching one of a set of issuer names.
pvFindPara
[in] Pointer to a CERT_CHAIN_FIND_BY_ISSUER_PARA structure that contains members that modify the search. The structure also contains a pointer to a callback function that provides additional filtering.
pPrevChainContext
[in] Pointer to a CERT_CHAIN_CONTEXT structure of the last chain built. For the first call to the function, pPrevChainContext must be NULL. In all subsequent calls, it is the pointer returned by the previous call to the function. If this pointer is not changed, the function continues to build the same chain.

Return Values

If the first or next chain context is not built, NULL is returned. Otherwise, a pointer to a read-only CERT_CHAIN_CONTEXT structure is returned. CERT_CHAIN_CONTEXT is freed when passed as the pPrevChainContext on a subsequent call, otherwise, it must be freed explicitly by calling CertFreeCertificateChain.

Remarks

The pPrevChainContext parameter must be NULL on the first call to build the chain context. To build the next chain context, the pPrevChainContext is set to the CERT_CHAIN_CONTEXT structure returned by a previous call. A non-NULL pPrevChainContext is always freed by this function using CertFreeCertificateChain, even for an error.

A callback function can be passed as a member of the CERT_CHAIN_FIND_BY_ISSUER_PARA structure to further filter the search.

Examples

See Example C Program: Creating a Certificate Chain.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Chain Verification Functions, CERT_CHAIN_FIND_BY_ISSUER_PARA


CertFreeCertificateChain

The CertFreeCertificateChain function frees a certificate chain by reducing its reference count. If the reference count becomes zero, memory allocated for the chain is released.

void WINAPI CertFreeCertificateChain(
  PCCERT_CHAIN_CONTEXT pChainContext
);

Parameters

pChainContext
[in] Pointer to a CERT_CHAIN_CONTEXT certificate chain context to be freed. If the reference count on the context reaches zero, the storage allocated for the context is freed.

Return Values

This function does not return a value.

Examples

See Example C Program: Creating a Certificate Chain.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Chain Verification Functions, CertGetCertificateChain


CertFreeCertificateChainEngine

The CertFreeCertificateChainEngine function frees a certificate trust engine.

void WINAPI CertFreeCertificateChainEngine(
  HCERTCHAINENGINE hChainEngine
);

Parameters

hChainEngine
[in] Handle of the chain engine to be freed.

Return Values

This function does not return a value.

Examples

See Example C Program: Creating a Certificate Chain.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Chain Verification Functions, CertCreateCertificateChainEngine


CertGetCertificateChain

The CertGetCertificateChain function builds a certificate chain context starting from an end certificate and going back, if possible, to a trusted root certificate.

BOOL WINAPI CertGetCertificateChain(
  HCERTCHAINENGINE hChainEngine,
  PCCERT_CONTEXT pCertContext,
  LPFILETIME pTime,
  HCERTSTORE hAdditionalStore,
  PCERT_CHAIN_PARA pChainPara,
  DWORD dwFlags,
  LPVOID pvReserved,
  PCCERT_CHAIN_CONTEXT *ppChainContext
);

Parameters

hChainEngine
[in/optional] Handle of the chain engine (name space and cache) to be used. If hChainEngine is NULL, the default chain engine, HHCE_CURRENT_USER, is used. Can be set to HCCE_LOCAL_MACHINE.
pCertContext
[in] Pointer to the CERT_CONTEXT of the end certificate, the certificate for which a chain is being built. This certificate context will be the zero-index element in the first simple chain.
pTime
[in/optional] Pointer to a FILETIME variable indicating the time for which the chain is to be validated. Note that the time does not affect trust list, revocation, or root store checking. The current system time is used if NULL is passed to this parameter. Trust in a particular certificate being a trusted root is based on the current state of the root store and not the state of the root store at a time passed in by this parameter. For revocation, a CRL, itself, must be valid at the current time. The process for determining whether a particular certificate listed in a valid CRL is revoked is not the same for Service Pack 4 (SP4) and Windows 2000. In Windows 2000, and not in SP4, the value of this parameter is used to determine if a certificate listed in a CRL has been revoked.
hAdditionalStore
[in] Handle of any additional store to searched for supporting certificates and CTLs. This parameter can be NULL if no additional store is to be searched.
pChainPara
[in] Pointer to a CERT_CHAIN_PARA structure that includes chain-building parameters.
dwFlags
[in] Flag values indicating special processing. The following flags can be used.
Flag | Meaning
CERT_CHAIN_REVOCATION_CHECK_END_CERT | Revocation checking is done on the end certificate and only the end certificate.
CERT_CHAIN_REVOCATION_CHECK_CHAIN | Revocation checking is done on all of the certificates in every chain.
CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT | Revocation checking in done on all certificates in all of the chains except the root certificate.
CERT_CHAIN_CACHE_END_CERT | When this flag is set, the end certificate is cached, which might speed up the chain-building process. By default, the end certificate is not cached and it would need to be verified each time a chain is built for it.
CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY | Revocation checking only accesses cached URLs and does not hit the wire to do any revocation URL retrieval
CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL | Uses only cached URLs in building a certificate chain. The Internet and Intranet are not searched for URL-based objects. Note, not applicable to revocation checking. Set CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY to use only cached URLs for revocation checking.
CERT_CHAIN_DISABLE_PASS1_QUALITY_FILTERING | For performance reasons, the second pass of chain building only considers potential chain paths that have quality greater than or equal to the highest quality determined during the first pass. The first pass only considers valid signature, complete chain and trusted roots to calculate chain quality. This flag can be set to disable this optimization and consider all potiential chain paths during the second pass.
CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS? | The default is to return only the highest quality chain path. Setting this flag will return the lower quality chains. These are returned in the chain context's cLowerQualityChainContext and rgpLowerQualityChainContext fields.
CERT_CHAIN_DISABLE_AUTH_ROOT_AUTO_UPDATE? | Setting this flag inhibits the auto update of third party roots from the Windows Update Web Server.

pvReserved
[in] Reserved parameter, must be NULL.
ppChainContext
[in] Pointer to a pointer to the chain context created.

Return Values

Returns TRUE (non-zero) if the function succeeds or FALSE (zero) if the function fails.For exended error information, call GetLastError.

Remarks

When an application requests a certificate chain, the structure returned is in the form of a CERT_CHAIN_CONTEXT. This context contains an array of CERT_SIMPLE_CHAIN where each simple chain goes from an end certificate to a self-signed certificate. The chain context connects simple chains through trust lists. Each simple chain contains the chain of certificates, summary trust information about the chain and trust information about each certificate element in the chain.

Examples

See Example C Program: Creating a Certificate Chain.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Chain Verification Functions, CERT_CHAIN_PARA, CertFreeCertificateChain, CertDuplicateCertificateChain


CertIsValidCRLForCertificate

[This is preliminary documentation and subject to change.]

The CertIsValidCRLForCertificate function checks a CRL to find out if it is a CRL that would include a specific certificate if that certificate were revoked. If the CRL has an issuing distribution point (IDP) extension, the function checks whether that IDP is valid for the certificate being checked.

BOOL WINAPI CertIsValidCRLForCertificate(
  PCCERT_CONTEXT pCert,
  PCCRL_CONTEXT pCRL,
  DWORD dwFlags,
  void *pvReserved
);

Parameters

pCert
[in] Pointer to a certificate context.
pCRL
[in] Pointer to a CRL. The function checks this CRL to determine whether or not it could contain the certificate context pointed to by pCert. The function does not look for the certificate in the CRL.
dwFlags
Currently not used and must be set to zero (0).
pvReserved
Currently not used and must be set to NULL.

Return Values

The function returns TRUE if the CRL is a valid CRL to be searched for the specific certificate. It returns FALSE if the CRL is not a valid CRL for searching for the certificate.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.
Library: Use Crypt32.lib.
Unicode: Defined as Unicode and ANSI prototypes.


CertSetCertificateContextPropertiesFromCTLEntry

[This is preliminary documentation and subject to change.]

The CertSetCertificateContextPropertiesFromCTLEntry function sets the properties on the certificate context using the attributes in a the CTL entry.

WINCRYPT32API BOOL WINAPI
CertSetCertificateContextPropertiesFromCTLEntry(
  PCCERT_CONTEXT pCertContext,
  PCTL_ENTRY pCtlEntry,
  DWORD dwFlags
);

Parameters

pCertContext
[in] Pointer to the CCERT_CONTEXT whose attributes are to be set.
PCtlEntry
[in] Pointer to the CTL_ENTRY structure used to set the attributes on the certificate.
dwFlags
[in] DWORD. This parameter can be set to CERT_SET_PROPERTY_IGNORE_PERSIST_ERROR_FLAG to ignore any persisted error flags.

Return Values

Returns TRUE (non-zero) if the function succeeds or FALSE (zero) if the function fails.For exended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.
Library: Use Crypt32.lib.


CertVerifyCertificateChainPolicy

The CertVerifyCertificateChainPolicy function checks a certificate chain to verify its validity, including its compliance with any specified validity policy criteria.

BOOL WINAPI CertVerifyCertificateChainPolicy(
  LPCSTR pszPolicyOID,
  PCCERT_CHAIN_CONTEXT pChainContext,
  PCERT_CHAIN_POLICY_PARA pPolicyPara,
  PCERT_CHAIN_POLICY_STATUS pPolicyStatus
);

Parameters

pszPolicyOID
[in] Current predefined verify chain policy structures are listed in the following table.
Policy structure | Meaning
CERT_CHAIN_POLICY_BASE | Implements the base chain policy verification checks. The dwFlags member of the structure pointed to by pPolicyPara can be set to alter the default policy checking behavior.
CERT_CHAIN_POLICY_AUTHENTICODE Implements the Authenticode chain policy verification checks. The pvExtraPolicyPara member of the structure pointed to by pPolicyPara can be set to point to an AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_PARA structure.

The pvExtraPolicyStatus member of the structure pointed to by pPolicyStatus can be set to point to an AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_STATUS structure.
CERT_CHAIN_POLICY_AUTHENTICODE_TS Implements Authenticode Time Stamp chain policy verification checks. The pvExtraPolicyPara member of the data structure pointed to by pPolicyPara can be set to point to an AUTHENTICODE_TS_EXTRA_CERT_CHAIN_POLICY_PARA structure.

The pvExtraPolicyStatus member of the data structure pointed to by pPolicyStatus is not used and must be set to NULL
CERT_CHAIN_POLICY_SSL | Implements the SSL client/server chain policy verification checks. The pvExtraPolicyPara member in the data structure pointed to by pPolicyPara can be set to point to an SSL_EXTRA_CERT_CHAIN_POLICY_PARA structure initialized with additional policy criteria.
CERT_CHAIN_POLICY_BASIC_CONSTRAINTS Implements the basic constraints chain policy. Iterates through all the certificates in the chain checking for either a szOID_BASIC_CONSTRAINTS or a szOID_BASIC_CONSTRAINTS2 extension. If neither extension is present, the certificate is assumed to have valid policy. Otherwise, for the first certificate element, checks if it matches the expected CA_FLAG or END_ENTITY_FLAG specified in pPolicyPara->dwFlags. If neither or both flags are set, then, the first element can be either a CA or END_ENTITY. All other elements must be a CA. If the PathLenConstraint is present in the extension, it is checked.

The first elements in the remaining simple chains (that is, the certificates used to sign the CTL) are checked to be an END_ENTITY. If this verification fails, dwError will be set to TRUST_E_BASIC_CONSTRAINTS.
CERT_CHAIN_POLICY_NT_AUTH Implements the Windows NT Authentication chain policy, which consists of three distinct chain verifications in the following order:
  1. CERT_CHAIN_POLICY_BASE - Implements the base chain policy verification checks. The LOWORD of dwFlags can be set in pPolicyPara to alter the default policy checking behavior. For more information, see CERT_CHAIN_POLICY_BASE.
  2. CERT_CHAIN_POLICY_BASIC_CONSTRAINTS - Implements the basic constraints chain policy. The HIWORD of dwFlags can be set to specify if the first element must be either a CA or END_ENTITY. For more information, see CERT_CHAIN_POLICY_BASIC_CONSTRAINTS.
  3. Checks if the second element in the chain, the CA that issued the end certificate, is a trusted CA for NT Authentication. A CA is considered to be trusted if it exists in the "NTAuth" system registry store found in the CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE store location. If this verification fails, the CA is untrusted, and dwError is set to CERT_E_UNTRUSTEDCA.

If CERT_PROT_ROOT_DISABLE_NT_AUTH_REQUIRED_FLAG is set in the "Flags" value of the HKLM policy "ProtectedRoots" subkey, defined by CERT_PROT_ROOT_FLAGS_REGPATH and the above check fails, the chain is checked for CERT_TRUST_HAS_VALID_NAME_CONSTRAINTS set in dwInfoStatus. This is set if there was a valid name constraint for all name spaces including UPN. If the chain does not have this info status set, dwError is set to CERT_E_UNTRUSTEDCA.
CERT_CHAIN_POLICY_MICROSOFT_ROOT | Checks the last element of the first simple chain for a Microsoft root public key. If that element does not contain a Microsoft root public key, dwError is set to CERT_E_UNTRUSTEDROOT.

pChainContext
[in] Pointer to a CERT_CHAIN_CONTEXT structure containing a chain to be verified.
pPolicyPara
[in] Pointer to a CERT_CHAIN_POLICY_PARA structure that provides the policy verification criteria for the chain. The dwFlags member of that structure can be set to change the default policy checking behavior.

In addition, policy-specific parameters can also be passed in the pvExtraPolicyPara member of the structure.

pPolicyStatus
[in/out] Pointer to a CERT_CHAIN_POLICY_STATUS structure where status information on the chain is returned. OID-specific extra status can be returned in the pvExtraPolicyStatus member of this structure.

Remarks

A dwError member of the CERT_CHAIN_POLICY_STATUS structure pointed to by pPolicyStatus can apply to a single chain element, to a simple chain, or to an entire chain context. If dwError applies to the entire chain context, both the lChainIndex and the lElementIndex members of the CERT_CHAIN_POLICY_STATUS structure are set to –1. If dwError applies to a complete simple chain, lElementIndex is set to –1 and lChainIndex is set to the index of the first chain that has an error. If dwError applies to a single certificate element, lChainIndex and lElementIndex index the first certificate that has the error. That certificate element is: pChainContext->rgpChain[lChainIndex]->rgpElement[lElementIndex].

Return Values

If the chain can be verified for the specified policy, TRUE is returned and the dwError member of the pPolicyStatus is updated. A dwError of 0 (ERROR_SUCCESS or S_OK) indicates the chain satisfies the specified policy. If the chain cannot be validated, FALSE is returned.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Chain Verification Functions, CERT_CHAIN_POLICY_PARA, CERT_CHAIN_POLICY_STATUS


Message Functions

CryptoAPI message functions consist of two groups of functions: the low-level message functions and the simplified message functions.

Low-level message functions create and work directly with PKCS #7 messages. These functions encode PKCS #7data for transmission and decode PKCS #7 data received. They also decrypt and verify the signatures of received messages. For an overview of the PKCS #7 standard and low-level messages, see Low Level Messages.

Simplified message functions are at a higher level and wrap several low-level message functions and certificate functions into single functions that perform a specific task in a specific manner. These functions reduce the number of function calls needed accomplish a task, thereby simplifying CryptoAPI use. For an overview of simplified messages, see Simplified Messages.

These functions can be divided into groups as follows:

  • Low-Level Message Functions
  • Simplified Message Functions


Low-Level Message Functions

The low-level message functions provide the necessary functionality to encode data for transmission and to decode PKCS #7 messages received. Functionality is also provided to decrypt and verify the signatures of received messages. The use of these low level message functions in most applications is not recommended. For most applications, the use of Simplified Message Functions, that wrap several low level functions into a single function call, is preferred.

Function | Description
CryptMsgCalculateEncodedLength | Calculates the length of an encoded cryptographic message.
CryptMsgClose | Closes a handle of a cryptographic message.
CryptMsgControl | Performs a special control function after the final CryptMsgUpdate of an encoded or decoded cryptographic message.
CryptMsgCountersign | Countersigns an already existing signature in a message.
CryptMsgCountersignEncoded | Countersigns an already existing signature (encoded SignerInfo, as defined by PKCS #7).
CryptMsgDuplicate | Duplicates a cryptographic message handle by incrementing the reference count. The reference count keeps track of the lifetime of the message.
CryptMsgGetParam | Acquires a parameter after encoding or decoding a cryptographic message.
CryptMsgOpenToDecode | Opens a cryptographic message for decoding.
CryptMsgOpenToEncode | Opens a cryptographic message for encoding.
CryptMsgUpdate | Updates the contents of a cryptographic message.
CryptMsgVerifyCountersignatureEncoded | Verifies a countersignature in terms of the SignerInfo structure (as defined by PKCS # 7).
CryptMsgVerifyCountersignatureEncodedEx | Verifies a countersignature in terms of the SignerInfo structure. The signer can be a CERT_PUBLIC_KEY_INFO structure, a certificate context or a chain context.


CryptMsgCalculateEncodedLength

The CryptMsgCalculateEncodedLength function calculates the maximum number of bytes need for an encoded cryptographic message given the message type, encoding parameters, and total length of the data to be encoded. Note that the result will always be greater than or equal to the actual number of bytes needed.

DWORD WINAPI CryptMsgCalculateEncodedLength(
  DWORD dwMsgEncodingType,
  DWORD dwFlags,
  DWORD dwMsgType,
  const void *pvMsgEncodeInfo,
  LPSTR pszInnerContentObjID,
  DWORD cbData
);

Parameters

dwMsgEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

dwFlags
[in] Currently defined flags are shown in the following table.
Flag | Meaning
CMSG_BARE_CONTENT_FLAG | Indicates that streamed output will not have an outer ContentInfo wrapper (as defined by PKCS #7). This makes it suitable to be streamed into an enclosing message.
CMSG_DETACHED_FLAG | Indicates that there is detached data being supplied for the subsequent calls to CryptMsgUpdate.
CMSG_CONTENTS_OCTETS_FLAG | Used when you are calculating the size of a DER encoding of a message that is going to be nested inside an enveloped message. This is particularly useful when streaming is being performed.
CMSG_CMS_ENCAPSULATED_CONTENT_FLAG | Non-Data type inner content is encapsulated within an OCTET STRING. This flag is applicable for both Signed and Enveloped messages.

dwMsgType
[in] Currently defined message types are shown in the following table.
Message type | Associated pvMsgEncodeInfo structures
CMSG_DATA | An octet (BYTE) string.
CMSG_SIGNED | CMSG_SIGNED_ENCODE_INFO
CMSG_ENVELOPED | CMSG_ENVELOPED_ENCODE_INFO
CMSG_SIGNED_AND_ENVELOPED | Not implemented.
CMSG_HASHED | CMSG_HASHED_ENCODE_INFO
CMSG_ENCRYPTED | Not implemented.

pvMsgEncodeInfo
[in] Pointer to the data to be encoded. The type of data pointed to depends on the value of dwMsgType. For details, see the dwMsgType table.
pszInnerContentObjID
[in/optional] When calling CryptMsgCalculateEncodedLength with data provided to CryptMsgUpdate already encoded, the appropriate object identifier is passed in pszInnerContentObjID. If pszInnerContentObjID is NULL, the inner content type is assumed not to have been previously encoded, and is encoded as an octet string and given the type CMSG_DATA.

When streaming is being used, pszInnerContentObjID must be either NULL or szOID_RSA_data.

The following algorithm object identifiers are commonly used:

  • szOID_RSA_data
  • szOID_RSA_signedData
  • szOID_RSA_envelopedData
  • szOID_RSA_signEnvData
  • szOID_RSA_digestedData
  • szOID_RSA_encryptedData
  • SPC_INDIRECT_DATA_OBJID

A user can define new inner content usage. The user must ensure that the sender and receiver of the message agree upon the semantics associated with the object identifier.

cbData
[in] Size, in bytes, of the content.

Return Values

Returns the required length for an encoded cryptographic message. This length might not be the exact length but it will not be less than the required length. Zero is returned if the function fails.

To retrieve extended error information, use the GetLastError function.

The following table lists the error codes most commonly returned by the GetLastError function.

Error Code | Description
CRYPT_E_INVALID_MSG_TYPE | The message type is invalid.
CRYPT_E_UNKNOWN_ALGO | The cryptographic algorithm is unknown.
E_INVALIDARG | One or more arguments are invalid.

Examples

See Example C Program: Signing, Encoding, Decoding, and Verifying a Message, Example C Program: Encoding and Decoding an Enveloped Message, Alternate Code for Encoding an Enveloped Message, Example C Program: Encoding an Enveloped, Signed Message, and Example C Program: Encoding and Decoding a Hashed Message.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Low-Level Message Functions, Simplified Message Functions, CryptMsgOpenToEncode


CryptMsgClose

The CryptMsgClose function closes a cryptographic message handle. At each call to this function, the reference count on the message is reduced by one. When the reference count reaches zero, the message is fully released.

BOOL WINAPI CryptMsgClose(
  HCRYPTMSG hCryptMsg
);

Parameters

hCryptMsg
[in] Handle of the cryptographic message to be closed.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Examples

See Example C Program: Signing, Encoding, Decoding, and Verifying a Message, Example C Program: Encoding and Decoding an Enveloped Message, Alternate Code for Encoding an Enveloped Message, Example C Program: Encoding an Enveloped, Signed Message, and Example C Program: Encoding and Decoding a Hashed Message.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Low-Level Message Functions, Simplified Message Functions, CryptMsgOpenToEncode, CryptMsgOpenToDecode


CryptMsgControl

The CryptMsgControl function performs a control operation after a message has been decoded by a final CryptMsgUpdate call. The control operations provided by this function are used for decryption, signature and hash verification, and the addition and deletion of certificates, CRLs, signers, and unauthenticated attributes.

Important changes that affect the handling of enveloped messages have been made to CryptoAPI in order to support S/MIME e-mail interoperability. See the Remarks for CryptMsgOpenToEncode for details.

BOOL WINAPI CryptMsgControl(
  HCRYPTMSG hCryptMsg,
  DWORD dwFlags,
  DWORD dwCtrlType,
  const void *pvCtrlPara
);

Parameters

hCryptMsg
[in] Handle of a cryptographic message for which a control is to be applied.
dwFlags
[in] Reserved for future use and must be zero (0).
dwCtrlType
[in] Specifies the type of operation to be performed. Currently defined message control types and their associated pvCtrlPara structures are shown in the following table.
Message control type | Associated structure
CMSG_CTRL_VERIFY_SIGNATURE | CERT_INFO identifying the signer of the message whose signature is to be verified. This type is not supported before Windows 2000.
CMSG_CTRL_DECRYPT | CMSG_CTRL_DECRYPT_PARA used to decrypt the message for the specified key transport recipient. Applicable to RSA recipients.
CMSG_CTRL_VERIFY_HASH | Not used and set to NULL.
CMSG_CTRL_ADD_SIGNER | CMSG_SIGNER_ENCODE_INFO containing the signer information to be added to the message
CMSG_CTRL_DEL_SIGNER | The index of the signer to be deleted.
CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR | CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA containing the index of the signer and a BLOB containing the unauthenticated attribute information to be added to the message.
CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR | CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA containing an index specifying the signer and the index specifying the signer's unauthenticated attribute to be deleted
CMSG_CTRL_ADD_CERT | CRYPTOAPI_BLOB containing the encoded bytes of the certificate to be added to the message.
CMSG_CTRL_DEL_CERT | Index of the certificate to be deleted from the message.
CMSG_CTRL_ADD_CRL | BLOB containing the encoded bytes of the CRL to be added to the message.
CMSG_CTRL_DEL_CRL | Index of the CRL to be deleted from the message.
CMSG_CTRL_ADD_ATTR_CERT | BLOB containing the encoded bytes of attribute certificate.
CMSG_CTRL_DEL_ATTR_CERT | Index of the attribute certificate to be removed.
CMSG_CTRL_KEY_TRANS_DECRYPT | CMSG_KEY_TRANS_RECIPIENT_INFO structure used to decrypt the message for the specified key transport recipient. Key transport is used with RSA encryption/decryption.
CMSG_CTRL_KEY_AGREE_DECRYPT | CMSG_KEY_AGREE_RECIPIENT_INFO structure used to decrypt the message for the specified key agreement session key. Key agreement is used with Diffie Hellman encryption/decryption.
CMSG_CTRL_MAIL_LIST_DECRYPT | CMSG_MAIL_LIST_RECIPIENT_INFO structure used to decrypt the message for the specified recipient using a previously distributed key-encryption key (KEK).
CMSG_CTRL_VERIFY_SIGNATURE_EX | CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA specifies the signer index and public key to verify the message signature. The signer public key can be a CERT_PUBLIC_KEY_INFO structure, a certificate context, or a certificate chain context.

pvCtrlPara
[in] Pointer to a structure determined by the value of dwCtrlType. See the table above for details.

If dwCtrlType is CMSG_CTRL_DECRYPT, CMSG_CTRL_KEY_TRANS_DECRYPT, CMSG_CTRL_KEY_AGREE_DECRYPT, or CMSG_CTRL_MAIL_LIST_DECRYPT and the streamed enveloped message is being decoded, decoding will be done as if the streamed content where being decrypted. If any encrypted streamed content has accumulated prior to this call, some or all of the plaintext resulting from the decryption of the Cipher text is passed back to the application through the callback function specified in the call to CryptMsgOpenToDecode.

Note When streaming an enveloped message, CryptMsgControl is not called until the polling for the availability of the CMSG_ENVELOPE_ALGORITHM_PARAM succeeds. If the polling does not succeed, an error results. See CryptMsgOpenToDecode for a description of that polling.

If dwCtrlType is CMSG_CTRL_VERIFY_HASH the hash computed from the content of the message is compared against the hash contained in the message.

For a value of CMSG_CTRL_ADD_SIGNER in dwCtrlType, pvCtrlPara points to a CMSG_SIGNER_ENCODE_INFO structure containing the signer information to be added to the message.

For a value of CMSG_CTRL_DEL_SIGNER, once a deletion is made, any other signer indices in use for this message are invalidated and must be reacquired by calling CryptMsgGetParam.

If dwCtrlType is CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR, once a deletion is made, any other unauthenticated attribute indices in use for this signer are invalidated and must be reacquired by calling CryptMsgGetParam.

If dwCtrlType is CMSG_CTRL_DEL_CERT, once a deletion is made, any other certificate indices in use for this message are invalidated and must be reacquired by calling CryptMsgGetParam.

If dwCtrlType is CMSG_CTRL_DEL_CRL, once a deletion is made, any other CRL indices in use for this message are invalidated and will need to be reacquired by calling CryptMsgGetParam.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

When a streamed, enveloped message is being decoded, errors encountered in the application-defined callback function specified by pStreamInfo in CryptMsgOpenToDecode might be propagated to CryptMsgControl. If this happens, SetLastError is not called by CryptMsgControl after the callback returns. This preserves any errors encountered under the control of the application. It is the responsibility of the callback function (or one of the APIs that it calls) to call SetLastError if an error occurs while the application is processing the streamed data.

The following table lists the error codes most commonly returned by the GetLastError function.

Error Code | Description
CRYPT_E_CONTROL_TYPE | The control type is not valid.
for dwCtrlType == CMSG_CTRL_VERIFY_SIGNATURE |
CRYPT_E_AUTH_ATTR_MISSING | The message does not contain an expected authenticated attribute.
CRYPT_E_BAD_ENCODE | An error was encountered while encoding or decoding.
CRYPT_E_HASH_VALUE | The hash value is not correct.
CRYPT_E_INVALID_MSG_TYPE | The message type is invalid.
CRYPT_E_SIGNER_NOT_FOUND | The specified signer for the message was not found.
CRYPT_E_UNEXPECTED_ENCODING | The message is not encoded as expected.
CRYPT_E_UNKNOWN_ALGO | The cryptographic algorithm is unknown.
E_OUTOFMEMORY | Ran out of memory.
Propagated errors that might be encountered: | An error can be propagated from: CryptCreateHash CryptHashData CryptGetHashParam CryptImportKey CryptVerifySignature
for dwCtrlType == CMSG_CTRL_DECRYPT |
CRYPT_E_ALREADY_DECRYPTED | The message content has already been decrypted.
CRYPT_E_INVALID_INDEX | The index value is not valid.
CRYPT_E_INVALID_MSG_TYPE | The message type is invalid.
CRYPT_E_RECIPIENT_NOT_FOUND | The enveloped data message does not contain the specified recipient.
CRYPT_E_UNKNOWN_ALGO | The cryptographic algorithm is unknown.
E_INVALIDARG | One or more arguments are invalid.
E_OUTOFMEMORY | Ran out of memory.
Propagated errors that might be encountered: | An error can be propagated from: CryptGetUserKey CryptImportKey CryptDecrypt
for dwCtrlType == CMSG_CTRL_VERIFY_HASH |
CRYPT_E_HASH_VALUE | The hash value is not correct.
CRYPT_E_INVALID_MSG_TYPE | The message type is invalid.
E_OUTOFMEMORY | Ran out of memory.
Propagated errors that might be encountered: | An error can be propagated from: CryptGetHashParam
for dwCtrlType == CMSG_CTRL_ADD_SIGNER |
CRYPT_E_OID_FORMAT | The object identifier is badly formatted.
CRYPT_E_UNKNOWN_ALGO | The cryptographic algorithm is unknown.
E_OUTOFMEMORY | Ran out of memory.
Propagated errors that might be encountered: | An error can be propagated from: CryptCreateHash CryptHashData CryptGetHashParam CryptSignHash
for dwCtrlType == CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR |
CRYPT_E_INVALID_INDEX | The index value is not valid.
E_OUTOFMEMORY | Ran out of memory.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Examples

See Example C Program: Signing, Encoding, Decoding, and Verifying a Message, Example C Program: Encoding and Decoding an Enveloped Message, Alternate Code for Encoding an Enveloped Message, Example C Program: Encoding an Enveloped, Signed Message, and Example C Program: Encoding and Decoding a Hashed Message.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Low-Level Message Functions, Simplified Message Functions


CryptMsgCountersign

The CryptMsgCountersign function countersigns an existing signature in a message. Countersignatures are used to sign an existing signature's encrypted hash of the message. Countersignatures can be used for various purposes including time stamping a message.

BOOL WINAPI CryptMsgCountersign(
  HCRYPTMSG hCryptMsg,
  DWORD dwIndex,
  DWORD cCountersigners,
  PCMSG_SIGNER_ENCODE_INFO rgCountersigners
);

Parameters

hCryptMsg
[in/out] Cryptographic message handle to be used.
dwIndex
[in] Zero-based index of the signer in the signed or signed-and-enveloped message to be countersigned.
cCountersigners
[in] Number of countersigners in the rgCountersigners array.
rgCountersigners
[in] Array of countersigners' CMSG_SIGNER_ENCODE_INFO structures.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

The following table lists the error codes most commonly returned by the GetLastError function.

Error Code | Description
E_INVALIDARG | One or more arguments are invalid.
E_OUTOFMEMORY | Ran out of memory.
ERROR_MORE_DATA | The specified is not large enough to hold the returned data.
Propagated errors that might be encountered: | An error can be propagated from: CryptMsgCountersignEncoded.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Examples

See Example C Program: Encoding and Decoding a CounterSigned Message.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Low-Level Message Functions, Simplified Message Functions, CryptMsgCountersignEncoded, CryptMsgVerifyCountersignatureEncoded


CryptMsgCountersignEncoded

The CryptMsgCountersignEncoded function countersigns an existing PKCS #7 message signature. The pbCountersignature BYTE buffer it creates is an PKCS #7 encoded SignerInfo that can be used as an unauthenticated Countersignature attribute of a PKCS #9 signed-data or signed-and-enveloped-data message.

BOOL WINAPI CryptMsgCountersignEncoded(
  DWORD dwEncodingType,
  PBYTE pbSignerInfo,
  DWORD cbSignerInfo,
  DWORD cCountersigners,
  PCMSG_SIGNER_ENCODE_INFO rgCountersigners,
  PBYTE pbCountersignature,
  PDWORD pcbCountersignature
);

Parameters

dwEncodingType
[in] Specifies the encoding type used. Currently, only X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are being used; however, additional encoding types may be added in the future. For either current encoding type, use:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
pbSignerInfo
[in] Pointer to the encoded SignerInfo that is to be countersigned.
cbSignerInfo
[in] Count, in bytes, of the encoded SignerInfo data.
cCountersigners
[in] Number of countersigners in the rgCountersigners array.
rgCountersigners
[in] Array of countersigners' CMSG_SIGNER_ENCODE_INFO structures.
pbCountersignature
[out] Pointer to a buffer to receive an encoded PKCS #9 countersignature attribute.

On input, this parameter can be NULL to set the size of this information for memory allocation purposes. See Retrieving Data of Unknown Length.

pcbCountersignature
[in/out] Pointer to a variable that specifies the size, in bytes, of the buffer pointed to by the pbCountersignature parameter. When the function returns, the variable pointed to by the pcbCountersignature parameter contains the number of bytes stored in the buffer.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

The following table lists the error codes most commonly returned by the GetLastError function.

Error Code | Description
CRYPT_E_OID_FORMAT | The object identifier is badly formatted.
E_INVALIDARG | One or more arguments are invalid.
E_OUTOFMEMORY | Ran out of memory.
Propagated errors that might be encountered: | An error can be propagated from CryptCreateHash CryptHashData CryptGetHashParam CryptSignHash CryptMsgOpenToEncode CryptMsgUpdate An error can be propagated from CryptMsgControl if dwCtrlType == CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Low-Level Message Functions, Simplified Message Functions, CryptMsgCountersign, CryptMsgVerifyCountersignatureEncoded


CryptMsgDuplicate

The CryptMsgDuplicate function duplicates a cryptographic message handle by incrementing its reference count.

HCRYPTMSG WINAPI CryptMsgDuplicate(
  HCRYPTMSG hCryptMsg
);

Parameters

hCryptMsg
[in] Handle of the cryptographic message to be duplicated. Duplication is done by incrementing the reference count of the message. A copy of the message is not made.

Return Values

The returned handle is the same as the handle input. A copy of the message is not created.

Remarks

CryptMsgDuplicate is used to increase the reference count on an HCRYPTMSG handle so that multiple calls to CryptMsgClose are required to actually release the handle.

Examples

See Example C Program: Encoding and Decoding a Hashed Message.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Low-Level Message Functions, Simplified Message Functions, CryptMsgClose


CryptMsgGetParam

The CryptMsgGetParam function acquires a message parameter after a cryptographic message has been encoded or decoded. This function is called after the final CryptMsgUpdate call.

BOOL WINAPI CryptMsgGetParam(
  HCRYPTMSG hCryptMsg,
  DWORD dwParamType,
  DWORD dwIndex,
  void *pvData,
  DWORD *pcbData
);

Parameters

hCryptMsg
[in] Handle of a cryptographic message.
dwParamType
[in] Indicates the parameter types of data to be retrieved. The type of data to be retrieved determines the type of structure to use for pvData.

For an encoded message, only the CMSG_BARE_CONTENT, CMSG_ENCODE_SIGNER, CMSG_CONTENT_PARAM and CMSG_COMPUTED_HASH_PARAM dwParamTypes are valid.
dwParamType value | Meaning | pvData pointer type required
CMSG_ATTR_CERT_COUNT_PARAM | Count of the attribute certificates in a SIGNED or ENVELOPED message. | DWORD to receive the count.
CMSG_ATTR_CERT_PARAM | Retrieves an attribute certificate. To get all the attribute certificates, call CryptMsgGetParam varying dwIndex set to 0 the number of attributes minus one. | Buffer to contain the encoded attribute certificate's bytes.
CMSG_BARE_CONTENT_PARAM | Retrieves the encoded content of an encoded cryptographic message, without the outer layer of CONTENT_INFO. That is, only the encoding of the PKCS #7 defined ContentInfo.content field is returned. | Buffer for the encoded bytes.
CMSG_CERT_COUNT_PARAM | Determines the number of certificates in a received SIGNED or ENVELOPED message. | DWORD to receive the count.
CMSG_CERT_PARAM | Retrieves a signer's certificate. To get all of the signer's certificates, call CryptMsgGetParam, varying dwIndex from 0 to the number of available certificates minus one. | Buffer for the encoded bytes.
CMSG_COMPUTED_HASH_PARAM | Retrieves the value of the hash calculated of the data in the message. This type is applicable to both encode and decode. | Buffer for the hash bytes.
CMSG_CONTENT_PARAM Retrieves the whole PKCS #7 message from a message opened to encode. Retrieves the inner content of a message opened to decode. If the message is enveloped, the inner type is data, and CryptMsgControl has been called to decrypt the message, the decrypted content is returned. If the inner type is not data, the encoded BLOB that requires further decoding is returned.
If the message is not enveloped and the inner content is DATA, the returned data is the octets of the inner content.
This type is applicable to both encode and decode. 		Buffer.

For decoding, if the type is CMSG_DATA, the content's octets are returned; else, the encoded inner content is returned.
CMSG_CRL_COUNT_PARAM | Determines the count of CRLs in a received, SIGNED or ENVELOPED message. | DWORD to receive the count.
CMSG_CRL_PARAM | Retrieves a CRL. To get all the CRLs, call CryptMsgGetParam, varying dwIndex from 0 to the number of available CRLs minus one. | Buffer for the encoded CRL bytes.
CMSG_ENCODED_MESSAGE | Changes the contents of an already encoded message. The message must first be decoded with a call to CryptMsgOpenToDecode. Then the change to the message is made through a call to CryptMsgControl, CryptMsgCountersign, or CryptMsgCountersignEncoded. The message is then encoded again with a call to CryptMsgGetParam, specifying CMSG_ENCODED_MESSAGE to get a new encoding that reflects the changes made. This can be used, for instance, to add a time-stamp attribute to a message. | Buffer for the encoded bytes.
CMSG_ENCODED_SIGNER | Retrieves the encoded CMSG_SIGNER_INFO signer information for a message signer. | Buffer for the encoded bytes.
CMSG_ENCRYPTED_DIGEST | Retrieves the encrypted hash of a signature. Typically used for performing time-stamping. | Buffer for the encoded bytes.
CMSG_ENCRYPT_PARAM | Retrieves the encryption algorithm used to encrypted the message. | Buffer for a CRYPT_ALGORITHM_IDENTIFIER structure.
CMSG_ENVELOPE_ALGORITHM_PARAM | Retrieves the encryption algorithm used to encrypt an ENVELOPED message. | Buffer for a CRYPT_ALGORITHM_IDENTIFIER structure.
CMSG_HASH_ALGORITHM_PARAM | Retrieves the hash algorithm used to hash the message when it was created. | Buffer for a CRYPT_ALGORITHM_IDENTIFIER structure.
CMSG_HASH_DATA_PARAM | Retrieves the hash value stored in the message when it was created. | Buffer to receive the hash value.
CMSG_INNER_CONTENT_TYPE_PARAM | Determines the inner content type of a received message. This type is not applicable to messages of type DATA. | Buffer to receive a NULL-terminated object identifier (OID) string.
CMSG_RECIPIENT_COUNT_PARAM | Returns the number of key transport recipients of an ENVELOPED received message. | DWORD to receive the count.
CMSG_CMS_RECIPIENT_COUNT_PARAM | Returns the total count of all message recipients including key agreement and mail list recipients | DWORD to receive the count.
CMSG_RECIPIENT_INDEX_PARAM | Returns the index of the key transport recipient used to decrypt an ENVELOPED message. This value is available only after a message has been decrypted. | DWORD to receive the index value.
CMSG_CMS_RECIPIENT_INDEX_PARAM | Returns the index of the key transport, key agreement, or mail list recipient used to decrypt an ENVELOPED message. | DWORD to receive the index value.
CMSG_CMS_RECIPIENT_ENCRYPTED_KEY_INDEX_PARAM | Returns the index of the encrypted key of a key agreement recipient used to decrypt an ENVELOPED message. | DWORD to receive the index value.
CMSG_RECIPIENT_INFO_PARAM Returns certificate information about a key transport message's recipient. To get certificate information on all key transport message's recipients, repetitively call CryptMsgGetParam, varying dwIndex from 0 to the number of recipients minus one.
Only the Issuer, SerialNumber, and PublicKeyAlgorithm members of the CERT_INFO structure returned are available and valid. 		Buffer to receive a CERT_INFO structure.
CMSG_CMS_RECIPIENT_INFO_PARAM Returns information about a key transport, key agreement, or mail list recipient. It is not limited to key transport message recipients.
To get information on all of a message's recipients, repetitively call CryptMsgGetParam, varying dwIndex from 0 to the number of recipients minus one. 		Buffer to receive a CMSG_CMS_RECIPIENT_INFO structure.
CMSG_SIGNER_AUTH_ATTR_PARAM | Returns the authenticated attributes of a message signer. To retrieve the authenticated attributes for a specified signer, call CryptMsgGetParam, with dwIndex equal to that signer's index. | Buffer to receive a CRYPT_ATTRIBUTES structure.
CMSG_SIGNER_CERT_INFO_PARAM Returns information on a message signer needed to identify the signer's certificate. A certificate's Issuer and SerialNumber can be used to uniquely identify a certificate for retrieval. To retrieve information for all the signers, repetitively call CryptMsgGetParam varying dwIndex from 0 to the number of signers minus one.
Only the Issuer and SerialNumber fields in the CERT_INFO structure returned contain available, valid data 		Buffer to receive the CERT_INFO structure.
CMSG_SIGNER_CERT_ID_PARAM | Returns information on a message signer needed to identify the signer's public key. This could be a certificate's Issuer and SerialNumber, a KeyID, or a HashId. To retrieve information for all the signers, call CryptMsgGetParam varying dwIndex from 0 to the number of signers minus one. | Buffer to receive a CERT_ID structure.
CMSG_SIGNER_COUNT_PARAM | Returns the number of signers of a received SIGNED message. | DWORD to receive the count.
CMSG_SIGNER_HASH_ALGORITHM_PARAM | Returns the hash algorithm used by a signer of the message. To get the hash algorithm for a specified signer, call CryptMsgGetParam, with dwIndex equal to that signer's index. | Buffer to receive the CRYPT_ALGORITHM_IDENTIFIER structure.
CMSG_SIGNER_INFO_PARAM Returns information on a message signer. This includes the issuer and serial number of the signer's certificate and authenticated and unauthenticated attributes of the signer's certificate.
To retrieve signer information on all of the signers of a message, call CryptMsgGetParam, varying dwIndex from 0 to the number of signers minus one. 		Buffer to receive a CMSG_SIGNER_INFO structure.
CMSG_CMS_SIGNER_INFO_PARAM Returns information on a message signer. This includes a signerId and authenticated and unauthenticated attributes.
To retrieve signer information on all of the signers of a message, call CryptMsgGetParam, varying dwIndex from 0 to the number of signers minus one. 		Buffer to receive a CMSG_CMS_SIGNER_INFO structure.
CMSG_SIGNER_UNAUTH_ATTR_PARAM | Returns a message signer's unauthenticated attributes. To retrieve the unauthenticated attributes for a specified signer, call CryptMsgGetParam, with dwIndex equal to that signer's index. | Buffer to receive a CRYPT_ATTRIBUTES structure.
CMSG_TYPE_PARAM | Returns the message type of a decoded message of unknown type. The retrieved message type can be compared to supported types to determine whether processing can continued. For supported message types, see the dwMessageType parameter of CryptMsgOpenToDecode. | DWORD to receive the message type.
CMSG_UNPROTECTED_ATTR_PARAM | Returns the unprotected attributes in an enveloped message. | Pointer to a buffer to receive a CMSG_ATTR structure.
CMSG_VERSION_PARAM | Returns he version of the decoded message. For detailed information, see the table in the Remarks section | DWORD to receive the version number.

dwIndex
[in] Index for the parameter being retrieved, where applicable. When a parameter is not being retrieved, this parameter is ignored and is set to zero.
pvData
[out] Pointer to a buffer that receives the data retrieved. The form of this data will vary, depending on the parameter type.

This parameter can be NULL to set the size of this information for memory allocation purposes. See Retrieving Data of Unknown Length.

When processing the data returned in this buffer, applications need to use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

pcbData
[in/out]Pointer to a variable that specifies the size, in bytes, of the buffer pointed to by the pvData parameter. When the function returns, the variable pointed to by the pcbData parameter contains the number of bytes stored in the buffer.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

The following table lists the error codes most commonly returned by the GetLastError function.

Error Code | Description
CRYPT_E_ATTRIBUTES_MISSING | The message does not contain the requested attributes.
CRYPT_E_INVALID_INDEX | The index value is not valid.
CRYPT_E_INVALID_MSG_TYPE | The message type is invalid.
CRYPT_E_NOT_DECRYPTED | The message content has not been decrypted yet.
CRYPT_E_OID_FORMAT | The object identifier is badly formatted.
CRYPT_E_UNEXPECTED_ENCODING | The message is not encoded as expected.
E_INVALIDARG | One or more arguments are invalid.
ERROR_MORE_DATA | The specified is not large enough to hold the returned data.

For dwParamType CMSG_COMPUTED_HASH_PARAM, an error can be propagated from CryptGetHashParam.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Remarks

The following version numbers, returned by calls to CryptMsgGetParam with dwParamType set to CMSG_VERSION_PARAM are defined:

CMSG_SIGNED_DATA_V1
CMSG_SIGNED_DATA_V3
CMSG_SIGNED_DATA_PKCS_1_5_VERSION
CMSG_SIGNED_DATA_CMS_VERSION
CMSG_SIGNER_INFO_V1
CMSG_SIGNER_INFO_V3
CMSG_SIGNER_INFO_PKCS_1_5_VERSION
CMSG_SIGNER_INFO_CMS_VERSION
CMSG_HASHED_DATA_V0
CMSG_HASHED_DATA_V2
CMSG_HASHED_DATA_PKCS_1_5_VERSION
CMSG_HASHED_DATA_CMS_VERSION
CMSG_ENVELOPED_DATA_V0
CMSG_ENVELOPED_DATA_V2
CMSG_ENVELOPED_DATA_PKCS_1_5_VERSION
CMSG_ENVELOPED_DATA_CMS_VERSION

Examples

See Example C Program: Signing, Encoding, Decoding, and Verifying a Message, Example C Program: Encoding and Decoding an Enveloped Message, Alternate Code for Encoding an Enveloped Message, Example C Program: Encoding an Enveloped, Signed Message, and Example C Program: Encoding and Decoding a Hashed Message.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Low-Level Message Functions, Simplified Message Functions, CryptMsgUpdate, CryptMsgOpenToDecode, CryptMsgOpenToEncode


CryptMsgOpenToDecode

The CryptMsgOpenToDecode function opens a cryptographic message for decoding and returns a handle of the opened message. The message remains open until CryptMsgClose is called.

Important changes that affect the handling of enveloped messages have been made to CryptoAPI to support S/MIME e-mail interoperability. For details, see the Remarks section in CryptMsgOpenToEncode.

HCRYPTMSG WINAPI CryptMsgOpenToDecode(
  DWORD dwMsgEncodingType,
  DWORD dwFlags,
  DWORD dwMsgType,
  HCRYPTPROV hCryptProv,
  PCERT_INFO pRecipientInfo,
  PCMSG_STREAM_INFO pStreamInfo
);

Parameters

dwMsgEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

dwFlags
[in] The following flags are defined
Value | Description
CMSG_DETACHED_FLAG | Indicates that the message to be decoded is detached. If this flag is not set, the message is not detached.
CMSG_CRYPT_RELEASE_CONTEXT_FLAG | If set, the hCryptProv passed to this function is released on the final CryptMsgUpdate. The handle is not released if the function fails.

dwMsgType
[in] In most cases message type is determined from the message header and zero is passed. In some cases, notably with Internet Explorer 3.0, message do not have headers and the type of message to be decoded must be supplied in the function call. If the header is missing and zero (0) is passed, the function fails.

The following non-zero, currently predefined message types are:

  • CMSG_DATA
  • CMSG_ENVELOPED
  • CMSG_HASHED
  • CMSG_SIGNED
  • CMSG_SIGNED_AND_ENVELOPED
hCryptProv
[in] Specifies a handle for the cryptographic provider to use for hashing the message. For signed messages, hCryptProv is used for signature verification.

Unless there is a strong reason for passing in a specific cryptographic provider in hCryptProv, set this parameter to zero. Passing in zero causes the default RSA or DSS provider to be acquired before performing hash, signature verification, or recipient encryption operations.

pRecipientInfo
[in/reserved]This parameter is reserved for future use and must be NULL.
pStreamInfo
[in/optional]When streaming is not being used, this parameter must be set to NULL.

Note Streaming is not used with CMSG_HASHED. When dealing with hashed data, this parameter must be set to NULL.

When streaming is being used, pStreamInfo is a pointer to a CMSG_STREAM_INFO structure that contains a pointer to a callback to be called when CryptMsgUpdate is executed or when CryptMsgControl is executed when decoding a streamed enveloped message.

For a signed message, the callback is passed a block of the decoded bytes from the inner content of the message.

For an enveloped message, after each call to CryptMsgUpdate, check to see if CMSG_ENVELOPE_ALGORITHM_PARAM is available by calling CryptMsgGetParam. CryptMsgGetParam will fail with LastError CRYPT_E_STREAM_MSG_NOT_READY until CryptMsgUpdate has processed enough of the message to make the CMSG_ENVELOPE_ALGORITHM_PARAM structure available. Once that structure is available, the application can iterate through the recipients, retrieving a CERT_INFO structure for each one using CryptMsgGetParam (CMSG_RECIPIENT_INFO_PARAM).

CERT_INFO is used to find a matching certificate in a previously opened certificate store using CertGetSubjectCertificateFromStore. When the correct certificate is found, CertGetCertificateContextProperty with a CERT_KEY_PROV_INFO_PROP_ID parameter is called to retrieve a CRYPT_KEY_PROV_INFO structure. The structure contains the information necessary to acquire the recipient's private key by calling CryptAcquireContext, using the pwszContainerName, pwszProvName, dwProvType, and dwFlags members of CRYPT_KEY_PROV_INFO. The hCryptProv acquired and the dwKeySpec from the CRYPT_KEY_PROV_INFO are passed to CryptMsgControl as a member of the CMSG_CTRL_DECRYPT_PARA structure to permit the start of the decryption of the inner content. The streaming code will then perform the decryption as the data is input. The resulting blocks of plaintext are passed to the callback function specified by pfnStreamOutput to handle the output of the decrypted message.

Note Streaming decoding of an enveloped message queues the ciphertext in memory until CryptMsgControl is called to start the decryption. The application must initiate decrypting in a timely manner so that the data can be saved to disk or routed elsewhere before the accumulated ciphertext becomes too large and the system runs out of memory.

In the case of a signed message enclosed in an enveloped message, the plaintext output from the streaming decode of the enveloped* message can be fed into another streaming decode to process the signed message.

Return Values

If successful, returns the handle of the opened message. Returns NULL if the operation failed.

To retrieve extended error information, use the GetLastError function.

The following table lists the error codes most commonly returned by the GetLastError function.

Error Code | Description
E_INVALIDARG | One or more arguments are invalid.
E_OUTOFMEMORY | Ran out of memory.

Examples

See Example C Program: Signing, Encoding, Decoding, and Verifying a Message, Example C Program: Encoding and Decoding an Enveloped Message, Alternate Code for Encoding an Enveloped Message, Example C Program: Encoding an Enveloped, Signed Message, and Example C Program: Encoding and Decoding a Hashed Message.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Low-Level Message Functions, Simplified Message Functions, CryptMsgClose, CryptMsgUpdate, CryptMsgGetParam, CryptMsgOpenToEncode


CryptMsgOpenToEncode

The CryptMsgOpenToEncode function opens a cryptographic message for encoding and returns a handle of the opened message. The message remains open until CryptMsgClose is called.

HCRYPTMSG WINAPI CryptMsgOpenToEncode(
  DWORD dwMsgEncodingType,
  DWORD dwFlags,
  DWORD dwMsgType,
  const void *pvMsgEncodeInfo,
  LPSTR pszInnerContentObjID,
  PCMSG_STREAM_INFO pStreamInfo
);

Parameters

dwMsgEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

dwFlags
[in] Currently defined dwFlags are shown in the following table.
Flag | Meaning
CMSG_BARE_CONTENT_FLAG | The streamed output will not have an outer ContentInfo wrapper (as defined by PKCS #7). This makes it suitable to be streamed into an enclosing message.
CMSG_DETACHED_FLAG | There is detached data being supplied for the subsequent calls to CryptMsgUpdate.
CMSG_AUTHENTICATED_ATTRIBUTES_FLAG | Authenticated attributes are forced to be included in the SignerInfo (as defined by PKCS #7) in cases where they would not otherwise be required.
CMSG_CONTENTS_OCTETS_FLAG | Used when calculating the size of a DER-encoded message that is nested inside an enveloped message. This is particularly useful when performing streaming
CMSG_CMS_ENCAPSULATED_CONTENT_FLAG | When set, non-Data type inner content is encapsulated within an OCTET STRING. Applicable to both Signed and Enveloped messages.
CMSG_CRYPT_RELEASE_CONTEXT_FLAG If set, the hCryptProv passed to this function is released on the final CryptMsgUpdate. The handle is not released if the function fails.
Note, envelope recipients' hCryptProvs are not released

dwMsgType
[in] Indicates message type. Currently defined message types are shown in the following table.
Message type | Associated pvMsgEncodeInfo structures
CMSG_DATA | Not used.
CMSG_SIGNED | CMSG_SIGNED_ENCODE_INFO
CMSG_ENVELOPED | CMSG_ENVELOPED_ENCODE_INFO
CMSG_SIGNED_AND_ENVELOPED | Not currently implemented.
CMSG_HASHED | CMSG_HASHED_ENCODE_INFO

pvMsgEncodeInfo
[in] Pointer to the data to be encoded. The type of data pointed to depends on the value of dwMsgType. For details, see the dwMsgType table.
pszInnerContentObjID
[in/optional] If CryptMsgCalculateEncodedLength is called and the data for CryptMsgUpdate has already been message encoded, the appropriate object identifier is passed in pszInnerContentObjID. If pszInnerContentObjID is NULL, the inner content type is assumed not to have been previously encoded, and is encoded as an octet string and given the type CMSG_DATA.

Note When streaming is being used, pszInnerContentObjID must be either NULL or szOID_RSA_data.

The following algorithm object identifiers are commonly used. A user can define new inner content usage by ensuring that the sender and receiver of the message agree upon the semantics associated with the object identifier.

szOID_RSA_data
szOID_RSA_signedData
szOID_RSA_envelopedData
szOID_RSA_signEnvData
szOID_RSA_digestedData
szOID_RSA_encryptedData
SPC_INDIRECT_DATA_OBJID

pStreamInfo
[in/option] When streaming is not being used, this parameter is set to NULL.

Note Streaming is not used with CMSG_HASHED. When dealing with hashed data, this parameter must be set to NULL.

When streaming is being used, this parameter points to a CMSG_STREAM_INFO structure. The callback specified by pfnStreamOutput in the CMSG_STREAM_INFO structure is called when CryptMsgUpdate is executed. The callback is passed the encoded bytes resulting from the encoding. For more information on how to use the callback, see CMSG_STREAM_INFO.

Consider the case of a signed message being enclosed in an enveloped message. The encoded output from the streamed encoding of the signed message feeds into another streaming encoding of the enveloped message. The callback for the streaming encoding calls CryptMsgUpdate to encode the enveloped message. The callback for the enveloped message receives the encoded bytes of the nested signed message.

Return Values

If the function succeeds, it returns a handle of the opened message. If it fails, NULL is returned.

To retrieve extended error information, use the GetLastError function.

The following table lists the error codes most commonly returned by the GetLastError function.

Error Code | Description
CRYPT_E_INVALID_MSG_TYPE | The message type is invalid.
CRYPT_E_OID_FORMAT | The object identifier is badly formatted.
CRYPT_E_UNKNOWN_ALGO | The cryptographic algorithm is unknown.
E_INVALIDARG | One or more arguments are invalid.
E_OUTOFMEMORY | Ran out of memory.

In addition, if dwMsgType is CMSG_SIGNED, errors can be propagated from CryptCreateHash.

If dwMsgTyp is CMSG_ENVELOPED, errors can be propagated from CryptGenKey, CryptImportKey, and CryptExportKey.

If dwMsgType is CMSG_HASHED, errors can be propagated from CryptCreateHash.

Remarks

Important changes have been made to the CryptoAPI that affects the handling of enveloped messages to support S/MIME e-mail interoperability. The changes take effect for products released after Service Pack 3, such as Internet Explorer 4.0 and Windows 2000. The following changes have been made:

For functions that perform encryption, the encrypted symmetric keys are reversed from little-endian format to big-endian format after CryptExportKey is called internally. For functions that perform decryption, the encrypted symmetric keys are reversed from big-endian format to little-endian format before CryptImportKey is called.

CRYPT_NO_SALT is specified when symmetric keys are generated and imported with CryptGenKey and CryptImportKey. Previously, 11 bytes of zero value salt was used instead of no salt.

Messages encrypted with the RC2 encryption algorithm use KP_EFFECTIVE_KEYLEN with CryptGetKeyParam to determine the effective key length of the RC2 key importing or exporting keys. Previously, a default key length of 40 bits was always used to import or export keys.

For messages encrypted with the RC2 encryption algorithm, encode and decode operations have been updated to handle ASN RC2 parameters for the ContentEncryptionAlgorithm member of the CMSG_ENVELOPED_ENCODE_INFO structure. Previously, the values were not supported. See the S/MIME documentation for more information.

For messages encrypted with the RC4, DES, and 3DES encryption algorithms, encode and decode operations now handle the ASN IV octet string parameter for the ContentEncryptionAlgorithm member of the CMSG_ENVELOPED_ENCODE_INFO structure. Previously, that value was not supported. See the S/MIME documentation for more information.

Examples

See Example C Program: Signing, Encoding, Decoding, and Verifying a Message, Example C Program: Encoding and Decoding an Enveloped Message, Alternate Code for Encoding an Enveloped Message, Example C Program: Encoding an Enveloped, Signed Message, and Example C Program: Encoding and Decoding a Hashed Message.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Low-Level Message Functions, Simplified Message Functions, CryptMsgClose, CryptMsgUpdate, CryptMsgGetParam, CryptMsgOpenToDecode


CryptMsgUpdate

The CryptMsgUpdate function adds contents to a cryptographic message. The use of this function allows messages to be constructed piece by piece through repetitive calls of CryptMsgUpdate. The added message content is either encoded or decoded depending on whether the message was opened with CryptMsgOpenToEncode or CryptMsgOpenToDecode.

BOOL WINAPI CryptMsgUpdate(
  HCRYPTMSG hCryptMsg,
  const BYTE *pbData,
  DWORD cbData,
  BOOL fFinal
);

Parameters

hCryptMsg
[in] Cryptographic message handle of the message to be updated.
pbData
[in] Pointer to the buffer holding the data to be encoded or decoded.
cbData
[in] Number of bytes of data in the pbData buffer.
fFinal
[in] Indicates that the last block of data for encoding or decoding is being processed. Correct usage of this flag is dependent upon whether the message being processed has detached data. The inclusion of detached data in a message is indicated by setting dwFlags to CMSG_DETACHED_FLAG in the call to the function that opened the message.

If CMSG_DETACHED_FLAG was not set and the message was opened using either CryptMsgOpenToDecode or CryptMsgOpenToEncode, fFinal is set to TRUE, and CryptMsgUpdate is only called once.

If the CMSG_DETACHED_FLAG flag was set and a message is opened using CryptMsgOpenToEncode, fFinal is set to TRUE only on the last call to CryptMsgUpdate.

If the CMSG_DETACHED_FLAG flag was set and a message is opened using CryptMsgOpenToDecode, fFinal is set to TRUE when the header is processed by a single call to CryptMsgUpdate. It is set to FALSE while processing the detached data in subsequent calls to CryptMsgUpdate until the last detached data block is to be processed. On the last call to CryptMsgUpdate, it is set to TRUE.

When detached data is decoded, the header and the content of a message are contained in different BLOBs. Each BLOB requires that fFinal be set to TRUE when the last call to the function is made for that BLOB.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Errors encountered in the application defined callback function specified by pStreamInfo in CryptMsgOpenToDecode and CryptMsgOpenToEncode might be propagated to CryptMsgUpdate if streaming is used. If this happens, SetLastError is not called by CryptMsgUpdate after the callback returns, which preserves any errors encountered under the control of the application. It is the responsibility of the callback function (or one of the APIs that it calls) to call SetLastError if an error occurs while the application is processing the streamed data.

The following table lists the error codes most commonly returned by the GetLastError function.

Error Code | Description
CRYPT_E_INVALID_MSG_TYPE | The message type is invalid.
CRYPT_E_MSG_ERROR | An error was encountered doing a cryptographic operation.
CRYPT_E_OID_FORMAT | The object identifier is badly formatted.
CRYPT_E_UNEXPECTED_ENCODING | The message is not encoded as expected.
CRYPT_E_UNKNOWN_ALGO | The cryptographic algorithm is unknown.
E_INVALIDARG | One or more arguments are invalid.
E_OUTOFMEMORY | Ran out of memory.

Propagated errors might be encountered from any of the following functions:

CryptHashData
CryptGetHashParam
CryptSignHash
CryptGetKeyParam
CryptEncrypt
CryptHashData
CryptGetHashParam
CryptCreateHash

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Examples

See Example C Program: Signing, Encoding, Decoding, and Verifying a Message, Example C Program: Encoding and Decoding an Enveloped Message, Alternate Code for Encoding an Enveloped Message , Example C Program: Encoding an Enveloped, Signed Message, and Example C Program: Encoding and Decoding a Hashed Message.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Low-Level Message Functions, Simplified Message Functions, CryptMsgGetParam, CryptMsgOpenToEncode, CryptMsgOpenToDecode


CryptMsgVerifyCountersignatureEncoded

The CryptMsgVerifyCountersignatureEncoded function verifies the countersignature of a message.

BOOL WINAPI CryptMsgVerifyCountersignatureEncoded(
  HCRYPTPROV hCryptProv,
  DWORD dwEncodingType,
  PBYTE pbSignerInfo,
  DWORD cbSignerInfo,
  PBYTE pbSignerInfoCountersignature,
  DWORD cbSignerInfoCountersignature,
  PCERT_INFO pciCountersigner
);

Parameters

hCryptProv
[in] NULL or the handle of the cryptographic provider to use to hash the encryptedDigest field of pbSignerInfo.

Unless there is a strong reason for passing in a specific cryptographic provider in hCryptProv, pass NULL to cause the default RSA or DSS provider to be used.

dwEncodingType
[in] Specifies the encoding type used. Currently, only X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are being used; however, additional encoding types may be added in the future. For either current encoding type, use:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
pbSignerInfo
[in] Pointer to the encoded BLOB that contains the signer of the contents of a message to be countersigned.
cbSignerInfo
[in] Count, in bytes, of the encoded BLOB for the signer of the contents.
pbSignerInfoCountersignature
[in] Pointer to the encoded BLOB containing the countersigner information.
cbSignerInfoCountersignature
[in] Count, in bytes, of the encoded BLOB for the countersigner of the message.
pciCountersigner
[in] Pointer to a CERT_INFO that includes with the issuer and serial number of the countersigner. See the following Remarks section.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

The following table lists the error codes most commonly returned by the GetLastError function.

Error Code | Description
CRYPT_E_AUTH_ATTR_MISSING | The message does not contain an expected authenticated attribute.
CRYPT_E_HASH_VALUE | The hash value is not correct.
CRYPT_E_UNEXPECTED_ENCODING | The message is not encoded as expected.
CRYPT_E_UNKNOWN_ALGO | The cryptographic algorithm is unknown.
E_INVALIDARG | One or more arguments are invalid.
E_OUTOFMEMORY | Ran out of memory.

Propagated errors from the following functions might be returned.

CryptCreateHash
CryptHashData
CryptGetHashParam
CryptImportKey
CryptVerifySignature

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Remarks

Countersigner verification is done using the PKCS #7 SIGNERINFO structure. The signature must contain the encrypted hash of the encryptedDigest field of pbSignerInfo.

The issuer and serial number of the countersigner must match the countersigner information from pbSignerInfoCountersignature. The only fields referenced from pciCountersigner are SerialNumber, Issuer, and SubjectPublicKeyInfo. The SubjectPublicKeyInfo is used to access the public key that is then used to encrypt the hash from the pciCountersigner so compare it with the hash from the pbSignerInfo.

Examples

See Example C Program: Encoding and Decoding a CounterSigned Message.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Low-Level Message Functions, Simplified Message Functions, CryptMsgCountersign, CryptMsgCountersignEncoded


CryptMsgVerifyCountersignatureEncodedEx

The CryptMsgVerifyCountersignatureEncodedEx function verifies that the pbSignerInfoCounterSignature parameter contains the encrypted hash of the encryptedDigest field of the pbSignerInfo parameter structure. The signer can be a CERT_PUBLIC_KEY_INFO structure, a certificate context, or a chain context.

BOOL WINAPI CryptMsgVerifyCountersignatureEncoded(
  HCRYPTPROV hCryptProv,
  DWORD dwEncodingType,
  PBYTE pbSignerInfo,
  DWORD cbSignerInfo,
  PBYTE pbSignerInfoCountersignature,
  DWORD cbSignerInfoCountersignature,
  DWORD dwSignerType,
  void *pvSigner,
  DWORD dwFlags,
  void *pvReserved
);

Parameters

hCryptProv
[in] NULL or the handle of the cryptographic provider to use to hash the encryptedDigest field of pbSignerInfo.

Unless there is a strong reason for passing in a specific cryptographic provider in hCryptProv, pass NULL to cause the default RSA or DSS provider to be used.

dwEncodingType
[in] Specifies the encoding type used. Currently, only X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are being used; however, additional encoding types may be added in the future. For either current encoding type, use:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
pbSignerInfo
[in] Pointer to the encoded BLOB that contains the signer of the contents of a message to be countersigned.
cbSignerInfo
[in] Count, in bytes, of the encoded BLOB for the signer of the contents.
pbSignerInfoCountersignature
[in] Pointer to the encoded BLOB containing the countersigner information.
cbSignerInfoCountersignature
[in] Count, in bytes, of the encoded BLOB for the countersigner of the message.
dwSignerType
Indication of the structure containing the signer information. The following table shows the predefined values and the structures indicated.
Value | pvSigner structure pointed to
CMSG_VERIFY_SIGNER_PUBKEY | CERT_PUBLIC_KEY_INFO
CMSG_VERIFY_SIGNER_CERT | CCERT_CONTEXT
CMSG_VERIFY_SIGNER_CHAIN | CERT_CHAIN_CONTEXT

pvSigner
Pointer to a CERT_PUBLIC_KEY_INFO structure, a certificate context, or a chain context depending on the value of dwSignerType.
dwFlags,
Reserved for future use. Must be set to zero (0).
pvReserved
Reserved for future use. Must be set to NULL.
pciCountersigner
[in] Pointer to a CERT_INFO structure included with the issuer and serial number of the countersigner. See the following Remarks section.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

The following table lists the error codes most commonly returned by the GetLastError function.

Error Code | Description
CRYPT_E_AUTH_ATTR_MISSING | The message does not contain an expected authenticated attribute.
CRYPT_E_HASH_VALUE | The hash value is not correct.
CRYPT_E_UNEXPECTED_ENCODING | The message is not encoded as expected.
CRYPT_E_UNKNOWN_ALGO | The cryptographic algorithm is unknown.
E_INVALIDARG | One or more arguments are invalid.
E_OUTOFMEMORY | Ran out of memory.

Propagated errors from the following functions might be returned.

CryptCreateHash
CryptHashData
CryptGetHashParam
CryptImportKey
CryptVerifySignature

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Remarks

Countersigner verification is done using the PKCS #7 SIGNERINFO structure. The signature must contain the encrypted hash of the encryptedDigest field of pbSignerInfo.

The issuer and serial number of the countersigner must match the countersigner information from pbSignerInfoCountersignature. The only fields referenced from pciCountersigner are SerialNumber, Issuer, and SubjectPublicKeyInfo. The SubjectPublicKeyInfo is used to access the public key that is then used to encrypt the hash from the pciCountersigner so compare it with the hash from the pbSignerInfo

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.


Simplified Message Functions

Simplified message functions wrap low-level CryptoAPI functions into a single function to accomplish a specified task.

The following functions are included in this category.

Function | Description
CryptDecodeMessage | Decodes a cryptographic message.
CryptDecryptAndVerifyMessageSignature | Decrypts the specified message and verifies the signer.
CryptDecryptMessage | Decrypts the specified message.
CryptEncryptMessage | Encrypts the message for the recipient or recipients.
CryptGetMessageCertificates | Returns the certificate store containing the message's certificates and CRLs.
CryptGetMessageSignerCount | Returns the count of signers in the signed message.
CryptHashMessage | Creates a hash of the message.
CryptSignAndEncryptMessage | Signs the message and encrypts for the recipient or recipients.
CryptSignMessage | Signs the message.
CryptVerifyDetachedMessageHash | Verifies a hashed message containing a detached hash.
CryptVerifyDetachedMessageSignature | Verifies a signed message containing a detached signature or signatures.
CryptVerifyMessageHash | Verifies a hashed message.
CryptVerifyMessageSignature | Verifies a signed message.


CryptDecodeMessage

The CryptDecodeMessage function decodes, decrypts, and verifies a cryptographic message.

This function can be used when the type of cryptographic message is unknown. The dwMsgTypeFlags constants can be combined with a bitwise-OR operation so that the function will try to find one of the types. When one of the types is found, the function reports the type found, and returns the data appropriate to that type.

In each pass, the function cracks only a single level of encryption or encoding. For additional cracking, this function, or one of the other Simplified Message Functions must to be called again.

BOOL WINAPI CryptDecodeMessage(
  DWORD dwMsgTypeFlags,
  PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara,
  PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
  DWORD dwSignerIndex,
  const BYTE *pbEncodedBlob,
  DWORD cbEncodedBlob,
  DWORD dwPrevInnerContentType,
  DWORD *pdwMsgType,
  DWORD *pdwInnerContentType,
  BYTE *pbDecoded,
  DWORD *pcbDecoded,
  PCCERT_CONTEXT *ppXchgCert,
  PCCERT_CONTEXT *ppSignerCert
);

Parameters

dwMsgTypeFlags
[in] Indicates the message type. The following types are defined. Message types can be combined with the bitwise-OR operator:
  • CMSG_DATA_FLAG
  • CMSG_SIGNED_FLAG
  • CMSG_ENVELOPED_FLAG
  • CMSG_SIGNED_AND_ENVELOPED_FLAG
  • CMSG_HASHED_FLAG

Note Upon return, the DWORD pointed to by pdwMsgType is set with the type of the message.

pDecryptPara
[in] Pointer to a CRYPT_DECRYPT_MESSAGE_PARA structure containing decryption parameters.
pVerifyPara
[in] Pointer to a CRYPT_VERIFY_MESSAGE_PARA structure containing verification parameters.
dwSignerIndex
[in] Indicates which signer among the possible many signers of a message is to be verified. This index can be changed in multiple calls to the function to verify additional signers.

It is set to zero for the first signer. If the function returns FALSE, and GetLastError returns CRYPT_E_NO_SIGNER, the previous call returned the last signer of the message. This parameter is used only with messages of types: CMSG_SIGNED_AND_ENVELOPED or CMSG_SIGNED. For all other message types, it should be set to zero.

pbEncodedBlob
[in] Pointer to the encoded BLOB that is to be decoded.
cbEncodedBlob
[in] Size, in bytes, of the encoded BLOB.
dwPrevInnerContentType
[in] Only applicable when processing nested cryptographic messages. When processing an outer cryptographic message, it must be set to zero. When decoding a nested cryptographic message, it is set to the value returned at pdwInnerContentType by a previous calling of CryptDecodeMessage for the outer message. It can be any of the CMSG types listed in pdwMsgType. Set to zero for backward compatibility.
pdwMsgType
[out/optional] Pointer to a DWORD specifying the message type returned. Possible message types are shown in the following table.

CMSG_DATA
CMSG_SIGNED
CMSG_ENVELOPED
CMSG_SIGNED_AND_ENVELOPED
CMSG_HASHED

pdwInnerContentType
[out/optional] Pointer to a DWORD specifying the type of an inner message. The message type codes used for pdwMsgType are used here, also.

If there is no cryptographic nesting, CMSG_DATA is returned.

pbDecoded
[out/optional] Pointer to a buffer to receive the decoded message.

This parameter can be NULL if the decoded message is not required or to set the size of the decoded message for memory allocation purposes. A decoded message will not be returned if this parameter is NULL. See Retrieving Data of Unknown Length.

pcbDecoded
[in/out/optional] Pointer to a variable that specifies the size, in bytes, of the buffer pointed to by the pbDecoded parameter. When the function returns, this variable contains the size of the decoded message.

Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

ppXchgCert
[out/optional] Pointer to a CERT_CONTEXT structure with a certificate corresponding to the private exchange key needed to decode the message. This parameter is only set for message types CMSG_ENVELOPED and CMSG_SIGNED_AND_ENVELOPED.
ppSignerCert
[out/optional] Pointer to a CERT_CONTEXT structure of the certificate context of the signer. This parameter is only set for message types CMSG_SIGNED and CMSG_SIGNED_AND_ENVELOPED.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

CryptDecryptMessage, CryptVerifyMessageSignature, or CryptVerifyMessageHash can be propagated to this function.

This function has the following error code.

Error Code | Description
ERROR_MORE_DATA | If the buffer specified by the pbDecoded parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcbDecoded.

Remarks

The dwMsgTypeFlags parameter specifies the set of allowable messages. For example, to decode either SIGNED or ENVELOPED messages, set dwMsgTypeFlags to CMSG_SIGNED_FLAG | CMSG_ENVELOPED_FLAG. Either or both of the pDecryptPara or pVerifyPara parameters must be specified.

For a successfully decoded or verified message, the certificate context pointers pointed to by ppXchgCert and ppSignerCert are updated. They must be freed by calling CertFreeCertificateContext. If the function fails, they are set to NULL.

The ppXchgCert or ppSignerCert parameters can be set to NULL before the function is called indicating that the caller is not interested in getting the exchange certificate or the signer certificate context.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Simplified Message Functions, CryptDecryptMessage, CryptVerifyMessageHash, CryptVerifyMessageSignature


CryptDecryptAndVerifyMessageSignature

The CryptDecryptAndVerifyMessageSignature function decrypts a message and verifies its signature.

BOOL WINAPI CryptDecryptAndVerifyMessageSignature(
  PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara,
  PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
  DWORD dwSignerIndex,
  const BYTE *pbEncryptedBlob,
  DWORD cbEncryptedBlob,
  BYTE *pbDecrypted,
  DWORD *pcbDecrypted,
  PCCERT_CONTEXT *ppXchgCert,
  PCCERT_CONTEXT *ppSignerCert
);

Parameters

pDecryptPara
[in] Pointer to a CRYPT_DECRYPT_MESSAGE_PARA structure containing decryption parameters.
pVerifyPara
[in] Pointer to a CRYPT_VERIFY_MESSAGE_PARA structure containing verification parameters.
dwSignerIndex
[in] Identifies a particular signer of the message. A message can be signed by more than one signer and this function can be called multiple times changing this parameter to check several signers. It is set to zero for the first signer. If the function returns FALSE, and GetLastError returns CRYPT_E_NO_SIGNER, the previous call received the last signer of the message.
pbEncryptedBlob
[in] Pointer to the signed, encoded, and encrypted message to be decrypted and verified.
cbEncryptedBlob
[in] Size, in bytes, of the encrypted message.
pbDecrypted
[out/optional] Pointer to a buffer to receive the decrypted message.

This parameter can be NULL if the decrypted message is not required, or to set the size of the decrypted message for memory allocation purposes. A decrypted message will not be returned if this parameter is NULL. See Retrieving Data of Unknown Length.

pcbDecrypted
[in/out/optional ] Pointer to a DWORD specifying the size, in bytes, of the buffer pointed to by the pbDecrypted parameter. When the function returns, it contains the size of the decrypted message copied to pbDecrypted.

Note When processing the data returned in the pbDecrypted buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified in pcbDecrypted on input. On output, the variable pointed to by this parameter is set to reflect the actual size of the data copied to the buffer.

ppXchgCert
[out/optional] Pointer to a CERT_CONTEXT structure of the certificate corresponding to the private exchange key needed to decrypt the message.
ppSignerCert
[out/optional] Pointer to a CERT_CONTEXT structure of the certificate of the signer.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Note Errors from the called functions CryptDecryptMessage and CryptVerifyMessageSignature might be propagated to this function.

This function has the following error code.

Error Code | Description
ERROR_MORE_DATA | If the buffer specified by the pbDecrypted parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcbDecrypted.

Remarks

For a successfully decrypted and verified message, the certificate context pointers pointed to by ppXchgCert and ppSignerCert are updated. They must be freed by calling CertFreeCertificateContext. If the function fails, they are set to NULL.

The ppXchgCert and ppSignerCert parameters can be NULL to indicate the caller is not interested in the exchange certificate or the signer certificate context.

Examples

See Example C Program: Sending and Receiving a Signed and Encrypted Message.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Simplified Message Functions, CryptDecryptMessage, CryptSignAndEncryptMessage


CryptDecryptMessage

The CryptDecryptMessage function decodes and decrypts a message.

BOOL WINAPI CryptDecryptMessage(
  PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara,
  const BYTE *pbEncryptedBlob,
  DWORD cbEncryptedBlob,
  BYTE *pbDecrypted,
  DWORD *pcbDecrypted,
  PCCERT_CONTEXT *ppXchgCert
);

Parameters

pDecryptPara
[in] Pointer to a CRYPT_DECRYPT_MESSAGE_PARA structure containing decryption parameters.
pbEncryptedBlob
[in] Pointer to a buffer containing the encoded and encrypted message to be decrypted.
cbEncryptedBlob
[in] Size of the encoded and encrypted message, in bytes.
pbDecrypted
[out/optional] Pointer to a buffer that receives the decrypted message.

This parameter can be NULL to set the size of this information for memory allocation purposes. A decrypted message will not be returned if this parameter is NULL. See Retrieving Data of Unknown Length.

pcbDecrypted
[in/out/optional] Pointer to a DWORD specifying the size, in bytes, of the buffer pointed to by the pbDecrypted parameter. When the function returns, this variable contains the size, in bytes, of the decrypted message copied to pbDecrypted.

Note When processing the data returned in the pbDecrypted buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified in pcbDecrypted on input. On input, buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer. On output, the DWORD is updated to the actual size of the data copied to the buffer.

ppXchgCert
[out/optional] Pointer to a CERT_CONTEXT structure of a certificate corresponding to the private exchange key needed to decrypt the message. This parameter can be set to NULL indicating that the function should not return the certificate context used to decrypt.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Note Errors from calls to CryptImportKey and CryptDecrypt might be propagated to this function.

This function has the following error codes.

Error Code | Description
ERROR_MORE_DATA | If the buffer specified by the pbDecrypted parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcbDecrypted.
E_INVALIDARG | Invalid message and certificate encoding types. Currently only PKCS_7_ASN_ENCODING and X509_ASN_ENCODING_TYPE are supported. Invalid cbSize in *pDecryptPara.
CRYPT_E_UNEXPECTED_MSG_TYPE | Not an enveloped cryptographic message.
NTE_BAD_ALGID | The message was encrypted using an algorithm we don't know about or support.
CRYPT_E_NO_DECRYPT_CERT | No certificate was found having a private key property to use for decrypting.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Remarks

Notice that when NULL is passed for pbDecrypted, and pcbDecrypted is not NULL, NULL is returned for the address passed in ppXchgCert. Otherwise, a pointer to a CERT_CONTEXT is returned. For a successfully decrypted message, this pointer to a CERT_CONTEXT points to the certificate context used to decrypt the message. It must be freed by calling CertFreeCertificateContext. If the function fails, the value at ppXchgCert is set to NULL.

Examples

See Example C Program: Using CryptEncryptMessage and CryptDecryptMessage.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Simplified Message Functions, CryptDecryptAndVerifyMessageSignature


CryptEncryptMessage

The CryptEncryptMessage function encrypts and encodes a message.

BOOL WINAPI CryptEncryptMessage(
  PCRYPT_ENCRYPT_MESSAGE_PARA pEncryptPara,
  DWORD cRecipientCert,
  PCCERT_CONTEXT rgpRecipientCert[ ],
  const BYTE *pbToBeEncrypted,
  DWORD cbToBeEncrypted,
  BYTE *pbEncryptedBlob,
  DWORD *pcbEncryptedBlob
);

Parameters

pEncryptPara
[in] Pointer to a CRYPT_ENCRYPT_MESSAGE_PARA structure containing the encryption parameters.
cRecipientCert
[in] Number of elements in the rgpRecipientCert array.
rgpRecipientCert
[in] Array of pointers to CERT_CONTEXT structures of certificate of intended recipients of the message.
pbToBeEncrypted
[in] Pointer to buffer containing the message that is to be encrypted.
cbToBeEncrypted
[in] Size, in bytes, of the message that is to be encrypted.
pbEncryptedBlob
[out] Pointer to BLOB containing a buffer that receives the encrypted and encoded message.

This parameter can be NULL to set the size of this information for memory allocation purposes. See Retrieving Data of Unknown Length.

pcbEncryptedBlob
[in/out] Pointer to a DWORD specifying the size, in bytes, of the buffer pointed to by the pbEncryptedBlob parameter. When the function returns, this variable contains the size, in bytes, of the encrypted and encoded message copied to pbEncryptedBlob.

Note When processing the data returned in the buffer of the pbEncryptedBlob, applications need to use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Note Errors from calls to CryptGenKey, CryptEncrypt, CryptImportKey, and CryptExportKey can be propagated to this function.

This function has the following error codes.

Error Code | Description
ERROR_MORE_DATA | If the buffer specified by the pbEncryptedBlob parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcbEncryptedBlob.
E_INVALIDARG | Invalid message encoding type. Currently only PKCS_7_ASN_ENCODING is supported. Invalid cbSize in *pEncryptPara.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Examples

See Example C Program: Using CryptEncryptMessage and CryptDecryptMessage.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Simplified Message Functions


CryptGetMessageCertificates

The CryptGetMessageCertificates function returns the handle of an open certificate store containing the message's certificates and CRLs. This function calls CertOpenStore using provider type CERT_STORE_PROV_PKCS7 as its lpszStoreProvider parameter.

HCERTSTORE WINAPI CryptGetMessageCertificates(
  DWORD dwMsgAndCertEncodingType,
  HCRYPTPROV hCryptProv,
  DWORD dwFlags,
  const BYTE *pbSignedBlob,
  DWORD cbSignedBlob
);

Parameters

dwMsgAndCertEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

hCryptProv
[in] Handle of the CSP passed to CertOpenStore. See CertOpenStore for additional details.

Unless there is a strong reason for passing a specific cryptographic provider in hCryptProv, pass zero to cause the default RSA or DSS provider to be acquired.

dwFlags
[in] Flags passed to CertOpenStore. See CertOpenStore for additional details.
pbSignedBlob
[in] Pointer a buffer CRYPTOAPI_BLOB containing the signed message.
cbSignedBlob
[in] Size, in bytes, of the signed message.

Return Values

Returns the certificate store containing the message's certificates and CRLs. For an error, NULL is returned.

Call GetLastError to see the reason for any failures.

This function has the following error codes.

Error Code | Description
E_INVALIDARG | Invalid message and certificate encoding types. Currently only PKCS_7_ASN_ENCODING and X509_ASN_ENCODING are supported.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Remarks

Use GetLastError. to determine the reason for any errors.

Examples

See Example C Program: Setting and Getting Certificate Store Properties.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Simplified Message Functions, CryptVerifyMessageSignature


CryptGetMessageSignerCount

The CryptGetMessageSignerCount function returns the number of signers of a signed message.

LONG WINAPI CryptGetMessageSignerCount(
  DWORD dwMsgEncodingType,
  const BYTE *pbSignedBlob,
  DWORD cbSignedBlob
);

Parameters

dwMsgEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pbSignedBlob
[in] Pointer to a buffer containing the signed message.
cbSignedBlob
[in] Size, in bytes, of the signed message.

Return Values

Returns the number of signers of a signed message, zero (0) when there are no signers, and minus one (-1) for an error.

For extended error information, call GetLastError. This function has the following error codes.

Error Code | Description
E_INVALIDARG | Invalid message encoding type. Currently only PKCS_7_ASN_ENCODING is supported.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Examples

See Example C Program: Setting and Getting Certificate Store Properties.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Simplified Message Functions, CryptVerifyMessageSignature


CryptHashMessage

The CryptHashMessage function creates a hash of the message.

BOOL WINAPI CryptHashMessage(
  PCRYPT_HASH_MESSAGE_PARA pHashPara,
  BOOL fDetachedHash,
  DWORD cToBeHashed,
  const BYTE *rgpbToBeHashed[ ],
  DWORD rgcbToBeHashed[ ],
  BYTE *pbHashedBlob,
  DWORD *pcbHashedBlob,
  BYTE *pbComputedHash,
  DWORD *pcbComputedHash
);

Parameters

pHashPara
[in] Pointer to a CRYPT_HASH_MESSAGE_PARA structure containing the hash parameters.
fDetachedHash
[in] If this parameter is set to TRUE, only pbComputedHash is encoded in pbHashedBlob. Otherwise, both rgpbToBeHashed and pbComputedHash are encoded.
cToBeHashed
[in] Number of array elements in rgpbToBeHashed and rgcbToBeHashed. This parameter can only be one unless fDetachedHash is set to TRUE.
rgpbToBeHashed
[in] Array of pointers to buffers with contents to be hashed.
rgcbToBeHashed
[in] Array of sizes, in bytes, of the buffers pointed to by rgpbToBeHashed.
pbHashedBlob
[out] Pointer to a buffer to receive the hashed message encoded for transmission.

This parameter can be NULL if the hashed message is not needed for additional processing, or to set the size of the hashed message for memory allocation purposes. A hashed message will not be returned if this parameter is NULL. See Retrieving Data of Unknown Length.

pcbHashedBlob
[in/out] Pointer to a DWORD specifying the size, in bytes, of the buffer pointed to by the pbHashedBlob parameter. When the function returns, this variable contains the size, in bytes, of the decrypted message copied to pbHashedBlob. This parameter must be the address of a DWORD and not NULL or the length of the buffer will not be returned.

Note When processing the data returned, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

pbComputedHash
[out/optional]Pointer to a buffer to receive the newly created, unencoded hash. This parameter can be NULL if the newly created hash is not needed for additional processing, or to set the size of the hash for memory allocation purposes. See Retrieving Data of Unknown Length.
pcbComputedHash
[in/out/optional] Pointer to a DWORD specifying the size, in bytes, of the buffer pointed to by the pbComputedHash parameter. When the function returns, this DWORD contains the size, in bytes, of the newly created hash that was copied to pbComputedHash.

Note When processing the data returned, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Note Errors from the called functions CryptCreateHash, CryptHashData, and CryptGetHashParam might be propagated to this function.

This function has the following error codes.

Error Code | Description
E_INVALIDARG | Invalid message encoding type. Currently only PKCS_7_ASN_ENCODING is supported. Invalid cbSize in *pHashPara.
ERROR_MORE_DATA | If the buffer specified by the pbHashedBlob parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcbHashedBlob.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Examples

See Example C Program: Setting and Getting Certificate Store Properties.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Simplified Message Functions, CryptVerifyDetachedMessageHash, CryptVerifyMessageHash


CryptSignAndEncryptMessage

The CryptSignAndEncryptMessage function creates a hash of the specified content, signs the hash, encrypts the content, hashes the encrypted contents and the signed hash, and then encodes both the encrypted content and the signed hash. The result is the same as if the hash were first signed and then encrypted.

BOOL WINAPI CryptSignAndEncryptMessage(
  PCRYPT_SIGN_MESSAGE_PARA pSignPara,
  PCRYPT_ENCRYPT_MESSAGE_PARA pEncryptPara,
  DWORD cRecipientCert,
  PCCERT_CONTEXT rgpRecipientCert[ ],
  const BYTE *pbToBeSignedAndEncrypted,
  DWORD cbToBeSignedAndEncrypted,
  BYTE *pbSignedAndEncryptedBlob,
  DWORD *pcbSignedAndEncryptedBlob
);

Parameters

pSignPara
[in] Pointer to a CRYPT_SIGN_MESSAGE_PARA structure that contains the signature parameters.
pEncryptPara
[in] Pointer to a CRYPT_ENCRYPT_MESSAGE_PARA structure containing encryption parameters.
cRecipientCert
[in] Number of array elements in rgpRecipientCert.
rgpRecipientCert
[in] Array of pointers to CERT_CONTEXT structures. Each structure is the certificates of an intended recipients of the message.
pbToBeSignedAndEncrypted
[in] Pointer to a buffer containing the content to be signed and encrypted.
cbToBeSignedAndEncrypted
[in] Size, in bytes, of the pbToBeSignedAndEncrypted buffer.
pbSignedAndEncryptedBlob
[out] Pointer to a buffer to receive the encrypted and encoded message.

This parameter can be NULL to set the size of this information for memory allocation purposes. See Retrieving Data of Unknown Length.

pcbSignedAndEncryptedBlob
[in/out] Pointer to DWORD specifying the size, in bytes, of the buffer pointed to by pbSignedAndEncryptedBlob. When the function returns, this variable contains the size, in bytes, of the signed and encrypted message copied to *pbSignedAndEncryptedBlob.

Note When processing the data returned, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE).

For extended error information, call GetLastError. This function has the following error code.

Error Code | Description
ERROR_MORE_DATA | If the buffer specified by the pbSignedAndEncryptedBlob parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcbSignedAndEncryptedBlob.

Note Errors from the called functions CryptSignMessage and CryptEncryptMessage might be propagated to this function.

Examples

See Example C Program: Sending and Receiving a Signed and Encrypted Message.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Simplified Message Functions, CryptSignMessage, CryptDecryptAndVerifyMessageSignature


CryptSignMessage

The CryptSignMessage function creates a hash of the specified content, signs the hash, and then encodes both the original message content and the signed hash.

BOOL WINAPI CryptSignMessage(
  PCRYPT_SIGN_MESSAGE_PARA pSignPara,
  BOOL fDetachedSignature,
  DWORD cToBeSigned,
  const BYTE *rgpbToBeSigned[ ],
  DWORD rgcbToBeSigned[ ],
  BYTE *pbSignedBlob,
  DWORD *pcbSignedBlob
);

Parameters

pSignPara
[in] Pointer to CRYPT_SIGN_MESSAGE_PARA structure containing the signature parameters.
fDetachedSignature
[in] TRUE if this is to be a detached signature. Otherwise, FALSE. If this parameter is set to TRUE, only the signed hash is encoded in pbSignedBlob. Otherwise, both rgpbToBeSigned and the signed hash are encoded.
cToBeSigned
[in] Count of the number of array elements in rgpbToBeSigned and rgcbToBeSigned. This parameter must be set to one unless fDetachedSignature is set to TRUE.
rgpbToBeSigned
[in] Array of pointers to buffers that contain the contents to be signed.
rgcbToBeSigned
[in] Array of sizes, in bytes, of the content buffers pointed to in rgpbToBeSigned.
pbSignedBlob
[out] Pointer to a buffer to receive the encoded signed hash, if fDetachedSignature is TRUE, or to both the encoded content and signed hash if fDetachedSignature is FALSE.

This parameter can be NULL to set the size of this information for memory allocation purposes. See Retrieving Data of Unknown Length.

pcbSignedBlob
[in/out] Pointer to a DWORD specifying the size, in bytes, of the pbSignedBlob buffer. When the function returns, this variable contains the size, in bytes, of the signed and encoded message.

Note When processing the data returned, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE).

For extended error information, call GetLastError. This function has the following error codes.

Error Code | Description
ERROR_MORE_DATA | If the buffer specified by the pbSignedBlob parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcbSignedBlob.
E_INVALIDARG | Invalid message encoding type. Currently only PKCS_7_ASN_ENCODING is supported. Invalid cbSize in *pSignPara.
CRYPT_E_NO_KEY_PROPERTY | The pSigningCert in *pSignPara does not have a CERT_KEY_PROV_INFO_PROP_ID or CERT_KEY_CONTEXT_PROP_ID property.

Note Errors from the called functions CryptCreateHash, CryptHashData, and CryptSignHash might be propagated to this function.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Examples

See Example C Program: Signing a Message and Verifying a Message Signature.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Simplified Message Functions, CryptSignAndEncryptMessage, CryptVerifyMessageSignature


CryptVerifyDetachedMessageHash

The CryptVerifyDetachedMessageHash function verifies a detached hash.

BOOL WINAPI CryptVerifyDetachedMessageHash(
  PCRYPT_HASH_MESSAGE_PARA pHashPara,
  BYTE *pbDetachedHashBlob,
  DWORD cbDetachedHashBlob,
  DWORD cToBeHashed,
  const BYTE *rgpbToBeHashed[ ],
  DWORD rgcbToBeHashed[ ],
  BYTE *pbComputedHash,
  DWORD *pcbComputedHash
);

Parameters

pHashPara
[in] Pointer to a CRYPT_HASH_MESSAGE_PARA structure containing the hash parameters.
pbDetachedHashBlob
[in] Pointer to the encoded, detached hash.
cbDetachedHashBlob
[in] Size, in bytes, of the detached hash.
cToBeHashed
[in] Number of elements in the rgpbToBeHashed and rgcbToBeHashed arrays.
rgpbToBeHashed
[in] Array of pointers to content buffers to be hashed.
rgcbToBeHashed
[in] Array of sizes, in bytes, for the content buffers pointed to by the elements of the rgcbToBeHashed array.
pbComputedHash
[out] Pointer to a buffer to receive the computed hash.

This parameter can be NULL if the newly created hash is not needed for additional processing, or to set the size of the hash for memory allocation purposes. See Retrieving Data of Unknown Length.

pcbComputedHash
[in/out] Pointer to a DWORD specifying the size, in bytes, of the pbComputedHash buffer. When the function returns, this DWORD contains the size, in bytes, of the created hash. The hash will not be returned if this parameter is NULL.

Note When processing the data returned , applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE).

For extended error information, call GetLastError. This function has the following error codes.

Error Code | Description
CRYPT_E_UNEXPECTED_MSG_TYPE | Not a hashed cryptographic message.
E_INVALIDARG | Invalid message encoding type. Currently only PKCS_7_ASN_ENCODING is supported. Invalid cbSize in *pHashPara.
ERROR_MORE_DATA | If the buffer specified by the pbComputedHash parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcbComputedHash.

Note Errors from the called functions CryptCreateHash, CryptHashData, and CryptGetHashParam might be propagated to this function.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Simplified Message Functions, CryptVerifyMessageHash


CryptVerifyDetachedMessageSignature

The CryptVerifyDetachedMessageSignature function verifies a signed message containing a detached signature or signatures.

BOOL WINAPI CryptVerifyDetachedMessageSignature(
  PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
  DWORD dwSignerIndex,
  const BYTE *pbDetachedSignBlob,
  DWORD cbDetachedSignBlob,
  DWORD cToBeSigned,
  const BYTE *rgpbToBeSigned[ ],
  DWORD *rgcbToBeSigned[ ],
  PCCERT_CONTEXT *ppSignerCert
);

Parameters

pVerifyPara
[in] Pointer to a CRYPT_VERIFY_MESSAGE_PARA structure containing the verification parameters.
dwSignerIndex
[in] Index of the signature to be verified. A message might have several signers and this function can be called repeatedly, changing dwSignerIndex to verify other signatures. If the function returns FALSE, and GetLastError returns CRYPT_E_NO_SIGNER, the previous call received the last signer of the message.
pbDetachedSignBlob
[in] Pointer to a BLOB containing the encoded message signatures.
cbDetachedSignBlob
[in] Size, in bytes, of the detached signature.
cToBeSigned
[in] Number of array elements in rgpbToBeSigned and rgcbToBeSigned.
rgpbToBeSigned
[in] Array of pointers to buffers containing the contents to be hashed.
rgcbToBeSigned
[in] Array of sizes, in bytes, for the content buffers pointed to in rgpbToBeSigned.
ppSignerCert
[out/optional] Pointer to a CERT_CONTEXT of a signer certificate. A CERT_CONTEXT structure will not be returned if this parameter is NULL.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE).

For extended error information, call GetLastError. This function has the following error codes:

Error Code | Description
E_INVALIDARG | Invalid message and certificate encoding types. Currently only PKCS_7_ASN_ENCODING and X509_ASN_ENCODING_TYPE are supported. Invalid cbSize in *pVerifyPara.
CRYPT_E_UNEXPECTED_MSG_TYPE | Not a signed cryptographic message.
CRYPT_E_NO_SIGNER | The message doesn't have any signers or a signer for the specified dwSignerIndex.
NTE_BAD_ALGID | The message was hashed and signed using an algorithm we don't know about or support.
NTE_BAD_SIGNATURE | The message's signature was not verified.

Note Errors from the called functions CryptCreateHash, CryptHashData, CryptVerifySignature, and CryptImportKey might be propagated to this function.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Simplified Message Functions, CryptVerifyMessageSignature


CryptVerifyMessageHash

The CryptVerifyMessageHash function verifies the hash of specified content.

BOOL WINAPI CryptVerifyMessageHash(
  PCRYPT_HASH_MESSAGE_PARA pHashPara,
  BYTE *pbHashedBlob,
  DWORD cbHashedBlob,
  BYTE *pbToBeHashed,
  DWORD *pcbToBeHashed,
  BYTE *pbComputedHash,
  DWORD *pcbComputedHash
);

Parameters

pHashPara
[in] Pointer to a CRYPT_HASH_MESSAGE_PARA structure containing hash parameters.
pbHashedBlob
[in] Pointer to a buffer containing original content and its hash.
cbHashedBlob
[in] Size, in bytes, of the original hash buffer.
pbToBeHashed
[out] Pointer to a buffer to receive the original content that was hashed.

This parameter can be NULL if the original content is not needed for additional processing, or to set the size of the original content for memory allocation purposes. See Retrieving Data of Unknown Length.

pcbToBeHashed
[in/out] Pointer to a DWORD specifying the size, in bytes, of the pbToBeHashed buffer. When the function returns, this variable contains the size, in bytes, of the original content copied to pbToBeHashed. The original content will not be returned if this parameter is NULL.

Note When processing the data returned, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

pbComputedHash
[out/optional] Pointer to a buffer to receive the computed hash. This parameter can be NULL if the created hash is not needed for additional processing, or to set the size of the original content for memory allocation purposes. See Retrieving Data of Unknown Length.
pcbComputedHash
[in/out/optional] Pointer to a DWORD specifying the size, in bytes, of the pbComputedHash buffer. When the function returns, this variable contains the size, in bytes, of the created hash. The hash is not returned if this parameter is NULL.

Note When processing the data returned, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE).

For extended error information, call GetLastError. This function has the following error codes.

Error Code | Description
CRYPT_E_UNEXPECTED_MSG_TYPE | Not a hashed cryptographic message.
E_INVALIDARG | Invalid message encoding type. Currently only PKCS_7_ASN_ENCODING is supported. Invalid cbSize in *pHashPara.
ERROR_MORE_DATA | If the buffer specified by the pbToBeHashed parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcbToBeHashed.

Note Errors from the called functions CryptCreateHash, CryptHashData, and CryptGetHashParam might be propagated to this function.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Simplified Message Functions, CryptVerifyDetachedMessageHash


CryptVerifyMessageSignature

The CryptVerifyMessageSignature function verifies a signed message's signature.

BOOL WINAPI CryptVerifyMessageSignature(
  PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
  DWORD dwSignerIndex,
  const BYTE *pbSignedBlob,
  DWORD cbSignedBlob,
  BYTE *pbDecoded,
  DWORD *pcbDecoded,
  PCCERT_CONTEXT *ppSignerCert
);

Parameters

pVerifyPara
[in] Pointer to a CRYPT_VERIFY_MESSAGE_PARA structure containing verification parameters.
dwSignerIndex
[in] Index of the desired signature. There can be more than one signature. CryptVerifyMessageSignature can be called repeatedly, incrementing dwSignerIndex each time. Set this parameter to zero for the first signer, or if there is only one signer. If the function returns FALSE, and GetLastError returns CRYPT_E_NO_SIGNER, the previous call processed the last signer of the message.
pbSignedBlob
[in] Pointer to a buffer containing the signed message.
cbSignedBlob
[in] Size, in bytes, of the signed message buffer.
pbDecoded
[out] Pointer to a buffer to receive the decoded message.

This parameter can be NULL if the decoded message is not needed for additional processing, or to set the size of the message for memory allocation purposes. See Retrieving Data of Unknown Length.

pcbDecoded
[in/out] Pointer to a DWORD specifying the size, in bytes, of the pbDecoded buffer. When the function returns, this DWORD contains the size, in bytes, of the decoded message. The decoded message will not be returned if this parameter is NULL.

Note When processing the data returned , applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

ppSignerCert
[out/optional] Pointer to a CERT_CONTEXT containing the certificate of the signer. This parameter can be NULL if the signer's certificate is not needed.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE).

For extended error information, call GetLastError. This function has the following error codes.

Error Code | Description
ERROR_MORE_DATA | If the buffer specified by the pbDecoded parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code, and stores the required buffer size, in bytes, in the variable pointed to by pcbDecoded.
E_INVALIDARG | Invalid message and certificate encoding types. Currently only PKCS_7_ASN_ENCODING and X509_ASN_ENCODING_TYPE are supported. Invalid cbSize in *pVerifyPara.
CRYPT_E_UNEXPECTED_MSG_TYPE | Not a signed cryptographic message.
CRYPT_E_NO_SIGNER | The message doesn't have any signers or a signer for the specified dwSignerIndex.
NTE_BAD_ALGID | The message was hashed and signed using an algorithm we don't know about or support.
NTE_BAD_SIGNATURE | The message's signature was not verified.

Note Errors from the called functions CryptCreateHash, CryptHashData, CryptVerifySignature, and CryptImportKey can be propagated to this function.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Remarks

For a verified signer and message, ppSignerCert is updated with the CERT_CONTEXT of the signer. It must be freed by calling CertFreeCertificateContext. Otherwise, ppSignerCert is set to NULL.

For a message containing only certificates and CRLs, pcbDecoded is set to NULL.

Examples

See Example C Program: Signing a Message and Verifying a Message Signature.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Simplified Message Functions, CryptVerifyDetachedMessageSignature, CryptSignMessage


Auxiliary Functions

Additional CryptoAPI functions that do not fit neatly into any other category are available.

  • Data Management Functions
  • Data Conversion Functions
  • Enhanced Key Usage Functions
  • Key Identifier Functions
  • Certificate Store Provider Callback Functions
  • OID Support Functions
  • Remote Object Retrieval Functions
  • PFX Functions


Data Management Functions

The following CryptoAPI auxiliary functions are used to manage data and certificates.

Function | Description
CertCompareCertificate | Compares two certificates to determine whether they are identical.
CertCompareCertificateName | Compares two certificate names to determine whether they are identical.
CertCompareIntegerBlob | Compares two integer BLOBs.
CertComparePublicKeyInfo | Compares two public keys to determine whether they are identical.
CertFindAttribute | Finds the first attribute identified by its object identifier (OID).
CertFindExtension | Finds the first extension identified by its object identifier.
CertFindRDNAttr | Finds the first RDN attribute identified by its Object Identifier in the name list of the Relative Distinguished Names.
CertGetIntendedKeyUsage | Acquires the intended key usage bytes from the certificate.
CertGetPublicKeyLength | Acquires the public/private key's bit length from the public key BLOB
CertIsRDNAttrsInCertificateName | Compares the attributes in the certificate name with the specified RDN's array of attributes to determine whether all attributes are included there.
CertVerifyCRLRevocation | Verifies that the subject certificate is not on the CRL.
CertVerifyCRLTimeValidity | Verifies the time validity of a CRL.
CertVerifyRevocation | Verifies that the subject certificate is not on the CRL.
CertVerifyTimeValidity | Verifies the time validity of a certificate.
CertVerifyValidityNesting | Verifies that the subject's time validity nests within the issuer's time validity.
CryptExportPublicKeyInfo | Exports the public key information associated with the provider's corresponding private key.
CryptExportPublicKeyInfoEx | Exports the public key information associated with the provider's corresponding private key. This function differs from CryptExportPublicKeyInfo in that the user can specify the public key algorithm, overriding the default provided by the CSP.
CryptFindCertificateKeyProvInfo | Enumerates the cryptographic providers and their key containers to find the private key corresponding to a certificate's public key.
CryptFindLocalizedName | Finds the localized name for a specified name such as the Root system's stores name.
CryptHashCertificate | Hashes the encoded content.
CryptHashPublicKeyInfo | Computes the hash of the encoded public key information.
CryptHashToBeSigned | Computes the hash of the "to be signed" information in the encoded signed content (CERT_SIGNED_CONTENT_INFO).
CryptImportPublicKeyInfo | Converts and imports the public key information into the provider and returns a handle of the public key.
CryptImportPublicKeyInfoEx | Converts and imports the public key information into the provider and returns a handle of the public key. Additional parameters (over those specified by CryptImportPublicKeyInfo) that can be used to override defaults are provided to supplement CERT_PUBLIC_KEY_INFO.
CryptMemAlloc | Allocates memory for a buffer. It is used by all Crypt32.lib functions that return allocated buffers.
CryptMemFree | Frees memory allocated by CryptMemAlloc or CryptMemRealloc.
CryptMemRealloc | Frees memory currently allocated for a buffer and allocates memory for a new buffer.
CryptQueryObject | Retrieves information about the content of a BLOB or a file.
CryptSignAndEncodeCertificate | Encodes the "to be signed" information, signs this encoded information, and encodes the resulting signed, encoded information.
CryptSignCertificate | Signs the "to be signed" information in the encoded, signed content.
CryptVerifyCertificateSignature | Verifies the signature of a subject certificate or a CRL using the public key information.
CryptVerifyCertificateSignatureEx | An extended version of CryptVerifyCertificateSignature.


CertCompareCertificate

The CertCompareCertificate function compares two certificates to determine whether or not they are identical.

BOOL WINAPI CertCompareCertificate(
  DWORD dwCertEncodingType,
  PCERT_INFO pCertId1,
  PCERT_INFO pCertId2
);

Parameters

dwCertEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pCertId1
[in] Pointer to the CERT_INFO for the first certificate in the comparison.
pCertId2
[in] Pointer to the CERT_INFO for the second certificate in the comparison.

Return Values

If the certificates are identical and function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE).

Examples

See Example C Program: Deleting Certificates from a Certificate Store.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions, CertCompareCertificateName


CertCompareCertificateName

The CertCompareCertificateName function compares two certificate CERT_NAME_BLOB structures to determine whether they are identical. The CERT_NAME_BLOB structures are used for the subject and the issuer of certificates.

BOOL WINAPI CertCompareCertificateName(
  DWORD dwCertEncodingType,
  PCERT_NAME_BLOB pCertName1,
  PCERT_NAME_BLOB pCertName2
);

Parameters

dwCertEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pCertName1
[in] Pointer to a CERT_NAME_BLOB for the first name in the comparison. See CRYPTOAPI_BLOB.
pCertName2
[in] Pointer to a CERT_NAME_BLOB for the second name in the comparison.

Return Values

If the names are identical and the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE).

Examples

See Example C Program: Deleting Certificates from a Certificate Store.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions, CertCompareCertificate


CertCompareIntegerBlob

The CertCompareIntegerBlob function compares two integer BLOBs to determine whether they represent equal numeric values. Before doing the comparison, most significant bytes with a value of 0x00 are removed from a positive number. Positive here means that the most significant bit in the next non-zero byte is not set.

Most significant bytes with a value of 0xFF are removed from a negative number. Negative here means that the most significant bit in the next non0xFF byte is set. This produces the unique representation of that integer. For instance:

Original bytes | Reduced form
0xFFFFFF88 | 0xFF88
0xFF23 | 0xFF23
0x007F | 0x7F
0x00000080 | 0x80

Multiple-byte integers are treated as little-endian. The least significant byte is pbData[0]. The most significant byte is pbData[cbData - 1], that is, 0xFFFFFF88 is stored in four bytes as :

{0x88, 0xFF, 0xFF, 0xFF}.

BOOL WINAPI CertCompareIntegerBlob(
  PCRYPT_INTEGER_BLOB pInt1,
  PCRYPT_INTEGER_BLOB pInt2
);

Parameters

pInt1
[in] Pointer to a CRYPT_INTEGER_BLOB structure containing the first integer in the comparison.
pInt2
[in] Pointer to a CRYPT_INTEGER_BLOB structure containing the second integer in the comparison.

Return Values

If the representations of the integer BLOBs are identical and the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Examples

See Example C Program: Using CertOIDToAlgId and CertCompareIntegerBlob.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions


CertComparePublicKeyInfo

The CertComparePublicKeyInfo function compares two encoded public keys to determine whether they are identical.

BOOL WINAPI CertComparePublicKeyInfo(
  DWORD dwCertEncodingType,
  PCERT_PUBLIC_KEY_INFO pPublicKey1,
  PCERT_PUBLIC_KEY_INFO pPublicKey2
);

Parameters

dwCertEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are shown in the following table.

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pPublicKey1
[in] Pointer to the CERT_PUBLIC_KEY_INFO for the first public key in the comparison.
pPublicKey2
[in] Pointer to the CERT_PUBLIC_KEY_INFO for the second public key in the comparison.

Returned Values

If the public keys are identical and the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE).

Examples

See Example C Program: Deleting Certificates from a Certificate Store.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions


CertFindAttribute

The CertFindAttribute function finds the first attribute in the CRYPT_ATTRIBUTE array, as identified by its object identifier (OID). This function can be used in the processing of a decoded certificate request. A CERT_REQUEST_INFO structure is derived from a decoded certificate request. The rgAttribute array is retrieved from that structure and passed to this function in the rgAttr parameter. This function determines whether a particular attribute is in the array, and if so, returns a pointer to it.

PCRYPT_ATTRIBUTE WINAPI CertFindAttribute(
  LPCSTR pszObjId,
  DWORD cAttr,
  CRYPT_ATTRIBUTE rgAttr[ ]
);

Parameters

pszObjId
[in] Pointer to the object identifier (OID) to use in the search.
cAttr
[in] Number of attributes in the rgAttr array.
rgAttr
[in] Array of CRYPT_ATTRIBUTE structures.

Return Values

Returns a pointer to the attribute, if one is found. Otherwise, NULL is returned.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions, CertFindExtension, CertFindRDNAttr


CertFindExtension

The CertFindExtension function finds the first extension in the CERT_EXTENSION array, as identified by its object identifier (OID). This function can be used in the processing of a decoded certificate. A CERT_INFO structure is derived from a decoded certificate. The rgExtension array is retrieved from that structure and passed to this function in the rgExtension parameter. This function determines whether a particular extension is in the array, and if so, returns a pointer to it

PCERT_EXTENSION WINAPI CertFindExtension(
  LPCSTR pszObjId,
  DWORD cExtensions,
  CERT_EXTENSION rgExtensions[ ]
);

Parameters

pszObjId
[in] Pointer to the object identifier (OID) to use in the search.
cExtensions
Number of extensions in the rgExtensions array.
rgExtensions
Array of CERT_EXTENSION structures.

Return Values

Returns a pointer to the extension, if one is found. Otherwise, NULL is returned.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions, CertFindAttribute, CertFindRDNAttr


CertFindRDNAttr

The CertFindRDNAttr function finds the first RDN attribute identified by its object identifier (OID) in a list of the Relative Distinguished Names (RDN).

PCERT_RDN_ATTR WINAPI CertFindRDNAttr(
  LPCSTR pszObjId,
  PCERT_NAME_INFO pName
);

Parameters

pszObjId
[in] Pointer to the object identifier (OID) to use In the search.
pName
[in] Pointer to a CERT_NAME_INFO structure containing the list of the Relative Distinguished Names to be searched.

Return Values

Returns a pointer to the attribute, if one is found. Otherwise, NULL is returned.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions, CertFindAttribute, CertFindExtension


CertGetIntendedKeyUsage

The CertGetIntendedKeyUsage function acquires the intended key usage bytes from a certificate. The intended key usage can be in either the szOID_KEY_USAGE ("2.5.29.15") or szOID_KEY_ATTRIBUTES ("2.5.29.2") extension.

BOOL WINAPI CertGetIntendedKeyUsage(
  DWORD dwCertEncodingType,
  PCERT_INFO pCertInfo,
  BYTE *pbKeyUsage,
  DWORD cbKeyUsage
);

Parameters

dwCertEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pCertInfo
[in] Pointer to CERT_INFO structure of the specified certificate.
pbKeyUsage
[in] Pointer to a buffer containing the intended key usage. The following table shows currently defined values. These can be combined using bitwise-OR operations.

Intended key usage

CERT_DATA_ENCIPHERMENT_KEY_USAGE
CERT_DIGITAL_SIGNATURE_KEY_USAGE
CERT_KEY_AGREEMENT_KEY_USAGE
CERT_KEY_CERT_SIGN_KEY_USAGE
CERT_KEY_ENCIPHERMENT_KEY_USAGE
CERT_NON_REPUDIATION_KEY_USAGE
CERT_OFFLINE_CRL_SIGN_KEY_USAGE

cbKeyUsage
[in] Size, in bytes, of the intended key usage. Currently, the intended key usage occupies only 1 byte of data.

Return Values

If the certificate does not have any intended key usage bytes, FALSE is returned and pbKeyUsage is zeroed. Otherwise, TRUE is returned and up to cbKeyUsage number of bytes are copied into pbKeyUsage. Any remaining bytes not copied are zeroed.

Call GetLastError to see the reason for any failures. This function has the following error codes.

Error Code | Description
ERROR_FILE_NOT_FOUND | Invalid certificate encoding type. Currently only X509_ASN_ENCODING is supported.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions


CertGetPublicKeyLength

The CertGetPublicKeyLength function acquires the bit length of public/private keys from a public-key BLOB.

DWORD WINAPI CertGetPublicKeyLength(
  DWORD dwCertEncodingType,
  PCERT_PUBLIC_KEY_INFO pPublicKey
);

Parameters

dwCertEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pPublicKey
[in] Pointer to the public key BLOB containing the keys for which the length is being retrieved.

Return Values

Returns the length of the public/private keys in bits. If unable to determine the key's length, returns zero.

Call GetLastError to see the reason for any failures.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions


CertIsRDNAttrsInCertificateName

The CertIsRDNAttrsInCertificateName function compares the attributes in the certificate name with the specified CERT_RDN to determine whether all attributes are included there. The comparison iterates through the CERT_RDN and looks for an attribute match in any of the certificate name's CERT_RDNs.

BOOL WINAPI CertIsRDNAttrsInCertificateName(
  DWORD dwCertEncodingType,
  DWORD dwFlags,
  PCERT_NAME_BLOB pCertName,
  PCERT_RDN pRDN
);

Parameters

dwCertEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

dwFlags
[in] CERT_UNICODE_IS_RDN_ATTRS_FLAG must be set if the pRDN was initialized with UNICODE strings as in CryptEncodeObject with lpszStructType set to X509_UNICODE_NAME.

CERT_CASE_INSENSITIVE_IS_RDN_ATTRS_FLAG is set to do a case insensitive match. Otherwise, an exact, case sensitive match is done.

pCertName
[in] Pointer to a CRYPTOAPI_BLOB containing the encoded subject or issuer name.
pRDN
[in] Array of CERT_RDN structures containing the attributes to be found in the name. The CERT_RDN_ATTR member of the CERT_RDN follow the following rules.
  • If pszObjId is NULL, the attribute object identifier (OID) is ignored.
  • If dwValueType is CERT_RDN_ANY_TYPE the value type is ignored.
  • If the pbData member of Value is NULL, any value can be a match.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

This function has the following error codes.

Error Code | Description
CRYPT_E_NO_MATCH | Not all the attributes were found and matched.
ERROR_FILE_NOT_FOUND | Invalid certificate encoding type. Currently only X509_ASN_ENCODING is supported.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Remarks

Currently, only an exact, case-sensitive match is supported.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions, CertFindCertificateInStore


CertVerifyCRLRevocation

The CertVerifyCRLRevocation function check a CRL to determine whether a subject's certificate has or has not been revoked. The new Certificate Chain Verification Functions are recommended instead of the use of this function.

BOOL WINAPI CertVerifyCRLRevocation(
  DWORD dwCertEncodingType,
  PCERT_INFO pCertId,
  DWORD cCrlInfo,
  PCRL_INFO rgpCrlInfo[ ]
);

Parameters

dwCertEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pCertId
[in] Pointer to the CERT_INFO structure of the certificate to be checked against the CRL.
cCrlInfo
[in] Number of CRL_INFO pointers in the rgpCrlInfo array.
rgpCrlInfo
[in] Array of pointers to CRL_INFO structures.

Return Values

Returns TRUE if the certificate is not on the CRL and therefore is valid.

It returns FALSE if the certificate is on the list and therefore has been revoked and is invalid.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions, CertVerifyCRLTimeValidity, CertVerifyTimeValidity, CertVerifyValidityNesting


CertVerifyCRLTimeValidity

The CertVerifyCRLTimeValidity function verifies the time validity of a CRL.

LONG WINAPI CertVerifyCRLTimeValidity(
  LPFILETIME pTimeToVerify,
  PCRL_INFO pCrLInfo
);

Parameters

pTimeToVerify
[in] Pointer to FILETIME structure containing the time to be used in the verification. If set to NULL, the current time is used.
pCrLInfo
[in] Pointer to a CRL_INFO structure containing the CRL for which the time is to be verified.

Return Values

Returns a minus one (–1) if the comparison time is before the ThisUpdate member of the CRL_INFO pointed to by pCrLInfo. Returns a plus one (+1) if the comparison time is after the NextUpdate time. Returns zero (0) for valid time for the CRL.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions, CertVerifyCRLRevocation, CertVerifyTimeValidity, CertVerifyValidityNesting


CertVerifyRevocation

The CertVerifyRevocation function checks the revocation status of the certificates contained in the rgpvContext array. If a certificate in the list is found to be revoked, no further checking is done. This array can be a chain of certificates propagating upwards from an end entity to the root certification authority (CA), but this nature of the list of certificates is not required or assumed.

BOOL WINAPI CertVerifyRevocation(
  DWORD dwEncodingType,
  DWORD dwRevType,
  DWORD cContext,
  PVOID rgpvContext[ ],
  DWORD dwFlags,
  PCERT_REVOCATION_PARA pRevPara,
  PCERT_REVOCATION_STATUS pRevStatus
);

Parameters

dwEncodingType
[in]Specifies the encoding type used. Currently, only X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are being used; however, additional encoding types may be added in the future. For either current encoding type, use:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
dwRevType
[in] Indicates the type of the context structure passed in rgpvContext. Currently only CERT_CONTEXT_REVOCATION_TYPE, the revocation of certificates, is defined.
cContext
[in] Count of elements in the rgpvContext array.
rgpvContext
[in] When the dwRevType is CERT_CONTEXT_REVOCATION_TYPE, rgpvContext is an array of pointers to CERT_CONTEXT structures. These contexts must contain sufficient information to allow the installable or registered revocation DLLs to find the revocation server. This information would normally be conveyed in an extension such as the CRLDistributionsPoints extension defined by the Internet Engineering Task Force (IETF) in PKIX Part 1.

For efficiency, the more contexts that are passed in at one time, the better.

dwFlags
[in] Indicates any special processing needs. The following flags are defined:
Value | Description
CERT_VERIFY_REV_CHAIN_FLAG | Verification of the chain of certificates is done assuming each certificate except the first certificate is the issuer of the certificate that precedes it. If the dwRevType is not CERT_CONTEXT_REVOCATION_TYPE, no assumptions are made about the order of the contexts.
CERT_VERIFY_CACHE_ONLY_BASED_REVOCATION | Prevents the revocation handler from accessing any network based resources for revocation checking.
CERT_VERIFY_REV_ACCUMULATIVE_TIMEOUT_FLAG | When set, dwUrlRetrievalTimeout is the accumulative timeout across all URL wire retrievals.

pRevPara
[in/optional] Optionally set to assist in finding the issuer. See the CERT_REVOCATION_PARA structure for details.
pRevStatus
[in/out] Only the cbSize member of the CERT_REVOCATION_STATUS pointed to by pRevStatus needs to be set before CertVerifyRevocation is called.

If the function returns FALSE, this structure's members will contain error status information. See CERT_REVOCATION_STATUS for additional detail. See the "Remarks" section below for an example describing how pRevStatus is updated when a revocation verification problem is encountered.

Return Values

CertVerifyRevocation returns TRUE if all of the contexts were successfully checked and none were revoked. Otherwise, it returns FALSE and updates the CERT_REVOCATION_STATUS structure pointed to by pRevStatus as described in CERT_REVOCATION_STATUS.

When the revocation handler for any of the contexts returns FALSE due to an error, the dwError member in the structure pointed to by pRevStatus will be set by the handler to specify which error was encountered. GetLastError returns a error code equal to the error specified in the dwError member of the CERT_REVOCATION_STATUS structure.

Error Code | Description
CRYPT_E_NO_REVOCATION_CHECK | An installed or registered revocation function wasn't able to do a revocation check on the context.
CRYPT_E_NO_REVOCATION_DLL | No installed or registered DLL was found that was able to verify revocation.
CRYPT_E_NOT_IN_REVOCATION_DATABASE | The context to be checked was not found in the revocation server's database.
CRYPT_E_REVOCATION_OFFLINE | It was not possible to connect to the revocation server.
CRYPT_E_REVOKED | The context was revoked. dwReason in pRevStatus contains the reason for revocation.
ERROR_SUCCESS | The context was good.
E_INVALIDARG | cbSize in pRevStatus is less than sizeof(CERT_REVOCATION_STATUS). Note that dwError in pRevStatus is not updated for this error.

Remarks

The following example shows how pRevStatus is updated when a revocation verification problem is encountered:

Consider the case where cContext is four. If CertVerifyRevocation can verify that rgpvContext[0] and rgpvContext[1] are not revoked, but cannot check rgpvContext[2], the pRevStatus member dwIndex is set to two, indicating that the context at index two has the problem, the dwError member of pRevStatus is set to CRYPT_E_NO_REVOCATION_CHECK, and FALSE is returned.

If rgpvContext[2] is found to be revoked, the dwIndex member of pRevStatus is set to two and the dwError member of pRevStatus is set l to CRYPT_E_REVOKED, dwReason is updated, and FALSE is returned. In either case, both rgpvContext[0] and rgpvContext[1] are verified not to be revoked, rgpvContext[2] is the last array index checked, and rgpvContext[3] has not been checked at all.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions, CertVerifyCRLTimeValidity, CertVerifyTimeValidity, CertVerifyValidityNesting


CertVerifyTimeValidity

The CertVerifyTimeValidity function verifies the time validity of a certificate.

LONG WINAPI CertVerifyTimeValidity(
  LPFILETIME pTimeToVerify,
  PCERT_INFO pCertInfo
);

Parameters

pTimeToVerify
[in] Pointer to a FILETIME structure containing the comparison time. If NULL, the current time is used.
pCertInfo
[in] Pointer to the CERT_INFO structure of the certificate for which the time is being verified.

Return Values

Returns a minus one if the comparison time is before the NotBefore member of the CERT_INFO structure. Returns a plus one if the comparison time is after the NotAfter member. Returns zero for valid time for the certificate.

Examples

See Example C Program: Certificate Store Operations.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions, CertVerifyCRLTimeValidity, CertVerifyCRLRevocation, CertVerifyValidityNesting


CertVerifyValidityNesting

The CertVerifyValidityNesting function verifies that a subject certificate's time validity nests correctly within its issuer's time validity.

BOOL WINAPI CertVerifyValidityNesting(
  PCERT_INFO pSubjectInfo,
  PCERT_INFO pIssuerInfo
);

Parameters

pSubjectInfo
[in] Pointer to the CERT_INFO structure of the subject certificate.
pIssuerInfo
[in] Pointer to the CERT_INFO structure of the issuer certificate.

Return Values

Returns TRUE if the NotBefore time of the subject's certificate is after the NotBefore time of the issuer's certificate and the NotAfter time of the subjects certificate is not after the NotAfter time of the issuer's certificate. Otherwise, returns FALSE.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions, CertVerifyCRLTimeValidity, CertVerifyCRLRevocation, CertVerifyTimeValidity


CryptExportPublicKeyInfo

The CryptExportPublicKeyInfo function exports the public key information associated with the provider's corresponding private key. See CryptExportPublicKeyInfoEx for an updated version of this function.

BOOL WINAPI CryptExportPublicKeyInfo(
  HCRYPTPROV hCryptProv,
  DWORD dwKeySpec,
  DWORD dwCertEncodingType,
  PCERT_PUBLIC_KEY_INFO pInfo,
  DWORD *pcbInfo
);

Parameters

hCryptProv
[in] Handle of the CSP to use when exporting the public key information. This handle must have already been created using CryptAcquireContext.
dwKeySpec
[in] Identifies the private key to use from the provider's container. It can be AT_KEYEXCHANGE or AT_SIGNATURE.
dwCertEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pInfo
[in] Pointer to a CERT_PUBLIC_KEY_INFO structure to receive the public key information to be exported.

This parameter can be NULL to set the size of this information for memory allocation purposes. See Retrieving Data of Unknown Length.

pcbInfo
[in/out] Pointer to a DWORD that contains the size, in bytes, of the buffer pointed to by the pInfo parameter. When the function returns, the DWORD contains the number of bytes needed for the return buffer.

Note When processing the data returned in the buffer, applications need to use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Note Errors from the called functions CryptGetUserKey and CryptExportKey might be propagated to this function. This function has the following error codes.

Error Code | Description
ERROR_MORE_DATA | If the buffer specified by the pInfo parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcbInfo.
ERROR_FILE_NOT_FOUND | Invalid certificate encoding type. Currently only X509_ASN_ENCODING is supported.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Examples

See Example C Program: Making a Certificate Request.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions, CryptImportPublicKeyInfo


CryptExportPublicKeyInfoEx

The CryptExportPublicKeyInfoEx function exports the public key information associated with the provider's corresponding private key. This function allows the application to specify the public key algorithm, overriding the default provided by the CSP.

BOOL WINAPI CryptExportPublicKeyInfoEx(
  HCRYPTPROV hCryptProv,
  DWORD dwKeySpec,
  DWORD dwCertEncodingType,
  LPSTR pszPublicKeyObjId,
  DWORD dwFlags,
  void *pvAuxInfo,
  PCERT_PUBLIC_KEY_INFO pInfo,
  DWORD *pcbInfo
);

Parameters

hCryptProv
[in] Handle of the CSP to use when exporting the public key information. This handle must have already been created using CryptAcquireContext.
dwKeySpec
[in] Identifies the private key to use from the provider's container. It can be AT_KEYEXCHANGE or AT_SIGNATURE.
dwCertEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pszPublicKeyObjId
[in] Specifies the public key algorithm.

Note pszPublicKeyObjId and dwCertEncodingType are used together in determining the installable CRYPT_OID_EXPORT_PUBLIC_KEY_INFO_FUNC to call. If an installable function was not found for the pszPublicKeyObjId, an attempt is made to export the key as a RSA Public Key (szOID_RSA_RSA).

dwFlags
[in] Reserved for future use and must be zero (0).
pvAuxInfo
[in] Reserved for future use and must be NULL.
pInfo
[out] Pointer to a CERT_PUBLIC_KEY_INFO structure to receive the public key information to be exported.

This parameter can be NULL to set the size of this information for memory allocation purposes. See Retrieving Data of Unknown Length.

pcbInfo
[in/out] Pointer to a DWORD that contains the size, in bytes, of the buffer pointed to by the pInfo parameter. When the function returns, the DWORD contains the number of bytes stored in the buffer.

Note When processing the data returned in the buffer, applications need to use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Note Errors from the called functions CryptGetUserKey and CryptExportKey can be propagated to this function.

This function has the following error codes.

Error Code | Description
ERROR_FILE_NOT_FOUND | An installable or registerable export function could not be found for the specified dwCertEncodingType and pszPublicKeyObjId.
ERROR_MORE_DATA | If the buffer specified by the pInfo parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcbInfo.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions, CryptImportPublicKeyInfoEx


CryptFindCertificateKeyProvInfo

The CryptFindCertificateKeyProvInfo function enumerates the cryptographic providers and their containers to find the private key corresponding to the certificate's public key.

BOOL WINAPI CryptFindCertificateKeyProvInfo(
  PCCERT_CONTEXT pCert,
  DWORD dwFlags,
  void *pvReserved
);

Parameters

pCert
[in] Pointer to the CERT_CONTEXT structure of the certificate to use when exporting public key information.
dwFlags
[in] The following flag values are defined.
Flag name | Description
CRYPT_FIND_USER_KEYSET_FLAG | Restricts the search to the user container.
CRYPT_FIND_MACHINE_KEYSET_FLAG | Restricts the search to the machine container.
CRYPT_FIND_SILENT_KEYSET_FLAG | The application requests that the CSP not display any user interface (UI) for this context. If the CSP must display the UI to operate, the call fails and the NTE_SILENT_CONTEXT error code is set as the last error.

If no flag value is specified, both the user and the machine containers are searched.

pvReserved
[in] Reserved for future use and must be NULL.

Note This function enumerates the cryptographic providers and their containers to find the private key corresponding to the certificate's public key. For a match, the function updates the certificate's CERT_KEY_PROV_INFO_PROP_ID property. If the CERT_KEY_PROV_INFO_PROP_ID is already set, it is checked to see if it matches the provider's public key. For a match, the function skips the previously mentioned enumeration.

Return Values

TRUE if the function finds a private key corresponding to the certificate's public key within a searched container, FALSE if the function fails to find a container or a private key within a container.

GetLastError returns the following error:

Error Code | Description
NTE_NO_KEY | No container found.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions


CryptFindLocalizedName

The CryptFindLocalizedName function finds the localized name for the specified name, such as the localize name of the "Root" system store. This function can be used before displaying any UI that included a name that might have a localized form.

LPCWSTR WINAPI CryptFindLocalizedName(
  LPCWSTR pwszCryptName
);

Parameters

pwszCryptName
[in] Pointer to a specified name. An internal table is searched to compare a predefined localized name to the specified name. The search matches the localized name using a case insensitive string comparison.

Note Localized names for the predefined system stores ("Root", "My") and predefined physical stores (".Default", ".LocalMachine") are pre-installed as resource strings in crypt32.dll.

Return Values

If the specified name is found, a pointer to the localized name is returned. The returned pointer MUST NOT be freed.

If the specified name is not found, a NULL is returned.

Remarks

CryptSetOIDFunctionValue can be called as follows to register additional localized strings.

dwEncodingType = CRYPT_LOCALIZED_NAME_ENCODING_TYPE

pszFuncName = CRYPT_OID_FIND_LOCALIZED_NAME_FUNC

pszOID = CRYPT_LOCALIZED_NAME_OID

pwszValueName = Name to be localized, for example, L"ApplicationStore"

dwValueType = REG_SZ

pbValueData = pointer to the UNICODE localized string

cbValueData = (wcslen(UNICODE localized string) + 1) * sizeof(WCHAR)

CryptSetOIDFunctionValue can be called as follows to unregister the localized strings.

pbValueData = NULL

cbValueData = 0.

The registered names are searched before the pre-installed names.

CRYPT_LOCALIZED_NAME_ ENCODING_TYPE | 0
CRYPT_LOCALIZED_NAME_ OID | "LocalizedNames"
CRYPT_OID_FIND_LOCALIZED_ NAME_FUNC | "CryptDLLFindLocalizedName"

Examples

See Example C Program: Setting and Getting Certificate Store Properties.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions, CryptSetOIDFunctionValue


CryptHashCertificate

The CryptHashCertificate function hashes the entire encoded content of a certificate including its signature.

BOOL WINAPI CryptHashCertificate(
  HCRYPTPROV hCryptProv,
  ALG_ID Algid,
  DWORD dwFlags,
  const BYTE *pbEncoded,
  DWORD cbEncoded,
  BYTE *pbComputedHash,
  DWORD *pcbComputedHash
);

Parameters

hCryptProv
[in] Handle of the CSP to use to compute the hash.

Unless there is a strong reason for passing in a specific cryptographic provider in hCryptProv, zero is passed in. Passing in zero causes the default RSA or DSS provider to be acquired before doing hash, signature verification or recipient encryption operations.

Algid
[in] ALG_ID structure specifying the hash algorithm to use. If Algid is zero, the default hash algorithm, SHA1, is used.
dwFlags
[in] Value to be passed to the hash API. See CryptCreateHash for details.
pbEncoded
[in] Address of the encoded content to be hashed.
cbEncoded
[in] Size, in bytes, of the encoded content.
pbComputedHash
[out] Pointer to a buffer to receive the computed hash.

This parameter can be NULL to set the size of this information for memory allocation purposes. See Retrieving Data of Unknown Length.

pcbComputedHash
[in/out] Pointer to a DWORD that contains the size, in bytes, of the buffer pointed to by the pbComputedHash parameter. When the function returns, the DWORD contains the number of bytes stored in the buffer.

Note When processing the data returned in the buffer, applications need to use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Note Errors from the called functions CryptCreateHash, CryptGetHashParam and CryptHashData might be propagated to this function.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions, CryptHashPublicKeyInfo, CryptHashToBeSigned


CryptHashPublicKeyInfo

The CryptHashPublicKeyInfo function encodes the public key information in a CERT_PUBLIC_KEY_INFO structure and computes the hash of the encoded bytes. The hash created is used with key identifier functions.

BOOL WINAPI CryptHashPublicKeyInfo(
  HCRYPTPROV hCryptProv,
  ALG_ID Algid,
  DWORD dwFlags,
  DWORD dwCertEncodingType,
  PCERT_PUBLIC_KEY_INFO pInfo,
  BYTE *pbComputedHash,
  DWORD *pcbComputedHash
);

Parameters

hCryptProv
[in] Handle of the CSP to use to compute the hash.

Unless there is a strong reason for passing in a specific cryptographic provider in hCryptProv, zero is passed in. Passing in zero causes the default RSA or DSS provider to be acquired before doing hash, signature verification or recipient encryption operations.

Algid
[in] ALG_ID structure specifying the CryptoAPI hash algorithm to use. If Algid is zero, the default hash algorithm, SHA1, is used.
dwFlags
[in] Values to be passed on to CryptCreateHash.
dwCertEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pInfo
[in] Pointer to a CERT_PUBLIC_KEY_INFO structure containing the public key information to be encoded and hashed.
pbComputedHash
[out] Pointer to a buffer to receive the computed hash.

This parameter can be NULL to set the size of this information for memory allocation purposes. See Retrieving Data of Unknown Length.

pcbComputedHash
[in/out] Pointer to a DWORD that contains the size, in bytes, of the buffer pointed to by the pbComputedHash parameter. When the function returns, the DWORD contains the number of bytes stored in the buffer.

Note When processing the data returned in the buffer, applications need to use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Note Errors from the called functions CryptCreateHash, CryptGetHashParam and CryptHashData can be propagated to this function. This function has the following error codes.

Error Code | Description
ERROR_MORE_DATA | If the buffer specified by the pbComputedHash parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcbComputedHash.
ERROR_FILE_NOT_FOUND | Invalid certificate encoding type. Currently only X509_ASN_ENCODING is supported.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions, CryptHashCertificate, CryptHashToBeSigned


CryptHashToBeSigned

The CryptHashToBeSigned function computes the hash of the encoded content from a signed and encoded certificate. The hash is performed on only the "to be signed" encoded content and its signature.

BOOL WINAPI CryptHashToBeSigned(
  HCRYPTPROV hCryptProv,
  DWORD dwCertEncodingType,
  const BYTE *pbEncoded,
  DWORD cbEncoded,
  BYTE *pbComputedHash,
  DWORD *pcbComputedHash
);

Parameters

hCryptProv
[in] Handle of the CSP to use to compute the hash.

Unless there is a strong reason for passing in a specific cryptographic provider in hCryptProv, zero is passed in. Passing in zero causes the default RSA or DSS provider to be acquired before doing hash, signature verification or recipient encryption operations.

dwCertEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pbEncoded
[in] Address of a buffer containing the content to be hashed. This is the encoded form of a CERT_SIGNED_CONTENT_INFO.
cbEncoded
[in] Size, in bytes, of the buffer.
pbComputedHash
[out] Pointer to a buffer to receive the computed hash.

This parameter can be NULL to set the size of this information for memory allocation purposes. See Retrieving Data of Unknown Length.

pcbComputedHash
[in/out] Pointer to a DWORD that contains the size, in bytes, of the buffer pointed to by the pbComputedHash parameter. When the function returns, the DWORD contains the number of bytes stored in the buffer.

Note When processing the data returned in the buffer, applications need to use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Note Errors from the called functions CryptCreateHash, CryptGetHashParam and CryptHashData might be propagated to this function. This function has the following error codes.

Error Code | Description
ERROR_MORE_DATA | If the buffer specified by the pbComputedHash parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcbComputedHash.
ERROR_FILE_NOT_FOUND | Invalid certificate encoding type. Currently only X509_ASN_ENCODING is supported.
NTE_BAD_ALGID | The signature algorithm's object identifier (OID) doesn't map to a known or supported hash algorithm.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions, CryptHashCertificate, CryptHashPublicKeyInfo


CryptImportPublicKeyInfo

The CryptImportPublicKeyInfo function converts and imports the public key information into the provider and returns a handle of the public key. CryptImportPublicKeyInfoEx provides a revised version of this function.

BOOL WINAPI CryptImportPublicKeyInfo(
  HCRYPTPROV hCryptProv,
  DWORD dwCertEncodingType,
  PCERT_PUBLIC_KEY_INFO pInfo,
  HCRYPTKEY *phKey
);

Parameters

hCryptProv
[in] Handle of the CSP to use when importing the public key. This handle must have already been created using CryptAcquireContext.
dwCertEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pInfo
[in] Pointer to a CERT_PUBLIC_KEY_INFO that contains the public key to import into the provider.
phKey
[out] Pointer to the handle of the imported public key.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Note Errors from the called functions CryptGetUserKey and CryptExportKey might be propagated to this function. This function has the following error codes.

Error Code | Description
ERROR_FILE_NOT_FOUND | An installable or registerable import function could not be found for the specified dwCertEncodingType and pInfo->Algorithm.pszObjId.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions, CryptExportPublicKeyInfo


CryptImportPublicKeyInfoEx

The CryptImportPublicKeyInfoEx function imports public key information into the CSP and returns a handle of the public key. Additional parameters to override defaults are provided to supplement those in CERT_PUBLIC_KEY_INFO.

BOOL WINAPI CryptImportPublicKeyInfoEx(
  HCRYPTPROV hCryptProv,
  DWORD dwCertEncodingType,
  PCERT_PUBLIC_KEY_INFO pInfo,
  ALG_ID aiKeyAlg,
  DWORD dwFlags,
  void *pvAuxInfo,
  HCRYPTKEY *phKey
);

Parameters

hCryptProv
[in] Handle of the CSP that will receive the imported public key. This handle must have already been created using CryptAcquireContext.
dwCertEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pInfo
[in] Pointer to a CERT_PUBLIC_KEY_INFO structure containing the public key to import into the provider.

Note The pzObjId member of the Algorithm member pointed to by pInfo and the dwCertEncodingType parameter determine an installable CRYPT_OID_IMPORT_PUBLIC_KEY_INFO_FUNC callback function. If an installable function is not found, an attempt is made to import the key as a szOID_RSA_RSA, RSA Public Key.

aiKeyAlg
[in] ALG_ID structure containing a CSP specific algorithm to override the CALG_RSA_KEYX default algorithm.
dwFlags
[in] Reserved for future use and must be zero (0).
pvAuxInfo
[in] Reserved for future use and must be NULL.
phKey
[out] Pointer to the handle of the imported public key.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Note Errors from the called functions CryptGetUserKey and CryptExportKey might be propagated to this function. This function has the following error codes.

Error Code | Description
ERROR_FILE_NOT_FOUND | An installable or registerable import function could not be found for the specified dwCertEncodingType and pInfo.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions, CryptExportPublicKeyInfoEx


CryptMemAlloc

The CryptMemAlloc function allocates memory for a buffer. It is used by all Crypt32.lib functions that return allocated buffers.

LPVOID WINAPI CryptMemAlloc (
  ULONG cbSize
);

Parameters

cbSize
[in] Number of bytes to be allocated.

Return Values

Returns a pointer to the buffer allocated. If the function fails, NULL is returned.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 98 or later.
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.


CryptMemFree

The CryptMemFree function frees memory allocated by CryptMemAlloc or CryptMemRealloc.

void WINAPI CryptMemFree (
  LPVOID pv
);

Parameters

pv
[in] Pointer to the buffer to be freed.

Return Values

This function does not return a value.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 98 or later.
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.


CryptMemRealloc

The CryptMemRealloc function frees the memory currently allocated for a buffer and allocates memory for a new buffer.

LPVOID WINAPI CryptMemRealloc (
  LPVOID pv,
  ULONG cbSize
);

Parameters

pv
[in] Pointer to a currently allocated buffer.
cbSize
[in] Number of bytes to be allocated.

Return Values

Returns a pointer to the buffer allocated. If the function fails, NULL is returned.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Requires Windows 98 or later.
Header: Declared in Wincrypt.h.
Library: Use Advapi32.lib.


CryptQueryObject

[This is preliminary documentation and subject to change.]

The CryptQueryObject function takes a CERT_BLOB or a file name and returns information about the content of the BLOB or the file.

BOOL WINAPI CryptQueryObject(
  DWORD dwObjectType,
  const void *pvObject,
  DWORD dwExpectedContentTypeFlags,
  DWORD dwExpectedFormatTypeFlags,
  DWORD dwFlags,
  DWORD *pdwMsgAndCertEncodingType,
  DWORD *pdwContentType,
  DWORD *pdwFormatType,
  HCERTSTORE *phCertStore,
  HCRYPTMSG *phMsg,
  const void **ppvContext
);

Parameters

dwObjectType
[in] Indicates the type of the object to be queried. It should be one of the following.
Value | Type of object
CERT_QUERY_OBJECT_FILE | File
CERT_QUERY_OBJECT_BLOB | BLOB

If the dwObjectType is not correct for the object, the function's behavior is unspecified.

pvObject
[in] Pointer to the object to be queried.
dwObjectType | pvObject type
CERT_QUERY_OBJECT_FILE | LPWSTR.
CERT_QUERY_OBJECT_BLOB | PCERT_BLOB.

If the pvObject is not valid for the dwObjectType, the function's behavior is unspecified.

dwExpectedContentTypeFlags
[in] Indicates the expected content type. Can be one of the following:
Expected Content Type–Flag Name | Content Type
CERT_QUERY_CONTENT_FLAG_ALL | Any type
CERT_QUERY_CONTENT_FLAG_CERT | Single certificate
CERT_QUERY_CONTENT_FLAG_CTL | Single CTL
CERT_QUERY_CONTENT_FLAG_CRL | Single CRL
CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE | Serialized store
CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT Serialized single
certificate
CERT_QUERY_CONTENT_FLAG_SERIALIZED_CTL | Serialized single CTL
CERT_QUERY_CONTENT_FLAG_SERIALIZED_CRL | Serialized single CRL
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED PKCS#7 signed
message
CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED PKCS#7 unsigned
message
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED Embedded PKCS7
signed message
CERT_QUERY_CONTENT_FLAG_PKCS10 | PKCS#10
CERT_QUERY_CONTENT_FLAG_PFX | PFX BLOB
CERT_QUERY_CONTENT_FLAG_CERT_PAIR | ASN.1 encoded X509_CERT_PAIR (an encoded CertificatePair containing forward and/or reverse cross certificates)

If the dwExpectedContentTypeFlags is not correct for the type specified by pdwContentType, the function will return a FALSE.

dwExpectedFormatTypeFlags
[in] Indicates the expected format type. Can be one of the following:
Expected format type–flags name | Format type
CERT_QUERY_FORMAT_FLAG_ALL | Any format
CERT_QUERY_FORMAT_FLAG_BINARY | Binary format
CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED | Base64 encoded
CERT_QUERY_FORMAT_FLAG_ASN_ASCII_HEX_ENCODED | ASCII hex-encoded with a "{ASN}" prefix

If the dwExpectedFormatTypeFlags is not correct for the type specified by pdwFormatType, the function will return a FALSE.

dwFlags
[in] Reserved for future use and must be set to 0.
pdwMsgAndCertEncodingType
[out] Pointer to the type of encoding used in the message. If no return is needed, set pdwMsgAndCertEncodingType to NULL. The returned encoding type will be any combination of the following:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pdwContentType
[out] Pointer to the returned encoding type of the content. If no return is needed, set pdwContentType to NULL. The returned content type can be any one of the following.

CERT_QUERY_CONTENT_CERT
CERT_QUERY_CONTENT_CTL
CERT_QUERY_CONTENT_CRL
CERT_QUERY_CONTENT_SERIALIZED_STORE
CERT_QUERY_CONTENT_SERIALIZED_CERT
CERT_QUERY_CONTENT_SERIALIZED_CTL
CERT_QUERY_CONTENT_SERIALIZED_CRL
CERT_QUERY_CONTENT_PKCS7_SIGNED
CERT_QUERY_CONTENT_PKCS7_UNSIGNED
CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED
CERT_QUERY_CONTENT_PKCS10
CERT_QUERY_CONTENT_PFX
CERT_QUERY_CONTENT_CERT_PAIR

pdwFormatType
[out] Pointer to the returned format type of the content. If no return is needed, set pdwFormatType to NULL. The returned format type can be any one of the following.

CERT_QUERY_FORMAT_BINARY
CERT_QUERY_FORMAT_BASE64_ENCODED
CERT_QUERY_FORMAT_ASN_ASCII_HEX_ENCODED

phCertStore
[out] *phCertStore is a NULL unless dwContentType is one of the content types in the following table. If dwContentType is one of these content types, phCertStore is a pointer to a handle of a certificate store that includes all of the certificates, CRLs, and CTLs in the object.

The caller should free *phCertStore via CertCloseStore.

If no return is needed, set phCertStore to NULL.

Content type

CERT_QUERY_CONTENT_CERT
CERT_QUERY_CONTENT_CTL
CERT_QUERY_CONTENT_CRL
CERT_QUERY_CONTENT_SERIALIZED_STORE
CERT_QUERY_CONTENT_SERIALIZED_CERT
CERT_QUERY_CONTENT_SERIALIZED_CTL
CERT_QUERY_CONTENT_SERIALIZED_CRL
CERT_QUERY_CONTENT_PKCS7_SIGNED
CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED

phMsg
[out] NULL unless dwContentType is one of the content types in the following table. If dwContentType is one of these content types, phMsg is a pointer to a handle of an opened message.

dwContentType

CERT_QUERY_CONTENT_PKCS7_SIGNED

CERT_QUERY_CONTENT_PKCS7_UNSIGNED

CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED

The caller must free phMsg handle using CryptMsgClose.

If no output is wanted, set phMsg to NULL.

ppvContext
[out] Pointer to a context pointer. The type of context is dependent upon dwContentType. The following table contains the types contained at pvContext. The caller should free the pvContext through the function shown in the table.

If no output is wanted, set ppvContext to NULL.
pvContext | dwContentType | free pvContext via
PCCERT_CONTEXT CERT_QUERY_CONTENT_CERT CertFreeCertificate
Context
PCCERT_CONTEXT CERT_QUERY_CONTENT_SERIALIZED_CERT CertFreeCertificate
Context
PCCTL_CONTEXT | CERT_QUERY_CONTENT_CTL | CertFreeCTLContext
PCCTL_CONTEXT | CERT_QUERY_CONTENT_SERIALIZED_CTL | CertFreeCTLContext
PCCRL_CONTEXT | CERT_QUERY_CONTENT_CRL | CertFreeCRLContext
PCCRL_CONTEXT | CERT_QUERY_CONTENT_SERIALIZED_CRL | CertFreeCRLContext

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. For extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions


CryptSignAndEncodeCertificate

The CryptSignAndEncodeCertificate function encodes and signs a certificate, CRL, CTL or certificate request. This function performs the following operations:

  • Calls CryptEncodeObject using lpszStructType to encode the "to be signed" information.
  • Calls CryptSignCertificate to sign this encoded information.
  • Calls CryptEncodeObject again, with lpszStructType set to X509_CERT, to further encode the resulting signed, encoded information.
BOOL WINAPI CryptSignAndEncodeCertificate(
  HCRYPTPROV hCryptProv,
  DWORD dwKeySpec,
  DWORD dwCertEncodingType,
  LPCSTR lpszStructType,
  const void *pvStructInfo,
  PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm,
  const void *pvHashAuxInfo,
  PBYTE pbEncoded,
  DWORD *pcbEncoded
);

Parameters

hCryptProv
[in] Handle of the CSP to do the signature. This handle must have already been created using CryptAcquireContext.
dwKeySpec
[in] Identifies the private key to use from the provider's container. It can be AT_KEYEXCHANGE or AT_SIGNATURE.
dwCertEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

lpszStructType
[in] The following predefined lpszStructType constants are used with encode operations.
Defined Constant
X509_CERT_CRL_TO_BE_SIGNED
X509_CERT_REQUEST_TO_BE_SIGNED
X509_CERT_TO_BE_SIGNED
X509_KEYGEN_REQUEST_TO_BE_SIGNED

pvStructInfo
[in] Pointer to the structure to be signed and encoded. The most commonly used structures are:

CERT_INFO
CRL_INFO
CERT_REQUEST_INFO CERT_KEYGEN_REQUEST_INFO

pSignatureAlgorithm
[in] Pointer to a CRYPT_ALGORITHM_IDENTIFIER structure containing the object identifier (OID) of the signature algorithm and any additional parameters needed. This function uses the following algorithm OIDs:

szOID_RSA_MD5RSA
szOID_RSA_SHA1RSA
szOID_X957_SHA1DSA

pvHashAuxInfo
[in] Reserved. Must be NULL.
pbEncoded
[out] Pointer to a buffer to receive the signed and encoded output.

This parameter can be NULL to set the size of this information for memory allocation purposes. See Retrieving Data of Unknown Length.

pcbEncoded
[in/out] Pointer to a DWORD that contains the size, in bytes, of the buffer pointed to by the pbEncoded parameter. When the function returns, the DWORD contains the number of bytes stored or to be stored in the buffer.

Note When processing the data returned in the buffer, applications need to use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Note Errors from the called functions CryptCreateHash, CryptSignHash and CryptHashData might be propagated to this function.

This function has the following error codes.

Error Code | Description
ERROR_MORE_DATA | If the buffer specified by the pbEncoded parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcbEncoded.
ERROR_FILE_NOT_FOUND | Invalid certificate encoding type. Currently only X509_ASN_ENCODING is supported.
NTE_BAD_ALGID | The signature algorithm's object Identifier (OID) does not map to a known or supported hash algorithm.
CRYPT_E_BAD_ENCODE | An error was encountered while encoding or decoding. The most likely cause of this error is the improper initialization all of the fields in the structure pointed to by pvStructInfo.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Examples

See Example C Program: Making a Certificate Request.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions, CryptSignCertificate


CryptSignCertificate

The CryptSignCertificate function signs the "to be signed" information in the encoded signed content.

BOOL WINAPI CryptSignCertificate(
  HCRYPTPROV hCryptProv,
  DWORD dwKeySpec,
  DWORD dwCertEncodingType,
  const BYTE *pbEncodedToBeSigned,
  DWORD cbEncodedToBeSigned,
  PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm,
  const void *pvHashAuxInfo,
  BYTE *pbSignature,
  DWORD *pcbSignature
);

Parameters

hCryptProv
[in] Handle of the CSP that does the signature. This handle must have already been created using CryptAcquireContext.
dwKeySpec
[in] Identifies the private key to use from the provider's container. It can be AT_KEYEXCHANGE or AT_SIGNATURE.
dwCertEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pbEncodedToBeSigned
[in] Pointer to the encoded content to be signed.
cbEncodedToBeSigned
[in] Size, in bytes, of the encoded content, pbEncodedToBeSigned.
pSignatureAlgorithm
[in] Pointer to a CRYPT_ALGORITHM_IDENTIFIER structure with a pszObjId member set to one of the following:

szOID_RSA_MD5RSA
szOID_RSA_SHA1RSA
szOID_X957_SHA1DSA

pvHashAuxInfo
[in] Not currently used. Must be NULL.
pbSignature
[out] Pointer to a buffer to receive the signed hash of the content.

This parameter can be NULL to set the size of this information for memory allocation purposes. See Retrieving Data of Unknown Length.

pcbSignature
[in/out] Pointer to a DWORD that contains the size, in bytes, of the buffer pointed to by the pbSignature parameter. When the function returns, the DWORD contains the number of bytes stored or to be stored in the buffer.

Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Note Errors from the called functions CryptCreateHash, CryptSignHash and CryptHashData might be propagated to this function.

This function has the following error codes.

Error Code | Description
ERROR_MORE_DATA | If the buffer specified by the pbSignature parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcbSignature.
NTE_BAD_ALGID | The signature algorithm's object identifier (OID) doesn't map to a known or supported hash algorithm.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Management Functions, CryptSignAndEncodeCertificate


CryptVerifyCertificateSignature

The CryptVerifyCertificateSignature function verifies the signature of a certificate, CRL, or certificate request using the public key in a CERT_PUBLIC_KEY_INFO structure. The function does not require access to a private key.

BOOL WINAPI CryptVerifyCertificateSignature(
  HCRYPTPROV hCryptProv,
  DWORD dwCertEncodingType,
  BYTE *pbEncoded,
  DWORD cbEncoded,
  PCERT_PUBLIC_KEY_INFO pPublicKey
);

Parameters

hCryptProv
[in] Handle of the CSP used to verify the signature.

Null is passed unless there is a strong reason for passing in a specific cryptographic provider. Passing in NULL causes the default RSA or DSS provider to be acquired.

dwCertEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pbEncoded
[in] Pointer to a CERT_SIGNED_CONTENT_INFO structure containing the encoded content on which the signature is to be verified.
cbEncoded
[in] Size, in bytes, of the encoded content pbEncoded.
pPublicKey
[in] Pointer to a CERT_PUBLIC_KEY_INFO structure containing the public key to use when verifying the signature.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Note Errors from the called functions CryptCreateHash, CryptImportKey, CryptVerifySignature, and CryptHashData might be propagated to this function.

This function has the following error codes.

Error Code | Description
ERROR_FILE_NOT_FOUND | Invalid certificate encoding type. Currently only X509_ASN_ENCODING is supported.
NTE_BAD_ALGID | The signature algorithm's object identifier (OID) does not map to a known or supported hash algorithm.
NTE_BAD_SIGNATURE | The signature was not verified.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Remarks

This function currently calls the CryptVerifyCertificateSignatureEx function to perform the verification.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.


CryptVerifyCertificateSignatureEx

The CryptVerifyCertificateSignatureEx function verifies the signature of a subject certificate, CRL, certificate request, or keygen request using the issuer's public key. The function does not require access to a private key.

BOOL WINAPI CryptVerifyCertificateSignatureEx(
  HCRYPTPROV hCryptProv,
  DWORD dwCertEncodingType,
  DWORD dwSubjectType,
  void *pvSubject,
  DWORD dwIssuerType,
  void *pvIssuer,
  DWORD dwFlags,
  void *pvReserved
);

Parameters

hCryptProv
[in] Handle of the CSP used to verify the signature.

NULL is passed unless there is a strong reason for passing in a specific cryptographic provider. Passing in NULL causes the default RSA or DSS provider to be acquired.

dwCertEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

dwSubjectType
[in] Indicates the subject type. The following subject types are defined:
Subject type value | pvSubject type
CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB | PCRYPT_DATA_BLOB
CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT | PCCERT_CONTEXT
CRYPT_VERIFY_CERT_SIGN_SUBJECT_CRL | PCCRL_CONTEXT

pvSubject
[in] Buffer of the type indicated by dwSubjectType containing the signature to be verified.
dwIssuerType
[in] Indicates the issuer type. The following issuer types are defined:
Issuer type value | pvIssuer type
CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY | PCERT_PUBLIC_KEY_INFO
CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT | PCCERT_CONTEXT
CRYPT_VERIFY_CERT_SIGN_ISSUER_CHAIN | PCCERT_CHAIN_CONTEXT

pvIssuer
[in] Buffer containing a structure as indicated by the value of dwIssuerType. The buffer contains access to the public key needed to verify the signature.
dwFlags
[in] Reserved for future use.
pvReserved
[in] Reserved for future use.

Remarks

The subject buffer can contain an encoded BLOB or a context for a certificate or CRL. In the case of a certificate context, if the certificate's public key parameters are missing and if these parameters can be inherited from the certificate's issuer for example from the DSS public key parameter, the context's CERT_PUBKEY_ALG_PARA_PROP_ID property is updated with the issuer's public key algorithm parameters for a valid signature.

Return Values

The function returns TRUE for a valid signature. It returns FALSE if the signature could not be verified.

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Note Errors from the called functions CryptCreateHash, CryptImportKey, CryptVerifySignature, and CryptHashData might be propagated to this function.

This function has the following error codes.

Error Code | Description
ERROR_FILE_NOT_FOUND | Invalid certificate encoding type. Currently only X509_ASN_ENCODING is supported.
NTE_BAD_ALGID | The signature algorithm's object identifier (OID) does not map to a known or supported hash algorithm.
NTE_BAD_SIGNATURE | The signature was not verified.

GetLastError might return an ASN.1 encoding/decoding error (Windows 2000 or later) or an OSS encoding/decoding error (Windows 95, Windows 98 or Windows NT 4.0 or earlier). For information on these errors see ASN.1 encoding/decoding error Codes.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.


Data Conversion Functions

The following CryptoAPI functions are used to convert certificate structure members to different forms.

Function | Description
CertAlgIdToOID | Converts a CSP algorithm identifier to an ASN.1 Object Identifier string.
CertGetNameString | Acquires the subject or issuer name from a certificate and converts it to a NULL-terminated character string.
CertNameToStr | Converts a certificate name BLOB to a zero terminated string.
CertOIDToAlgId | Converts the ASN.1 Object Identifier string to the CSP algorithm identifier.
CertRDNValueToStr | Converts a Name Value to a NULL-terminated string.
CertStrToName | Converts a NULL-terminated X.500 string to an encoded certificate name
CryptBinaryToString | Converts a binary sequence into a formatted string.
CryptFormatObject | Formats an encoded data and returns a Unicode string.
CryptStringToBinary | Converts a formatted string to binary sequence.


CertAlgIdToOID

The CertAlgIdToOID function converts a CryptoAPI algorithm identifier (ALG_ID) to an ASN.1 object identifier (OID) string.

LPCSTR WINAPI CertAlgIdToOID(
  DWORD dwAlgId
);

Parameters

dwAlgId
[in[ Value to be converted to an object identifier (OID).

Return Values

Returns the NULL-terminated OID string or NULL if there no object identifier (OID) string corresponds to the algorithm identifier.

Examples

// EXAMPLE CODE USING CertAlgIdToOID() to
// convert the CALG_SHA algorithm identifier to an
// Object Identifier string.
+
//--------------------------------------------------------------------
//  Declare variables.

LPCSTR pszObjID;

if(pszObjID= CertAlgIdToOID(CALG_SHA))
{
   printf("The OID for CALG_SHA  is %s \n",pszObjID);
}
else
{
   printf("No object identifier string correlates to the ALG_ID. \n");
}

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Conversion Functions


CertGetNameString

The CertGetNameString function obtains the subject or issuer name from a certificate CERT_CONTEXT structure and converts it to a NULL-terminated character string.

DWORD WINAPI CertGetNameString(
  PCCERT_CONTEXT pCertContext,
  DWORD dwType,
  DWORD dwFlags,
  void *pvTypePara,
  LPTSTR pszNameString,
  DWORD cchNameString
);

Parameters

pCertContext
[in] Pointer to a CERT_CONTEXT certificate context that includes a subject and issuer name to be converted.
dwType
Type Code | Meaning
CERT_NAME_EMAIL_TYPE | If the certificate has a Subject Alternative Name extension or Issuer Alternative Name, uses the first rfc822Name choice. If no rfc822Name choice is found in the extension, uses the Subject Name field for the Email OID. If either rfc822Name or the Email OID is found, uses the string. Otherwise, returns an empty string (returned character count is 1). pvTypePara is not used and is set to NULL.
CERT_NAME_RDN_TYPE | Converts the Subject Name BLOB by calling CertNameToStr. pvTypePara points to a DWORD containing the dwStrType passed to CertNameToStr. If the Subject Name field is empty and the certificate has a Subject Alternative Name extension, uses the first directory Name choice from CertNameToStr.
CERT_NAME_ATTR_TYPE | pvTypePara points to an object identifier (OID) specifying the name attribute to be returned. For example, if pvTypePara is szOID_COMMON_NAME, uses the Subject Name member. If the Subject Name member is empty and the certificate has a Subject Alternative Name extension, uses the first directoryName choice.
CERT_NAME_SIMPLE_DISPLAY_TYPE Iterates through the following list of name attributes and uses the Subject Name or the Subject Alternative Name extension for the first occurrence of: szOID_COMMON_NAME, szOID_ORGANIZATIONAL_UNIT_NAME, szOID_ORGANIZATION_NAME, or szOID_RSA_emailAddr.

If one of these attributes is not found, uses the Subject Alternative Name extension for a rfc822Name choice. If there still no match, uses the first attribute.

pvTypePara is not used and is set to NULL.
CERT_NAME_FRIENDLY_DISPLAY_TYPE | Checks the certificate for a CERT_FRIENDLY_NAME_PROP_ID property. If the certificate has this property, it is returned. If the certificate does not have the property, the CERT_NAME_SIMPLE_DISPLAY_TYPE is returned.
CERT_NAME_DNS_TYPE If the certificate has a Subject Alternative Name extension for issuer, Issuer Alternative Name, search for first DNSName choice.

If the DNSName choice is not found in the extension, search the Subject Name field for the CN OID, "2.5.4.3".

If the DNSName or CN OID is found, return the string. Otherwise, return an empty string.
CERT_NAME_URL_TYPE | If the certificate has a Subject Alternative Name extension for issuer, Issuer Alternative Name, search for first URL choice. If the URL choice is found, return the string. Otherwise, return an empty string.
CERT_NAME_UPN_TYPE If the certificate has a Subject Alternative Name extension, search the OtherName choices looking for a pszObjId == szOID_NT_PRINCIPAL_NAME, ("1.3.6.1.4.1.311.20.2.3").

If the UPN OID is found, decode the BLOB as a X509_UNICODE_ANY_STRING and return the decoded string. Otherwise, return an empty string.

dwFlags
[in] Indicates the type of processing needed.
Flag value | Meaning
CERT_NAME_ISSUER_FLAG | Acquires the issuer's name. If not set, acquires the subject's name.
CERT_NAME_DISABLE_IE4_UTF8_FLAG | Skips the default initial attempt to decode the value as UTF8 and decodes as 8-bit characters.

pvTypePara
[in] Pointer to either a DWORD containing the dwStrType or an object identifier (OID) specifying the name attribute. The type pointed to is determined by the value of dwType.
pszNameString
[out] Pointer to an allocated buffer to receive the returned string. If pszNameString is not NULL and cchNameString is not zero, pszNameString is a NULL-terminated string.
cchNameString
[in] Size, in characters, allocated for the returned string. The size must include the terminating NULL character.

Return Values

Returns the number of characters converted, including the terminating zero character. If pszNameString is NULL or cchNameString is zero, returns the required size of the destination string (including the terminating NULL character). If the specified name type is not found, returns a NULL-terminated empty string with a returned character count of 1.

Examples

See Example C Program: Serializing Certificates and Adding Serialized Elements to Stores.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 4.0 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.
Unicode: Implemented as Unicode and ANSI versions on all platforms.

See Also

Data Conversion Functions


CertNameToStr

The CertNameToStr function converts the name in a CERT_NAME_BLOB to a NULL-terminated character string. The string representation follows distinguished name specifications in RFC 1779 except for the following deviations.

  • Embedded quotes are double-quoted
  • Empty strings are quoted
  • Strings containing consecutive spaces are not quoted
  • RDN values of type CERT_RDN_ENCODED_BLOB or CERT_RDN_OCTET_STRING are formatted in hexadecimal
DWORD WINAPI CertNameToStr(
  DWORD dwCertEncodingType,
  PCERT_NAME_BLOB pName,
  DWORD dwStrType,
  LPTSTR psz,
  DWORD csz
);

Parameters

dwCertEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pName
[in] Pointer to the CERT_NAME_BLOB to be converted.
dwStrType
[in] Specifies the desired returned string type. Possible types are shown in the following table.
String Type Code | Description
CERT_SIMPLE_NAME_STR | Object identifiers (OIDs) are discarded. CERT_RDN entries are separated by ", ". Multiple attributes in a CERT_RDN are separated by " + ". For example: Microsoft, Kim Abercrombie + Programmer.
CERT_OID_NAME_STR | OIDs are included with a "=" separator from their attribute value. CERT_RDN entries are separated by ", ". Multiple attributes in a CERT_RDN are separated by "+ ".
CERT_X500_NAME_STR OIDs are converted to their X.500 key names. Otherwise, same as CERT_OID_NAME_STR. If an OID does not have a corresponding X.500 name, the OID is used with an "OID." prefix.

Quotes the RDN value if it contains leading or trailing white space or one of the following characters: ",", "+", "=", """, "\n", "<", ">", "#" or ";". The quoting character is ". If the RDN Value contains a " it is double quoted ("").
CERT_NAME_STR_SEMICOLON_FLAG | This flag can be combined with a bitwise-OR operation into dwStrType to replace the ", " separator with a "; " separator.
CERT_NAME_STR_CRLF_FLAG | This flag can be combined with a bitwise-OR operation into dwStrType to replace the ", " separator with a "\r\n" separator.
CERT_NAME_STR_NO_PLUS_FLAG | This flag can be combined with a bitwise-OR operation into dwStrType to replace the " + " separator with a single space, " ".
CERT_NAME_STR_NO_QUOTING_FLAG | This flag can be combined with a bitwise-OR operation into dwStrType to inhibit the above quoting.
CERT_NAME_STR_REVERSE_FLAG | This flag can be combined with a bitwise-OR operation into dwStrType to specify that the order of the RDNs is to be reversed before converting to the string. This flag is to reverse the names as they occur in the RDN. To interoperate with LDAP and the RFC standards, the displayed X.500 name string is reversed by specifying this flag.
CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG | This flag can be combined with a bitwise-OR operation into dwStrType to select the encoded value type. If this flag is set, and if all the UNICODE characters are less than or equal to 0xFF, the CERT_RDN_T61_STRING encoded value type is used instead of the CERT_RDN_UNICODE_STRING.

psz
[out] Pointer to a buffer to receive the returned string.
csz
[in] Size, in characters, allocated for the returned string. The size must include the terminating NULL character.

Return Values

Returns the number of characters converted, including the terminating NULL character. If psz is NULL or csz is zero, returns the required size of the destination string.

Remarks

If psz is not NULL and csz is not zero, the returned psz is always a perhaps-empty NULL-terminated string.

Examples

See Example C Program: Certificate Store Operations and Example C Program: Converting Names from Certificates to ASN1 and Back.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.
Unicode: Implemented as Unicode and ANSI versions on all platforms.

See Also

Data Conversion Functions, CertStrToName, CertRDNValueToStr


CertOIDToAlgId

The CertOIDToAlgId function converts the ASN.1 object identifier (OID) string to the CryptoAPI algorithm identifier (ALG_ID).

DWORD WINAPI CertOIDToAlgId(
  LPCSTR pszObjId
);

Parameters

pszObjId
[in] Pointer to the ASN.1 object identifier (OID) to be converted to an algorithm identifier.

Return Values

Returns the ALG_ID corresponding to the object identifer (OID) or zero if no ALG_ID corresponds to the OID.

Examples

See Example C Program: Using CertOIDToAlgId and CertCompareIntegerBlob.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Data Conversion Functions


CertRDNValueToStr

The CertRDNValueToStr function converts a name in a CERT_RDN_VALUE_BLOB to a NULL-terminated character string.

DWORD WINAPI CertRDNValueToStr(
  DWORD dwValueType,
  PCERT_RDN_VALUE_BLOB pValue,
  LPTSTR psz,
  DWORD csz
);

Parameters

dwValueType
[in] Indicates the kind of RDN value to be converted. Can be one of the following:

CERT_RDN_ANY_TYPE
CERT_RDN_ENCODED_BLOB
CERT_RDN_OCTET_STRING
CERT_RDN_NUMERIC_STRING
CERT_RDN_PRINTABLE_STRING
CERT_RDN_TELETEX_STRING
CERT_RDN_T61_STRING
CERT_RDN_VIDEOTEX_STRING
CERT_RDN_IA5_STRING
CERT_RDN_GRAPHIC_STRING
CERT_RDN_VISIBLE_STRING
CERT_RDN_ISO646_STRING
CERT_RDN_GENERAL_STRING
CERT_RDN_UNIVERSAL_STRING
CERT_RDN_INT4_STRING
CERT_RDN_BMP_STRING
CERT_RDN_UNICODE_STRING
CERT_RDN_UTF8_STRING

pValue
[in] Pointer to an CERT_RDN_VALUE_BLOB of a type appropriate for the dwValueType.
psz
[out] Pointer to a buffer to receive the returned string.
csz
[in] Size, in characters, allocated for the returned string.

Return Values

Returns the number of characters converted, including the terminating NULL character. If psz is NULL or csz is zero, returns the required size of the destination string.

Remarks

If psz is not NULL and csz is not zero, the returned psz is always a possibly empty NULL-terminated string.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.
Unicode: Implemented as Unicode and ANSI versions on all platforms.

See Also

Data Conversion Functions, CertNameToStr


CertStrToName

The CertStrToName function converts a NULL-terminated X.500 string to an encoded certificate name. The input string is expected to be formatted the same as the output from CertNameToStr.

BOOL WINAPI CertStrToName(
  DWORD dwCertEncodingType,
  LPCTSTR pszX500,
  DWORD dwStrType,
  void *pvReserved,
  BYTE *pbEncoded,
  DWORD *pcbEncoded,
  LPCTSTR *ppszError
);

Parameters

dwCertEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pszX500
[in] Pointer to the NULL-terminated X500 string to be converted.
dwStrType
[in] Type of the input string. The possible types are as follows.
String type | Meaning
CERT_OID_NAME_STR Default. Input can contain a case-insensitive X.500 key (CN=), a case-insensitive "OID." prefixed object identifier (OID.1.2.3.4.5.6=) or an object identifier (OID).

If no flags are combined with a bitwise-OR operation into dwStrType, the input is allowed to contain "," or ";" as RDN separators and "+" as the multiple RDN value separator.

Quoting is supported. A quote can be included in a quoted value by double quoting, for example (CN="Joe ""Cool"""). A value starting with a "#" is treated as ASCII hex and converted to a CERT_RDN_OCTET_STRING. Embedded whitespace is skipped (1.2.3 = # AB CD 01 is the same as 1.2.3=#ABCD01).

Whitespace surrounding the keys, object identifiers and values is removed.
CERT_X500_NAME_STR | Same as CERT_OID_NAME_STR.
CERT_NAME_STR_COMMA_FLAG | This flag can be combined with a bitwise-OR operation into dwStrType to only allow the "," as the RDN separator.
CERT_NAME_STR_SEMICOLON_FLAG | This flag can be combined with a bitwise-OR operation into dwStrType to only allow the ";" as the RDN separator.
CERT_NAME_STR_CRLF_FLAG | This flag can be combined with a bitwise-OR operation into dwStrType to only allow "\r" or "\n" as the RDN separator.
CERT_NAME_STR_NO_PLUS_FLAG | This flag can be combined with a bitwise-OR operation into dwStrType to ignore "+" as a separator and not allow multiple values per RDN.
CERT_NAME_STR_NO_QUOTING_FLAG | This flag can be combined with a bitwise-OR operation into dwStrType to inhibit quoting.
CERT_NAME_STR_DISABLE_IE4_UTF8_FLAG | This flag can be combined with a bitwise-OR operation into dwStrType to skip the initial attempt to decode as UTF8.
CERT_SIMPLE_NAME_STR | Not supported.
CERT_NAME_STR_REVERSE_FLAG | This flag can be combined with a bitwise-OR operation into dwStrType to specify that the order of the RDNs is to be reversed after converting from the string and before encoding. See CertNameToStr for a demonstration of this flags usage.
CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG | Can be combined with other dwStrType values to select the CERT_RDN_T61_STRING encoded value type instead of CERT_RDN_UNICODE_STRING. Can be used if all the UNICODE characters are less than or equal to 0xFF
CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG | Can be combined with other dwStrType values to select the CERT_RDN_UTF8_STRING encoded value type instead of CERT_RDN_UNICODE_STRING.

The following X500 Keys are supported:
Key | Object identifier | RDN value type(s)
CN | szOID_COMMON_NAME | Printable, T61
L | szOID_LOCALITY_NAME | Printable, T61
O | szOID_ORGANIZATION_NAME | Printable, T61
OU | szOID_ORGANIZATIONAL_UNIT_NAME | Printable, T61
Email | szOID_RSA_emailAddr | Only IA5
C | szOID_COUNTRY_NAME | Only Printable
S | szOID_STATE_OR_PROVINCE_NAME | Printable, T61
ST | szOID_STATE_OR_PROVINCE_NAME | Printable, T61
STREET | szOID_STREET_ADDRESS | Printable, T61
T | szOID_TITLE | Printable, T61
Title | szOID_TITLE | Printable, T61
G | szOID_GIVEN_NAME | Printable, T61
GivenName | szOID_GIVEN_NAME | Printable, T61
I | szOID_INITIALS | Printable, T61
Initials | szOID_INITIALS | Printable, T61
SN | szOID_SUR_NAME | Printable, T61
DC | szOID_DOMAIN_COMPONENT | IA5, UTF8

If either Printable or T61 is allowed as the RDN Value Type for the key (CN=), Printable is selected if the name string components are restricted to the following character set:

A, B, …, Z
a, b, …, z
0, 1, …, 9
(space) ' ( ) +, - . / : = ?

pvReserved
[in] Reserved for future use and must be NULL.
pbEncoded
[out] Pointer to a buffer to receive the encoded structure.

This parameter can be NULL to set the size of the key usage for memory allocation purposes. See Retrieving Data of Unknown Length.

pcbEncoded
[in/out] Pointer to a DWORD to specify the size, in bytes, of the buffer pointed to by the pbEncoded parameter. When the function returns, the DWORD contains the number of bytes stored or to be stored in the buffer.
ppszError
[out/optional] Optional pointer to a pointer to receive an error indication about an invalid input string.

If the input string is invalid, ppszError is updated by this function to point to the beginning of the invalid character sequence. If no errors are detected in the input string, ppszError is set to NULL.

ppszError can be set to NULL by the application not interested in receiving a pointer to any invalid character sequence found.

ppszError is updated with a non-NULL pointer for the following errors:

CRYPT_E_INVALID_X500_STRING
CRYPT_E_INVALID_NUMERIC_STRING
CRYPT_E_INVALID_PRINTABLE_STRING
CRYPT_E_INVALID_IA5_STRING

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Remarks

The T61 types are UTF-8 encoded.

Examples

See Example C Program: Converting Names from Certificates to ASN1 and Back.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.
Unicode: Implemented as Unicode and ANSI versions on all platforms.

See Also

Data Conversion Functions, CertNameToStr


CryptBinaryToString

[This is preliminary documentation and subject to change.]

The CryptBinaryToString function converts a sequence of bytes into a formatted string.

BOOL WINAPI CryptBinaryToString(
  CONST BYTE *pbBinary,
  DWORD cbBinary,
  DWORD dwFlags,
  LPWSTR pszString,
  DWORD *pcchString
);

Parameters

pbBinary
[in] Pointer to the binary sequence to be converted into a string.
cbBinary
[in] Length of the binary sequence to be converted.
dwFlags
[in] Determines the format of the resulting formatted string. The following flags are used.
Flag | Format of result string
CRYPT_STRING_BASE64HEADER | Base64, with certificate beginning and ending headers
CRYPT_STRING_BASE64 | Base64, without headers
CRYPT_STRING_BINARY | Pure binary copy
CRYPT_STRING_BASE64REQUESTHEADER | Base64, with request beginning and ending headers
CRYPT_STRING_HEX | Hex-only
CRYPT_STRING_HEXASCII | Hex, with ASCII char display
CRYPT_STRING_BASE64X509CRLHEADER | Base64, with x509 CRL beginning and ending headers
CRYPT_STRING_HEXADDR | Hex, with address display
CRYPT_STRING_HEXASCIIADDR | Hex, with ASCII char and address display

pszString
[in] Pointer to a buffer to hold the converted string. Can be NULL to have the function calculate the number of bytes that must be allocated to hold the returned string. Upon return, *pcchString will hold the required number of bytes needed.
pcchString
[in, out] Pointer to a double word holding the length of the string to be returned. If the pszString parameter is set to NULL, the function calculates the length of the return string (including a NULL terminator at the end) in TCHARs and returns it in this parameter. If pszString is not NULL and big enough, the function converts the binary data into specified string format including NULL terminator, but pcchString returns the length in TCHARs not including the NULL terminator.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE).

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.
Unicode: Declared as Unicode and ANSI prototypes.

See Also

CryptStringToBinary


CryptFormatObject

The CryptFormatObject function formats the encoded data and returns a Unicode string in the allocated buffer according to the certificate encoding type.

BOOL WINAPI CryptFormatObject(
  DWORD dwCertEncodingType,     // in
  DWORD dwFormatType,           // in
  DWORD dwFormatStrType,        // in
  void *pFormatStruct,          // in
  LPCSTR lpszStructType,        // in
  const BYTE *pbEncoded,        // in
  DWORD cbEncoded,              // in
  void *pbFormat,               // out
  DWORD *pcbFormat              // in/out
);

Parameters

dwCertEncodingType
[in] Type of encoding used on the certificate. The currently defined certificate encoding type used is X509_ASN_ENCODING,
dwFormatType
[in] Format type values. Not used. Set to zero (0).
dwFormatStrType
[in] Structure format type values. This parameter can be zero, or you can specify one or more of the following flags by using the bitwise-OR operator to combine them.

Currently defined values are shown in the following table:
Format value | Description
0 | Display the data in single line. Each subfield is concatenated with a ", " (see Remarks).
CRYPT_FORMAT_ STR_MULTI_LINE | Display the data in multiple lines rather than the default of a single line display (see Remarks).
CRYPT_FORMAT_ STR_NO_HEX | Disables the hex dump (see Remarks).

pFormatStruct
[in] Pointer to the format of the structure. Not used. Set to NULL.
lpszStructType
[in] Pointer to an OID defining the encoded data. If the high-order word of the lpszStructType parameter is zero, the low-order word specifies the integer identifier for the type of the given structure. Otherwise, this parameter is a long pointer to a NULL-terminated string.

The following table is a listing of supported OIDs with the associated OID extension:
OID Name | OID
SPC_FINANCIAL_CRITERIA_OBJID | 1.3.6.1.4.1.311.2.1.27
SPC_SP_AGENCY_INFO_OBJID | 1.3.6.1.4.1.311.2.1.10
szOID_AUTHORITY_INFO_ACCESS | 1.3.6.1.5.5.7.1.1
szOID_AUTHORITY_KEY_IDENTIFIER2 | 2.5.29.35
szOID_BASIC_CONSTRAINTS2 | 2.5.29.19
szOID_CERT_POLICIES | 2.5.29.32
szOID_CRL_DIST_POINTS | 2.5.29.31
szOID_CRL_REASON_CODE | 2.5.29.21
szOID_ENHANCED_KEY_USAGE | 2.5.29.37
szOID_ISSUER_ALT_NAME2 | 2.5.29.18
szOID_KEY_ATTRIBUTES | 2.5.29.2
szOID_KEY_USAGE | 2.5.29.15
szOID_KEY_USAGE_RESTRICTION | 2.5.29.4
szOID_NEXT_UPDATE_LOCATION | 1.3.6.1.4.1.311.10.2
szOID_RSA_SMIMECapabilities | 1.2.840.113549.1.9.15
szOID_SUBJECT_ALT_NAME2 | 2.5.29.17
szOID_SUBJECT_KEY_IDENTIFIER | 2.5.29.14

pbEncoded
[in] Pointer to the encoded data to be formatted. If lpszStructType is one of the OIDs listed above, the pbEncoded is the encoded extension.
cbEncoded
[in] Size, in bytes, of the pbEncoded structure.
pbFormat
[out] Pointer to a buffer that receives the formatted string. When the buffer that is specified is not large enough to receive the decoded structure, the function sets ERROR_MORE_DATA and stores the required buffer size, in bytes, into the variable pointed to by pcbFormat. This parameter can be NULL to set the size of this information for memory allocation purposes. For more information, see Common In/Out Parameter Conventions.
pcbFormat
[in/out] Pointer to a variable that specifies the size, in bytes, of the buffer pointed to by the pbFormat parameter. When the function returns, the variable pointed to by the pcbFormat parameter contains the number of bytes stored in the buffer. This parameter can be NULL, only if pbFormat is NULL.

Note When processing the data returned in the buffer, applications need to use the actual size of the data returned. The actual size may be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to insure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is TRUE. If it does not succeed, the return value is FALSE. To retrieve extended error information, use the GetLastError function.

Remarks

The default behavior of this function is to return single line display of the encoded data, that is, each sub-field will be concatenated with a ", " on one line. If a user prefers to display the data in multiple line, set the CRYPT_FORMAT_STR_MULTI_LINE flag. Each sub-field will be displayed on a separate line.

If there is no formatting routine installed or registered for the lpszStructType, the hex dump of the encoded CRYPTOAPI_BLOB will be returned. A user can set the CRYPT_FORMAT_STR_NO_HEX flag to disable the hex dump.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.


CryptStringToBinary

[This is preliminary documentation and subject to change.]

The CryptStringToBinary function converts a formatted string into a sequence of bytes.

BOOL WINAPI CryptStringToBinary(
  LPCWSTR pszString,
  DWORD cchString,
  DWORD dwFlags,
  BYTE *pbBinary,
  DWORD *pcbBinary,
  DWORD *pdwSkip,
  DWORD *pdwFlags
);

Parameters

pszString
[in] Pointer to the formatted string to be converted.
cchString
[in] Number of characters of the formatted string to be converted. If pszString is NULL-terminated, cchString can be zero. The length of pszString is calculated including the NULL terminator.
dwFlags
[in] Indicates the format of the string to be converted. The following table gives details.
Flag | Format of the string to be converted
CRYPT_STRING_BASE64HEADER | Base64, with certificate beginning and ending headers
CRYPT_STRING_BASE64 | Base64, without headers
CRYPT_STRING_BINARY | Pure binary copy
CRYPT_STRING_BASE64REQUESTHEADER | Base64, with request beginning and ending headers
CRYPT_STRING_HEX | Hex only format
CRYPT_STRING_HEXASCII | Hex format with ASCII char display
CRYPT_STRING_BASE64X509CRLHEADER | Base64, with x509 CRL beginning and ending headers
CRYPT_STRING_HEXADDR | Hex, with address display
CRYPT_STRING_HEXASCIIADDR | Hex, with ASCII char and address display
CRYPT_STRING_BASE64_ANY Tries the following, in order:

CRYPT_STRING_BASE64HEADER
CRYPT_STRING_BASE64
CRYPT_STRING_ANY Tries the following, in order:

CRYPT_STRING_BASE64_ANY
CRYPT_STRING_BINARY
CRYPT_STRING_HEX_ANY Tries the following, in order:

CRYPT_STRING_HEXADDR
CRYPT_STRING_HEXASCIIADDR
CRYPT_STRING_HEXASCII
CRYPT_STRING_HEX

pbBinary
[in] Pointer to a buffer to hold the returned sequence of bytes. If it is set to NULL, the function calculates the length of the buffer needed for the return sequence and returns the size of required memory for the DWORD pointed to by pcbBinary.
pcbBinary
[in, out] Length of the returned binary sequence. If the value of *pcbBinary passed in is not big enough, the function fails with GetLastError returning ERROR_MORE_DATA.
pdwSkip
[out] Count of characters in any skipped strings up to the beginning of actual base64 or hex strings.
pdwFlags
[out] Actual format used in the conversion.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE).

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.
Unicode: Declared as Unicode and ANSI prototypes.

See Also

CryptBinaryToString


Enhanced Key Usage Functions

The following functions deal with the enhanced key usage (EKU) extension and the EKU extended property of certificates. The EKU extension and extended property specify and limit the valid uses of a certificate. The extensions are part of the certificate itself. They are set by the issuer of the certificate and are read-only. Certificate extended properties are values associated with a certificate that can be set in an application.

Function | Description
CertAddEnhancedKeyUsageIdentifier | Adds a usage identifier to a certificate's EKU property.
CertGetEnhancedKeyUsage | Acquires information on the EKU extension or property from a certificate.
CertRemoveEnhancedKeyUsageIdentifier | Removes the usage identifier OID from a certificate's EKU extended property.
CertSetEnhancedKeyUsage | Sets the EKU property for a certificate.


CertAddEnhancedKeyUsageIdentifier

The CertAddEnhancedKeyUsageIdentifier function adds a usage identifier OID to the certificate's EKU extended property.

BOOL WINAPI CertAddEnhancedKeyUsageIdentifier(
  PCCERT_CONTEXT pCertContext,
  LPCSTR pszUsageIdentifier
);

Parameters

pCertContext
[in] Pointer to the CERT_CONTEXT of the certificate for which the usage identifier is to be added.
pszUsageIdentifier
[in] Specifies the usage identifier OID to add.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Examples

See Example C Program: Getting and Setting Certificate Properties.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Enhanced Key Usage Functions


CertGetEnhancedKeyUsage

The CertGetEnhancedKeyUsage function returns information from the EKU extension or the EKU extended property of a certificate. EKUs indicate valid uses of the certificate.

BOOL WINAPI CertGetEnhancedKeyUsage(
  PCCERT_CONTEXT pCertContext,
  DWORD dwFlags,
  PCERT_ENHKEY_USAGE pUsage,
  DWORD *pcbUsage
);

Parameters

pCertContext
[in] Pointer to a CERT_CONTEXT certificate context.
dwFlags
[in] Indicates whether the function will report on a certificate's extensions, its extended properties, or both. If set to zero (0), the function returns the valid uses of a certificate based on both the certificate's EKU extension and its EKU extended property value.

To return only the EKU extension or EKU property value, the following flags can be set.
Flag value | Meaning
CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG | Get only the extension.
CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG | Get only the extended property value.

pUsage
[out] Pointer to receive a CERT_ENHKEY_USAGE structure (equivalent to a CTL_USAGE structure) indicating the valid uses of the certificate.

This parameter can be NULL to set the size of the key usage for memory allocation purposes. See Retrieving Data of Unknown Length.

pcbUsage
[in/out] Pointer to a DWORD that specifies the size, in bytes, of the structure pointed to by pUsage. When the function returns, the DWORD contains the size in bytes of the structure.

Return Values

Returns non-zero (TRUE) if the function succeeds and zero (FALSE) if the function fails.

On platforms before Windows 2000 and Windows Me, the function also returns zero (FALSE) if the EKU extension is not found. On these platforms, a GetLastError.return of zero (0) indicates that the certificate has no valid uses, and a return of CRYPT_E_NOT_FOUND indicates that the certificate is valid for all uses.

Remarks

If a certificate has an EKU extension, that extension lists object identifiers (OIDs) for valid uses of that certificate. In a Microsoft environment, a certificate might also have EKU extended properties specifying valid uses for the certificate.

  • If a certificate has neither an EKU extension nor EKU extended properties, it is assumed to be valid for all uses.
  • If it has either an EKU extension or EKU extended properties but not both, it is valid only for the uses indicated in the extension or extended properties that it has.
  • If a certificate has both an EKU extension and EKU extended properties, it is valid only for the uses that are on both lists.

If dwFlags is set to zero (0), the cUsageIdentifier member of the CERT_ENHKEY_USAGE structure is set to the number of valid uses of the certificate determined by the value of both the EKU extension and the EKU extended property value.

In Windows Me and Windows 2000 and later, if the cUsageIdentifier member is zero (0), the certificate might be valid for all uses or the certificate might have no valid uses. The return from a call to GetLastError can be used to determine whether the certificate is good for all uses or for none. If GetLastError returns CRYPT_E_NOT_FOUND, the certificate is good for all uses. If it returns zero (0), the certificate has no valid uses.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Enhanced Key Usage Functions, CertSetEnhancedKeyUsage


CertRemoveEnhancedKeyUsageIdentifier

The CertRemoveEnhancedKeyUsageIdentifier function removes a usage identifier OID from the certificate's EKU extended property.

BOOL WINAPI CertRemoveEnhancedKeyUsageIdentifier(
  PCCERT_CONTEXT pCertContext,
  LPCSTR pszUsageIdentifier
);

Parameters

pCertContext
[in] Pointer to a CERT_CONTEXT of the certificate for which the usage identifier OID is to be removed.
pszUsageIdentifier
[in] Pointer to the usage identifier OID to remove.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Enhanced Key Usage Functions


CertSetEnhancedKeyUsage

The CertSetEnhancedKeyUsage function sets the EKU property for the certificate. Use of this function replaces any EKUs associated with the certificate. To add a single EKU usage without changing existing usages, use CertAddEnhancedKeyUsageIdentifier. To delete as single EKU usage, use CertRemoveEnhancedKeyUsageIdentifier

BOOL WINAPI CertSetEnhancedKeyUsage(
  PCCERT_CONTEXT pCertContext,
  PCERT_ENHKEY_USAGE pUsage
);

Parameters

pCertContext
[in] Pointer to the CERT_CONTEXT of the specified certificate.
pUsage
[in] Pointer to a CERT_ENHKEY_USAGE structure (equivalent to a CTL_USAGE structure) that contains an array of enhanced key usage object identifiers (OIDs) to be set as extended properties of the certificate.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Enhanced Key Usage Functions, CertGetEnhancedKeyUsage


Key Identifier Functions

Key identifier functions allow the user to create, set, retrieve, or locate a key identifier or its properties.

A key identifier is the unique identifier of a public/private key pair. It can be any unique identifier but is usually the 20 byte SHA1 hash of an encoded CERT_PUBLIC_KEY_INFO structure. A key identifier can be obtained through the certificate's CERT_KEY_IDENTIFIER_PROP_ID. The key identifier allows the use of that key pair to encrypt or decrypt messages without using the certificate.

Key identifiers are not associated with CRLs or CTLs.

A key identifier can have the same properties as a certificate context. See CertCreateContext.

The following table lists key identifier functions.

Function | Description
CryptCreateKeyIdentifierFromCSP | Creates a key identifier from a CSP's public key BLOB.
CryptEnumKeyIdentifierProperties | Enumerates key identifiers and their properties.
CryptGetKeyIdentifierProperty | Acquires a specific property from a specified key identifier.
CryptSetKeyIdentifierProperty | Sets a property of a specified key identifier.


CryptCreateKeyIdentifierFromCSP

The CryptCreateKeyIdentifierFromCSP function creates a key identifier from a CSP public key CRYPTOAPI_BLOB.

This function converts a CSP's PUBLICKEYSTRUC into an X.509 CERT_PUBLIC_KEY_INFO structure and encodes it. The encoded structure is then hashed with the SHA1 algorithm to obtain the key identifier.

BOOL WINAPI CryptCreateKeyIdentifierFromCSP(
  DWORD dwCertEncodingType,
  LPCSTR pszPubKeyOID,
  const PUBLICKEYSTRUC *pPubKeyStruc,
  DWORD cbPubKeyStruc,
  DWORD dwFlags,
  void *pvReserved,
  BYTE *pbHash,
  DWORD *pcbHash
);

Parameters

dwCertEncodingType
[in] Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pszPubKeyOID
[in] Pointer to the Public Key object identifier (OID). A non-NULL value overrides the default OID obtained from the aiKeyAlg member of the structure pointed to by pPubKeyStruc. Set pszPubKeyOID to NULL to use the default OID.
pPubKeyStruc
[in] Pointer to a PUBLICKEYSTRUC structure. In the default case, the aiKeyAlg member of the structure pointed to by pPubKeyStruc is used to find the Public Key object identifier (OID). A non-NULL pszPubKeyOID overrides the default.
cbPubKeyStruc
[in] Size, in bytes, of the PUBLICKEYSTRUC.
dwFlags
[in] Reserved for future use and must be zero (0).
pvReserved
[in] Reserved for future use and must be NULL.
pbHash
[out] Pointer to a buffer to receive the hash of the public key and the key identifier.

This parameter can be NULL to get the size of this information for memory allocation purposes. See Retrieving Data of Unknown Length.

pcbHash
[in/out] Pointer to a DWORD specifying the size, in bytes, of the buffer pointed to by the pbHash parameter. When the function returns, the DWORD contains the number of bytes stored in the buffer. Currently using SHA1 hashing, the length of the required buffer is twenty.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Examples

See Example C Program: Working with Key Identifiers.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Key Identifier Functions, CryptEnumKeyIdentifierProperties, CryptGetKeyIdentifierProperty, CryptSetKeyIdentifierProperty


CryptEnumKeyIdentifierProperties

The CryptEnumKeyIdentifierProperties function enumerates key identifiers and their properties. This function is not called in a loop. Rather, it loops internally until the last key identifier property is enumerated or the callback function returns FALSE. The callback function is called if dwPropId is 0 or if the key identifier's properties match the dwPropId.

BOOL WINAPI CryptEnumKeyIdentifierProperties(
  const CRYPT_HASH_BLOB *pKeyIdentifier,
  DWORD dwPropId,
  DWORD dwFlags,
  LPCWSTR pwszComputerName,
  void *pvReserved,
  void *pvArg,
  PFN_CRYPT_ENUM_KEYID_PROP pfnEnum
);

Parameters

pKeyIdentifier
[in/optional] Pointer to a CRYPT_HASH_BLOB structure containing the key identifier.

If pKeyIdentifier is NULL, the function enumerates all key identifiers.

If pKeyIdentifier is not NULL the callback function pfnEnum is only called for the specified key identifier.

dwPropId
[in] Indicates the Property identifier to be listed.

If dwPropId is set to zero, this function calls the callback function with all the properties.

If dwPropId is not zero and pKeyIdentifier is NULL, the callback function, is called only for those key identifiers that have the specified property (sets cProp parameter of pfnEnum to one). All key identifiers that do not have the property are skipped.

Any certificate property identifier can be used.

dwFlags
[in] By default, the CurrentUser's list of key identifiers is searched. If CRYPT_KEYID_MACHINE_FLAG is set the list of key identifiers of the LocalMachine (if pwszComputerName is NULL) or of a remote computer (if pwszComputerName is not NULL) is searched. See pwszComputerName.
pwszComputerName
[in/optional] Pointer to a name of a remote computer to be searched. If CRYPT_KEYID_MACHINE_FLAG is set in dwFlags, searches the remote computer for a list of key identifiers. If the local computer is to be searched and not a remote computer, pwszComputerName is set to NULL.
pvReserved
[in] Reserved for future use and must be NULL.
pvArg
[in/optional] Pointer to data to be passed to the callback function. The type is a void that allows the application to declare, define, and initialize a structure or argument to hold any information.
pfnEnum
[in] Pointer to an application-defined callback function that is executed for each key identifier entry matching the input parameters. See Remarks for details about the callback functions parameters.

Return Values

The CryptEnumKeyIdentifierProperties repeatedly calls the pfnEnum callback function until the last key identifier is enumerated or the callback returns FALSE.

If the main function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Remarks

A key identifier can have the same properties as a certificate context.

The following signature applies to pfnEnum.

BOOL (WINAPI *PFN_CRYPT_ENUM_KEYID_PROP)(
  const CRYPT_HASH_BLOB *pKeyIdentifier,
  DWORD dwFlags,
  void *pvReserved,
  void *pvArg,
  DWORD cProp,
  DWORD *rgdwPropId,
  void **rgpvData,
  DWORD *rgcbData
);

Parameters

pKeyIdentifier
Pointer to a CRYPT_HASH_BLOB (see CRYPTOAPI_BLOB) containing the key identifier.
dwFlags
Reserved for future use and must be zero (0).
pvReserved
Reserved for future use and must be NULL.
pvArg
Pointer to an argument that is passed through from the callback function.
cProp
Count of elements in the array of rgdwPropId.
rgdwPropId
Pointer to an array of property identifiers. Each entry in the array will be one of the value types listed for in the table for dwPropId in the CryptSetKeyIdentifierProperty function.
rgpvData
Pointer to an array that contains pointers to pvData elements corresponding the rgdwPropId array elements.

For CERT_KEY_PROV_INFO_PROP_ID the rgpvData element points to a CRYPT_KEY_PROV_INFO structure. For all other properties, the rgpvData element points to an array of bytes.

rgcbData
Array of DWORDs that specify the size, in bytes, of corresponding elements in the rgpvData array.

Return Values

Returns TRUE to continue enumeration.

Returns FALSE and sets the last error code to stop enumeration.

Examples

See Example C Program: Working with Key Identifiers.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Key Identifier Functions, CryptGetKeyIdentifierProperty, CryptSetKeyIdentifierProperty


CryptGetKeyIdentifierProperty

The CryptGetKeyIdentifierProperty acquires a specific property from a specified key identifier.

BOOL WINAPI CryptGetKeyIdentifierProperty(
  const CRYPT_HASH_BLOB *pKeyIdentifier,
  DWORD dwPropId,
  DWORD dwFlags,
  LPCWSTR pwszComputerName,
  void *pvReserved,
  void *pvData,
  DWORD *pcbData
);

Parameters

pKeyIdentifier
[in] Pointer to the CRYPT_HASH_BLOB containing the key identifier.
dwPropId
[in] Identifies the property to retrieve. The value of dwPropId determines the type and content of the pvData parameter. Any certificate property ID can be used.
dwFlags
[in] The following flags can be used. They can be combined with a bitwise-OR operation.
Flag value | Meaning
CRYPT_KEYID_MACHINE_FLAG | Search the list of key identifiers of the LocalMachine (if pwszComputerName is NULL) or remote computer (if pwszComputerName is not NULL). See pwszComputerName.
CRYPT_KEYID_ALLOC_FLAG | LocalAlloc() is called to allocate memory for pvData. *pvData is updated with a pointer to the allocated memory. LocalFree() must be called to free the allocated memory.

pwszComputerName
[in] Pointer to a name of a remote computer to be searched. If CRYPT_KEYID_MACHINE_FLAG flag is set, searches the remote computer for a list of key identifiers. If the local computer is to be searched and not a remote computer, set pwszComputerName to NULL.
pvReserved
[in] Reserved for future use and must be NULL.
pvData
[out] Pointer to a buffer to receive the data as determined by dwPropId. Elements pointed to by fields in the pvData structure follow the structure. Therefore, the size contained in pcbData can exceed the size of the structure.

If dwPropId is CERT_KEY_PROV_INFO_PROP_ID, pvData points to a CRYPT_KEY_PROV_INFO structure containing the property of the key identifier.

If dwPropId is not CERT_KEY_PROV_INFO_PROP_ID, pvData points to an array of bytes containing the property of the key identifier.

When the CRYPT_KEYID_ALLOC_FLAG is not set, this parameter can be NULL to get the size of this information for memory allocation purposes. See Retrieving Data of Unknown Length.

When the CRYPT_KEYID_ALLOC_FLAG is set, pvData is the address of a pointer to the buffer that will be updated. Because memory is allocated and its pointer is stored at *pvData, pvData must be non-NULL.

pcbData
[in/out] Pointer to a DWORD that contains the size, in bytes, of the buffer pointed to by the pvData parameter. When the function returns, the DWORD contains the number of bytes stored in the buffer. The size contained in the variable pointed to by pcbData can indicate a size larger than the CRYPT_KEY_PROV_INFO structure as the structure can contain pointers to auxiliary data. This size is the sum of the size needed by the structure and all auxiliary data.

When the CRYPT_KEYID_ALLOC_FLAG is set, pcbData is the address of a pointer to the DWORD that will be updated.

Note

When processing the data returned in the buffer, applications need to use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Examples

See Example C Program: Working with Key Identifiers.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Key Identifier Functions, CryptEnumKeyIdentifierProperties, CryptSetKeyIdentifierProperty


CryptSetKeyIdentifierProperty

The CryptSetKeyIdentifierProperty function sets the property of a specified key identifier. This function can set the property on the computer identified in pwszComputerName.

BOOL WINAPI CryptSetKeyIdentifierProperty(
  const CRYPT_HASH_BLOB *pKeyIdentifier,
  DWORD dwPropId,
  DWORD dwFlags,
  LPCWSTR pwszComputerName,
  void *pvReserved,
  const void *pvData
);

Parameters

pKeyIdentifier
[in] Pointer to a CRYPT_HASH_BLOB containing the key identifier.
dwPropId
[in] Identifies the property to be set. The value of dwPropId determines the type and content of the pvData parameter. Any certificate property ID can be used. CERT_KEY_PROV_INFO_PROP_ID is the property of most interest.
dwFlags
[in] The following flags can be set. They can be combined with a bitwise-OR operation.
Flag value | Meaning
CRYPT_KEYID_MACHINE_FLAG | Sets the property of the LocalMachine (if pwszComputerName is NULL) or remote computer (if pwszComputerName is not NULL). See pwszComputerName.
CRYPT_KEYID_DELETE_FLAG | The key identifier and all of its properties are deleted.
CRYPT_KEYID_SET_NEW_FLAG | Sets a new key identifier property. If the property already exists, the attempt fails, and FALSE is returned with the last error code set to CRYPT_E_EXISTS.

pwszComputerName
[in] Pointer to a name of a remote computer that has the key identifier where the properties are set. If CRYPT_KEYID_MACHINE_FLAG flag is set, searches the remote computer for a list of key identifiers. If the local computer is to be set and not a remote computer, set pwszComputerName to NULL.
pvReserved
[in] Reserved for future use and must be NULL.
pvData
[out] If dwPropId is CERT_KEY_PROV_INFO_PROP_ID, pvData points to a CRYPT_KEY_PROV_INFO structure containing the property of the key identifier.

If dwPropId is not CERT_KEY_PROV_INFO_PROP_ID, pvData points to a CRYPT_DATA_BLOB structure containing the property of the key identifier.

Setting pvData to NULL deletes the property.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Note If CRYPT_KEYID_SET_NEW_FLAG is set and the property already exists, FALSE is returned with the last error code set to CRYPT_E_EXISTS.

Examples

See Example C Program: Working with Key Identifiers.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP4 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Key Identifier Functions, CryptEnumKeyIdentifierProperties, CryptGetKeyIdentifierProperty


Certificate Store Provider Callback Functions

The callback functions in this section are used to register or install application-defined certificate store providers and to provide related functionality through callback functions. Callback functions are written with an application and are called by CryptoAPI functions. Callback functions enable the application to control in part the way that CryptoAPI functions manipulate data.

The following callback functions can be written and used with certificate store provider CryptoAPI functions.

Callback function | Use
CertDllOpenStoreProv | Defines the store provider open function.
CertStoreProvCloseCallback | Determines what happens when an open store's reference count becomes zero.
CertStoreProvDeleteCertCallback | Determines actions to be taken before a certificate is deleted from a certificate store.
CertStoreProvDeleteCRLCallback | Determines actions to be taken before a CRL is deleted from a certificate store.
CertStoreProvReadCertCallback | Currently not used but might be exported to future CSPs.
CertStoreProvReadCRLCallback | Currently not used but might be exported to future CSPs.
CertStoreProvSetCertPropertyCallback | Determines actions to be taken before a call to CertSetCertificateContextProperty and CertGetCertificateContextProperty.
CertStoreProvSetCRLPropertyCallback | Determines actions to be taken before a call to CertSetCRLContextProperty and CertGetCRLContextProperty.
CertStoreProvWriteCertCallback | Determines actions to be taken before adding a certificate to a store.
CertStoreProvWriteCRLCallback | Determines actions to be taken before adding a CRL to a store.
CertStoreProvReadCTL | Read the provider's copy of the CTL context, and, if it exists, to create a new CTL context.
CertStoreProvWriteCTL | Determines whether or not a CTL can be added to the store.
CertStoreProvDeleteCTL | Determines whether or not a CTL can be deleted.
CertStoreProvSetCTLProperty | Determines whether or not a property can be set on a CTL
CertStoreProvControl | Allows an application to be notified when there is a difference between the contents of a cached store in use and the contents of that store as it is persisted to storage.
CertStoreProvFindCert | Finds the first or next certificate in a store that matches specified criteria.
CertStoreProvFreeFindCert | Frees a previously found certificate context.
CertStoreProvGetCertProperty | Retrieves a specified property of a certificate.
CertStoreProvFindCRL | Finds the first or next CRL in a store that matches specified criteria.
CertStoreProvFreeFindCRL | Frees a previously found CRL context.
CertStoreProvGetCRLProperty | Retrieves a specified property of a CRL.
CertStoreProvFindCTL | Finds the first or next CTL in a store that matches specified criteria.
CertStoreProvFreeFindCTL | Frees a previously found CTL context.
CertStoreProvGetCTLProperty | Retrieves a specified property of a CTL.


CertDllOpenStoreProv

The CertDllOpenStoreProv function is an object identifier (OID) registerable or installable store-provider function that is called by CertOpenStore. It defines the store provider open function.

BOOL WINAPI CertDllOpenStoreProv(
  LPCSTR lpszStoreProvider,
  DWORD dwEncodingType,
  HCRYPTPROV hCryptProv,
  DWORD dwFlags,
  const void *pvPara,
  HCERTSTORE hCertStore,
  OUT PCERT_STORE_PROV_INFO pStoreProvInfo
);

Note The first five parameters are those that were passed as parameters to CertOpenStore.

Parameters

lpszStoreProvider
[in] See CertOpenStore.
dwEncodingType
[in] See CertOpenStore.
hCryptProv
[in] See CertOpenStore.
dwFlags
[in] See CertOpenStore.
pvPara
[in] See CertOpenStore.
hCertStore
[in] Handle of the store in memory that has been opened and can be used to make calls to other store-related API calls, such as CertAddSerializedElementToStore.
pStoreProvInfo
[in] Pointer to the CERT_STORE_PROV_INFO to be updated. The data structure has been zeroed, and cbSize set before the call.

pStoreProvInfo->cStoreProvFunc is the count of callback functions that are implemented, and should be set last. Once set, all subsequent store calls, such as CertAddEncodedCertificateToStore will call the appropriate provider callback function.

Return Values

Returns TRUE if successful, FALSE if it was unable to open the store.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Provider Callback Functions


CertStoreProvCloseCallback

An application-defined callback function that is called by CertCloseStore when the store's reference count is decremented to zero.

void WINAPI CertStoreProvCloseCallback(
  HCERTSTOREPROV hStoreProv,
  DWORD dwFlags
);

Parameters

hStoreProv
[in] Provider-specific value returned in CERT_STORE_PROV_INFO by CertDllOpenStoreProv.
dwFlags
[in] Copy of the dwFlags passed as a parameter to CertCloseStore.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Provider Callback Functions


CertStoreProvDeleteCertCallback

An application-defined callback function that is called by CertDeleteCertificateFromStore before deleting a certificate from the store.

BOOL WINAPI CertStoreProvDeleteCertCallback(
  HCERTSTOREPROV hStoreProv,
  PCCERT_CONTEXT pCertContext,
  DWORD dwFlags
);

Parameters

hStoreProv
[in] Provider-specific value returned in CERT_STORE_PROV_INFO by CertDllOpenStoreProv.
pCertContext
[in] Pointer to the certificate context to be deleted.
dwFlags
[in] Reserved for future use and is set to zero.

Return Values

Returns TRUE if it is okay to delete the certificate from the store. Otherwise, returns FALSE.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Provider Callback Functions


CertStoreProvDeleteCRLCallback

An application-defined callback function that is called by CertDeleteCRLFromStore before deleting the CRL from the store.

BOOL WINAPI CertStoreProvDeleteCRLCallback(
  HCERTSTOREPROV hStoreProv,
  PCCRL_CONTEXT pCrlContext,
  DWORD dwFlags
);

Parameters

hStoreProv
[in] Provider-specific value returned in CERT_STORE_PROV_INFO by CertDllOpenStoreProv.
pCrlContext
[in] Pointer to the CRL context to be deleted.
dwFlags
[in] Reserved for future use and is set to zero.

Return Values

Returns TRUE if it is okay to delete from the store. Otherwise, returns FALSE.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Provider Callback Functions


CertStoreProvReadCertCallback

An application-defined callback function that reads the provider's copy of the certificate context. If one exists, a new certificate context is created. Currently not called directly by the certificate store functions. However, it might be exported to support other providers.

BOOL WINAPI CertStoreProvReadCertCallback(
  HCERTSTOREPROV hStoreProv,
  PCCERT_CONTEXT pStoreCertContext,
  DWORD dwFlags,
  PCCERT_CONTEXT *ppProvCertContext
);

Parameters

hStoreProv
[in] Provider-specific value returned in CERT_STORE_PROV_INFO by CertDllOpenStoreProv.
pStoreCertContext
[in] Pointer to the CERT_CONTEXT of the certificate to be read.
dwFlags
[in] Reserved for future use and is set to zero.
ppProvCertContext
[out] Pointer to a pointer to provider's copy of the certificate context. The context will be freed by calling CertFreeCertificateContext.

Return Values

Returns TRUE if the certificate was successfully read.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Provider Callback Functions


CertStoreProvReadCRLCallback

An application-defined callback function that reads the provider's copy of the CRL context. If one exists, a new CRL context is created.

Currently not called directly by the certificate store functions. However, might be exported to support other providers.

BOOL WINAPI CertStoreProvReadCRLCallback(
  HCERTSTOREPROV hStoreProv,
  PCCRL_CONTEXT pStoreCrlContext,
  DWORD dwFlags,
  PCCRL_CONTEXT *ppProvCrlContext
);

Parameters

hStoreProv
[in] Provider-specific value returned in CERT_STORE_PROV_INFO by CertDllOpenStoreProv.
pStoreCrlContext
[in] Pointer to the CRL_CONTEXT of the CRL to be read.
dwFlags
[in] Reserved for future use and is set to zero.
ppProvCrlContext
[out] Pointer to a pointer to provider's copy of the CRL context. The context will be freed by calling CertFreeCRLContext.

Return Values

Returns TRUE if the CRL was successfully read.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Provider Callback Functions


CertStoreProvSetCertPropertyCallback

An application-defined callback function that is called by CertSetCertificateContextProperty before setting the certificate's property. It is also called by CertGetCertificateContextProperty when getting a hash property that needs to be created and then persisted via the set.

Upon input, the property has not been set for the pCertContext parameter.

BOOL WINAPI CertStoreProvSetCertPropertyCallback(
  HCERTSTOREPROV hStoreProv,
  PCCERT_CONTEXT pCertContext,
  DWORD dwPropId,
  DWORD dwFlags,
  const void *pvData
);

Parameters

hStoreProv
[in] Provider-specific value returned in CERT_STORE_PROV_INFO by CertDllOpenStoreProv.
pCertContext
[in] See CertSetCertificateContextProperty.
dwPropId
[in] See CertSetCertificateContextProperty.
dwFlags
[in] Copy of the dwFlags passed as a parameter to CertSetCertificateContextProperty.
pvData
[in] See CertSetCertificateContextProperty.

Return Values

Returns TRUE if it is okay to set the property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Provider Callback Functions


CertStoreProvSetCRLPropertyCallback

An application-defined callback function that is called by CertSetCRLContextProperty before setting the CRL's property. It is also called by CertGetCRLContextProperty, when getting a hash property that needs to be created and then persisted via the set.

Upon input, the property has not been set for the pCrlContext parameter.

BOOL CertStoreProvSetCRLPropertyCallback(
  HCERTSTOREPROV hStoreProv,
  PCCRL_CONTEXT pCrlContext,
  DWORD dwPropId,
  DWORD dwFlags,
  const void *pvData
);

Parameters

hStoreProv
[in] Provider-specific value returned in CERT_STORE_PROV_INFO by CertDllOpenStoreProv.
pCrlContext
[in] See CertSetCRLContextProperty.
dwPropId
[in] See CertSetCRLContextProperty.
dwFlags
[in] Copy of the dwFlags passed as a parameter to CertSetCRLContextProperty.
pvData
[in] See CertSetCRLContextProperty.

Return Values

Returns TRUE if it is okay to set the property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Provider Callback Functions


CertStoreProvWriteCertCallback

An application-defined callback function that is called by CertAddEncodedCertificateToStore, CertAddCertificateContextToStore and CertAddSerializedElementToStore before adding to the store. In addition to the encoded certificate, the added pCertContext might also have properties.

BOOL WINAPI CertStoreProvWriteCertCallback(
  HCERTSTOREPROV hStoreProv,
  PCCERT_CONTEXT pCertContext,
  DWORD dwFlags
);

Parameters

hStoreProv
[in] Provider specific value returned in CERT_STORE_PROV_INFO by CertDllOpenStoreProv.
pCertContext
[in] See CertAddCertificateContextToStore.
dwFlags
[in] CERT_STORE_PROV_WRITE_ADD_FLAG is set when this function is called by the following functions that add a certificate to the store:

CertAddEncodedCertificateToStore

CertAddCertificateContextToStore

CertAddSerializedElementToStore

Return Values

Returns TRUE if it is okay to update the store.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Provider Callback Functions


CertStoreProvWriteCRLCallback

An application-defined callback function that is called by CertAddEncodedCRLToStore, CertAddCRLContextToStore and CertAddSerializedElementToStore before adding to the store. In addition to the encoded CRL, the added pCrlContext might also have properties.

BOOL WINAPI CertStoreProvWriteCRLCallback(
  HCERTSTOREPROV hStoreProv,
  PCCRL_CONTEXT pCrlContext,
  DWORD dwFlags
);

Parameters

hStoreProv
[in] Provider-specific value returned in CERT_STORE_PROV_INFO by CertDllOpenStoreProv.
pCrlContext
[in] See CertAddCRLContextToStore.
dwFlags
[in] CERT_STORE_PROV_WRITE_ADD_FLAG is used to specify when this function is called by the following functions that add a CRL to the store:

CertAddEncodedCRLToStore

CertAddCRLContextToStore

CertAddSerializedElementToStore

Return Values

Returns TRUE if it is okay to update the store.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

Certificate Store Provider Callback Functions


CertStoreProvReadCTL

The CertStoreProvReadCTL callback function is called to read the provider's copy of the CTL context and, if it exists, to create a new CTL context. Currently, this callback function is not called directly by the store APIs but it can be exported to support other providers based on it.

BOOL WINAPI CertStoreProvReadCTL(
  HCERTSTOREPROV hStoreProv,
  PCCTL_CONTEXT pStoreCtlContext,
  DWORD dwFlags,
  PCCTL_CONTEXT *ppProvCtlContext
);

Parameters

hStoreProv
[in] HCERTSTOREPROV handle to a certificate store.
pStoreCtlContext
[in] Pointer to a CTL_CONTEXT structure.
dwFlags
[in] Any needed flag values.
ppProvCtlContext
[out] Pointer to a pointer to a CTL_CONTEXT structure to be returned by the function.

Return Values

Returns TRUE if the function succeeds or FALSE if it fails.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wincrypt.h.


CertStoreProvWriteCTL

The CertStoreProvWriteCTL callback function can be called by CertAddEncodedCTLToStore, CertAddCTLContextToStore or CertAddSerializedElementToStore before a CTL is added to the store.

BOOL WINAPI CertStoreProvWriteCTL(
  HCERTSTOREPROV hStoreProv,
  PCCTL_CONTEXT pCtlContext,
  DWORD dwFlags
);

Parameters

hStoreProv
[in] HCERTSTOREPROV handle to a certificate store.
pCtlContext
[in] Pointer to a CTL_CONTEXT structure.
dwFlags
[in] Any needed flag values.

Return Values

Returns TRUE if elements can be added to the store.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wincrypt.h.


CertStoreProvDeleteCTL

The CertStoreProvDeleteCTL callback function is called by CertDeleteCTLFromStore before deleting a CTL from the store. This function determines whether or not a CTL can be deleted.

BOOL WINAPI CertStoreProvDeleteCTL(
  HCERTSTOREPROV hStoreProv,
  PCCTL_CONTEXT pCtlContext,
  DWORD dwFlags
);

Parameters

hStoreProv
[in] HCERTSTOREPROV handle to a certificate store.
pCtlContext
[in] Pointer to a CTL_CONTEXT structure.
dwFlags
[in] Any needed flag values.

Return Values

Returns TRUE if a CTL can be deleted from the store.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wincrypt.h.


CertStoreProvSetCTLProperty

The CertStoreProvSetCTLProperty callback function determines whether or not a property can be set on a CTL. It is called by CertSetCTLContextProperty before setting a CTL's property. It can also be called by CertGetCTLContextProperty, when getting a hash property that needs to be created and then persisted. This callback function does not set the CTL_CONTEXT's property.

BOOL WINAPI CertStoreProvSetCTLProperty(
  HCERTSTOREPROV hStoreProv,
  PCCTL_CONTEXT pCtlContext,
  DWORD dwPropId,
  DWORD dwFlags,
  const void *pvData
);

Parameters

hStoreProv
[in] HCERTSTOREPROV handle to a certificate store.
pCtlContext
[in] Pointer to a CTL_CONTEXT structure.
dwPropId,
[in] Identifier of the property to be set.
dwFlags
[in] Any needed flag values.
pvData
[in] Pointer to a buffer containing the property value to be set.

Return Values

Returns TRUE if the property can be set. Returns FALSE if the property cannot be set.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wincrypt.h.


CertStoreProvControl

The CertStoreProvControl callback function supports the CertControlStore API. All of the API's parameters are passed straight through to the callback. For details, see CertControlStore.

BOOL WINAPI CertStoreProvControl(
  HCERTSTOREPROV hStoreProv,
  DWORD dwFlags,
  DWORD dwCtrlType,
  void const *pvCtrlPara
);

Parameters

hStoreProv
[in] HCERTSTOREPROV handle to a certificate store passed from the call to CertContolStore.
dwFlags
[in] Passed from the call to CertContolStore.
dwCtrlType
[in].Control action to be taken. Passed from the call to CertContolStore.
pvCtrlPara
[in] Pointer to a buffer whose structure and content is determined by the values of dwFlags and dwCtrlType. Passed from the call to CertContolStore.

Return Values

Returns TRUE if the function succeeds or FALSE if it fails.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.


CertStoreProvFindCert

The CertStoreProvFindCert callback function enumerates or finds the first or next certificate in an external store that matches specified criteria.

BOOL WINAPI CertStoreProvFindCert(
  HCERTSTOREPROV hStoreProv,
  PCCERT_STORE_PROV_FIND_INFO pFindInfo,
  PCCERT_CONTEXT pPrevCertContext,
  DWORD dwFlags,
  void **ppvStoreProvFindInfo,
  PCCERT_CONTEXT *ppProvCertContext
);

Parameters

hStoreProv
[in] HCERTSTOREPROV handle to a certificate store.
pFindInfo
[in] Pointer to a CERT_STORE_PROV_FIND_INFO structure containing all the parameters passed to the CertFindCertificateInStore function.
pPrevCertContext
[in] Pointer to a CERT_CONTEXT of the certificate found. On first call to the function, this parameter should be set to NULL. On subsequent calls, it should be set to the pointer returned in the ppProvCertContext parameter on the last call. A non-NULL pointer passed in this parameter is freed by the callback function.
dwFlags
[in] Any needed flag values.
ppvStoreProvFindInfo
[in/out] Pointer to a pointer to a buffer to return the store provider information. Optionally, the callback can return a pointer to internal find information in this parameter. After the first call, this parameter is set to the pointer returned by the previous call to the function.
ppProvCertContext
[out] On a successful find, a pointer to the certificate found is returned in this parameter.

Return Values

Returns TRUE if the function succeeds or FALSE if it fails.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wincrypt.h.


CertStoreProvFreeFindCert

The CertStoreProvFreeFindCert callback function is called when the certificate returned by the CertStoreProvFindCert callback was not used, and thus released, in a subsequent call to CertStoreProvFindCert. Before the CLOSE callback is called, all certificates returned by the CertStoreProvFindCert callback must be released by the provider using CertStoreProvFindCert or CertStoreProvFreeFindCert.

BOOL WINAPI CertStoreProvFreeFindCert(
  HCERTSTOREPROV hStoreProv,
  PCCERT_CONTEXT pCertContext,
  void *pvStoreProvFindInfo,
  DWORD dwFlags
);

Parameters

hStoreProv
[in] HCERTSTOREPROV handle to a certificate store.
pCertContext
[in] Pointer to a CERT_CONTEXT.
pvStoreProvFindInfo
[in] Pointer to a buffer containing find information.
dwFlags
[in] Any needed flag values.

Return Values

Returns TRUE if the function succeeds or FALSE if it fails.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wincrypt.h.


CertStoreProvGetCertProperty

The CertStoreProvGetCertProperty callback function retrieves a specified property of a certificate.

BOOL WINAPI CertStoreProvGetCertProperty(
  HCERTSTOREPROV hStoreProv,
  PCCERT_CONTEXT pCertContext,
  DWORD dwPropId,
  DWORD dwFlags,
  void *pvData,
  DWORD *pcbData
);

Parameters

hStoreProv
[in] HCERTSTOREPROV handle to a certificate store.
pCertContext
[in] Pointer to a CERT_CONTEXT structure.
dwPropId
[in] Indicates a property identifier.
dwFlags
[in] Any needed flag values.
pvData
[out] Pointer to a buffer to contain the pointer to a CERT_CONTEXT structure to be returned by the function. May be set to NULL on a first call to the function to get the value of pcbData before allocating memory for the buffer.
pcbData
[in/out] Pointer to a DWORD indicating the length of the pvData buffer.

Return Values

Returns TRUE if the function succeeds or FALSE if it fails.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wincrypt.h.


CertStoreProvFindCRL

The CertStoreProvFindCRL callback function enumerates or finds the first or next CRL in an external store that matches specified criteria.

BOOL WINAPI CertStoreProvFindCRL(
  HCERTSTOREPROV hStoreProv,
  PCCERT_STORE_PROV_FIND_INFO pFindInfo,
  PCCRL_CONTEXT pPrevCrlContext,
  DWORD dwFlags,
  void **ppvStoreProvFindInfo,
  PCCRL_CONTEXT *ppProvCrlContext
);

Parameters

hStoreProv
[in] HCERTSTOREPROV handle to a certificate store.
pFindInfo
[in] Pointer to a CERT_STORE_PROV_FIND_INFO structure containing all the parameters passed to the CertFindCRLInStore. function.
pPrevCrlContext
[in] Pointer to a CRL_CONTEXT structure of the last CRL found. On first call to the function, this parameter should be set to NULL. On subsequent calls, it should be set to the pointer returned in the ppProvCRLContext parameter on the last call. A non-NULL pointer passed in this parameter is freed by the callback function.
dwFlags
[in] Any needed flag values.
ppvStoreProvFindInfo
[in/out] Pointer to a pointer to a buffer to return the store provider information. Optionally, the callback can return a pointer to internal find information in this parameter. After the first call, this parameter is set to the pointer returned by the previous call to the function.
ppProvCrlContext
[out] On a successful find, a pointer to the CRL found is returned in this parameter.

Return Values

Returns TRUE if the function succeeds or FALSE if it fails.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wincrypt.h.


CertStoreProvFreeFindCRL

The CertStoreProvFreeFindCRL callback function is called when the certificate returned by the CertStoreProvFindCRL callback was not used, and thus released, in a subsequent call to CertStoreProvFindCRL. Before the CLOSE callback is called, all certificates returned by the CertStoreProvFindCRL callback must be released by the provider using CertStoreProvFindCRL or CertStoreProvFreeFindCRL.

BOOL WINAPI CertStoreProvFreeFindCRL(
  HCERTSTOREPROV hStoreProv,
  PCCRL_CONTEXT pCrlContext,
  void *pvStoreProvFindInfo,
  DWORD dwFlags
);

Parameters

hStoreProv
[in] HCERTSTOREPROV handle to a certificate store.
pCrlContext
[in] Pointer to a CRL_CONTEXT.
pvStoreProvFindInfo
[in] Pointer to a buffer containing find information.
dwFlags
[in] Any needed flag values.

Return Values

Returns TRUE if the function succeeds or FALSE if it fails.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wincrypt.h.


CertStoreProvGetCRLProperty

The CertStoreProvGetCRLProperty callback function retrieves a specified property of a CRL.

BOOL WINAPI CertStoreProvGetCRLProperty(
  HCERTSTOREPROV hStoreProv,
  PCCRL_CONTEXT pCrlContext,
  DWORD dwPropId,
  DWORD dwFlags,
  void *pvData,
  OUT DWORD *pcbData
);

Parameters

hStoreProv
[in] HCERTSTOREPROV handle to a certificate store.
pCrlContext
[in] Pointer to a CRL_CONTEXT structure.
dwPropId
[in] Indicates a property identifier.
dwFlags
[in] Any needed flag values.
pvData
[out] Pointer to a buffer to contain the pointer to a CRL_CONTEXT structure to be returned by the function. May be set to NULL on a first call to the function to get the value of pcbData before allocating memory for the buffer.
pcbData
[in/out] Pointer to a DWORD indicating the length of the pvData buffer.

Return Values

Returns TRUE if the function succeeds or FALSE if it fails.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wincrypt.h.


CertStoreProvFindCTL

The CertStoreProvFindCTL callback function enumerates or finds the first or next CTL in an external store that matches specified criteria.

BOOL WINAPI CertStoreProvFindCTL(
  HCERTSTOREPROV hStoreProv,
  PCCERT_STORE_PROV_FIND_INFO pFindInfo,
  PCCTL_CONTEXT pPrevCtlContext,
  DWORD dwFlags,
  void **ppvStoreProvFindInfo,
  PCCTL_CONTEXT *ppProvCtlContext
);

Parameters

hStoreProv
[in] HCERTSTOREPROV handle to a certificate store.
pFindInfo
[in] Pointer to a CERT_STORE_PROV_FIND_INFO structure containing all the parameters passed to the CertFindCTLInStore. function.
pPrevCtlContext
[in] Pointer to a CTL_CONTEXT structure of the last CTL found. On first call to the function, this parameter should be set to NULL. On subsequent calls, it should be set to the pointer returned in the ppProvCTLContext parameter on the last call. A non-NULL pointer passed in this parameter is freed by the callback function.
dwFlags
[in] Any needed flag values.
ppvStoreProvFindInfo
[in/out] Pointer to a pointer to buffer to return the store provider information. Optionally, the callback can return a pointer to internal find information in this parameter. After the first call, this parameter is set to the pointer returned by the previous call to the function.
ppProvCtlContext
[out] On a successful find, a pointer to the CTL found is returned in this parameter.

Return Values

Returns TRUE if the function succeeds or FALSE if it fails.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wincrypt.h.


CertStoreProvFreeFindCTL

The CertStoreProvFreeFindCTL callback function is called when the certificate returned by the CertStoreProvFindCTL callback was not used, and thus released, in a subsequent call to CertStoreProvFindCTL. Before the CLOSE callback is called, all certificates returned by the CertStoreProvFindCTL callback must be released by the provider using CertStoreProvFindCTL or CertStoreProvFreeFindCTL.

BOOL WINAPI (
  HCERTSTOREPROV hStoreProv,
  PCCTL_CONTEXT pCtlContext,
  void *pvStoreProvFindInfo,
  DWORD dwFlags
);

Parameters

hStoreProv
[in] HCERTSTOREPROV handle to a certificate store.
pCtlContext
[in] Pointer to a CTL_CONTEXT structure.
pvStoreProvFindInfo
[in] Pointer to a buffer containing find information.
dwFlags
[in] Any needed flag values.

Return Values

Returns TRUE if the function succeeds or FALSE if it fails.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wincrypt.h.


CertStoreProvGetCTLProperty

The CertStoreProvGetCTLProperty callback function retrieves a specified property of a CTL.

BOOL WINAPI CertStoreProvGetCTLProperty(
  HCERTSTOREPROV hStoreProv,
  PCCTL_CONTEXT pCtlContext,
  DWORD dwPropId,
  DWORD dwFlags,
  void *pvData,
  DWORD *pcbData
);

Parameters

hStoreProv
[in] HCERTSTOREPROV handle to a certificate store.
pCtlContext
[in] Pointer to a CTL_CONTEXT structure.
dwPropId
[in] Indicates a property identifier.
dwFlags
[in] Any needed flag values.
pvData
[out] Pointer to buffer to contain the a pointer to a CTL_CONTEXT structure to be returned by the function. May be set to NULL on a first call to the function to get the value of pcbData before allocating memory for the buffer.
pcbData
[in/out] Pointer to a DWORD indicating the length of the pvData buffer.

Return Values

Returns TRUE if the function succeeds or FALSE if it fails.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wincrypt.h.


OID Support Functions

These Win32 functions provide object identifier (OID) support. These functions install, register, and dispatch to OID and encoding type-specific functions.

The following API functions use these OID support functions:

  • CryptEncodeObject
  • CryptEncodeObjectEx
  • CryptDecodeObject
  • CryptDecodeObjectEx
  • CertVerifyRevocation
  • CertOpenStore

For an overview of this process, see Extending CryptoAPI Functionality

The following functions work with OIDs.

Function | Description
CryptEnumOIDFunction | Enumerates the registered OID functions identified by their encoding type, function name, and OID.
CryptEnumOIDInfo | Enumerates the registered OID information identified by their group and calls pfnEnumOIDInfo for matches.
CryptFindOIDInfo | Uses the specified key and group to find OID information.
CryptFreeOIDFunctionAddress | Releases the handle count that was incremented and returned by CryptGetOIDFunctionAddress or CryptGetDefaultOIDFunctionAddress.
CryptGetDefaultOIDDllList | Acquires the list of registered default DLL entries for the specified function set and encoding type.
CryptGetDefaultOIDFunctionAddress | Either acquires the first or next installed default function or loads the DLL containing the default function.
CryptGetOIDFunctionAddress | Searches the list of installed functions for an encoding type and OID match. If a match is not found there, the registry is searched for a match.
CryptGetOIDFunctionValue | Acquires the value for the specified encoding type, function name, OID, and value name.
CryptInitOIDFunctionSet | Initializes and returns a handle of the OID function set identified by the function name supplied.
CryptInstallOIDFunctionAddress | Installs a set of callable OID function addresses.
CryptRegisterDefaultOIDFunction | Registers the DLL containing the default function to be called for the specified encoding type and function name.
CryptRegisterOIDFunction | Registers the DLL containing the function to be called for the specified encoding type, function name, and OID.
CryptRegisterOIDInfo | Registers the OID information specified in the CRYPT_OID_INFO structure, persisting it to the registry.
CryptSetOIDFunctionValue | Sets the value for the specified encoding type, function name, OID, and value name.
CryptUnregisterDefaultOIDFunction | Removes the registration for the DLL containing the default function to be called for the specified encoding type and function name.
CryptUnregisterOIDFunction | Removes the registration for the DLL containing the function to be called for the specified encoding type, function name, and OID.
CryptUnregisterOIDInfo | Removes the registration for the specified OID information.


CryptEnumOIDFunction

The CryptEnumOIDFunction function enumerates the registered object identifier (OID) functions. OID functions enumerated can be screened to include those identified by their encoding type, function name, OID, or any combination of encoding type, function name, and OID. For each OID function matching the selection criteria, an application provided callback function, pfnEnumOIDFunc, is called.

BOOL WINAPI CryptEnumOIDFunction(
  DWORD dwEncodingType,
  LPCSTR pszFuncName,
  LPCSTR pszOID,
  DWORD dwFlags,
  void *pvArg,
  PFN_CRYPT_ENUM_OID_FUNC pfnEnumOIDFunc
);

Parameters

dwEncodingType
[in] Specifies the encoding type to match. Setting this parameter to CRYPT_MATCH_ANY_ENCODING_TYPE matches any encoding type. Note that if CRYPT_MATCH_ANY_ENCODING_TYPE is not specified, either a certificate or message encoding type is required. If the low-order word containing the certificate encoding type is non-zero, it is used. Otherwise, the high-order word containing the message encoding type is used. If both are specified, the certificate encoding type in the low-order word is used.

Currently defined encoding types are:

CRYPT_ASN_ENCODING
X509_ASN_ENCODING
PKCS_7_ASN_ENCODING
CRYPT_MATCH_ANY_ENCODING_TYPE

pszFuncName
[in] Name of a function for which a case insensitive match search is performed. Setting this parameter to NULL results in a match being found for any function name.
pszOID
[in] If the high-order word of pszOID is non-zero, pszOID specifies the object identifier for which a case insensitive match search is performed. If the high-order word of pszOID is zero, pszOID is used to match a numeric object identifier. Setting this parameter to NULL matches any object identifier. Setting this parameter to CRYPT_DEFAULT_OID restricts the enumeration to only the default functions.
dwFlags
[in] Reserved for future use and must be zero (0).
pvArg
[in] Pointer to arguments to be passed through to the callback function.
pfnEnumOIDFunc
[in] Pointer to the callback function that is executed for each OID function matching the input parameters. See the Remarks section for details.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Remarks

The pfnEnumOIDFunc is a pointer to a callback function with the following signature and parameters:

BOOL (WINAPI *PFN_CRYPT_ENUM_OID_FUNC)(
  DWORD dwEncodingType,
  LPCSTR pszFuncName,
  LPCSTR pszOID,
  DWORD cValue,
  const DWORD rgdwValueType[ ],
  LPCWSTR const rgpwszValueName[ ],
  const BYTE *const rgpbValueData[ ],
  const DWORD rgcbValueData[ ],
  void *pvArg
);

Parameters

dwEncodingType
[in] Specifies the encoding type to match. Setting this parameter to CRYPT_MATCH_ANY_ENCODING_TYPE matches any encoding type. Note that if CRYPT_MATCH_ANY_ENCODING_TYPE is not specified, either a certificate or message encoding type is required. If the low-order word containing the certificate encoding type is non-zero, it is used. Otherwise, the high-order word containing the message encoding type is used. If both are specified, the certificate encoding type in the low-order word is used.

Currently defined encoding types are:

CRYPT_ASN_ENCODING
X509_ASN_ENCODING
PKCS_7_ASN_ENCODING
CRYPT_MATCH_ANY_ENCODING_TYPE

pszFuncName
[in] Name of the OID function.
pszOID
[in] Pointer to either an OID string, such as "2.5.29.1", an ASCII string, such as "file", or a numeric string, such as #2000.
cValue
[in] Count of elements in the array of value types.
rgdwValueType
[in] Array of value types. Each entry in the array will be one of the value types listed for CryptGetOIDFunctionValue under pdwValueType.
rgpwszValueName
[in] Array of NULL-terminated strings containing the name of the value.
rgpbValueData
[in] Array containing the values corresponding to the names in the rgpwszValueName array elements.
rgcbValueData
[in] Array that specifies the size, in bytes, of the corresponding elements in the rgpbValueData array.
pvArg
[in] Pointer to arguments passed through to the callback function.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

OID Support Functions


CryptEnumOIDInfo

[This is preliminary documentation and subject to change.]

The CryptEnumOIDInfo function enumerates predefined and registered OID CRYPT_OID_INFO structures. This function enumerates either all of the predefined and registered structures or only structures identified by a selected OID group. For each OID information structure enumerated, an application provided callback function, pfnEnumOIDInfo, is called.

BOOL WINAPI CryptEnumOIDInfo(
  DWORD dwGroupId,
  DWORD dwFlags,
  void *pvArg,
  PFN_CRYPT_ENUM_OID_INFO pfnEnumOIDInfo
);

Parameters

dwGroupId
[in] Indicates which OID groups to be matched. Setting dwGroupId to zero matches all groups. If dwGroupId is greater than zero, only the OID entries in the specified group are enumerated.

Currently defined OID group IDs are:

None
CRYPT_HASH_ALG_OID_GROUP_ID
CRYPT_ENCRYPT_ALG_OID_GROUP_ID
CRYPT_PUBKEY_ALG_OID_GROUP_ID
CRYPT_SIGN_ALG_OID_GROUP_ID
CRYPT_RDN_ATTR_OID_GROUP_ID
CRYPT_EXT_OR_ATTR_OID_GROUP_ID
CRYPT_ENHKEY_USAGE_OID_GROUP_ID
CRYPT_POLICY_OID_GROUP_ID
CRYPT_TEMPLATE_OID_GROUP_ID

Note The CRYPT_TEMPLATE_OID_GROUP_ID value for dwGroupId can be used only with Windows Whistler and later.

dwFlags
[in] Reserved for future use and must be zero (0).
pvArg
[in] Pointer to arguments to be passed through to the callback function.
pfnEnumOIDInfo
[in] Pointer to the callback function that is executed for each object identifier (OID) information entry enumerated. See the Remarks section for details on the callback typedef.

Return Values

The function returns FALSE when the function has stopped the enumeration.

Remarks

The following is the signature for pfnEnumOIDInfo. The callback function is typically used to print out the contents of each object identifier (OID) entry enumerated.

BOOL (WINAPI *PFN_CRYPT_ENUM_OID_INFO)(
  PCCRYPT_OID_INFO pInfo,
  void *pvArg
);

Parameters

pInfo
[in] Pointer to the OID information.
pvArg
[in] Pointer to arguments passed through to the callback function.

Examples

See Example C Program: Using CertOIDToAlgId and CertCompareIntegerBlob.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

OID Support Functions


CryptFindOIDInfo

[This is preliminary documentation and subject to change.]

The CryptFindOIDInfo function retrieves the first predefined or registered CRYPT_OID_INFO structure matching a specified key type and key. The search can be limited to OIDs within a specified OID group.

Use CryptEnumOIDInfo to list all or selected subsets of CRYPT_OID_INFO structures. New CRYPT_OID_INFO structures can be registered using CryptRegisterOIDInfo. User-registered OIDs can be removed from the list of registered OIDs with CryptUnregisterOIDInfo.

New OIDs can be placed in the list of registered OIDs either before or after the predefined entries. Because CryptFindOIDInfo returns the first key on the list that matches the search criteria, a newly-registered OID placed before a predefined OID entry with the same key overrides a predefined entry.

PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(
  DWORD dwKeyType,
  void *pvKey,
  DWORD dwGroupId
);

Parameters

dwKeyType
[in] Specifies the key type to use when finding OID information.

Currently defined key types are shown in the following table.
Key type | Type of pvKey
CRYPT_OID_INFO_OID_KEY | pvKey points to a szOID
CRYPT_OID_INFO_NAME_KEY | pvKey points to a pwszName
CRYPT_OID_INFO_ALGID_KEY | pvKey points to an ALG_ID
CRYPT_OID_INFO_SIGN_KEY pvKey points to an array of two ALG_IDs where:

ALG_ID[0] is the Hash AlgId

ALG_ID[1] is the PubKey AlgId

pvKey
[in] Depends on the dwKeyType. See the table under dwkeytype for details.
dwGroupId
[in] Specifies the group identifier to use when finding OID information. Setting dwGroupId to zero searches all groups according to the dwKeyType. Otherwise, only the dwGroupId indicated is searched. Some dwGroupId values are valid only for Windows Whistler and later.

For information on code that lists the OID information by group identifier, see CryptEnumOIDInfo.

Return Values

Returns a pointer to a constant structure of CRYPT_OID_INFO type. The returned pointer must not be freed. NULL is returned when the specified key and group is not found.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

OID Support Functions, ALG_ID, CRYPT_ALGORITHM_IDENTIFIER, CRYPT_OID_INFO, CryptRegisterOIDInfo, CryptUnregisterOIDInfo


CryptFreeOIDFunctionAddress

The CryptFreeOIDFunctionAddress function releases a handle returned by CryptGetOIDFunctionAddress or CryptGetDefaultOIDFunctionAddress by decrementing the reference count on the function handle. In some cases, the DLL file associated with the function is unloaded. See the Remarks section for details.

BOOL WINAPI CryptFreeOIDFunctionAddress(
  HCRYPTOIDFUNCADDR hFuncAddr,
  DWORD dwFlags
);

Parameters

hFuncAddr
[in] Handle of the function previously obtained from a call to CryptGetOIDFunctionAddress or CryptGetDefaultOIDFunctionAddress
dwFlags
[in] Reserved for future use and must be zero (0).

Remarks

If the reference count becomes zero and a DLL is loaded for the function being freed, the DLL might be unloaded. If the DLL exports the DLLCanUnloadNow function, that function is called and its return is checked. An S_FALSE return from this function cancels the unloading of the DLL at this time. If the function returns S_TRUE or if the DLL does not export the DLLCanUnloadNow function, an unloading process is started. In this case, actual unloading is deferred for 15 seconds. If another CryptGetOIDFunctionAddress or CryptGetDefaultOIDFunctionAddress that requires the DLL occurs before the 15 seconds elapse, the deferred unload process is canceled.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE).

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

OID Support Functions


CryptGetDefaultOIDDllList

The CryptGetDefaultOIDDllList function acquires the list of the names of DLL files that contain registered default OID functions for a specified function set and encoding type.

BOOL WINAPI CryptGetDefaultOIDDllList(
  HCRYPTOIDFUNCSET hFuncSet,
  DWORD dwEncodingType,
  LPWSTR pwszDllList,
  DWORD *pcchDllList
);

Parameters

hFuncSet
[in] Function set handle previously obtained by a call to CryptInitOIDFunctionSet.
dwEncodingType
[in] Specifies the encoding type to be matched. Currently, only X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are being used; however, additional encoding types may be added in the future. To match both current encoding types, use:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Note Either a certificate or message encoding type is required. X509_ASN_ENCODING is the default. If that type is indicated, it is used. Otherwise, if the PKCS7_ASN_ENCODING type is indicated, it is used.

pwszDllList
[out] Pointer to a buffer to receive the returned list, that consists of either zero or more NULL-terminated file names. The returned list is terminated with a NULL entry. For example, a list of two names could be:

L"first.dll\0" L"second.dll\0" L"\0"

This parameter can be NULL to acquire the number of wide characters the buffer must hold. See Retrieving Data of Unknown Length.

pcchDllList
[in/out] Pointer to a DWORD that specifies the size, in wide characters, of the returned list pointed to by pwszDllList parameter. When the function returns, the variable pointed to by the pcchDllList parameter contains the number of bytes stored in the buffer.

Note When processing the data returned in the buffer, applications need to use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

This function has the following error codes.

Error Code | Description
ERROR_MORE_DATA | If the buffer specified by the pwszDllList parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcchDllList.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

OID Support Functions


CryptGetDefaultOIDFunctionAddress

The CryptGetDefaultOIDFunctionAddress function loads the DLL containing a default function address. It can also be used to return the address of first or next installed default OID function in an initialized function set and load the DLL containing that function address.

BOOL WINAPI CryptGetDefaultOIDFunctionAddress(
  HCRYPTOIDFUNCSET hFuncSet,
  DWORD dwEncodingType,
  LPCWSTR pwszDll,
  DWORD dwFlags,
  void **ppvFuncAddr,
  HCRYPTOIDFUNCADDR *phFuncAddr
);

Parameters

hFuncSet
[in] Function set handle previously obtained from a call to CryptInitOIDFunctionSet.
dwEncodingType
[in] Encoding type to be matched. Currently, only X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are being used; however, additional encoding types may be added in the future. To match both current encoding types, use:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
pwszDll
[in/optional] Name of the DLL to load. Normally, the DLL name is obtained from the list returned by CryptGetDefaultOIDDllList. If pwszDll is NULL, a search is performed on the list of installed default functions.
dwFlags
[in] Reserved for future use and must be zero (0).
ppvFuncAddr
[out] Pointer to the return function's address. If the function fails, a NULL is returned in ppvFuncAddr.
phFuncAddr
[in/out] Used only if pwszDll is NULL. On the first call to the function, *phFuncAddr must be NULL to acquire the first installed function.

When this function is successful, *phFuncAddr is set to a function handle. The function's handle reference count is incremented.

After the first call to the function, phFuncAddr is set to the pointer returned by the previous call. This input pointer is always freed within the function through a call to CryptFreeOIDFunctionAddress by this function. The call to free the pointer is always made even the main function returns an error.

A non NULL phFuncAddr must be released either through a call to CryptFreeOIDFunctionAddress or by being passed back as input to this function or as input to CryptGetOIDFunctionAddress.

If pwszDll is not NULL, the value of this parameter is ignored and a non NULL pointer is not freed.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE).

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

OID Support Functions


CryptGetOIDFunctionAddress

The CryptGetOIDFunctionAddress function searches the list of registered and installed functions for an encoding type and OID match. If a match is found, the DLL containing the function is, if necessary, loaded. If a match is found, a pointer to the function address and a pointer to the function handle are also returned. The reference count on the function handle is incremented.

BOOL WINAPI CryptGetOIDFunctionAddress(
  HCRYPTOIDFUNCSET hFuncSet,
  DWORD dwEncodingType,
  LPCSTR pszOID,
  DWORD dwFlags,
  void **ppvFuncAddr,
  HCRYPTOIDFUNCADDR *phFuncAddr
);

Parameters

hFuncSet
[in] Function set handle previously obtained from a call to CryptInitOIDFunctionSet.
dwEncodingType
[in] Specifies the encoding type to be matched. Currently, only X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are being used; however, additional encoding types can be added in the future. To match both current encoding types, use:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
pszOID
[in] If the high-order word of the object identifier (OID) is non-zero, pszOID is a pointer to either an OID string such as "2.5.29.1" or an ASCII string such as "file". If the high-order word of the OID is zero, the low-order word specifies the numeric identifier to be used as the object identifier. This resulting OID maps to the function that was either installed or registered with the same OID.
dwFlags
[in] The following flag is defined.
Flag | Description
CRYPT_GET_INSTALLED_OID_FUNC_FLAG | Searches only the installed list of functions.

ppvFuncAddr
[out] Pointer to a pointer to a function address. If a match is found, ppvFuncAddr points to the function address.
phFuncAddr
[out] If a match is found, phFuncAddr points to the function handle. The handle's reference count is incremented. CryptFreeOIDFunctionAddress must be called to release the handle.

Note By default, both the registered and installed function lists are searched. Set CRYPT_GET_INSTALLED_OID_FUNC_FLAG to search only the installed list of functions. This flag would be set by a registered function to get the address of a pre-installed function it was replacing. For example, the registered function might handle a new special case and call the pre-installed function to handle the remaining cases.

Return Values

If the function succeeds and a match is found, the return value is non-zero (TRUE).

If no match is found, the function fails and the return value is zero (FALSE). For extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

OID Support Functions


CryptGetOIDFunctionValue

The CryptGetOIDFunctionValue function queries a value associated with an OID. The query is made for a specific named value associated with an OID, function name, and encoding type. The function can return the type of queried value, the value, itself, or both.

BOOL WINAPI CryptGetOIDFunctionValue(
  DWORD dwEncodingType,
  LPCSTR pszFuncName,
  LPCSTR pszOID,
  LPCWSTR pwszValueName,
  DWORD *pdwValueType,
  BYTE *pbValueData,
  DWORD *pcbValueData
);

Parameters

dwEncodingType
[in] Specifies the encoding type to be matched. Currently, only X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are being used; however, additional encoding types may be added in the future. To match both current encoding types, use:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
pszFuncName
[in] Name of the OID function set.
pszOID
[in] If the high-order word of the OID is non-zero, pszOID is a pointer to either an OID string such as "2.5.29.1" or an ASCII string such as "file." If the high-order word of the OID is zero, the low-order word specifies the numeric identifier to be used as the object identifier.
pwszValueName
[in] Pointer to a NULL-terminated UNICODE string containing the name of the value to be queried.
pdwValueType
[out] Pointer to a variable to receive the value's type. The type returned through this parameter will be one of the following.
Value | Meaning
REG_DWORD | A 32-bit number.
REG_EXPAND_SZ | A NULL-terminated UNICODE string that contains unexpanded references to environment variables such as "%PATH%"
REG_MULTI_SZ | An array of NULL-terminated UNICODE strings, terminated by two NULL characters.
REG_SZ | A NULL-terminated UNICODE string.

The pdwValueType parameter can be NULL if a returned type is not required.

pbValueData
[out] Pointer to a buffer to receive the value associated with the pwszValueName parameter. The buffer must be big enough to contain the terminating NULL character. This parameter can be NULL if returned data is not required.

This parameter can also be NULL to find the size of the buffer for memory allocation purposes. See Retrieving Data of Unknown Length.

pcbValueData
[in/out] Pointer to a DWORD that specifies the size, in bytes of the buffer pointed to by the pbValueData.

In all cases the value returned in *pcbValueData includes the size of the terminating NULL character in the string.

Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

This function has the following error code.

Error Code | Description
ERROR_MORE_DATA | If the buffer specified by the pbValueData parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcbValueData.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

OID Support Functions


CryptInitOIDFunctionSet

The CryptInitOIDFunctionSet initializes and returns the handle of the OID function set identified by a supplied function set name. If the set already exists, the handle of the existing set is returned. If the set does not exist, it is created. This allows different DLLs to install OID functions for the same function set name.

HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(
  LPCSTR pszFuncName,
  DWORD dwFlags
);

Parameters

pszFuncName
[in] Name of the OID function set.
dwFlags
[in] Reserved for future use and must be zero (0).

Return Values

Returns the handle of the OID function set identified by the function set name supplied.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

OID Support Functions


CryptInstallOIDFunctionAddress

The CryptInstallOIDFunctionAddress function installs a set of callable OID function addresses.

BOOL WINAPI CryptInstallOIDFunctionAddress(
  HMODULE hModule,
  DWORD dwEncodingType,
  LPCSTR pszFuncName,
  DWORD cFuncEntry,
  CRYPT_OID_FUNC_ENTRY rgFuncEntry[ ],
  DWORD dwFlags
);

Parameters

hModule
[in] This parameter is updated with the hModule passed to DllMain to prevent the DLL containing the function addresses from being unloaded by CryptGetOIDFunctionAddress/CryptFreeOIDFunctionAddress. This would be the case when the DLL has also registered OID functions through CryptRegisterOIDFunction.
dwEncodingType
[in] Specifies the encoding type to be matched. Currently, only X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are being used; however, additional encoding types may be added in the future. To match both current encoding types, use:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
pszFuncName
[in] Name of the function set being installed.
cFuncEntry
[in] Number of array elements in rgFuncEntry[].
rgFuncEntry[ ]
[in] Array of CRYPT_OID_FUNC_ENTRY each containing an OID and the starting address of its correlated routine.

Default functions are installed by setting the pszOID member of the CRYPT_OID_FUNC_ENTRY structure for their array element to CRYPT_DEFAULT_OID.

dwFlags
[in] By default, a new function set is installed at the end of the list of function sets. Setting CRYPT_INSTALL_OID_FUNC_BEFORE_FLAG installs function set at the beginning of the list.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE).

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

OID Support Functions, CRYPT_OID_FUNC_ENTRY


CryptRegisterDefaultOIDFunction

The CryptRegisterDefaultOIDFunction registers a DLL containing the default function to be called for the specified encoding type and function name. Unlike CryptRegisterOIDFunction, the function name to be exported by the DLL cannot be overridden.

BOOL WINAPI CryptRegisterDefaultOIDFunction(
  DWORD dwEncodingType,
  LPCSTR pszFuncName,
  DWORD dwIndex,
  LPCWSTR pwszDll
);

Parameters

dwEncodingType
[in] Specifies the encoding type to be matched. Currently, only X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are being used; however, additional encoding types may be added in the future. To match both current encoding types, use:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
pszFuncName
[in] Name of the function being registered.
dwIndex
[in] Index location for the insertion of the DLL in the list of DLLs. If dwIndex is zero, the DLL is inserted at the beginning of the list. If it is CRYPT_REGISTER_LAST_INDEX, the DLL is appended at the end of the list.
pwszDll
[in] Optional environment-variable string to be expanded using ExpandEnvironmentStrings before loading the DLL.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE).

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

OID Support Functions


CryptRegisterOIDFunction

The CryptRegisterOIDFunction registers a DLL containing the function to be called for the specified encoding type, function name, and OID.

By default, new function names are installed at the end of the list. To register new function before the installed functions, call CryptSetOIDFunctionValue with dwValueType set to REG_DWORD and pwszValueName set to CRYPT_OID_REG_FLAGS_VALUE_NAME.

In addition to registering a DLL, the name of the function to be called can be overridden. For example, pszFuncName can be set to CryptDllEncodeObject, and pszOverrideFuncName to MyEncodeXyz. The new form of CryptDLLEncodeObject can then be referred to using the name MyEncodeXyz. This allows a DLL to export multiple OID functions for the same function name without needing to interpose its own OID dispatcher function.

CRYPT_OID_REG_FLAGS_VALUE_NAME is defined as L"CryptFlags".

BOOL WINAPI CryptRegisterOIDFunction(
  DWORD dwEncodingType,
  LPCSTR pszFuncName,
  LPCSTR pszOID,
  LPCWSTR pwszDll,
  LPCSTR pszOverrideFuncName
);

Parameters

dwEncodingType
[in] Specifies the encoding type to be matched. Currently, only X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are being used; however, additional encoding types may be added in the future. To match both current encoding types, use:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
pszFuncName
[in] Name of the function being registered.
pszOID
Object identifier (OID) of the function to be registered. If the high-order word of the OID is non-zero, pszOID is a pointer to either an OID string such as "2.5.29.1" or an ASCII string such as "file." If the high-order word of the OID is zero, the low-order word specifies the numeric identifier to be used as the object identifier.
pwszDll
[in] Name of the DLL file to be registered. It can contain environment-variable strings to be expanded using ExpandEnvironmentStrings before loading the DLL.
pszOverrideFuncName
[in] String specifying a name for the function exported in the DLL. If pszOverrideFuncName is NULL, the function name specified by pszFuncName is used.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE).

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

OID Support Functions, CryptSetOIDFunctionValue


CryptRegisterOIDInfo

The CryptRegisterOIDInfo function registers the OID information specified in the CRYPT_OID_INFO structure, persisting it to the registry.

Crypt32.dll contains predefined information for the commonly known OIDs. This function allows applications to augment the predefined OID information. During CryptFindOIDInfo's first call, the registered OID information is installed.

When expanding the tables using CryptRegisterOIDInfo, the new entries can be placed either before or after predefined entries, controlled by dwFlags. The placement of registered OID information affects the result of CryptFindOIDInfo because the tables are searched in order. First registered entries placed before the predefined entries are checked, then the predefined entries are checked, and finally, registered entries placed after the predefined entries are checked. The first match found is returned. A newly-registered entry placed before the predefined entries can override one of the predefined entries.

BOOL WINAPI CryptRegisterOIDInfo(
  PCCRYPT_OID_INFO pInfo,
  DWORD dwFlags
);

Parameters

pInfo
[in] Pointer to a CRYPT_OID_INFO structure with the OID information to register. Specify the group that the OID information is to be registered for by setting the dwGroupId member of the structure.
dwFlags
[in] By default, the registered OID information is installed after Crypt32.dll's OID entries. If CRYPT_INSTALL_OID_INFO_BEFORE_FLAG is set, new OID information is install before Crypt32.dll's entries.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE).

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

OID Support Functions, ALG_ID, CRYPT_ALGORITHM_IDENTIFIER, CRYPT_OID_INFO, CryptFindOIDInfo, CryptEnumOIDInfo, CryptUnregisterOIDInfo


CryptSetOIDFunctionValue

The CryptSetOIDFunctionValue function sets a value for the specified encoding type, function name, OID, and value name.

BOOL WINAPI CryptSetOIDFunctionValue(
  DWORD dwEncodingType,
  LPCSTR pszFuncName,
  LPCSTR pszOID,
  LPCWSTR pwszValueName,
  DWORD dwValueType,
  const BYTE *pbValueData,
  DWORD cbValueData
);

Parameters

dwEncodingType
[in] Specifies the encoding type to be matched. Currently, only X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are being used; however, additional encoding types may be added in the future. To match both current encoding types, use:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
pszFuncName
[in] Name of the function for which the encoding type, OID, and value name is being updated.
pszOID
[in] If the high-order word of the object identifier (OID) is non-zero, pszOID is a pointer to either an OID string such as "2.5.29.1" or an ASCII string such as "file". If the high-order word of the OID is zero, the low-order word specifies the integer identifier to be used as the object identifier.
pwszValueName
[in] Pointer to a UNICODE string containing the name of the value to set. If a value with this name is not already present, the function creates it.
dwValueType
[in] Specifies the type of information to be stored as the value's data. This parameter can be one of the following values.
Value | Meaning
REG_DWORD | A 32-bit number.
REG_EXPAND_SZ | A NULL-terminated UNICODE string that contains unexpanded references to environment variables (for example, "%PATH%").
REG_MULTI_SZ | An array of NULL-terminated UNICODE strings, terminated by two NULL characters.
REG_SZ | A NULL-terminated UNICODE string.

pbValueData
[in] Points to a buffer containing the data to be stored for the specified value name.
cbValueData
[in] Specifies the size, in bytes, of the information pointed to by the pbValueData parameter. If the data is of type REG_SZ, REG_EXPAND_SZ, or REG_MULTI_SZ, the size must include the terminating NULL wide character.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE).

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

OID Support Functions


CryptUnregisterDefaultOIDFunction

The CryptUnregisterDefaultOIDFunction removes the registration of a DLL containing the default function to be called for the specified encoding type and function name.

BOOL WINAPI CryptUnregisterDefaultOIDFunction(
  DWORD dwEncodingType,
  LPCSTR pszFuncName,
  LPCWSTR pwszDll
);

Parameters

dwEncodingType
[in] Specifies the encoding type to be matched. Currently, only X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are being used; however, additional encoding types may be added in the future. To match both current encoding types, use:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
pszFuncName
[in] Name of the function being unregistered.
pwszDll
[in] Name of the DLL where the function is located.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE).

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

OID Support Functions


CryptUnregisterOIDFunction

The CryptUnregisterOIDFunction removes the registration of a DLL containing the function to be called for the specified encoding type, function name, and OID.

BOOL WINAPI CryptUnregisterOIDFunction(
  DWORD dwEncodingType,
  LPCSTR pszFuncName,
  LPCSTR pszOID
);

Parameters

dwEncodingType
[in] Specifies the encoding type to be matched. Currently, only X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are being used; however, additional encoding types may be added in the future. To match both current encoding types, use:
    X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
pszFuncName
[in] Name of the function being unregistered.
pszOID
[in] Pointer to the object identifier (OID) corresponding to the name of the function being unregistered. If the high-order word of the OID is non-zero, pszOID is a pointer to either an OID string such as "2.5.29.1" or an ASCII string such as "file." If the high-order word of the OID is zero, the low-order word specifies the integer identifier to be used as the object identifier.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE).

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

OID Support Functions


CryptUnregisterOIDInfo

The CryptUnregisterOIDInfo function removes the registration of a specified CRYPT_OID_INFO OID information structure. The structure to be unregistered is identified by the structure's pszOID and dwGroupId members.

BOOL WINAPI CryptUnregisterOIDInfo(
  PCCRYPT_OID_INFO pInfo
);

Parameters

pInfo
[in] Specifies the object identifier (OID) information for which the registration is to be removed. The group that the registration is removed for is specified by the dwGroupId member in the pInfo.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE).

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.
Library: Use Crypt32.lib.

See Also

OID Support Functions, ALG_ID, CRYPT_ALGORITHM_IDENTIFIER, CRYPT_OID_INFO, CryptFindOIDInfo, CryptRegisterOIDInfo


Remote Object Retrieval Functions

These functions allow the user to retrieve a Public Key Infrastructure (PKI) object, acquire the URL of a certificate, CTL, or CRL, or to extract a URL from an object.

The following functions are included in this category.

Function | Description
CryptGetObjectUrl | Acquires the URL of the remote object from a certificate, CTL, or CRL.
CryptRetrieveObjectByUrl | Retrieves the PKI object from a location specified by a URL.


CryptGetObjectUrl

[This is preliminary documentation and subject to change.]

The CryptGetObjectUrl function acquires the URL of the remote object from a certificate, CTL, or CRL.

The function takes the object, decodes it, and provides a pointer to an array of URLs from the object. For example; from a certificate, a CRL distribution list of URLs would be in the array.

BOOL WINAPI CryptGetObjectUrl(
  LPCSTR pszUrlOid,
  LPVOID pvPara,
  DWORD dwFlags,
  PCRYPT_URL_ARRAY pUrlArray,
  DWORD *pcbUrlArray,
  PCRYPT_URL_INFO pUrlInfo,
  DWORD *pcbUrlInfo,
  LPVOID pvReserved
);

Parameters

pszUrlOid
[in] Pointer to an object identifier (OID) identifying the URL being requested. If the HIWORD of the pszUrlOid parameter is zero, the LOWORD specifies the integer identifier for the type of the specified structure.

The following table lists currently supported OIDs.
OID | Meaning | pvPara contents
URL_OID_CERTIFICATE_ISSUER | Provides the URL of the certificate issuer retrieved from the authority information access extension or property of a certificate. | Pointer to a CERT_CONTEXT whose issuer's URL is being requested.
URL_OID_CERTIFICATE_CRL_DIST_POINT | Provides a list URLs of the CRL distribution points retrieved from the CRL distribution point extension or property of a certificate. | Pointer to a CERT_CONTEXT whose CRL distribution point is requested.
URL_OID_CTL_ISSUER | Provides the URL of the CTL issuer retrieved from an authority information access attribute method encoded in each signer information in the PKCS #7 (CTL). | Pointer to a Signer Index CTL_CONTEXT whose issuer's URL, identified by the signer index, is requested.
URL_OID_CTL_NEXT_UPDATE | Provides the URL of the next update of that CTL retrieved from an authority information access CTL extension, property, or signer information attribute method. | Pointer to a Signer Index CTL_CONTEXT whose next update URL is requested, and an optional signer index, in case it is needed to check the signer information attributes.
URL_OID_CRL_ISSUER | Provides the URL of the CRL issuer retrieved from a property on a CRL that was inherited from the subject certificate (either from the subject certificate issuer or the subject certificate distribution point extension). It is encoded as an authority information access extension method. | Pointer to a CRL_CONTEXT whose issuer's URL is requested.
URL_OID_CERTIFICATE_FRESHEST_CRL | Retrieves the freshest CRL extension or property of the certificate. | PCCERT_CONTEXT of a certificate whose freshest CRL distribution point is being requested.
URL_OID_CRL_FRESHEST_CRL | Retrieves the freshest CRL extension or property of the CRL. | PCCERT_CRL_CONTEXT_PAIR, of a certificate's base CRL whose freshest CRL distribution point is being requested.
URL_OID_CROSS_CERT_DIST_POINT | Retrieves the cross certificate distribution point extension or property of the certificate. | PCCERT_CONTEXT of a certificate whose cross certificate distribution point is being requested.

pvPara
[in] Structure determined by the value of pszUrlOid. See the table for details.
dwFlags
[in] Used to get the URL locator for an object.
Flag value | Description
CRYPT_GET_URL_FROM_PROPERTY | Locates the URL from the object's property (the location of the data).
CRYPT_GET_URL_FROM_EXTENSION | Locates the URL from the object's extension.
CRYPT_GET_URL_FROM_UNAUTH_ATTRIBUTE | Locates the URL from an unauthenticated attribute from the signer information data.
CRYPT_GET_URL_FROM_AUTH_ATTRIBUTE | Locates the URL from an authenticated attribute from the signer information data.

pUrlArray
[out] Pointer to a buffer to receive the data for the value entry. This parameter can be NULL to find the length of the buffer required to hold the data.

See Retrieving Data of Unknown Length.

pcbUrlArray
[in/out] Pointer to a DWORD specifying the size, in bytes, of the buffer pointed to by the pUrlArray parameter. When the function returns, the DWORD contains the number of bytes stored in the buffer. This parameter can be NULL only if pUrlArray is NULL.
pUrlInfo
[out] Pointer to a buffer that receives the data for the value entry.
pcbUrlInfo
[in/out] Pointer to a DWORD specifying the size, in bytes, of the buffer pointed to by the pUrlInfo parameter. When the function returns, the DWORD contains the number of bytes stored in the buffer.

Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

pvReserved
Reserved for future use and must be NULL.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.

Remarks

CryptGetObjectUrl has the same signature as UrlDllGetObjectUrl. The developer can implement a UrlDllGetObjectUrl with the signature of CryptGetObjectUrl and install it for the object identifier (OID).

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Cryptnet.lib.

See Also

Remote Object Retrieval Functions


CryptRetrieveObjectByUrl

[This is preliminary documentation and subject to change.]

The CryptRetrieveObjectByUrl function retrieves the PKI object from a location specified by a URL.

These remote objects are in encoded format and are retrieved in a "context" form.

BOOL WINAPI CryptRetrieveObjectByUrl(
  LPCTSTR pszUrl,
  LPCSTR pszObjectOid,
  DWORD dwRetrievalFlags,
  DWORD dwTimeout,
  LPVOID *ppvObject,
  HCRYPTASYNC hAsyncRetrieve,
  PCRYPT_CREDENTIALS pCredentials,
  LPVOID pvVerify,
  PCRYPT_RETRIEVE_AUX_INFO pAuxInfo
);

Parameters

pszUrl
[in] Address of a PKI object to be retrieved. The following schemes are supported:
  • ldap
  • http
  • ftp
  • file
pszObjectOid
[in] Pointer to the object identifier (OID) of the object to be retrieved. Valid OIDs are as shown in the following table.
OID value | Description | Returned ppvObject type
NULL | BLOB | Encoded bits are returned in a single buffer with a count, array of pointers, and data that must be freed with CryptMemFree.
CONTEXT_OID_CERTIFICATE | certificate | PCERT_CONTEXT for single object retrieval. HCERTSTORE, that contains the certificates, for multiple object retrieval.
CONTEXT_OID_CRL | CRL | PCRL_CONTEXT for single object retrieval. HCERTSTORE, that contains the CRLs, for multiple object retrieval.
CONTEXT_OID_CTL | CTL | PCTL_CONTEXT for single object retrieval. HCERTSTORE, that contains the CTLs, for multiple object retrieval.
CONTEXT_OID_PKCS7 | PKCS7 | HCERTSTORE containing the object from the message.
CONTEXT_OID_CAPI2_ANY | Function will determine appropriate item | HCERTSTORE containing the object.

dwRetrievalFlags
[in] Determines whether to utilize the cached URL or a URL retrieved from the wire URL. The form in which objects are returned is determined by the pszObjectOid.
Flag value | Description
CRYPT_RETRIEVE_MULTIPLE_OBJECTS | Retrieves multiple objects if available. All objects must be of a homogeneous object type as determined by the pszObjectOid, unless the OID Value is CONTEXT_OID_CAPI2_ANY.
CRYPT_CACHE_ONLY_RETRIEVAL | Retrieves the encoded bits from the URL cache only. Do not use the wire to retrieve the URL.
CRYPT_WIRE_ONLY_RETRIEVAL | Retrieves the encoded bits from the wire only. Does not use the URL cache.
CRYPT_DONT_CACHE_RESULT | Does not store the retrieved encoded bits to the URL cache. If this flag is not set, the retrieved URL is cached.
CRYPT_ASYNC_RETRIEVAL | Reserved. Set to NULL.
CRYPT_VERIFY_CONTEXT_SIGNATURE | Acquires signature verification on the context created. In this case pszObjectOid must be non-NULL and pvVerify points to the signer certificate context.
CRYPT_STICKY_CACHE_RETRIEVAL | Tags the URL as exempt from being flushed from the cache. See STICKY_CACHE_ENTRY in INTERNET_CACHE_ENTRY_INFO.
CRYPT_LDAP_SCOPE_BASE_ONLY_RETRIEVAL | Fails if the LDAP search scope is not set to base in the URL. Use with LDAP only.
CRYPT_OFFLINE_CHECK_RETRIEVAL | Keeps track of off-line failures and delays before hitting the wire on subsequent retrievals For wire retrieval only.
CRYPT_LDAP_INSERT_ENTRY_ATTRIBUTE Inserts the following two NULL-terminated ASCII strings at the beginning of each returned BLOB:

"%d\0%s\0", dwEntryIndex, pszAttribute.

The first, dwEntryIndex, is 0, pszObjectOid must be NULL, so that a PCRYPT_BLOB_ARRAY is returned.

dwTimeout
[in] Specifies the maximum number of milliseconds to wait for retrieval. If a value of zero is specified, this function does not time-out. This parameter is not used if the URL scheme is file.
ppvObject
[out] Pointer to a pointer to the returned object. The return type can be one of the supported type shown in pszObjectOid.
hAsyncRetrieve
[in] Reserved. Set to NULL.
pCredentials
[in/optional] Pointer to the Credentials structure used to access the URL. The only type of credentials currently supported are username and password credentials. pCredentials is used only when the object is retrieved from the wire. This parameter is not used for cache-only retrieval or if the URL scheme is file.
pvVerify
[in/optional] Pointer to a verification object. This object is a function of the dwRetrievalFlags. It can be NULL to indicate the caller is not interested in getting the certificate context or index of the signer if dwRetrievalFlags is CRYPT_VERIFY_CONTEXT_SIGNATURE.
pAuxInfo
[in] If not NULL, this parameter returns the time of the last successful wire retrieval.

Return Values

If the function succeeds, the return value is non-zero (TRUE).

If the function fails, the return value is zero (FALSE).

Remarks

The remote object retrieval manager exposes two provider models. One is the Scheme Provider model that allows for installable protocol providers as defined by the URL scheme; that is, ldap, http, ftp, file. The scheme provider entry point is the same as the CryptRetrieveObjectByUrl; however, the *ppvObject returned is always a counted array of encoded bits (one per object retrieved).

The second provider model is the Context Provider model that allows for installable creators of the context handles (objects) based on the retrieved encoded bits. These are dispatched based on the object OID specified in the call to CryptRetrieveObjectByUrl.

This functions supports "http:", "ftp:", "ldap:", "file:" URL schemes as well as newly defined schemes.

Individual PKI objects such as certificates, trusts lists, revocation lists, PKCS #7 messages, and multiple homogenous objects can be retrieved.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.
Library: Use Cryptnet.lib.

See Also

Remote Object Retrieval Functions


PFX Functions

[This is preliminary documentation and subject to change.]

These Win32 functions support PFX BLOBs.

Function | Description
PFXExportCertStore | Exports from the referenced certificate store the certificates and, if available, their associated private keys.
PFXExportCertStoreEx | Exports from the referenced certificate store the certificates and, if available, their associated private keys.
PFXImportCertStore | Imports a PFX BLOB and returns the handle of a store containing certificates and any associated private keys.
PFXIsPFXBlob | Attempts to decode the outer layer of a BLOB as a pfx packet.
PFXVerifyPassword | Attempts to decode the outer layer of a BLOB as a pfx packet and to decrypt it with the given password.


PFXExportCertStore

[This is preliminary documentation and subject to change.]

The PFXExportCertStore function exports the certificates and, if available, the associated private keys from the referenced certificate store. This is an old function kept for compatibility with Internet Explorer 4.0 clients. New applications should use the PfxExportCertStoreEx function that provides enhanced private key security.

BOOL WINAPI PFXExportCertStore(
  HCERTSTORE hStore,
  CRYPT_DATA_BLOB *pPFX,
  LPCWSTR szPassword,
  DWORD dwFlags
);

Parameters

hStore
[in] Handle of the certificate store containing the certificates to be exported.
pPFX
[in/out] Pointer to a CRYPT_DATA_BLOB structure to contain the PFX packet with the exported certificates and keys. If pPFX->pbData is NULL, the function calculates the number of bytes needed for the encoded BLOB and returns this in pPFX->cbData. When the function is called with pPFX-pdData pointing an allocated buffer of the needed size, the function copies the encoded bytes into the buffer and updates pPFX->cbData with the encode byte length.
szPassword
[in] String password used to encrypt and verify the PFX packet.
dwFlags
[in] Flag values can be set to any combination of the following.
Flag | Description
EXPORT_PRIVATE_KEYS | Private keys are exported as well as the certificates.
REPORT_NO_PRIVATE_KEY | If a certificate is encountered that has no associated private key, the function returns FALSE with the last error set to either CRYPT_E_NOT_FOUND or NTE_NO_KEY.
REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY | If a certificate is encountered that has a non-exportable private key, the function returns FALSE with the last error set to either CRYPT_E_NOT_FOUND or NTE_BAD_KEY.

Return Values

Returns TRUE (non-zero) if the function succeeds, and FALSE (zero) if the function fails. For extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Use Advapi32.lib.
Unicode: Defined as Unicode and ANSI prototypes.

See Also

PFXExportCertStoreEx, PFXImportCertStore


PFXExportCertStoreEx

[This is preliminary documentation and subject to change.]

The PFXExportCertStoreEx function exports the certificates and, if available, their associated private keys from the referenced certificate store. This function replaces the older PfxExportCertStore function. It should be used for its enhanced private key security.

BOOL WINAPI PFXExportCertStoreEx(
  HCERTSTORE hStore,
  CRYPT_DATA_BLOB *pPFX,
  LPCWSTR szPassword,
  void *pvReserved,
  DWORD dwFlags
);

Parameters

hStore
[in] Handle of the certificate store containing the certificates to be exported.
pPFX
[in/out] Pointer to a CRYPT_DATA_BLOB structure to contain the PFX packet with the exported certificates and keys. If pPFX->pbData is NULL, the function calculates the number of bytes needed for the encoded BLOB and returns this in pPFX->cbData. When the function is called with pPFX-pdData pointing an allocated buffer of the needed size, the function copies the encoded bytes into the buffer and updates pPFX->cbData with the encode byte length.
szPassword
[in] String password used to encrypt and verify the PFX packet.
pvReserved
[reserved] Reserved for future use. Currently, this parameter must be NULL.
dwFlags
[in] Flag values can be set to any combination of the following.
Flag | Description
EXPORT_PRIVATE_KEYS | Private keys are exported as well as the certificates.
REPORT_NO_PRIVATE_KEY | If a certificate is encountered that has no associated private key, the function returns FALSE with the last error set to either CRYPT_E_NOT_FOUND or NTE_NO_KEY.
REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY | If a certificate is encountered that has a non-exportable private key, the function returns FALSE with the last error set to either CRYPT_E_NOT_FOUND or NTE_BAD_KEY.

Return Values

Returns TRUE (non-zero) if the function succeeds, and FALSE (zero) if the function fails. For extended error information, call GetLastError.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Use Advapi32.lib.
Unicode: Defined as Unicode and ANSI prototypes.

See Also

PFXExportCertStore, PFXImportCertStore


PFXImportCertStore

[This is preliminary documentation and subject to change.]

The PFXImportCertStore function imports a PFX BLOB and returns the handle of a store containing certificates and any associated private keys.

HCERTSTORE WINAPI PFXImportCertStore (
  CRYPT_DATA_BLOB *pPFX,
  LPCWSTR szPassword,
  DWORD dwFlags
);

Parameters

pPFX
[in] Pointer to a .CRYPT_DATA_BLOB structurecontaining a PFX packet with the exported and encrypted certificates and keys.
szPassword
[in] String password used to decrypt and verify the PFX packet. This password must be exactly the same as the password that was used to encrypt the packet.
dwFlags
[in] Flag values can be set to the following.
Flag | Description
CRYPT_EXPORTABLE | Imported keys are marked as exportable If this flag is not used, calls to CryptExportKey with the key handle fail.
CRYPT_USER_PROTECTED | The user is to be notified through a dialog box or other method when certain actions are attempting to use this key. The precise behavior is specified by the CSP being used. Prior to Internet Explorer 4.0, Microsoft cryptographic service providers ignored this flag. Starting with Internet Explorer 4.0, Microsoft providers support this flag value. Windows 98, Windows NT 4.0 with Service Pack 4, and Windows 2000 support this flag value. If the provider context was opened with the CRYPT_SILENT flag set, using this flag causes a failure and the last error is set to NTE_SILENT_CONTEXT.
CRYPT_MACHINE_KEYSET | The private keys are stored under local machine and not the current user.
CRYPT_USER_KEYSET | The private keys are stored under the current user and not the local machine even if the PFX BLOB specifies they should go into local machine.

Return Values

If successful, this function returns that handle to a certificate store containing the imported certificates including available private keys. If the password parameter does not contain an exact match with the password used to encrypt the exported packet, or if there were any other problems decoding the PFX BLOB, the function returns NULL and an error code can be found by calling the GetLastError function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Use Advapi32.lib.
Unicode: Defined as Unicode and ANSI prototypes.

See Also

PFXExportCertStore, PFXExportCertStoreEx


PFXIsPFXBlob

[This is preliminary documentation and subject to change.]

The PFXIsPFXBlob function attempts to decode the outer layer of a BLOB as a PFX packet.

BOOL WINAPI IsPFXBlob (
  CRYPT_DATA_BLOB *pPFX
);

Parameters

pPFX
[in] Pointer to a CRYPT_DATA_BLOB structure that the function will attempt to decode as a PFX packet.

Return Values

The function returns TRUE if the BLOB can be decoded as a PFX packet. If outer layer of the BLOB cannot be decoded as a PFX packet, the function returns FALSE.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Use Advapi32.lib.
Unicode: Defined as Unicode and ANSI prototypes.

See Also

PFXVerifyPassword


PFXVerifyPassword

[This is preliminary documentation and subject to change.]

The PFXVerifyPassword function attempts to decode the outer layer of a BLOB as a PFX packet and to decrypt it with the given password. No data from the BLOB is imported.

BOOL WINAPI VerifyPassword(
  CRYPT_DATA_BLOB *pPFX,
  LPCWSTR szPassword,
  DWORD dwFlags
);

Parameters

pPFX
[in] Pointer to a CRYPT_DATA_BLOB structure that the function will attempt to decode as a PFX packet.
szPassword
[in] String password to be checked. For this function to succeed, this password must be exactly the same as the password used to encrypt the packet.
dwFlags
[in] Reserved for future use.

Return Values

The function return TRUE if password appears correct; otherwise, it returns FALSE.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Library: Use Advapi32.lib.
Unicode: Defined as Unicode and ANSI prototypes.


Cryptographic Provider Types

The field of cryptography is large and growing. There are many different standard data formats and protocols. These are generally organized into groups or families, each of which has its own set of data formats and way of doing things. Even if two families use the same algorithm (for example, the RC2 block cipher), they will often use different padding schemes, different key lengths, and different default modes. CryptoAPI is designed so that a CSP provider type represents a particular family.

When an application connects to a CSP of a particular type, each of the CryptoAPI functions will, by default, operate in a way prescribed by the family that corresponds to that CSP type. An application's choice of provider type specifies the following items:

Item | Description
Key exchange algorithm | Each provider type specifies one and only one key exchange algorithm. Every CSP of a particular type must implement this algorithm. Applications specify the key exchange algorithm to use by selecting a CSP of the appropriate provider type.
Digital signature algorithm | Each provider type specifies one and only one digital signature algorithm. Every CSP of a particular type must implement this algorithm. Applications specify the digital signature algorithm to use by selecting a CSP of the appropriate provider type.
Key BLOB formats | The provide type determines the format of the key BLOB used to export keys from the CSP and to import keys into a CSP.
Digital signature format | The provider type determines the digital signature format. This ensures that a signature produced by a CSP of a given provider type can be verified by any CSP of the same provider type.
Session key derivation scheme | The provider type determines the method used to derived a session key from a hash.
Key length | Some provider types specify the length of public/private key pairs and the session keys.
Default modes | The provider type often specifies default modes for various options, such as the block encryption cipher mode or the block encryption padding method.

Some advanced application might connect to more than one CSP at a time, but most application generally use only a single CSP

There are currently a number of predefined provider types. The next sections provide information on the following provider types:

  • PROV_RSA_FULL
  • PROV_RSA_SIG
  • PROV_RSA_SCHANNEL
  • PROV_DSS
  • PROV_DSS_DH
  • PROV_DH_SCHANNEL
  • PROV_FORTEZZA
  • PROV_MS_EXCHANGE
  • PROV_SSL

Even though some CSP types might be partially compatible with others, two or more applications that need to exchange keys and encrypted messages should use CSPs of the same type.

A custom CSP writer can define a new provider type. However, the CSP writer is then responsible for distributing the new provider type to the authors of any applications that are to use it. See Cryptographic Service Providers for details on writing custom CSPs.


PROV_RSA_FULL

The PROV_RSA_FULL provider type supports both digital signatures and data encryption. It is considered a general purpose CSP. The RSA public-key algorithm is used for all public-key operations.

Algorithms Supported

See the glossary for descriptions of each of these algorithms.

Key Exchange
RSA
Signature
RSA
Encryption
RC2

RC4

Hashing
MD5

SHA

Related Documentation

This provider type is defined by Microsoft and RSA Data Security. It is described in the following documents:

  • Microsoft Cryptographic Service Provider Programmer's Guide, Microsoft, 1996.
  • RSA Laboratories, Public-Key Cryptography Standards, RSA Data Security, November 1993.


PROV_RSA_SIG

The PROV_RSA_SIG provider type is a subset of PROV_RSA_FULL. It supports only those functions and algorithms required for hashes and digital signatures.

Algorithms Supported

See the glossary for descriptions of each of these algorithms.

Key Exchange
none
Signature
RSA
Encryption
none
Hashing
MD5

SHA

Related Documentation

The documentation for the PROV_RSA_FULL provider type also applies to the PROV_RSA_SIG provider type.


PROV_RSA_SCHANNEL

The PROV_RSA_SCHANNEL provider type supports both RSA and Schannel protocols.

Algorithms Supported

See the glossary for descriptions of each of these algorithms.

Key Exchange
RSA
Signature
RSA
Encryption
Any PROV_RSA_SCHANNEL CSP must implement one or more of the following algorithms

RC4

DES

Triple DES

Hashing
MD5

SHA


PROV_DSS

The PROV_DSS provider type, like PROV_RSA_SIG, only supports hashes and digital signatures. The signature algorithm specified by the PROV_DSS provider type is the Digital Signature Algorithm (DSA).

Algorithms Supported

See the glossary for descriptions of each of these algorithms.

Key Exchange
none
Signature
DSS
Encryption
none
Hashing
MD5

SHA

Related Documentation

The DSA was proposed by the National Institute of Standards and Technology (NIST). A description of the algorithm can be found in the following government reference: "Proposed Federal Information Processing Standard for Digital Signature Standard (DSS)," Federal Register, v. 57, no. 21, 31 Jan 1992, pp. 3747-3749.


PROV_DSS_DH

The PROV_DSS_DH provider is a superset of the PROV_DSS provider type.

Algorithms Supported

See the glossary for descriptions of each of these algorithms.

Key Exchange
DH
Signature
DSS
Encryption
CYLINK_MEK
Hashing
MD5

SHA

Related Documentation

The DSA was proposed by the National Institute of Standards and Technology (NIST). A description of the algorithm can be found in the following government reference:

  • "Proposed Federal Information Processing Standard for Digital Signature Standard (DSS)," Federal Register, v. 57, no. 21, 31 Jan 1992, pp. 3747-3749.


PROV_DH_SCHANNEL

The PROV_DH_SCHANNEL provider type supports both Diffie-Hellman and Schannel protocols

Algorithms Supported

See the glossary for descriptions of each of these algorithms.

Key Exchange
DH (ephemeral)
Signature
DSS
Encryption
DES

Triple DES

Hashing
MD5

SHA


PROV_FORTEZZA

The PROV_FORTEZZA provider type contains a set of cryptographic protocols and algorithms owned by the National Institute of Standards and Technology (NIST).

Algorithms Supported

See the glossary for descriptions of each of these algorithms.

Key Exchange
KEA
Signature
DSS
Encryption
Skipjack
Hashing
SHA

Related Documentation

More information is available directly from the National Institute of Standards and Technology (NIST).


PROV_MS_EXCHANGE

The PROV_MS_EXCHANGE provider type is designed for the cryptographic needs of the Microsoft Exchange mail application and other applications compatible with Microsoft Mail. This provider type is preliminary.

Algorithms Supported

See the glossary for descriptions of each of these algorithms.

Key Exchange
RSA
Signature
RSA
Encryption
CAST
Hashing
MD5


PROV_SSL

The PROV_SSL provider type supports the Secure Sockets Layer (SSL) protocol.

Algorithms Supported

See the glossary for descriptions of each of these algorithms.

Key Exchange
RSA
Signature
RSA
Encryption
Varies
Hashing
Varies

Related Documentation

A specification explaining the SSL protocol is available from Netscape Communications Corporation.


Microsoft Cryptographic Service Providers

The following cryptographic service providers (CSP) are currently available from Microsoft:

Provider | Description
Microsoft Base Cryptographic Provider | A broad set of basic cryptographic functionality that can be exported to other countries.
Microsoft Strong Cryptographic Provider | An extension of the Microsoft Base Cryptographic Provider available with Microsoft® Windows® 2000 and later
Microsoft Enhanced Cryptographic Provider | Microsoft Base Cryptographic Provider with through longer keys and additional algorithms.
Microsoft DSS Cryptographic Provider | Provides hashing, data signing, and signature verification capability using the Secure Hash Algorithm (SHA) and Digital Signature Standard (DSS) algorithms.
Microsoft Base DSS and Diffie-Hellman Cryptographic Provider | A superset of the DSS Cryptographic Provider that also supports Diffie-Hellman key exchange, hashing, data signing, and signature verification using the Secure Hash Algorithm (SHA) and Digital Signature Standard (DSS) algorithms.
Microsoft DSS and Diffie-Hellman/Schannel Cryptographic Provider | Supports hashing, data signing with DSS, generating Diffie-Hellman (D-H) keys, exchanging D-H keys, and exporting a D-H key. This CSP supports key derivation for the SSL3 and TLS1 protocols.
Microsoft RSA/Schannel Cryptographic Provider | Supports hashing, data signing, and signature verification. The algorithm identifier CALG_SSL3_SHAMD5 is used for SSL 3.0 and TLS 1.0 client authentication. This CSP supports key derivation for the SSL2, PCT1, SSL3 and TLS1 protocols.


Microsoft Base Cryptographic Provider

The Microsoft Base Cryptographic Provider is the initial cryptographic service provider (CSP) provider, and is distributed with CryptoAPI versions 1.0 and 2.0. It is a general-purpose provider that supports digital signatures and data encryption. This provider is currently included with the Microsoft® Windows NT®/Windows 2000, Windows 95, and Windows 98 operating system. It is also included with Microsoft® Internet Explorer version 3.0 or later.

The RSA public-key algorithm is used for all public-key operations.

To maintain backward compatibility with earlier versions the new version of the provider retains the version 1.0 designation of the name in Wincrypt.h. However, version 2.0 of this provider is currently shipping. To determine the actual version of the provider in use, call CryptGetProvParam with the dwParam argument set to PP_VERSION. If 0x0200 is returned in pbData, then you have version 2.0.
Provider Type: PROV_RSA_FULL
Provider Name: MS_DEF_PROV


Base Provider Algorithms

[This is preliminary documentation and subject to change.]

The following table lists the algorithms supported by the Microsoft Base Cryptographic Provider:

Algorithm ID | Description | Comments
CALG_MD2 | MD2 hashing algorithm. |
CALG_MD5 | MD5 hashing algorithm. |
CALG_SHA | SHA hashing algorithm. |
CALG_SHA1 | Same as CALG_SHA. |
CALG_MAC | MAC keyed-hash algorithm. | Block cipher MAC.
CALG_HMAC | MAC keyed-hash algorithm. | HMAC computation.
CALG_SSL3_SHAMD5 | SLL3 client authentication algorithm. | For more information, see Creating a CALG_SSL3_SHAMD5 Hash
CALG_RSA_SIGN | RSA public-key signature algorithm. | Key length: can be set from 384 bits to 16,384 bits in 8-bit increments. Default key length: 512 bits. Signature conforms to PKCS #6.
CALG_RSA_KEYX | RSA public-key exchange algorithm. | Key length: can be set from 384 bits to 512 bits in 8-bit increments. Default key length: 512 bits.
CALG_RC2 | RC2 block encryption algorithm. | Key length: 40 bits. Default mode: Cipher block chaining. Block size: 64 bits. Salt length: 88 bits.
CALG_RC4 | RC4 stream encryption algorithm. | Key length: 40 bits. Salt length: 88 bits.
CALG_DES | DES encryption | Add with Windows 2000 and with Windows NT 4.0 Service Pack 6.


Base Provider Key BLOBs

The Base Provider and Extended Provider use the same key BLOBs.

Public-key BLOBs

Public-key BLOBs, type PUBLICKEYBLOB, are used to store public keys outside a CSP. Base provider public-key BLOBs have the following format:

PUBLICKEYSTRUC  publickeystruc ;
RSAPUBKEY rsapubkey;
BYTE modulus[rsapubkey.bitlen/8];

The following table describes each public-key component. All values are in little-endian format.

Field | Description
publickeystruc | A PUBLICKEYSTRUC structure.
rsapubkey | A RSAPUBKEY structure. The magic member must be set to 0x31415352. This hex value is the ASCII encoding of "RSA1"
modulus | The public-key modulus data is located directly after the RSAPUBKEY structure. The size of this data will vary, depending on the size of the public key. The number of bytes can be determined by dividing the value of the RSAPUBKEY bitlen field by eight.

Note Public-key BLOBs are not encrypted. They contain public keys in plaintext form.

Private-Key BLOBs

Private-key BLOBs, type PRIVATEKEYBLOB, are used to store private keys outside a CSP. Base provider private-key BLOBs have the following format:

PUBLICKEYSTRUC  publickeystruc ;
RSAPUBKEY rsapubkey;
BYTE modulus[rsapubkey.bitlen/8];
BYTE prime1[rsapubkey.bitlen/16];
BYTE prime2[rsapubkey.bitlen/16];
BYTE exponent1[rsapubkey.bitlen/16];
BYTE exponent2[rsapubkey.bitlen/16];
BYTE coefficient[rsapubkey.bitlen/16];
BYTE privateExponent[rsapubkey.bitlen/8];

The following table describes the private-key BLOB component.

Field | Description
publickeystruc | A PUBLICKEYSTRUC
rsapubkey | A RSAPUBKEY structure. The magic member must be set to 0x32415352. This hex value is the ASCII encoding of "RSA2"
Modulus | The modulus. This has a value of "prime1 * prime2" and is often known as "n".
prime1 | Prime number 1, often known as "p".
prime2 | Prime number 2, often known as "q".
exponent1 | Exponent 1. This has a numeric value of "d mod (p - 1)".
exponent2 | Exponent 2. This has a numeric value of "d mod (q - 1)".
coefficient | Coefficient. This has a numeric value of "(inverse of q) mod p".
privateExponent | Private exponent, often known as "d".

Note These fields correspond to the fields described in section 7.2 of Public-Key Cryptography Standards (PKCS) #1 with minor differences.

Note Private-key BLOBs are not encrypted. They contain private keys in plaintext form.

When calling CryptExportKey the developer can choose whether or not to encrypt the key. The PRIVATEKEYBLOB is encrypted if the hExpKey parameter contains a valid handle to a session key. Everything but the PUBLICKEYSTRUC portion of the BLOB is encrypted.

Note The encryption algorithm and encryption key parameters are not stored along with the private-key BLOB. The application must manage and store this information. If zero is passed for hExpKey, the private key will be exported without encryption.

Warning It is dangerous to export private keys without encryption because they are then vulnerable to interception and use by unauthorized entities.

Simple-Key BLOBs

Simple key BLOBs, type SIMPLEBLOB, are used to store and transport session keys outside a CSP. Base provider simple-key BLOBs are always encrypted with a key exchange public key. The pbData member of the SIMPLEBLOB is a sequence of bytes in the following format:

PUBLICKEYSTRUC  publickeystruc ;
ALG_ID algid;
BYTE encryptedkey[rsapubkey.bitlen/8];

The ALG_ID structure immediately following the PUBLICKEYSTRUC structure specifies the encryption algorithm used to encrypt the session key data. This typically has a value of CALG_RSA_KEYX, indicating that the session key data was encrypted with a key exchange public key using the RSA Public-Key algorithm.

The encrypted session key data is in the form of a PKCS #1, type 2 encryption block. For details on this data format, see the Public-Key Cryptography Standards (PKCS), published by RSA Data Security, Inc.

This data is always the same size as the public key's modulus. For example, public keys generated by the Microsoft RSA Base Provider can be 512 bits (64 bytes) in length, so, in that case, the encrypted session key data is also 512 bits (64 bytes).


Microsoft Strong Cryptographic Provider

The Microsoft Strong Cryptographic Provider is used as the default RSA Full cryptographic service provider (CSP). It supports all of the algorithms of the Microsoft Enhanced Cryptographic Provider and all of the same key lengths, but for backwards compatibility, it uses the same default key lengths as the Microsoft Base Cryptographic Provider. For details on default key lengths, see Microsoft Base Cryptographic Provider. For details on longer key lengths and available algorithms, see Microsoft Enhanced Cryptographic Provider.


Microsoft Enhanced Cryptographic Provider

[This is preliminary documentation and subject to change.]

The Microsoft Enhanced Cryptographic Provider, called the Enhanced Provider, supports the same capabilities as the Microsoft Base Cryptographic Provider, called the Base Provider. The Enhanced Provider supports for stronger security through longer keys and additional algorithms. It can be used with all versions of CryptoAPI.

To maintain backward compatibility with earlier provider versions, the provider name, as defined in the Wincrypt.h header file, retains the version 1.0 designation. However, version 2.0 of this provider is currently shipping. To determine the version of the provider in use, call CryptGetProvParam with the dwParam argument set to PP_VERSION. Version 2.0 is in use if 0x0200 is returned.
Provider Type: PROV_RSA_FULL
Provider Name: MS_ENHANCED_PROV

The following table highlights differences between the Base Provider, Strong Provider, and Enhanced Provider. The key lengths shown are the default key lengths.

Algorithm | Base Provider Key Length | Strong Provider Key Length | Enhanced Provider Key Length
RSA public-key signature algorithm | 512 bits | 512 bits | 1,024 bits
RSA public-key exchange algorithm | 512 bits | 512 bits | 1,024 bits
RC2 block encryption algorithm | 40 bits | 40 bits | 128 bits Salt length can be set
RC4 stream encryption algorithm | 40 bits | 40 bits | 128 bits Salt length can be set
DES | 56 bits | 56 bits | 56 bits
Triple DES (2 key) | Not supported | 112 bits | 112 bits
Triple DES (3 key) | Not supported | 168 bits | 168 bits

The Strong Provider and the Enhanced Provider are backward-compatible with the Base Provider except that the providers can only generate RC2 or RC4 keys of default key length. The default length for the Base Provider is 40 bits. The default length for the Enhanced Provider is 128 bits. Thus the Enhanced Provider cannot create keys with Base Provider-compatible key lengths. However, the Enhanced Provider can import RC2 and RC4 keys of up to 128 bits. Therefore, the Enhanced Provider can import and use 40 bit keys generated using the Base Provider.


Enhanced Provider Algorithms

The following table lists the algorithms supported by the Microsoft Enhanced Cryptographic Provider:

Algorithm ID | Description | Comments
CALG_MD2 | MD2 hashing algorithm |
CALG_MD5 | MD5 hashing algorithm |
CALG_SHA | SHA hashing algorithm |
CALG_SHA1 | Same as CALG_SHA |
CALG_MAC | MAC keyed hash algorithm | Block cipher MAC
CALG_HMAC | MAC keyed-hash algorithm | HMAC computation.
CALG_SSL3_SHAMD5 | SLL3 client authentication algorithm | For more information, see SSL3 Client Authentication Algorithm
CALG_RSA_SIGN | RSA public-key signature algorithm | Key length: can be set, 384 bits to 16,384 bits in 8 bit increments. Default key length: 1,024 bits. Signature conforms to PKCS #6.
CALG_RSA_KEYX | RSA public-key exchange algorithm | Key length: can be set, 384 bits to 16,384 bits in 8 bit increments. Default key length: 1,024 bits.
CALG_RC2 | RC2 block encryption algorithm | Key length: 128 bits. Default mode: Cipher block chaining. Block size: 64 bits. Salt length: can be set.
CALG_RC4 | RC4 stream encryption algorithm | Key length: 128 bits. Salt length: can be set.
CALG_DES | DES encryption | Key Length: 56 bits. Default mode: Cipher block chaining. Block size: 64 bits. No salt allowed.
CALG_3DES_112 | Two-key triple DES encryption | Key Length: 112 bits. Default mode: Cipher block chaining. Block size: 64 bits. No salt allowed.
CALG_3DES | Triple DES | Key Length: 168 bits. Default mode: Cipher block chaining. Block size: 64 bits. No salt allowed.


Extended Provider Key BLOBs

The Base Provider and Extended Provider use the same key BLOBs.

Public-key BLOBs

Public-key BLOBs, type PUBLICKEYBLOB, are used to store public keys outside a CSP. Extended provider public-key BLOBs have the following format:

PUBLICKEYSTRUC  publickeystruc ;
RSAPUBKEY rsapubkey;
BYTE modulus[rsapubkey.bitlen/8];

The following table describes each public-key component. All values are in little-endian format.

Field | Description
publickeystruc | A PUBLICKEYSTRUC structure.
rsapubkey | A RSAPUBKEY structure. The magic member must be set to 0x31415352. This hex value is the ASCII encoding of "RSA1"
modulus | The public-key modulus data is located directly after the RSAPUBKEY structure. The size of this data will vary, depending on the size of the public key. The number of bytes can be determined by dividing the value of the RSAPUBKEY bitlen field by eight.

Note Public-key BLOBs are not encrypted. They contain public keys in plaintext form.

Private-Key BLOBs

Private-key BLOBs, type PRIVATEKEYBLOB, are used to store private keys outside a CSP. Extended provider private-key BLOBs have the following format:

PUBLICKEYSTRUC  publickeystruc ;
RSAPUBKEY rsapubkey;
BYTE modulus[rsapubkey.bitlen/8];
BYTE prime1[rsapubkey.bitlen/16];
BYTE prime2[rsapubkey.bitlen/16];
BYTE exponent1[rsapubkey.bitlen/16];
BYTE exponent2[rsapubkey.bitlen/16];
BYTE coefficient[rsapubkey.bitlen/16];
BYTE privateExponent[rsapubkey.bitlen/8];

The following table describes the private-key BLOB component.

Field | Description
publickeystruc | A PUBLICKEYSTRUC
rsapubkey | A RSAPUBKEY structure. The magic member must be set to 0x32415352. This hex value is the ASCII encoding of "RSA2"
Modulus | The modulus. This has a value of "prime1 * prime2" and is often known as "n".
prime1 | Prime number 1, often known as "p".
prime2 | Prime number 2, often known as "q".
exponent1 | Exponent 1. This has a numeric value of "d mod (p - 1)".
exponent2 | Exponent 2. This has a numeric value of "d mod (q - 1)".
coefficient | Coefficient. This has a numeric value of "(inverse of q) mod p".
privateExponent | Private exponent, often known as "d".

Note These fields correspond to the fields described in section 7.2 of Public-Key Cryptography Standards (PKCS) #1 with minor differences.

Note Private-key BLOBs are not encrypted. They contain private keys in plaintext form.

When calling CryptExportKey the developer can choose whether or not to encrypt the key. The PRIVATEKEYBLOB is encrypted if the hExpKey parameter contains a valid handle to a session key. Everything but the PUBLICKEYSTRUC portion of the BLOB is encrypted.

Note The encryption algorithm and encryption key parameters are not stored along with the private-key BLOB. The application must manage and store this information. If zero is passed for hExpKey, the private key will be exported without encryption.

Warning It is dangerous to export private keys without encryption because they are then vulnerable to interception and use by unauthorized entities.

Simple-Key BLOBs

Simple key BLOBs, type SIMPLEBLOB, are used to store and transport session keys outside a CSP. Extended provider simple-key BLOBs are always encrypted with a key exchange public key. The pbData member of the SIMPLEBLOB is a sequence of bytes in the following format:

PUBLICKEYSTRUC  publickeystruc ;
ALG_ID algid;
BYTE encryptedkey[rsapubkey.bitlen/8];

The ALG_ID structure immediately following the PUBLICKEYSTRUC structure specifies the encryption algorithm used to encrypt the session key data. This typically has a value of CALG_RSA_KEYX, indicating that the session key data was encrypted with a key exchange public key using the RSA Public-Key algorithm.

The encrypted session key data is in the form of a PKCS #1, type 2 encryption block. For details on this data format, see the Public-Key Cryptography Standards (PKCS), published by RSA Data Security, Inc.

This data is always the same size as the public key's modulus. For example, public keys generated by the Microsoft RSA Base Provider can be 512 bits (64 bytes) in length, so, in that case, the encrypted session key data is also 512 bits (64 bytes).

For more detailed information on the Base Provider and Extended Provider key BLOBs, see Interoperability with RSA CSPs.


Key Length Comparison

The Microsoft Enhanced Cryptographic Provider provides an application with stronger security than currently available with the Microsoft Base Cryptographic Provider. Greater key length giving users a greater degree of protection for sensitive data.

The following table lists the default key lengths supported by the Base Provider and the Enhanced Provider for standard algorithms.

Algorithm | Base Provider | Enhanced Provider
RSA Key Exchange | 512-bit | 1,024-bit
RSA Signature | 512-bit | 1,024-bit
RC2 | 40-bit | 128-bit
RC4 | 40-bit | 128-bit
DES | Not supported | 56-bit
Triple DES (2-key) | Not supported | 112-bit
Triple DES (3-key) | Not supported | 168-bit

DES and Triple DES algorithms are supported in the Enhanced Provider.

The Enhanced Provider is backward-compatible with the Base Provider distributed with earlier versions of CryptoAPI with the following exception. Both the base provider and the Enhanced Provider can only generate session keys of default key length. The default length of session keys for the Base Provider is 40 bits. The default key length for the Enhanced Provider is 128 bits. The Enhanced Provider cannot create keys with Base Provider-compatible key lengths. However, the Enhanced Provider can import key lengths of any size, up to 128 bits.


New Key-Length Functionality

The Base Provider used only 40-bit symmetric keys. The addition of longer keys in the Enhanced Provider, and the fact that imported keys can be of arbitrary length requires a method of querying the length for a specific key. To find the actual length of a key in bits, a user can call CryptGetKeyParam with the KP_KEYLEN parameter value. The length of the key is returned in the DWORD pointed to by pbData.

Note To protect against stepping-down cryptanalysis attacks, applications must check for insufficient key lengths and notify the user when one is encountered.

The function call demonstrates querying the length of a key.

    DWORD dwKeyLength;
    DWORD dwLen=sizeof(DWORD);

    // Generate a key.
    if (CryptGenKey(
                hDefProv,
                CALG_RC2,
                0,
                &hKey))
     {
        printf("A key has been generated.\n");
        // Query the key length.
        if (CryptGetKeyParam(
                hKey,
                KP_KEYLEN,
                (BYTE*)&dwKeyLength,
                &dwLen,
                0))
        {
            printf("The key is %d bits long. \n", dwKeyLength);
        }
        else
        {
            printf("The query failed.\n");
        }
      }
      else
      {
          printf("Key generation failed.\n");
       }


New Salt Value Functionality

The Base Provider creates 40-bit symmetric keys created with eleven bytes of zero-value salt, eleven bytes of nonzero salt if CRYPT_CREATE_SALT is specified, or no salt value. A 40-bit symmetric key with zero-value salt, however, is not equivalent to a 40-bit symmetric key without salt. For interoperability, keys must be created without salt. This problem results from a default condition that occurs only with keys of exactly 40 bits. All other key lengths do not have salt allocated by default.

Both the Base Providers and the Extended Provider can use the CRYPT_NO_SALT flag to specify that no salt value is allocated for a 40-bit symmetric key. The functions that accept this flag are CryptGenKey, CryptDeriveKey, and CryptImportKey. By default, these functions provide backward compatibility for the 40-bit symmetric key case by continuing the use of the eleven-byte-long zero-value salt.

The following function call imports a key without a salt value:

    // Import a key without salt.
    if (CryptImportKey(
                hDefProv,
                pbKey,
                cbKey,
                NULL,
                CRYPT_NO_SALT,
                &hKey))
        printf("The key is imported.\n");
      else
        printf("The key import failed. \n");


Specifying a Salt Value

Both the Base Provider and the Extended Provider can specify the value and length of the salt value to be used. The Base Provider set a salt value using the KP_SALT parameter value. The Base Provider always sets eleven bytes of salt value.

The Enhanced Provider sets the salt value by calling CryptSetKeyParam with the KP_SALT_EX parameter value specified and with the pbData parameter pointing to a CRYPTOAPI_BLOB structure containing the salt:

Note The total length of an Enhanced Provider symmetric key and its salt value cannot be greater than 128 bits .

KP_SALT continues to be provided for backward compatibility with the Base Provider. Newer applications should use the KP_SALT_EX parameter value.

The following function call imports a key and set a salt value:

The example below shows the importation of a key and setting of a salt value.

    // Specify 4 bytes of salt.
    BYTE rgbSalt[] = {0x01, 0x02, 0x03, 0x04};
    CRYPT_DATA_BLOB sSaltData;
    sSaltData.pbData = rgbSalt;
    sSaltData.cbData = sizeof(rgbSalt);

// Import a key.
if (CryptImportKey(
                hDefProv,
                pbKey,
                cbKey,
                NULL,
                0,
                &hKey))
    {
        printf("The key is imported.\n");
        // Set the 4 bytes of salt required.
       if (CryptSetKeyParam(
                hKey,
                KP_SALT_EX,
                (BYTE*)&sSaltData,
                0))
        {
             printf("The salt value is set.\n");
        }
        else
        {
              printf("Setting the salt value failed.\n");
         }
      }
      else
      {
         printf("Importing the key failed. \n");
      }


SHA Functionality

The original Base Provider incorrectly reported that the SHA hash algorithm enumerating algorithms by calls to CryptGetProvParam with parameter PP_ENUMALGS specified. This has been fixed in the Base Provider. Both the revised Base Provider and the Extended Provider and now correctly report SHA-1.

A defined CALG_SHA1 constant has been added to Wincrypt.h with the same value as CALG_SHA.


Microsoft DSS Cryptographic Provider

The Microsoft DSS Cryptographic Provider supports hashing, data signing, and signature verification using the Secure Hash Algorithm (SHA) and Digital Signature Standard (DSS) algorithms. It can be exported outside North America, and is provided with the Windows 95, Windows 98, and Windows NT/Windows 2000 operating systems.

Provider Type: PROV_DSS
Provider Name: MS_DEF_DSS_PROV


DSS Provider Algorithms

The following table lists the algorithms supported by the Microsoft DSS Cryptographic Provider:

Algorithm ID | Description | Comments
CALG_MD5 | MD5 hashing algorithm. | Provided only for hashing.
CALG_SHA | SHA hashing algorithm. | Must be used for DSS signatures.
CALG_SHA1 | Same as CALG_SHA. |
CALG_DSS_SIGN | DSS public/private-key signature algorithm. | Key length: can be set, 512 bits to 1,024 bits in 64 bit increments. Default key length: 1,024 bits.


DSS Provider Key BLOBs

BLOBs are used with the DSS provider to export keys from the CSP and import keys into the CSP.

Public-Key BLOBs

A DSS public key is exported and imported as a BLOB, a sequence of bytes structured as follows:

PUBLICKEYSTRUC    publickeystruc ;
DSSPUBKEY         dsspubkey;
BYTE              p[dsspubkey.bitlen/8];
BYTE              q[20];
BYTE              g[dsspubkey.bitlen/8];
BYTE              y[dsspubkey.bitlen/8];
DSSSEED           seedstruct;

The following table describes these components. All values are in little-endian format.

Field | Description
publickeystruc | A PUBLICKEYSTRUC structure
dsspubkey | A DSSPUBKEY structure. The magic member must have a value of 0x31535344. This hexadecimal number is the ASCII encoding of "DSS1".
p | A BYTE sequence. The prime modulus, P. Must always have the most significant bit of the most significant byte set to 1.
q | A BYTE sequence. The prime, Q - 20 bytes in length. The most significant bit of the most significant byte must be set to 1.
g | A BYTE sequence. The generator, G. Must be the same length as p (must be padded with 0x00 bytes if it is less).
y | A BYTE sequence, The public key, Y. Must be same length as p, if smaller then it must be padded with 0x00.
seedstruct | A DSSSEED structure. Seed and counter values for verifying primes.

Note Public-key BLOBs are not encrypted. They contain public keys in plaintext form.

Private-Key BLOBs

A DSS private key is exported and imported as a sequence of bytes, structured as follows:

PUBLICKEYSTRUC    publickeystruc ;
DSSPUBKEY         dsspubkey;
BYTE              p[dsspubkey.bitlen/8];
BYTE              q[20];
BYTE              g[dsspubkey.bitlen/8];
BYTE              X[20];
DSSSEED           seedstruct;

The following table describes each public-key component. All values are in little-endian format.

Field | Description
publickeystruc | A PUBLICKEYSTRUC structure.
dsspubkey | A DSSPUBKEY structure. The magic member must be set to 0x32535344. This hexadecimal number is the ASCII encoding of "DSS2".
p | A BYTE sequence. The prime modulus, P. Must always have the most significant bit of the most significant byte set to 1.
q | A BYTE sequence. The prime, Q. It is 20 bytes in length. The most significant bit of the most significant byte must be set to 1.
g | A BYTE sequence. The generator, G. Must be the same length as p (must be padded with 0x00 bytes if it is less).
x | A BYTE sequence. The secret exponent, X. It must always be 20 bytes in length. If smaller, then it must be padded with 0x00.
seedstruct | A DSSSEED structure. Seed and counter values for verifying primes.

When calling CryptExportKey the developer can choose whether or not to encrypt the key. The PRIVATEKEYBLOB is encrypted if the hExpKey parameter contains a valid handle to a session key. Everything but the PUBLICKEYSTRUC portion of the BLOB is encrypted. Note that the encryption algorithm and encryption key parameters are not stored along with the private-key BLOB. The application must manage and store this information. If zero is passed for hExpKey, the private key will be exported without encryption.

Warning It is dangerous to export private keys without encryption, because they are then vulnerable to interception and use by unauthorized entities.


Microsoft Base DSS and Diffie-Hellman Cryptographic Provider

The Microsoft Base DSS and Diffie-Hellman Cryptographic Provider supports Diffie-Hellman (D-H) key exchange (a 40-bit DES derivative), SHA hashing, DSS data signing, and DSS signature verification. It can be exported to other countries, and is currently provided with the Windows 95, Windows 98, and Windows NT/Windows 2000 platforms.

Provider Type: PROV_DSS_DH
Provider Name: MS_DEF_DSS_DH_PROV


PROV_DSS_DH Provider Algorithms

The following table lists the algorithms supported by the Microsoft Base DSS and Diffie-Hellman Cryptographic Provider:

Algorithm ID | Description | Comments
CALG_MD5 | MD5 hashing algorithm. | Provided only for hashing.
CALG_SHA | SHA hashing algorithm. | Must be used for DSS signatures.
CALG_SHA1 | Same as CALG_SHA. |
CALG_DSS_SIGN | DSS public/private-key signature algorithm. | Key length: can be set, 512 bits to 1,024 bits in 64 bit increments. Default key length: 1,024 bits.
CALG_DH_SF | Store and Forward D-H key exchange. | Key length: can be set, 384 bits to 512 bits in 8 bit increments. Default key length: 512 bits.
CALG_DH_EPHEM | Ephemeral D-H key exchange. | Key length: can be set, 384 bits to 512 bits in 8 bit increments. Default key length: 512 bits.
CALG_CYLINK_MEK | A 40-bit variant of a DES key. | Key Length: 40 bits.


Diffie-Hellman Key BLOBs

BLOBs are used with the Diffie-Hellman provider to export keys from the CSP and import keys into the CSP.

Public Key BLOBs

Diffie-Hellman public key BLOBs (type PUBLICKEYBLOB) are used to exchange the (G^X) mod P value in a D-H key exchange. These keys are exported and imported as a sequence of bytes with the following format:

PUBLICKEYSTRUC  publickeystruc ;
DHPUBKEY dhpubkey;
BYTE y[dhpubkey.bitlen/8]; // Where y = (G^X) mod P

The following table describes each component of the key BLOB.

Field | Description
publickeystruc | A PUBLICKEYSTRUC structure.
dhpubkey | A DHPUBKEY structure. The magic member should be set to 0x31484400. This hex value is the ASCII encoding of "DH1."
y | A BYTE sequence. The Y value, (G^X) mod P, is located directly after the DHPUBKEY structure, and should always be the length (in bytes) of the DHPUBKEY bitlen field (bit length of P) divided by eight. If the length of the data that results from the calculation of (G^X) mod P is one or more bytes shorter than P divided by 8, the data must be padded with the necessary bytes (of zero value) to make the data the desired length (little-endian format).

Private-Key BLOBs

D-H private-key BLOBs (type PRIVATEKEYBLOB) are used to store the public/private information of a D-H key. These keys are exported and imported as a sequence of bytes with the following format:

PUBLICKEYSTRUC  publickeystruc ;
DHPUBKEY        dhpubkey;
BYTE            prime[dhpubkey.bitlen/8];
BYTE            generator[dhpubkey.bitlen/8];
BYTE            secret[dhpubkey.bitlen/8];

The following table describes each component of the key BLOB.

Field | Description
publickeystruc | A PUBLICKEYSTRUC structure.
dhpubkey | A DHPUBKEY structure. The magic member must set to 0x32484400. This hex value is the ASCII encoding of "DH2."
prime | A BYTE sequence. The prime modulus, P. This data must always have the most significant bit of the most significant byte set to 1.
generator | A BYTE sequence. The generator, G.
secret | A BYTE sequence. The secret exponent, X.

Note The generator and secret must always be the same byte length. If either is one byte or more shorter than the other, it must be padded with the necessary number of zero value bytes to make them the same. Both the generator and the secret are in little-endian format.


Microsoft DSS and Diffie-Hellman/Schannel Cryptographic Provider

The Microsoft DSS and Diffie-Hellman/Schannel Cryptographic Provider supports hashing, data signing with DSS, generating Diffie-Hellman (D-H) keys, exchanging D-H keys, and exporting a D-H key. This CSP supports key derivation for the SSL3 and TLS1 protocols. It can be exported to other countries, and is provided with Windows 2000 or later.

Provider Type: PROV_DH_SCHANNEL

Provider Name: MS_DEF_DH_SCHANNEL_PROV


Diffie-Hellman/Schannel Provider Algorithms

The purpose of the Diffie-Hellman algorithm is to make it possible for two or more hosts to create and share an identical, secret encryption key, by simply sharing information over an insecure network. The information that gets shared over the network is in the form of a couple of constant values, and a D-H public key.

The following table shows the algorithm list supported by the Microsoft Diffie-Hellman/Schannel Cryptographic Provider:

Algorithm ID | Description | Comments
CALG_DH_SF | Diffie-Hellman store and forward key exchange algorithm | Key length: can be set, 384 bits to 512 bits in 8 bit increments. Default key length: 512 bits.
CALG_MD5 | MD5 hashing algorithm. | Provided only for hashing.
CALG_DH_EPHEM | Ephemeral D-H key exchange. | Key length: can be set, 384 bits to 512 bits in 8 bit increments. Default key length: 512 bits.
CALG_SHA | SHA hashing algorithm. | Must be used for DSS signatures.
CALG_RC2 | RC2 block encryption algorithm | Key length 40 to 88 bits.
CALG_RC4 | RC4 stream encryption algorithm | Key length: 40 to 88 bits.
CALG_CYLINK_ MEK | DES variant encryption algorithm | Key length: 40 bits.


Diffie-Hellman/Schannel Key BLOBs

BLOBs are used with the Diffie-Hellman/Schannel provider to export keys from the CSP and import keys into the CSP.

Public Key BLOBs

D-H public-key BLOBs (type PUBLICKEYBLOB) are used to exchange the (G^X) mod P value in a D-H key exchange. These keys are exported and imported as a sequence of bytes with the following format:

PUBLICKEYSTRUC  publickeystruc ;
DHPUBKEY        dhpubkey;
BYTE            y[dhpubkey.bitlen/8]; // Where y = (G^X) mod P

The following table describes each component of the key BLOB.

Field | Description
publickeystruc | A PUBLICKEYSTRUC structure.
dhpubkey | A DHPUBKEY structure. The magic member must be set to 0x31484400 This hex value is the ASCII encoding of "DH1."
y | A BYTE sequence. The y value, (G^X) mod P, is located directly after the DHPUBKEY structure. The length of the sequence in bytes is the bitlen member of DHPUBKEY divided by eight. If the length of the data that results from the calculation of (G^X) mod P is one or more bytes shorter than P divided by 8, the data must be padded with the necessary bytes (of zero value) to make the data the desired length (little-endian format).

Private Key BLOBs

D-H private-key BLOBs (type PRIVATEKEYBLOB) are used to export and import private information of a D-H key. These keys are exported and imported as a sequence of bytes with the following format:

PUBLICKEYSTRUC  publickeystruc ;
DHPUBKEY        dhpubkey;
BYTE            prime[dhpubkey.bitlen/8];
BYTE            generator[dhpubkey.bitlen/8];
BYTE            secret[dhpubkey.bitlen/8];

The following table describes each component of the key BLOB.

Field | Description
publickeystruc | A PUBLICKEYSTRUC structure.
dhpubkey | A DHPUBKEY structure. The magic member must be set to 0x32484400. This hex value is the ASCII encoding of "DH2."
prime | A BYTE sequence. The prime modulus, P. This data must always have the most significant bit of the most significant byte set to 1.
generator | A BYTE sequence. The generator G. See note 1.
secret | A BYTE sequence. The secret exponent X. See note 1.

Note The prime, generator and secret must always have the same length in bytes. If any component is one byte or more shorter than the other, it must be padded with the necessary number of zero bytes to make them the same. All of the BYTE sequences are in little-endian format.


Microsoft RSA/Schannel Cryptographic Provider

The Microsoft RSA/Schannel Cryptographic Provider supports hashing, data signing, and signature verification. The algorithm identifier CALG_SSL3_SHAMD5 is used for SSL 3.0 and TLS 1.0 client authentication. This CSP supports key derivation for the SSL2, PCT1, SSL3 and TLS1 protocols. The hash consists of a concatenation of a MD5 hash with an SHA hash and signed with a RSA private key. It can be exported to other countries, and is provided with Windows 2000 or later.

Provider Type: PROV_RSA_SCHANNEL

Provider Name: MS_DEF_RSA_SCHANNEL_PROV

For additional information about RSA/Schannel providers see Schannel CSP Reference.


RSA/Schannel Provider Algorithms

The following table shows the algorithm list that might be supported by the Microsoft RSA/Schannel Cryptographic Provider:

Algorithm ID | Description | Comments
CALG_RSA_KEYX | RSA public-key key exchange algorithm | Key length: can be set, 384 bits to 16,384 bits in 8 bit increments. Default key length: 1,024 bits.
CALG_MD5 | MD5 hashing algorithm. | Provided only for hashing.
CALG_SHA | SHA hashing algorithm. | Must be used for DSS signatures.
CALG_RC2 | RC2 block encryption algorithm. | Key length: 40 to 88 bits
CALG_RC4 | RC4 stream encryption algorithm. | Key length: 40 to 88 bits


RSA/Schannel Key BLOBs

BLOBs are used with the RSA/Schannel provider to export keys from the CSP and import keys into the CSP.

Public Key BLOBs

Public-key BLOBs (type PUBLICKEYBLOB) are used to store public keys. These keys are exported and imported as a sequence of bytes with the following format:

PUBLICKEYSTRUC  publickeystruc ;
RSAPUBKEY       rsapubkey;
BYTE            modulus[rsapubkey.bitlen/8];

The following table describes each public-key components. All values are in little-endian format.

Field | Description
publickeystruc | A PUBLICKEYSTRUC structure.
rsapubkey | A RSAPUBKEY structure. The magic member must be set to 0x31415352. This hex value is the ASCII encoding of "RSA1."
modulus | A BYTE sequence. The public-key modulus data is located directly after the RSAPUBKEY structure. The length of this data varies, depending on the length of the public key. The number of bytes can be determined by dividing the value of the bitlen member of RSAPUBKEY by eight.

Note Public-key BLOBs are not encrypted. They contain public keys in plaintext form.

Private Key BLOBs

Private-key BLOBs (type PRIVATEKEYBLOB) are used to store public/private key pairs. These keys are exported and imported as a sequence of bytes with the following format:

PUBLICKEYSTRUC  publickeystruc ;
RSAPUBKEY       rsapubkey;
BYTE            modulus[rsapubkey.bitlen/8];
BYTE            prime1[rsapubkey.bitlen/16];
BYTE            prime2[rsapubkey.bitlen/16];
BYTE            exponent1[rsapubkey.bitlen/16];
BYTE            exponent2[rsapubkey.bitlen/16];
BYTE            coefficient[rsapubkey.bitlen/16];
BYTE            privateExponent[rsapubkey.bitlen/8];

If the key BLOB is encrypted, then everything but the PUBLICKEYSTRUC portion of the BLOB is encrypted. Note that the encryption algorithm and encryption key parameters are not stored along with the private key BLOB. It is the responsibility of the application to manage this information.

The following table describes each private-key BLOB components. Note that these fields largely correspond to the ones described in section 7.2 of Public-Key Cryptography Standards (PKCS) #1.

Field | Description
publickeystruc | A PUBLICKEYSTRUC structure.
rsapubkey | A RSAPUBKEY structure. The magic field must be set to 0x32415352. This hex value is the ASCII encoding of "RSA2".
Modulus | A BYTE sequence The modulus. This has a string containing "prime1 " or " prime2. " It is often known as "n".
prime1 | A BYTE sequence. Prime number 1, often known as "p".
prime2 | A BYTE sequence. Prime number 2, often known as "q".
exponent1 | A BYTE sequence. The first exponent This has a numeric value of "d mod (p - 1)".
exponent2 | A BYTE sequence. The second exponent. This has a numeric value of "d mod (q - 1)".
coefficient | A BYTE sequence. Coefficient. This has a numeric value of "(inverse of q) mod p".
privateExponent | A BYTE sequence. The private exponent, often known as "d".

Note Private-key BLOBs are not encrypted. They contain private keys in plaintext form.

When calling CryptExportKey the developer can choose whether or not to encrypt the key. The PRIVATEKEYBLOB is encrypted if the hExpKey parameter contains a valid handle to a session key. Everything but the PUBLICKEYSTRUC portion of the BLOB is encrypted. Note that the encryption algorithm and encryption key parameters are not stored along with the private-key BLOB. The application must manage and store this information. If zero is passed for hExpKey, the private key is exported without encryption.

Warning It is dangerous to export private keys without encryption, because they are then vulnerable to interception and use by unauthorized entities.

Simple Key BLOBs

Simple key BLOBs (type SIMPLEBLOB) are used to store and transport session keys. These are always encrypted with a key exchange public key. These keys are exported and imported as a sequence of bytes with the following format:

PUBLICKEYSTRUC  publickeystruc ;
ALG_ID          algid;
BYTE            encryptedkey[rsapubkey.bitlen/8];

The following table describes each simple BLOB component. The encrypted session key data is in the form of a PKCS #1, type 2 encryption block. For details on this data format, see The Public-Key Cryptography Standards (PKCS), published by RSA Data Security, Inc.

Field | Description
publickeystruc | A PUBLICKEYSTRUC structure.
algid | An ALG_ID structure. This typically specifies the CALG_RSA_KEYX algorithm, indicating that the session key data was encrypted with a key exchange public key, using the RSA Public-Key exchange algorithm.
encryptedkey | A BYTE sequence. The encrypted session key data is in the form of a PKCS #1, type 2 encryption block. For details on this data format, see the Public-Key Cryptography Standards (PKCS), published by RSA Data Security, Inc.

This data is always the same size as the public key's modulus. For example, public keys generated by the Microsoft Base Cryptographic Provider are always 512 bits (64 bytes) in length, so the encrypted session key data is also always 64 bytes.


CryptoAPI Structures

The following structures are used by the functions contained in CryptoAPI version 2.0. The structures are listed alphabetically by category:

  • Cryptography Structures
  • Common Certificate Structures
  • X.509 Certificate Extension Structures
  • Low-Level Message Structures
  • Simplified Message Structures
  • OID Support Structures
  • Certificate Chain Structures


Cryptography Structures

The following structures are used by the Base Cryptography Functions:

  • PUBLICKEYSTRUC
  • CERT_STORE_PROV_INFO
  • CRYPTPROTECT_PROMPTSTRUCT
  • DHPUBKEY
  • DSSPUBKEY
  • DSSSEED
  • HMAC_INFO
  • PROV_ENUMALGS
  • PROV_ENUMALGS_EX
  • RSAPUBKEY
  • DSSPUBKEY_VER3
  • DHPUBKEY_VER3
  • Diffie-Hellman version 3 Public-Key Blobs
  • DSS version 3 Public-Key Blobs
  • DSSPRIVKEY_VER3
  • DHPRIVKEY_VER3
  • DSS version 3 Private-Key Blobs
  • Diffie-Hellman version 3 Private-Key Blobs


PUBLICKEYSTRUC

The PUBLICKEYSTRUC structure, also known as the BLOBHEADER structure, indicates a key's BLOB type and the algorithm that the key uses. One of these structures is located at the beginning of the pbData member of every key BLOB.

This structure is not limited to the key BLOBs generated by the PROV_RSA_BASE and PROV_RSA_SIG provider types. The pbData member of any new key BLOB type must begin with this structure.

typedef struct _PUBLICKEYSTRUC {
  BYTE   bType;
  BYTE   bVersion;
  WORD   reserved;
  ALG_ID aiKeyAlg;
} BLOBHEADER, PUBLICKEYSTRUC;

Members

bType
Key BLOB type. The only BLOB types currently defined are PUBLICKEYBLOB, PRIVATEKEYBLOB, and SIMPLEBLOB. Other key BLOB types will be defined as needed.

PUBLICKEYBLOBs are used to transport public keys, PRIVATEKEYBLOBs are used to transport public/private key pairs, and SIMPLEBLOBs are used to transport session keys.

bVersion
Version number of the key BLOB format. This currently must always have a value of 0x02.
reserved
DWORD reserved for future use. Must be set to zero.
aiKeyAlg
Algorithm identifier for the key contained by the key BLOB. Some examples are CALG_RSA_SIGN, CALG_RSA_KEYX, CALG_RC2, and CALG_RC4.

Not all algorithm identifiers are valid with all BLOB types. For example, since an RC4 key is a session key, it cannot be exported into a PUBLICKEYBLOB.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

DSSPUBKEY, DSSSEED, RSAPUBKEY


CERT_STORE_PROV_INFO

CERT_STORE_PROV_INFO structures contain information returned by the installed CertDllOpenStoreProv when a store is opened with CertOpenStore.

When opening a store, CertOpenStore zeroes all fields in the CERT_STORE_PROV_INFO except cbSize, which is set to the size of CERT_STORE_PROV_INFO. The structure is updated by the CertDllOpenStoreProv installable function. If there are no additional callback functions to be called, then cStoreProvFunc remains zero upon return.

typedef struct _CERT_STORE_PROV_INFO {
  DWORD               cbSize;
  DWORD               cStoreProvFunc;
  void**              rgpvStoreProvFunc;
  HCERTSTOREPROV      hStoreProv;
  DWORD               dwStoreProvFlags;
  HCRYPTOIDFUNCADDR   HStoreProvFuncAddr2;
} CERT_STORE_PROV_INFO, *PCERT_STORE_PROV_INFO;

Members

cbSize
Set by CertOpenStore to the size of this structure.
cStoreProvFunc
The count of callback functions that are implemented, including any NULL values that are used in indexes prior to the last callback function implemented. For example, if only one callback function is implemented, but it is at index [2] (CERT_STORE_PROV_WRITE_CERT_FUNC), with NULL for indexes [0] and [1], then the number 3 should be passed for this parameter.
rgpvStoreProvFunc
An array of pointers to the callback functions. This array is indexed by the values given in the following table, and they must be in the order shown. The associated callback function is shown as well. When the count of callback functions (cStoreProvFunc) is greater than 1, the elements of rgpvStoreProvFunc that aren't supported with a callback function should be NULL. Otherwise they should contain the address of the callback function.
Index | Index Name | Associated callback function
0 | CERT_STORE_PROV_CLOSE_FUNC | CertStoreProvCloseCallback
1 | CERT_STORE_PROV_READ_CERT_FUNC | CertStoreProvReadCertCallback
2 | CERT_STORE_PROV_WRITE_CERT_FUNC | CertStoreProvWriteCertCallback
3 | CERT_STORE_PROV_DELETE_CERT_FUNC | CertStoreProvDeleteCertCallback
4 | CERT_STORE_PROV_SET_CERT_PROPERTY_FUNC | CertStoreProvSetCertPropertyCallback
5 | CERT_STORE_PROV_READ_CRL_FUNC | CertStoreProvReadCRLCallback
6 | CERT_STORE_PROV_WRITE_CRL_FUNC | CertStoreProvWriteCRLCallback
7 | CERT_STORE_PROV_DELETE_CRL_FUNC | CertStoreProvDeleteCRLCallback
8 | CERT_STORE_PROV_SET_CRL_PROPERTY_FUNC | CertStoreProvSetCRLPropertyCallback
9 | CERT_STORE_PROV_READ_CTL_FUNC | CertStoreProvReadCTL
10 | CERT_STORE_PROV_WRITE_CTL_FUNC | CertStoreProvWriteCTL
11 | CERT_STORE_PROV_DELETE_CTL_FUNC | CertStoreProvDeleteCTL
12 | CERT_STORE_PROV_SET_CTL_PROPERTY_FUNC | CertStoreProvSetCTLProperty
13 | CERT_STORE_PROV_CONTROL_FUNC | CertStoreProvControl
14 | CERT_STORE_PROV_FIND_CERT_FUNC | CertStoreProvFindCert
15 | CERT_STORE_PROV_FREE_FIND_CERT_FUNC | CertStoreProvFreeFindCert
16 | CERT_STORE_PROV_GET_CERT_PROPERTY_FUNC | CertStoreProvGetCertProperty
17 | CERT_STORE_PROV_FIND_CRL_FUNC | CertStoreProvFindCRL
18 | CERT_STORE_PROV_FREE_FIND_CRL_FUNC | CertStoreProvFreeFindCRL
19 | CERT_STORE_PROV_GET_CRL_PROPERTY_FUNC | CertStoreProvGetCRLProperty
20 | CERT_STORE_PROV_FIND_CTL_FUNC | CertStoreProvFindCTL
21 | CERT_STORE_PROV_FREE_FIND_CTL_FUNC | CertStoreProvFreeFindCTL
22 | CERT_STORE_PROV_GET_CTL_PROPERTY_FUNC | CertStoreProvGetCTLProperty

hStoreProv
This is the first parameter passed to all callbacks. Because this is a void pointer (HCERTSTOREPROV is type-defined to a void*), an application can specify the contents as desired. Typically, this may be a pointer to anything that is specific to an application's data structure, such as provider state information for each store opened.
dwStoreProvFlags
dwStoreProvFlags is set to CERT_STORE_PROV_EXTERNAL_FLAG to indicate that certificates, CRLs, and CTLs are external to the store's cache. It is set to CERT_STORE_PROV_DELETED_FLAG if the store was successfully deleted. Otherwise it is set to 0.
HStoreProvFuncAddr2
HStoreProvFuncAddr2 can be set to the handle returned by CryptGetOIDFunctionAddress. CertCloseStore calls CryptFreeOIDFunctionAddress to free a non-null hStoreProvFuncAddr2. This allows the callback to call one other installable function that will be freed when the store is closed.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.


CRYPT_ENCODE_PARA

The CRYPT_ENCODE_PARA structure is used by the CryptEncodeObjectEx function. It provides access to memory allocation and memory freeing callback functions.

typedef struct _CRYPT_ENCODE_PARA {
  DWORD                   cbSize;
  PFN_CRYPT_ALLOC         pfnAlloc;           // OPTIONAL
  PFN_CRYPT_FREE          pfnFree;            // OPTIONAL
} CRYPT_ENCODE_PARA, *PCRYPT_ENCODE_PARA;

Members

cbSize
Indicates the size of the structure.
pfnAlloc
OPTIONAL pointer to a callback function used to allocate memory.
pfnFree
OPTIONAL pointer to a callback function used to free memory allocated by the allocate callback function.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CRYPTPROTECT_PROMPTSTRUCT

The CRYPTPROTECT_PROMPTSTRUCT structure provides the text of a prompt and information about when and where that prompt is to be displayed when using the CryptProtectData and CryptUnprotectData functions.

typedef struct _CRYPTPROTECT_PROMPTSTRUCT{
  DWORD      cbSize;
  DWORD      dwPromptFlags;
  HWND       hwndApp;
  LPCWSTR    szPrompt;
} CRYPTPROTECT_PROMPTSTRUCT, *PCRYPTPROTECT_PROMPTSTRUCT;

Members

cbSize
Size of this structure in bytes.
dwPromptFlags
DWORD flags that indicate when prompts to the user are to be displayed. Current dwPromptFlags values are:
CRYPTPROTECT_PROMPT_ON_PROTECT
This flag is used to provide the prompt for the protect phase.
CRYPTPROTECT_PROMPT_ON_UNPROTECT
This flag can be combined with CRYPTPROTECT_PROMPT_ON_PROTECT to enforce the UI (user interface) policy of the caller. When CryptUnprotectData is called, the dwPromptFlags specified in the CryptProtectData call are enforced.
hwndApp
Window handle to the parent window.
szPrompt
A string containing the text of a prompt to be displayed.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CryptProtectData, CryptUnprotectData


DHPUBKEY

The DHPUBKEY structure contains information specific to the particular Diffie-Hellman public key contained in the key BLOB.

typedef struct _PUBKEY {
  DWORD magic;
  DWORD bitlen;
} DHPUBKEY;

Members

magic
This must always be set to DH1 (0x31484400) when used for public-key BLOBs and to DH2 (0x32484400) when used for private-key BLOBs.

Notice that the hex values are simply an ASCII encoding of DH1 and DH2.

bitlen
Number of bits in the prime modulus, P.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

PUBLICKEYSTRUC


DSSPUBKEY

The DSSPUBKEY structure contains information specific to the particular public key contained in the key BLOB.

typedef struct _PUBKEY {
  DWORD magic;
  DWORD bitlen;
} DSSPUBKEY;

Members

magic
This must always be set to 0x31535344, the ASCII encoding of DSS1.
bitlen
Number of bits in the DSS key BLOB's prime, P.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

PUBLICKEYSTRUC, DSSSEED, RSAPUBKEY


DSSSEED

The DSSSEED structure holds the seed and counter values that can be used to verify the primes of the DSS public key.

typedef struct _DSSSEED {
  DWORD counter;
  BYTE  seed[20];
} DSSSEED;

Members

counter
A DWORD containing the counter value. If the counter value is 0xFFFFFFFF, the seed and counter values are not available.
seed[20]
A BYTE string containing the seed value.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

PUBLICKEYSTRUC, DSSPUBKEY, RSAPUBKEY


HMAC_INFO

The HMAC_INFO structure specifying the hash algorithm and the inner and outer strings that are to be used to calculate the HMAC hash.

typedef struct _HMAC_Info {
  ALG_ID HashAlgid;
  BYTE *pbInnerString;
  DWORD cbInnerString;
  BYTE *pbOuterString;
  DWORD cbOuterString;
} HMAC_INFO, *PHMAC_INFO;

Members

HashAlgid
Specifies the hash algorithm to be used.
pbInnerString
Pointer to the inner string to be used in the HMAC calculation. The default inner string is defined as the byte 0x36 repeated 64 times.
cbInnerString
The count of bytes in pbInnerString. The CSP uses the default inner string if cbInnerString is equal to zero.
pbOuterString
Pointer to the outer string to be used in the HMAC calculation. The default outer string is defined as the byte 0x5C repeated 64 times.
cbOuterString
The count of bytes in pbOuterString. The CSP uses the default outer string if pbOuterString is equal to zero.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

ALG_ID, CryptCreateHash, CryptSetHashParam


PROV_ENUMALGS

The PROV_ENUMALGS structure is returned by calls to CryptGetProvParam or CPGetProvParam. It holds information on algorithms supported by a CSP.

typedef struct _PROV_ENUMALGS {
  ALG_ID    aiAlgid;
  DWORD     dwBitLen;
  DWORD     dwNameLen;
  CHAR      szName[20];
} PROV_ENUMALGS;

Members

aiAlgid
ALG_ID indicating an algorithm supported.
dwBitLen
DWORD indicating the length of the key.
dwNameLen
DWORD indicating the length of the name of the algorithm.
szName
NULL-terminated string containing the name of the algorithm.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.


PROV_ENUMALGS_EX

The PROV_ENUMALGS_EX structure is returned by calls to CryptGetProvParam or CPGetProvParam. It holds information on algorithms supported by a CSP.

typedef struct _PROV_ENUMALGS_EX
{
  ALG_ID    aiAlgid;
  DWORD     dwDefaultLen;
  DWORD     dwMinLen;
  DWORD     dwMaxLen;
  DWORD     dwProtocols;
  DWORD     dwNameLen;
  CHAR      szName[20];
  DWORD     dwLongNameLen;
  CHAR      szLongName[40];
} PROV_ENUMALGS_EX;

Members

aiAlgid
ALG_ID identifying an algorithm supported.
dwDefaultLen
DWORD indicating the default key length using the indicated algorithm.
dwMinLen
DWORD indicating the minimum key length using the indicated algorithm.
dwMaxLen
DWORD indicating the maximum key length using the indicated algorithm.
dwProtocols
DWORD indicating the number of protocols supported.
dwNameLen
DWORD indicating the length of the short protocol name.
szName
NULL-terminated string with the name of the supported protocol.
dwLongNameLen
DWORD indicating the length of the supported protocol name.
szLongName
NULL-terminated string with the long name of the supported protocol.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.


RSAPUBKEY

The RSAPUBKEY structure contains information specific to the particular public key contained in the key BLOB.

typedef struct _RSAPUBKEY {
  DWORD magic;
  DWORD bitlen;
  DWORD pubexp;
} RSAPUBKEY;

Members

magic
Set to RSA1 (0x31415352) for public keys and to RSA2 (0x32415352) for private keys.

Note The hex values are the ASCII encoding of RSA1 and RSA2.

bitlen
Number of bits in the modulus. In practice, this must always be a multiple of eight.
pubexp
The public exponent.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

PUBLICKEYSTRUC, DSSPUBKEY, DSSSEED


DSSPUBKEY_VER3

The DSSPUBKEY_VER3 structure contains information specific to the particular public key contained in the key BLOB.

typedef struct _PUBKEYVER3 {
  DWORD   magic;
  DWORD   bitlenP;
  DWORD   bitlenQ;
  DWORD   bitlenJ;
  DSSSEED DSSSeed;
} DSSPUBKEY_VER3;

Members

magic
This must always be set to 0x33535344, the ASCII encoding of "DSS3".
bitlenP
Number of bits in the DSS key BLOB's prime, P.
bitlenQ
Number of bits in the DSS key BLOB's prime, Q. If Q is not in the BLOB, this value should be zero (0).
bitlenJ
Number of bits in the DSS key BLOB's prime, J. If J is not in the BLOB, then this value should be 0.
DSSSeed
Seed structure holding the seed and counter values used to generate the primes Q and P. If values in the DSSSeed structure are not available, then the counter element of the structure should be 0xFFFFFFFF.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.

See Also

BLOBHEADER, DSSSEED


DHPUBKEY_VER3

The DHPUBKEY_VER3 structure contains information specific to the particular public key contained in the key BLOB.

typedef struct _PUBKEYVER3 {
  DWORD   magic;
  DWORD   bitlenP;
  DWORD   bitlenQ;
  DWORD   bitlenJ;
  DSSSEED DSSSeed;
} DHPUBKEY_VER3;

Members

magic
This must always be set to 0x33484400, the ASCII encoding of "DH3".
bitlenP
Number of bits in the DH key BLOB's prime, P.
bitlenQ
Number of bits in the DH key BLOB's prime, Q. If Q is not available, then this value should be 0.
bitlenJ
Number of bits in the DH key BLOB's prime, J. If J is not in the BLOB ,then this value should be 0.
DSSSeed
Seed structure holding the seed and counter values used to generate the primes Q and P. If values in the DSSSeed structure, are not available then the counter element of the structure should be 0xFFFFFFFF.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.

See Also

BLOBHEADER, DSSSEED


Diffie-Hellman Version 3 Public-Key BLOBs

Diffie-Hellman version 3 Public-Key BLOBs (type PUBLICKEYBLOB) are used to export and import information about a DH public key. They have the following format:

BLOBHEADER blobheader;
                 // As explained under "Data Structures"
DHPUBKEY_VER3 dhpubkeyver3;
BYTE p[dhpubkeyver3.bitlenP/8];
                 // Where P is the prime modulus
BYTE q[dhpubkeyver3.bitlenQ/8];
                 // Where Q is a large factor of P-1
BYTE g[dhpubkeyver3.bitlenP/8];
                 // Where G is the generator parameter
BYTE j[dhpubkeyver3.bitlenJ/8];
                 // Where J is (P-1)/Q
BYTE y[dhpubkeyver3.bitlenP/8];
                 // Where Y is (G^X) mod P

This BLOB format is exported when the CRYPT_BLOB_VER3 flag is used with CryptExportKey. Because the version is in the BLOB, there is no need to specify a flag when using this BLOB with CryptImportKey.

In addition, this BLOB format is used with the CryptSetKeyParam function when the dwParam value KP_PUB_PARAMS is used to set key parameters on a DH key. This is done when the CRYPT_PREGEN flag has been used to generate the key. When used in this situation, the y value is ignored and therefore should not be included in the BLOB.

The following table describes each component of the key BLOB.

Field | Description
Blobheader | A BLOBHEADER structure. The bType member must have a value of PUBLICKEYBLOB.
Dhpubkeyver3 | A DHPUBKEY_VER3 structure. The magic member should be set to "DH3" (0x33484400) for public keys. Notice that the hex value is just an ASCII encoding of "DH3."
P | The P value is located directly after the DHPUBKEY_VER3 structure, and should always be the length (in bytes) of the DHPUBKEY_VER3 bitlenP field (bit length of P) divided by eight (little-endian format).
Q | The Q value is located directly after the P value and should always be the length (in bytes) of the DHPUBKEY_VER3 bitlenQ field divided by eight (little-endian format). If the bitlenQ value is 0, then the value is absent from the BLOB.
G | The G value is located directly after the Q value and should always be the length (in bytes) of the DHPUBKEY_VER3 bitlenP field (bit length of P) divided by eight. If the length of the data is one or more bytes shorter than P divided by 8, the data must be padded with the necessary bytes (of zero value) to make the data the desired length (little-endian format).
J | The J value is located directly after the G value and should always be the length (in bytes) of the DHPUBKEY_VER3 bitlenJ field divided by eight (little-endian format). If the bitlenQ value is 0, then the value is absent from the BLOB.
Y | The Y value, (G^X) mod P, is located directly after the J value, and should always be the length (in bytes) of the DHPUBKEY_VER3 bitlenP field (bit length of P) divided by eight. If the length of the data that results from the calculation of (G^X) mod P is one or more bytes shorter than P divided by 8, the data must be padded with the necessary bytes (of zero value) to make the data the desired length (little-endian format). NOTE – When this structure is used with CryptSetKeyParam with the dwParam value KP_PUB_PARAMS, then this value is not included in the BLOB.

Notice that public-key BLOBs are not encrypted, but contain public keys in plaintext form.


DSS Version 3 Public-Key BLOBs

DSS version 3 Public-Key BLOBs of type PUBLICKEYBLOB are used to export and import information about a DH public key. They have the following format:

BLOBHEADER blobheader;
        // As explained under "Data Structures"
DSSPUBKEY_VER3 dsspubkeyver3;
BYTE p[dsspubkeyver3.bitlenP/8];
       // Where P is the prime modulus
BYTE q[dsspubkeyver3.bitlenQ/8];
       // Where Q is a large factor of P-1
BYTE g[dsspubkeyver3.bitlenP/8];
       // Where G is the generator parameter
BYTE j[dsspubkeyver3.bitlenJ/8];
       // Where J is (P-1)/Q
BYTE y[dsspubkeyver3.bitlenP/8];
       // Where Y is (G^X) mod P

This BLOB format is exported when the CRYPT_BLOB_VER3 flag is used with CryptExportKey. Because the version is in the BLOB, there is no need to specify a flag when using this BLOB with CryptImportKey.

In addition, this BLOB format is used with the CryptSetKeyParam function when the dwParam value KP_PUB_PARAMS is used to set key parameters on a DSS key. This is done when the CRYPT_PREGEN flag has been used to generate the key. When used in this situation, the y value is ignored and therefore should not be included in the BLOB.

The following table describes each component of the key BLOB.

Field | Description
Blobheader | A BLOBHEADER structure. The bType member must have a value of PUBLICKEYBLOB.
Dsspubkeyver3 | A DSSPUBKEY_VER3 structure. The magic member should be set to "DSS3" (0x33535344) for public keys. Notice that the hex value is just an ASCII encoding of "DSS3."
P | The P value is located directly after the DSSPUBKEY_VER3 structure, and should always be the length (in bytes) of the DSSPUBKEY_VER3 bitlenP field (bit length of P) divided by eight (little-endian format).
Q | The Q value is located directly after the P value and should always be the length (in bytes) of the DSSPUBKEY_VER3 bitlenQ field divided by eight (little-endian format).
G | The G value is located directly after the Q value and should always be the length (in bytes) of the DSSPUBKEY_VER3 bitlenP field (bit length of P) divided by eight. If the length of the data is one or more bytes shorter than P divided by 8, the data must be padded with the necessary bytes (of zero value) to make the data the desired length (little-endian format).
J | The J value is located directly after the G value and should always be the length (in bytes) of the DSSPUBKEY_VER3 bitlenJ field divided by eight (little-endian format). If the bitlenQ value is 0, then the value is absent from the BLOB.
Y | The Y value, (G^X) mod P, is located directly after the J value, and should always be the length (in bytes) of the DSSPUBKEY_VER3 bitlenP field (bit length of P) divided by eight. If the length of the data that results from the calculation of (G^X) mod P is one or more bytes shorter than P divided by 8, the data must be padded with the necessary bytes (of zero value) to make the data the desired length (little-endian format). NOTE – When this structure is used with CryptSetKeyParam with the dwParam value KP_PUB_PARAMS, then this value is not included in the BLOB.

Notice that public-key BLOBs are not encrypted, but contain public keys in plaintext form.


DSSPRIVKEY_VER3

The DSSPRIVKEY_VER3 structure contains information specific to the particular private key contained in the key BLOB.

typedef struct _PRIVKEYVER3 {
  DWORD   magic;
  DWORD   bitlenP;
  DWORD   bitlenQ;
  DWORD   bitlenJ;
  DWORD   bitlenX;
  DSSSEED DSSSeed;
} DSSPRIVKEY_VER3;

Members

magic
This must always be set to 0x34535344, the ASCII encoding of "DSS4".
bitlenP
Number of bits in the DSS key BLOB's prime, P.
bitlenQ
Number of bits in the DSS key BLOB's prime, Q.
bitlenJ
Number of bits in the DSS key BLOB's prime, J. If J is not in the BLOB, then this value should be 0.
bitlenX
Number of bits in the DSS key BLOB private exponent, X.
DSSSeed
Seed structure holding the seed and counter values used to generate the primes Q and P. If values in the DSSSeed structure are not available, then the counter element of the structure should be 0xFFFFFFFF.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.

See Also

BLOBHEADER, DSSSEED


DHPRIVKEY_VER3

The DHPRIVKEY_VER3 structure contains information specific to the particular private key contained in the key BLOB.

typedef struct _PRIVKEYVER3 {
  DWORD   magic;
  DWORD   bitlenP;
  DWORD   bitlenQ;
  DWORD   bitlenJ;
  DWORD   bitlenX;
  DSSSEED DSSSeed;
} DHPRIVKEY_VER3;

Members

magic
This must always be set to 0x34484400, the ASCII encoding of "DH4".
bitlenP
Number of bits in the DH key BLOB's prime, P.
bitlenQ
Number of bits in the DH key BLOB's prime, Q. If Q is not available then this value should be 0.
bitlenJ
Number of bits in the DH key BLOB's prime, J. If J is not in the BLOB, then this value should be 0.
bitlenX
Number of bits in the DH key BLOB private exponent, X.
DSSSeed
Seed structure holding the seed and counter values used to generate the primes Q and P. If values in the DSSSeed structure are not available, then the counter element of the structure should be 0xFFFFFFFF.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.

See Also

BLOBHEADER, DSSSEED


DSS version 3 Private-Key BLOBs

When a version 3 DSS private key is exported, it is in a format as follows:

BLOBHEADER        blobheader;
DSSPRIVKEY_VER3   dssprivkeyver3;
BYTE p[dssprivkeyver3.bitlenP/8];
                    // Where P is the prime modulus
BYTE q[dssprivkeyver3.bitlenQ/8];
                    // Where Q is a large factor of P-1
BYTE g[dssprivkeyver3.bitlenP/8];
                    // Where G is the generator parameter
BYTE j[dssprivkeyver3.bitlenJ/8];
                    // Where J is (P-1)/Q
BYTE y[dssprivkeyver3.bitlenP/8];
                    // Where Y is (G^X) mod P
BYTE x[dssprivkeyver3.bitlenX/8];
                    // Where X is the private exponent

This BLOB format is exported when the CRYPT_BLOB_VER3 flag is used with CryptExportKey. Because the version is in the BLOB, there is no need to specify a flag when using this BLOB with CryptImportKey.

The following table describes each component of the key BLOB.

Field | Description
Blobheader | A BLOBHEADER structure. The bType member must have a value of PUBLICKEYBLOB.
Dssprivkeyver3 | A DSSPRIVKEY_VER3 structure. The magic member should be set to "DSS4" (0x34535344) for private keys. Notice that the hex value is just an ASCII encoding of "DSS4."
P | The P value is located directly after the DSSPRIVKEY_VER3 structure, and should always be the length (in bytes) of the DSSPRIVKEY_VER3 bitlenP field (bit length of P) divided by eight (little-endian format).
Q | The Q value is located directly after the P value and should always be the length (in bytes) of the DSSPRIVKEY_VER3 bitlenQ field divided by eight (little-endian format).
G | The G value is located directly after the Q value and should always be the length (in bytes) of the DSSPRIVKEY_VER3 bitlenP field (bit length of P) divided by eight. If the length of the data is one or more bytes shorter than P divided by 8, the data must be padded with the necessary bytes (of zero value) to make the data the desired length (little-endian format).
J | The J value is located directly after the G value and should always be the length (in bytes) of the DSSPRIVKEY_VER3 bitlenJ field divided by eight (little-endian format). If the bitlenJ value is 0 then the value is absent from the BLOB.
Y | The Y value, (G^X) mod P, is located directly after the J value, and should always be the length (in bytes) of the DSSPRIVKEY_VER3 bitlenP field (bit length of P) divided by eight. If the length of the data that results from the calculation of (G^X) mod P is one or more bytes shorter than P divided by 8, the data must be padded with the necessary bytes (of zero value) to make the data the desired length (little-endian format).
X | The X value is a random large integer such that the public portion of the DH key pair, Y, is equal to: Y = (G^X) mod P.

When calling CryptExportKey, the developer can choose whether or not to encrypt the key. The key is encrypted if the hExpKey parameter contains a valid handle to a session key. Everything but the BLOBHEADER portion of the BLOB is encrypted. Note that the encryption algorithm and encryption key parameters are not stored along with the private-key BLOB. The application must manage and store this information. If zero is passed for hExpKey, the private key will be exported without encryption.

Warning It is very dangerous to export private keys without encryption, since they are then vulnerable to interception and use by unauthorized entities.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


Diffie-Hellman Version 3 Private-Key BLOBs

When a Diffie-Hellman version 3 private key BLOB is exported, it is in a format as follows:

BLOBHEADER        blobheader;
DHPRIVKEY_VER3   dhprivkeyver3;
BYTE p[dhprivkeyver3.bitlenP/8];
            // Where P is the prime modulus
BYTE q[dhprivkeyver3.bitlenQ/8];
            // Where Q is a large factor of P-1
BYTE g[dhprivkeyver3.bitlenP/8];
            // Where G is the generator parameter
BYTE j[dhprivkeyver3.bitlenJ/8];
            // Where J is (P-1)/Q
BYTE y[dhprivkeyver3.bitlenP/8];
            // Where Y is (G^X) mod P
BYTE x[dhprivkeyver3.bitlenX/8];
            // Where X is the private exponent

This BLOB format is exported when the CRYPT_BLOB_VER3 flag is used with CryptExportKey. Because the version is in the BLOB, there is no need to specify a flag when using this BLOB with CryptImportKey.

The following table describes each component of the key BLOB.

Field | Description
Blobheader | A BLOBHEADER structure. The bType member must have a value of PUBLICKEYBLOB.
Dhprivkeyver3 | A DHPRIVKEY_VER3 structure. The magic member should be set to "DH4" (0x34484400) for private keys. Notice that the hex value is just an ASCII encoding of "DH4."
P | The P value is located directly after the DHPRIVKEY_VER3 structure, and should always be the length (in bytes) of the DHPRIVKEY_VER3 bitlenP field (bit length of P) divided by eight (little-endian format).
Q | The Q value is located directly after the P value and should always be the length (in bytes) of the DHPRIVKEY_VER3 bitlenQ field divided by eight (little-endian format). If the bitlenQ value is 0, then the value is absent from the BLOB.
G | The G value is located directly after the Q value and should always be the length (in bytes) of the DHPRIVKEY_VER3 bitlenP field (bit length of P) divided by eight. If the length of the data is one or more bytes shorter than P divided by 8, the data must be padded with the necessary bytes (of zero value) to make the data the desired length (little-endian format).
J | The J value is located directly after the G value and should always be the length (in bytes) of the DHPRIVKEY_VER3 bitlenJ field divided by eight (little-endian format). If the bitlenJ value is 0, then the value is absent from the BLOB.
Y | The Y value, (G^X) mod P, is located directly after the J value, and should always be the length (in bytes) of the DHPRIVKEY_VER3 bitlenP field (bit length of P) divided by eight. If the length of the data that results from the calculation of (G^X) mod P is one or more bytes shorter than P divided by 8, the data must be padded with the necessary bytes (of zero value) to make the data the desired length (little-endian format).
X | The X value is a random large integer such that the public portion of the DH key pair, Y, is equal to: Y = (G^X) mod P.

When calling CryptExportKey, the developer can choose whether or not to encrypt the key. The key is encrypted if the hExpKey parameter contains a valid handle to a session key. Everything but the BLOBHEADER portion of the BLOB is encrypted. Note that the encryption algorithm and encryption key parameters are not stored along with the private-key BLOB. The application must manage and store this information. If zero is passed for hExpKey, the private key will be exported without encryption.

Warning It is dangerous to export private keys without encryption, because they are then vulnerable to interception and use by unauthorized entities.


Common Certificate Structures

The following structures are used by many of the certificate and simplified message functions. You can find definitions for each of these structures in Wincrypt.h.

  • CRYPTOAPI_BLOB
  • CERT_CONTEXT
  • CERT_DH_PARAMETERS
  • CERT_DSS_PARAMETERS
  • CERT_EXTENSION
  • CERT_EXTENSIONS
  • CERT_GENERAL_SUBTREE
  • CERT_ID
  • CERT_INFO
  • CERT_KEY_CONTEXT
  • CERT_KEYGEN_REQUEST_INFO
  • CERT_NAME_CONSTRAINTS_INFO
  • CERT_NAME_INFO
  • CERT_NAME_VALUE
  • CERT_PAIR
  • CERT_PHYSICAL_STORE_INFO
  • CERT_POLICY_CONSTRAINTS_INFO
  • CERT_POLICY_MAPPING
  • CERT_POLICY_MAPPINGS_INFO
  • CERT_PUBLIC_KEY_INFO
  • CERT_RDN
  • CERT_RDN_ATTR
  • CERT_REQUEST_INFO
  • CERT_REVOCATION_PARA
  • CERT_REVOCATION_STATUS
  • CERT_SIGNED_CONTENT_INFO
  • CERT_STORE_PROV_FIND_INFO
  • CERT_SYSTEM_STORE_INFO
  • CERT_SYSTEM_STORE_RELOCATE_PARA
  • CERT_TEMPLATE_EXT
  • CERT_X942_DH_PARAMETERS
  • CERT_X942_DH_VALIDATION_PARAMS
  • CMC_ADD_ATTRIBUTES_INFO
  • CMC_ADD_EXTENSIONS_INFO
  • CMC_DATA_INFO
  • CMC_PEND_INFO
  • CMC_RESPONSE_INFO
  • CMC_STATUS_INFO
  • CMC_TAGGED_ATTRIBUTE
  • CMC_TAGGED_CERT_REQUEST
  • CMC_TAGGED_CONTENT_INFO
  • CMC_TAGGED_OTHER_MSG
  • CMC_TAGGED_REQUEST
  • CRL_CONTEXT
  • CRL_ENTRY
  • CRL_INFO
  • CRL_ISSUING_DIST_POINT
  • CROSS_CERT_DIST_POINTS_INFO
  • CRYPT_ALGORITHM_IDENTIFIER
  • CRYPT_ATTRIBUTE
  • CRYPT_ATTRIBUTE_TYPE_VALUE
  • CRYPT_ATTRIBUTES
  • CRYPT_BIT_BLOB
  • CRYPT_CONTENT_INFO
  • CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY
  • CRYPT_KEY_PROV_INFO
  • CRYPT_KEY_PROV_PARAM
  • CRYPT_SEQUENCE_OF_ANY
  • CRYPT_TIME_STAMP_REQUEST_INFO
  • CRYPT_X942_OTHER_INFO
  • CTL_ANY_SUBJECT_INFO
  • CTL_CONTEXT
  • CTL_ENTRY
  • CTL_FIND_SUBJECT_PARA
  • CTL_FIND_USAGE_PARA
  • CTL_INFO
  • CTL_USAGE
  • CTL_VERIFY_USAGE_PARA
  • CTL_VERIFY_USAGE_STATUS


CRYPTOAPI_BLOB

The CryptoAPI CRYPTOAPI_BLOB structure is used for an arbitrary array of bytes. It is declared in Wincrypt.h and provides flexibility for objects that can contain various data types.

typedef struct _CRYPTOAPI_BLOB {
  DWORD    cbData;
  BYTE*    pbData;
} CRYPT_INTEGER_BLOB,    *PCRYPT_INTEGER_BLOB,
  CRYPT_UINT_BLOB,     *PCRYPT_UINT_BLOB,
  CRYPT_OBJID_BLOB,    *PCRYPT_OBJID_BLOB,
  CERT_NAME_BLOB,      *PCERT_NAME_BLOB,
  CERT_RDN_VALUE_BLOB, *PCERT_RDN_VALUE_BLOB,
  CERT_BLOB,           *PCERT_BLOB,
  CRL_BLOB,            *PCRL_BLOB,
  DATA_BLOB,           *PDATA_BLOB,
  CRYPT_DATA_BLOB,     *PCRYPT_DATA_BLOB,
  CRYPT_HASH_BLOB,     *PCRYPT_HASH_BLOB,
  CRYPT_DIGEST_BLOB,   *PCRYPT_DIGEST_BLOB,
  CRYPT_DER_BLOB,      *PCRYPT_DER_BLOB,
  CRYPT_ATTR_BLOB,     *PCRYPT_ATTR_BLOB;

Members

cbData
Count of bytes in the buffer pointed to by pbData.
pbData
Pointer to a block of data bytes.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CERT_EXTENSION, CERT_POLICY_QUALIFIER_INFO, CERT_REQUEST_INFO, CertCompareIntegerBlob, CertNameToStr, CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA, CMSG_SIGNER_INFO, CRYPT_ATTRIBUTE_TYPE_VALUE, CRYPT_TIME_STAMP_REQUEST_INFO


CERT_CONTEXT

The CERT_CONTEXT structure contains both the encoded and decoded representations of a certificate. A certificate context returned by one of the functions defined in Wincrypt.h must be freed by calling the CertFreeCertificateContext function. The CertDuplicateCertificateContext function can be called to make a duplicate copy (which also must be freed by calling CertFreeCertificateContext).

typedef struct _CERT_CONTEXT {
  DWORD         dwCertEncodingType;
  BYTE*         pbCertEncoded;
  DWORD         cbCertEncoded;
  PCERT_INFO    pCertInfo;
  HCERTSTORE    hCertStore;
} CERT_CONTEXT,  *PCERT_CONTEXT;
typedef const CERT_CONTEXT *PCCERT_CONTEXT;

Members

dwCertEncodingType
Type of encoding used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
     X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pbCertEncoded
Pointer to the encoded certificate.
cbCertEncoded
Size, in bytes, of the encoded certificate.
pCertInfo
Pointer to a structure of certificate information.
hCertStore
Handle to the certificate store that contains the certificate context.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.

See Also

CERT_INFO, CertAddCertificateContextToStore, CertAddEncodedCertificateToStore, CertCreateCertificateContext, CertEnumCertificatesInStore, CertFindCertificateInStore, CertFreeCertificateContext, CertGetIssuerCertificateFromStore, CertGetSubjectCertificateFromStore, CryptVerifyMessageSignature, CertVerifyRevocation, CRYPT_SIGN_MESSAGE_PARA, CRYPT_VERIFY_MESSAGE_PARA


CERT_DH_PARAMETERS

The CERT_DH_PARAMETERS structure contains parameters associated with a Diffie/Hellman public key algorithm.

typedef struct _CERT_DH_PARAMETERS {
  CRYPT_UINT_BLOB     p;
  CRYPT_UINT_BLOB     g;
} CERT_DH_PARAMETERS, *PCERT_DH_PARAMETERS;

Members

p
Prime modulus P. The most significant bit of the most significant byte must always be set to 1.
g
Generator G. Must be the same length as p (must be padded with 0x00 bytes if it is less).

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CERT_DSS_PARAMETERS

The CERT_DSS_PARAMETERS structure contains parameters associated with a DSS public key algorithm.

typedef struct _CERT_DSS_PARAMETERS {
  CRYPT_UINT_BLOB     p;
  CRYPT_UINT_BLOB     q;
  CRYPT_UINT_BLOB     g;
} CERT_DSS_PARAMETERS, *PCERT_DSS_PARAMETERS;

Members

p
Prime modulus P. The most significant bit of the most significant byte must always be set to 1.
q
Prime Q. It is 20 bytes in length. The most significant bit of the most significant byte must be set to 1.
g
Generator G. Must be the same length as p (must be padded with 0x00 bytes if it is less).

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.


CERT_EXTENSION

The CERT_EXTENSION structure contains the extension information for a certificate, Certificate Revocation List (CRL) or Certificate Trust List (CTL).

typedef struct _CERT_EXTENSION {
  LPSTR              pszObjId;
  BOOL               fCritical;
  CRYPT_OBJID_BLOB   Value;
} CERT_EXTENSION,     *PCERT_EXTENSION;

Members

pszObjId
Object identifier (OID) that specifies the structure of the extension data contained in the Value member. See X.509 Certificate Extension Structures for specifics on extension OIDs and their related structures.
fCritical
If TRUE, any limitations specified by the extension in the Value member of this structure are imperative. If FALSE, limitations set by this extension can be ignored.
Value
A CRYPTOAPI_BLOB structure that contains the encoded extension data. The cbData member of Value indicates the length in bytes of the pbData member. The pbData member byte string is the encoded extension.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB, CERT_EXTENSIONS, CERT_INFO, CertFindExtension, CRL_ENTRY, CRL_INFO, CTL_ENTRY, CTL_INFO


CERT_EXTENSIONS

The CERT_EXTENSIONS structure contains an array of extensions.

typedef struct _CERT_EXTENSIONS {
  DWORD              cExtension;
  PCERT_EXTENSION    rgExtension;
} CERT_EXTENSIONS,    *PCERT_EXTENSIONS;

Members

cExtension
Number of elements in the array rgExtension.
rgExtension
Array of structures, each holding information of type CERT_EXTENSION about a certificate or CRL.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CERT_EXTENSION


CERT_GENERAL_SUBTREE

[This is preliminary documentation and subject to change.]

The CERT_GENERAL_SUBTREE structure is used in CERT_NAME_CONSTRAINTS_INFO structure. This structure provides the identity of a certificate that can be included or excluded.

typedef struct _CERT_GENERAL_SUBTREE {
    CERT_ALT_NAME_ENTRY     Base;
    DWORD                   dwMinimum;
    BOOL                    fMaximum;
    DWORD                   dwMaximum;
} CERT_GENERAL_SUBTREE, *PCERT_GENERAL_SUBTREE;

Members

Base
CERT_ALT_NAME_ENTRY containing a base name identifier of a certificate.
dwMinimum
Currently not used.
fMaximum
Currently not used.
dwMaximum
Currently not used.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.


CERT_ID

The CERT_ID structure is used as a flexible means of uniquely identifying a certificate.

typedef struct _CERT_ID {
  DWORD   dwIdChoice;
  union {
      CERT_ISSUER_SERIAL_NUMBER   IssuerSerialNumber;
      CRYPT_HASH_BLOB             KeyId;
      CRYPT_HASH_BLOB             HashId;
  };
} CERT_ID, *PCERT_ID;

Members

dwIdChoice
DWORD indicating which member of the union is being used. The following table provides possible values.
dwIdChoice value | Union member used
CERT_ID_ISSUER_SERIAL_NUMBER | IssuerSerialNumber
CERT_ID_KEY_IDENTIFIER | KeyId
CERT_ID_SHA1_HASH | HashId

IssuerSerialNumber
CERT_ISSUER_SERIAL_NUMBER structure that uniquely identifies a certificate.
KeyId
CRYPT_HASH_BLOB containing a certificate key identifier.
HashId
CRYPT_HASH_BLOB containing an SHA1 hash of the certificate to be used as a unique identifier of the certificate.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CERT_INFO

The CERT_INFO structure contains a certificate's information.

typedef struct _CERT_INFO {
  DWORD                       dwVersion;
  CRYPT_INTEGER_BLOB          SerialNumber;
  CRYPT_ALGORITHM_IDENTIFIER  SignatureAlgorithm;
  CERT_NAME_BLOB              Issuer;
  FILETIME                    NotBefore;
  FILETIME                    NotAfter;
  CERT_NAME_BLOB              Subject;
  CERT_PUBLIC_KEY_INFO        SubjectPublicKeyInfo;
  CRYPT_BIT_BLOB              IssuerUniqueId;
  CRYPT_BIT_BLOB              SubjectUniqueId;
  DWORD                       cExtension;
  PCERT_EXTENSION             rgExtension;
} CERT_INFO, *PCERT_INFO;

Members

dwVersion
The certificate's version number. Defined version numbers are listed in the following table.
Value | Meaning
CERT_V1 | Version 1
CERT_V2 | Version 2
CERT_V3 | Version 3

SerialNumber
BLOB containing the certificate's serial number. The least significant byte is the zero byte of the pbData member of SerialNumber. The index for the last byte of pbData. is one less than the value of the cbData member of SerialNumber. The most significant byte is the last byte of pbData. Leading 0x00 or 0xFF bytes are removed. See CertCompareIntegerBlob.
SignatureAlgorithm
CRYPT_ALGORITHM_IDENTIFIER structure containing the signature algorithm type and encoded additional encryption parameters.
Issuer
The certificate issuer's name in encoded form.
NotBefore
Date and time before which the certificate is not valid. For dates between 1950 and 2049 inclusive, the date and time is encoded UTC-time in the form YYMMDDHHMMSS. This member uses a two-digit year and is precise to seconds. For dates before 1950 or after 2049, encoded generalized-time is used. Encoded generalized time is in the form YYYYMMDDHHSSMMM, using a four-digit year, and is precise to milliseconds. Even though generalized time supports millisecond resolution, the NotBefore time is only precise to seconds.
NotAfter
Date and time after which the certificate is not valid. For dates between 1950 and 2049 inclusive, the date and time is encoded UTC-time in the form YYMMDDHHMMSS. This member uses a two-digit year and is precise to seconds. For dates before 1950 or after 2049, encoded generalized time is used. Encoded generalized time is in the form YYYYMMDDHHSSMMM, using a four digit year, and is precise to milliseconds. Even though generalized time supports millisecond resolution, the NotAfter time is only precise to seconds.
Subject
Certificate subject's encoded name.
SubjectPublicKeyInfo
CRYPTOAPI_BLOB structure that contains the encoded public key and its algorithm.
IssuerUniqueId
BLOB containing a unique identifier of the issuer.
SubjectUniqueId
BLOB containing a unique identifier of the subject.
cExtension
Number of elements in the rgExtension array.
rgExtension
Array of pointers to CERT_EXTENSION structures, each containing extension information about the certificate.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB, CERT_EXTENSION, CERT_PUBLIC_KEY_INFO, CertCompareCertificate, CertGetSubjectCertificateFromStore, CMSG_ENVELOPED_ENCODE_INFO, CMSG_SIGNER_ENCODE_INFO, CRYPT_ALGORITHM_IDENTIFIER, CRYPT_BIT_BLOB, CRYPT_VERIFY_MESSAGE_PARA, CryptMsgControl, CryptMsgGetParam, CryptSignAndEncodeCertificate


CERT_ISSUER_SERIAL_NUMBER

The CERT_ISSUER_SERIAL_NUMBER structure acts as a unique identifier of a certificate containing the issuer and issuer's serial number for a certificate.

typedef struct _CERT_ISSUER_SERIAL_NUMBER {
  CERT_NAME_BLOB      Issuer;
  CRYPT_INTEGER_BLOB  SerialNumber;
} CERT_ISSUER_SERIAL_NUMBER, *PCERT_ISSUER_SERIAL_NUMBER;

Members

Issuer
BLOB containing the name of the issuer.
SerialNumber
CRYPT_INTEGER_BLOB containing the serial number of the certificate. The combination of the issuer name and the serial number is a unique identifier of a certificate.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CERT_KEY_CONTEXT

The CERT_KEY_CONTEXT structure contains data for the pvData member of a Value member of CERT_EXTENSION structure associated with a CERT_KEY_CONTEXT_PROP_ID property.

typedef struct _CERT_KEY_CONTEXT {
  DWORD            cbSize;
  HCRYPTPROV       hCryptProv;
  DWORD            dwKeySpec;
} CERT_KEY_CONTEXT, *PCERT_KEY_CONTEXT;

Members

cbSize
Size of this structure in bytes.
hCryptProv
Cryptographic service provider (CSP) handle.
dwKeySpec
The specification of the private key to retrieve.

The following dwKeySpec values are defined for the default provider.
Value | Meaning
AT_KEYEXCHANGE | Keys used to encrypt/decrypt session keys.
AT_SIGNATURE | Keys used to create and verify digital signatures.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.

See Also

CertGetCertificateContextProperty, CertSetCertificateContextProperty


CERT_KEYGEN_REQUEST_INFO

The CERT_KEYGEN_REQUEST_INFO structure contains information stored in the Netscape Keygen request. The subject and subject public key BLOBs are encoded.

typedef struct _CERT_KEYGEN_REQUEST_INFO {
  DWORD                   dwVersion;
  CERT_PUBLIC_KEY_INFO    SubjectPublicKeyInfo;
  LPWSTR                  pwszChallengeString;   // encoded as IA5
} CERT_KEYGEN_REQUEST_INFO, *PCERT_KEYGEN_REQUEST_INFO;

Members

dwVersion
Version number of the certificate. CERT_V1 is the only defined version number.
SubjectPublicKeyInfo
CERT_PUBLIC_KEY_INFO structure containing the encoded public key and its algorithm.
pwszChallengeString
Random printable string. It is used by the server to ensure that the key that it is certifying matches the client on the page.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CERT_REQUEST_INFO


CERT_NAME_CONSTRAINTS_INFO

[This is preliminary documentation and subject to change.]

The CERT_NAME_CONSTRAINTS_INFO structure contains information about certificates that are specifically permitted or excluded from trust.

typedef struct _CERT_NAME_CONSTRAINTS_INFO {
    DWORD                   cPermittedSubtree;
    PCERT_GENERAL_SUBTREE   rgPermittedSubtree;
    DWORD                   cExcludedSubtree;
    PCERT_GENERAL_SUBTREE   rgExcludedSubtree;
} CERT_NAME_CONSTRAINTS_INFO, *PCERT_NAME_CONSTRAINTS_INFO;

Members

cPermittedSubtree
DWORD indicating the number of subtrees in the rgPermittedSubtree array.
rgPermittedSubtree
Array of CERT_GENERAL_SUBTREE structures, each identifying a permitted certificate name.
cExcludedSubtree
DWORD indicating the number of subtrees in the rgExcludedSubtree array.
rgExcludedSubtree
Array of CERT_GENERAL_SUBTREE structures, each identifying an excluded certificate name.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.


CERT_NAME_INFO

The CERT_NAME_INFO structure contains subject or issuer names. The information is represented as an array of CERT_RDN structures.

typedef struct _CERT_NAME_INFO {
  DWORD            cRDN;
  PCERT_RDN        rgRDN;
} CERT_NAME_INFO, *PCERT_NAME_INFO;

Members

cRDN
Number of elements in the rgRDN array.
rgRDN
Array of pointers to CERT_RDN structures.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.

See Also

CERT_RDN, CryptDecodeObject, CryptEncodeObject


CERT_NAME_VALUE

The CERT_NAME_VALUE structure contains a relative distinguished name (RDN) attribute value. It is like the CERT_RDN_ATTR structure, except that it does not include the object identifier member that is a member of CERT_RDN_ATTR. As in CERT_RDN_ATTR, the interpretation of the Value member depends on dwValueType.

typedef struct _CERT_NAME_VALUE {
  DWORD                dwValueType;
  CERT_RDN_VALUE_BLOB  Value;
} CERT_NAME_VALUE,    *PCERT_NAME_VALUE;

Members

dwValueType
Indicates the interpretation of the Value member. For documentation on possible values of dwValueType, see CERT_RDN_ATTR.
Value
CRYPTOAPI_BLOB structure containing the RDN attribute. The cbData member of Value is the length in bytes of the pbData member. It is not the number of elements in the pbData string.

For example, a DWORD is 32 bits or 4 bytes long. If the pbData member of Value is a DWORD array, the cbData member of Value would be four times the number of DWORD elements in the array. A short data type is 16 bits or 2 bytes long. If the pbData member is an array of short data types, the cbData member must be two times the length of the array.

The pbData member of Value can be a null-terminated array of 8-bit or 16-bit characters or a fixed-length array of elements. If dwValueType is set to CERT_RDN_ENCODED_BLOB, pbData is encoded.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB, CERT_RDN, CertRDNValueToStr


CERT_PAIR

[This is preliminary documentation and subject to change.]

The CERT_PAIR structure contains a certificate and its pair cross certificate.

typedef struct _CERT_PAIR {
   CERT_BLOB    Forward;
   CERT_BLOB    Reverse;
} CERT_PAIR, *PCERT_PAIR;

Members

Forward
Optional CERT_BLOB containing a certificate. Can be empty when Forward.cbData is zero.
Reverse
Optional CERT_BLOB containing a certificate. Can be empty when Reverse.cbData is zero.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.


CERT_PHYSICAL_STORE_INFO

The CERT_PHYSICAL_STORE_INFO structure contains information on physical certificate stores. Some members of these structures are passed directly to system calls of CertOpenStore to open the physical store.

typedef struct _CERT_PHYSICAL_STORE_INFO {
  DWORD               cbSize;
  LPSTR               pszOpenStoreProvider;
  DWORD               dwOpenEncodingType;
  DWORD               dwOpenFlags;
  CRYPT_DATA_BLOB     OpenParameters;         // REG_BINARY
  DWORD               dwFlags;                // REG_DWORD
  DWORD               dwPriority;             // REG_DWORD
} CERT_PHYSICAL_STORE_INFO, *PCERT_PHYSICAL_STORE_INFO;

Members

cbSize
Size of this structure in bytes.
pszOpenStoreProvider
Pointer to a string that names a certificate store provider type. This string is passed in a system call to CertOpenStore and determines the provider type of a certificate store to be opened. For the names of pre-defined certificate store types, see CertOpenStore.

In addition to predefined certificate store provider types, new store provider types can be installed and registered with CryptInstallOIDFunctionAddress or CryptRegisterOIDFunction. For additional information, see Extending CertOpenStore Functionality.

dwOpenEncodingType
Applicable only when CERT_STORE_PROV_MSG, CERT_STORE_PROV_PKCS7, or CERT_STORE_PROV_FILENAME is passed in lpszStoreProvider. Otherwise, this member is not used.

It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:

     X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

dwOpenFlags
If a system store is opened with the SERVICES or USERS store location, the dwOpenFlags store location is set to CERT_SYSTEM_STORE_USERS or CERT_SYSTEM_STORE_SERVICES.
OpenParameters
BLOB containing data to be passed to the pvPara parameter of CertOpenStore. The data type depends on the provider specified. See descriptions of available providers in CertOpenStore for detailed information about the type and content to be passed.
dwFlags
The following dwFlags values for CERT_PHYSICAL_STORE_INFO are defined.
Flag value | Meaning
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG | Enables addition to a context to the store.
CERT_PHYSICAL_STORE_OPEN_DISABLE_FLAG | Set by CertRegisterPhysicalStore. By default, all system stores located in the registry have an implicit SystemRegistry physical store that is opened. To disable the opening of this store, the SystemRegistry physical store corresponding to the System store must be registered by setting CERT_PHYSICAL_STORE_OPEN_DISABLE_FLAG or by registering a physical store named ".Default" with CertRegisterPhysicalStore.
CERT_PHYSICAL_STORE_REMOTE_OPEN_DISABLE_FLAG | Disables remote opening of the physical store.
CERT_PHYSICAL_STORE_INSERT_COMPUTER_NAME_ENABLE_FLAG | Places the string \\ComputerName in front of other provider types.
CERT_SYSTEM_STORE_RELOCATE_FLAG | Enables CertOpenStore to open a store relative to a user-specified HKEY instead of one of the predefined HKEY constants. For example, HKEY_CURRENT_USER can be replaced with a user-specified HKEY. When CERT_SYSTEM_STORE_RELOCATE_FLAG is set, the pvPara parameter passed to CertOpenStore points to a CERT_SYSTEM_STORE_RELOCATE_PARA structure instead of pointing to the store name as a null-terminated Unicode or ASCII string.

dwPriority
When a system store is opened, its physical stores are ordered according to their dwPriority settings. A higher dwPriority indicates higher priority. The dwPriority member is passed to CertAddStoreToCollection.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 95 OSR2 or later.
Header: Declared in Wincrypt.h.

See Also

CertAddStoreToCollection, CertOpenStore, CertRegisterPhysicalStore, CryptInstallOIDFunctionAddress, CryptRegisterOIDFunction


CERT_POLICY_CONSTRAINTS_INFO

[This is preliminary documentation and subject to change.]

The CERT_POLICY_CONSTRAINTS_INFO structure contains established policies for accepting certificates as trusted.

typedef struct _CERT_POLICY_CONSTRAINTS_INFO {
    BOOL            fRequireExplicitPolicy;
    DWORD           dwRequireExplicitPolicySkipCerts;
    BOOL            fInhibitPolicyMapping;
    DWORD           dwInhibitPolicyMappingSkipCerts;
} CERT_POLICY_CONSTRAINTS_INFO, *PCERT_POLICY_CONSTRAINTS_INFO;

Members

fRequireExplicitPolicy
BOOL flag indicating whether explicit policy information is required.
dwRequireExplicitPolicySkipCerts
DWORD indicating the number of required explicit policy certificates.
fInhibitPolicyMapping
BOOL flag indicating whether policy mapping is inhibited.
dwInhibitPolicyMappingSkipCerts
DWORD indicating the number of policy mapping certificates to be skipped.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.


CERT_POLICY_MAPPING

[This is preliminary documentation and subject to change.]

The CERT_POLICY_MAPPING structure contains a mapping between issuer domain and subject domain policy OIDs.

typedef struct _CERT_POLICY_MAPPING {
    LPSTR    pszIssuerDomainPolicy;      // pszObjId
    LPSTR    pszSubjectDomainPolicy;     // pszObjId
} CERT_POLICY_MAPPING, *PCERT_POLICY_MAPPING;

Members

pszIssuerDomainPolicy
pszObjId of an issuer domain policy.
pszSubjectDomainPolicy
pszObjId of the equivalent subject domain policy.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.


CERT_POLICY_MAPPINGS_INFO

[This is preliminary documentation and subject to change.]

The CERT_POLICY_MAPPINGS_INFO structure provides mapping between the policy OIDs of two domains.

typedef struct _CERT_POLICY_MAPPINGS_INFO {
    DWORD                       cPolicyMapping;
    PCERT_POLICY_MAPPING        rgPolicyMapping;
} CERT_POLICY_MAPPINGS_INFO, *PCERT_POLICY_MAPPINGS_INFO;

Members

cPolicyMapping
Count of the number of elements in the rgPolicyMapping array.
rgPolicyMapping
Array of CERT_POLICY_MAPPING structures. Each element of this array provides pair of OIDs mapping the identifies of one domain to identifiers in the other domain.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.


CERT_PUBLIC_KEY_INFO

The CERT_PUBLIC_KEY_INFO structure contains a public key and its algorithm.

typedef struct _CERT_PUBLIC_KEY_INFO {
  CRYPT_ALGORITHM_IDENTIFIER  Algorithm;
  CRYPT_BIT_BLOB              PublicKey;
} CERT_PUBLIC_KEY_INFO,        *PCERT_PUBLIC_KEY_INFO;

Members

Algorithm
CRYPT_ALGORITHM_IDENTIFIER structure that contains the public key algorithm type and associated additional parameters.
PublicKey
BLOB containing an encoded public key.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CertComparePublicKeyInfo, CertFindCertificateInStore, CERT_INFO, CERT_REQUEST_INFO, CRYPT_ALGORITHM_IDENTIFIER, CRYPT_BIT_BLOB, CryptImportPublicKeyInfoEx


CERT_RDN_ATTR

The CERT_RDN_ATTR structure contains a single attribute of a relative distinguished name (RDN). A whole RDN is expressed in a CERT_RDN structure that contains an array of CERT_RDN_ATTR structures.

typedef struct _CERT_RDN_ATTR {
  LPSTR                  pszObjId;
  DWORD                  dwValueType;
  CERT_RDN_VALUE_BLOB    Value;
} CERT_RDN_ATTR,          *PCERT_RDN_ATTR;

Members

pszObjId
Object identifier (OID) for the type of the attribute defined in this structure. Defined OIDs are shown in the following table.
OID | Description
szOID_COMMON_NAME Case-insensitive string.
Labeling attribute.
szOID_SUR_NAME Case-insensitive string.
Labeling attribute.
szOID_DEVICE_SERIAL_NUMBER Printable string.
Labeling attribute.
szOID_COUNTRY_NAME Two-character printable string.
Geographic attribute.
szOID_LOCALITY_NAME Case-insensitive string.
Geographic attribute.
szOID_STATE_OR_PROVINCE_NAME Case-insensitive string.
Geographic attribute.
szOID_STREET_ADDRESS Case-insensitive string.
Geographic attribute.
szOID_ORGANIZATION_NAME Case-insensitive string.
Organizational attribute.
szOID_ORGANIZATIONAL_UNIT_NAME Case-insensitive string.
Organizational attribute.
szOID_TITLE Case-insensitive string.
Organizational attribute.
szOID_DESCRIPTION | Case-insensitive string. Explanatory attribute.
szOID_SEARCH_GUIDE | Explanatory attribute.
szOID_BUSINESS_CATEGORY Case-insensitive string.
Explanatory attribute.
szOID_POSTAL_ADDRESS Printable string.
Postal addressing attribute.
szOID_POSTAL_CODE Case-insensitive string.
Postal addressing attribute.
szOID_POST_OFFICE_BOX Case-insensitive string.
Postal addressing attribute.
szOID_PHYSICAL_DELIVERY_OFFICE_NAME Case-insensitive string.
Postal addressing attribute.
szOID_TELEPHONE_NUMBER | Telecommunications addressing attribute.
szOID_TELEX_NUMBER | Telecommunications addressing attribute.
szOID_TELETEXT_TERMINAL_IDENTIFIER | Telecommunications addressing attribute.
szOID_FACSIMILE_TELEPHONE_NUMBER | Telecommunications addressing attribute.
szOID_X21_ADDRESS Numeric string.
Telecommunications addressing attribute.
szOID_INTERNATIONAL_ISDN_NUMBER Numeric string.
Telecommunications addressing attribute.
szOID_REGISTERED_ADDRESS | Telecommunications addressing attribute.
szOID_DESTINATION_INDICATOR Printable string.
Telecommunications addressing attribute.
szOID_PREFERRED_DELIVERY_METHOD | Preference attribute.
szOID_PRESENTATION_ADDRESS | OSI application attribute.
szOID_SUPPORTED_APPLICATION_CONTEXT | OSI application attribute.
szOID_MEMBER | Relational application attribute.
szOID_OWNER | Relational application attribute.
szOID_ROLE_OCCUPANT | Relational application attribute.
szOID_SEE_ALSO | Relational application attribute.
szOID_USER_PASSWORD | Security attribute.
szOID_USER_CERTIFICATE | Security attribute.
szOID_CA_CERTIFICATE | Security attribute.
szOID_AUTHORITY_REVOCATION_LIST | Security attribute.
szOID_CERTIFICATE_REVOCATION_LIST | Security attribute.
szOID_CROSS_CERTIFICATE_PAIR | Security attribute.
szOID_GIVEN_NAME Case-insensitive string.
Name attribute.
szOID_INITIALS | Case-insensitive string. Name attribute.
szOID_RSA_emailAddr IA5 string.
E-mail attribute.
szOID_DOMAIN_COMPONENT | IA5 string. DNS name component such as "com".
szOID_PKCS_12_FRIENDLY_NAME_ATTR | PKCS 12 attribute.
szOID_PKCS_12_LOCAL_KEY_ID | PKCS 12 attribute.

dwValueType
Indicates the interpretation of the Value member.

The following table identifies defined dwValueType values and describes the structure of the Value member that corresponds to that type.
Value | Description
CERT_RDN_ANY_TYPE | The pszObjId member determines the assumed type and length.
CERT_RDN_ENCODED_BLOB | An encoded data BLOB.
CERT_RDN_OCTET_STRING | An arbitrary string of octets (8-bit).
CERT_RDN_GRAPHIC_STRING | Currently not used.
CERT_RDN_GENERAL_STRING | Currently not used.
CERT_RDN_NUMERIC_STRING | Only the characters 0 through 9 and the space character (8-bit).
CERT_RDN_PRINTABLE_STRING | An arbitrary string of printable characters (8-bit).
CERT_RDN_TELETEX_STRING | An arbitrary string of T.61 characters (8-bit)
CERT_RDN_T61_STRING | An arbitrary string of T.61 characters (8-bit).
CERT_RDN_VIDEOTEX_STRING | An arbitrary string of videotex characters.
CERT_RDN_IA5_STRING | An arbitrary string of IA5 (ASCII) characters.
CERT_RDN_VISIBLE_STRING | A 95-character set (8-bit).
CERT_RDN_ISO646_STRING | A 128-character set (8-bit).
CERT_RDN_UNIVERSAL_STRING | An array of INT4 elements (32-bit).
CERT_RDN_INT4_STRING | An array of INT4 elements (32-bit).
CERT_RDN_BMP_STRING | An array of Unicode characters (16-bit).
CERT_RDN_UNICODE_STRING | An array of Unicode characters (16-bit).
CERT_RDN_UTF8_STRING | An array of 16 bit Unicode characters UTF8 encoded on the wire as a sequence of one, two, or three eight-bit characters.

The following flags can be combined with a bitwise-OR operation into the dwValueType member.
Value | Description
CERT_RDN_ENABLE_T61_UNICODE_FLAG For encoding. When set, if all the Unicode characters are <= 0xFF, the CERT_RDN_T61_STRING is selected instead of the CERT_
RDN_UNICODE_STRING.
CERT_RDN_DISABLE_CHECK_TYPE_FLAG | For encoding. When set, the characters are not checked to see if they are valid for the value type.
CERT_RDN_DISABLE_IE4_UTF8_FLAG | For decoding. By default, CERT_RDN_T61_STRING encoded values are initially decoded as UTF8. If the UTF8 decoding fails, the value is decoded as 8-bit characters. If this flag is set, it skips the initial attempt to decode as UTF8 and decodes the value as 8-bit characters.

Value
BLOB containing the attribute value. The cbData member of Value is the length in bytes of the pbData member. It is not the number of elements in the pbData string.

For example, a DWORD is 32 bits or 4 bytes long. If pbData is a DWORD array, cbData would be four times the number of DWORD elements in the array. A short is 16 bits or 2 bytes long. If pbData is an array of short elements, cbData must be two times the length of the array.

The pbData member of Value can be a null-terminated array of 8-bit or 16-bit characters or a fixed length array of elements. If dwValueType is set to CERT_RDN_ENCODED_BLOB, pbData is encoded.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB, CERT_RDN, CertIsRDNAttrsInCertificateName


CERT_RDN

The CERT_RDN structure contains a relative distinguished name (RDN) consisting of an array of CERT_RDN_ATTR structures.

typedef struct _CERT_RDN {
  DWORD            cRDNAttr;
  PCERT_RDN_ATTR   rgRDNAttr;
} CERT_RDN,         *PCERT_RDN;

Members

cRDNAttr
Number of elements in the rgRDNAttr array.
rgRDNAttr
Array of CERT_RDN_ATTR structures.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CERT_NAME_INFO, CERT_RDN_ATTR, CertFindCertificateInStore, CertIsRDNAttrsInCertificateName, CertNameToStr


CERT_REQUEST_INFO

The CERT_REQUEST_INFO structure contains information for a certificate request. The subject, subject public key, and attribute BLOBs are encoded.

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;

Members

dwVersion
The certificate's version number. Defined version number is shown in the following table.
Certificate version name | Meaning
CERT_V1 | version 1

Subject
BLOB containing the certificate subject's encoded name.
SubjectPublicKeyInfo
CERT_PUBLIC_KEY_INFO structure containing the encoded public key and its algorithm.
cAttribute
Number of elements in the rgAttribute array.
rgAttribute
Array of pointers to CRYPT_ATTRIBUTE structures, each holding attribute information about the certificate.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB, CERT_PUBLIC_KEY_INFO, CRYPT_ATTRIBUTE, CryptSignAndEncodeCertificate


CERT_REVOCATION_PARA

[This is preliminary documentation and subject to change.]

The CERT_REVOCATION_PARA structure can optionally be passed to CertVerifyRevocation to assist in finding the issuer of the context to be verified.

typedef struct _CERT_REVOCATION_PARA {
  DWORD                      cbSize;
  PCCERT_CONTEXT             pIssuerCert;
  DWORD                      cCertStore;
  HCERTSTORE                *rgCertStore;
  HCERTSTORE                 hCrlStore;
  LPFILETIME                 pftTimeToUse;
  DWORD                      dwUrlRetrievalTimeout;
  BOOL                       fCheckFreshnessTime;
  DWORD                      dwFreshnessTime;
  LPFILETIME                 pftCurrentTime;
  PCERT_REVOCATION_CRL_INFO  pCrlInfo;
} CERT_REVOCATION_PARA, *PCERT_REVOCATION_PARA;

Members

cbSize
Size of this structure in bytes.
pIssuerCert
Pointer to the CERT_CONTEXT of the issuer of a certificate in the rgpvContext array in the CertVerifyRevocation parameter list.
cCertStore
Number of elements in the rgCertStore array.
rgCertStore
Array of certificate store handles. When used, these stores are searched for issuer certificates.
hCrlStore
Optional store handle. When specified, a handler that uses CRLs can search this store for CRLs. Supported with Windows 2000 and later
pftTimeToUse
Pointer to a FILETIME version of UTC time When specified, the handler must, if possible, determine revocation status relative to the time given. If NULL or the handler can not determine the status relative to the pftTimeToUse value, revocation status can be determined independent of time or relative to current time. Supported with Windows 2000 and later.
dwUrlRetrievalTimeout
This member is used only if CERT_REVOCATION_PARA_HAS_EXTRA_FIELDS is defined. If it is defined, the member must be zeroed out if it is unused. Timeout limit in millliseconds. If zero, the revocation handler's default timeout is used.
fCheckFreshnessTime
This member is used only if CERT_REVOCATION_PARA_HAS_EXTRA_FIELDS is defined. If it is defined, the member must be zeroed out if it is unused. When this flag is TRUE, an attempt is made to retrieve a new CRL if ThisUpdate is greater than or equal to Current Time minus dwFreshness. If this flag is not set, the CRL's NextUpdate time is used.
dwFreshnessTime
This member is used only if CERT_REVOCATION_PARA_HAS_EXTRA_FIELDS is defined. If it is defined, the member must be zeroed out if it is unused. The time in seconds is used to determine whether an attempt will be made to retrieve a new CRL.
pftCurrentTime
This member is used only if CERT_REVOCATION_PARA_HAS_EXTRA_FIELDS is defined. If it is defined, the member must be zeroed out if it is unused. Pointer to a FILETIME structure used in the freshness time check. If this pointer is NULL, the revocation handler uses the current time.
pCrlInfo
This member is used only if CERT_REVOCATION_PARA_HAS_EXTRA_FIELDS is defined. If it is defined, the member must be zeroed out if it is unused. If non-NULL, a CRL revocation handler updates with the base and delta CRL used. The CRL information is only applicable to the last context checked. To access the information in this CRL, CertVerifyRevocation can be called with cContext set to -1.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CertVerifyRevocation


CERT_REVOCATION_STATUS

[This is preliminary documentation and subject to change.]

The CERT_REVOCATION_STATUS structure contains information on the revocation status of the certificate. It is passed to and returned by CertVerifyRevocation. On return from the function, it specifies the status of a revoked or unchecked context.

typedef struct _CERT_REVOCATION_STATUS {
  DWORD                   cbSize;
  DWORD                   dwIndex;
  DWORD                   dwError;
  DWORD                   dwReason;
  BOOL                    fHasFreshnessTime;
  DWORD                   dwFreshnessTime;
} CERT_REVOCATION_STATUS, *PCERT_REVOCATION_STATUS;

Members

cbSize
Size of this structure in bytes.

Upon input to CertVerifyRevocation, cbSize must be set to a size greater than or equal to the size of a CERT_REVOCATION_STATUS structure. Otherwise, CertVerifyRevocation returns FALSE and GetLastError returns E_INVALIDARG.

dwIndex
Specifies an index value for the rgpvContext array passed to CertVerifyRevocation. It is the index of the first context in that array that was revoked or that could not be checked for revocation. For information about the contexts that were not checked, CertVerifyRevocation is called again, specifying a rgpvContext array that contains the unchecked contexts from the original list.
dwError
Specifies the returned error status. This value matches the return value of GetLastError on return from the call to CertVerifyRevocation. See the table in the Return Values section of CertVerifyRevocation for the list of these error values.
dwReason
Specifies the cause of the error. This member is set only if dwError is CRYPT_E_REVOKED. It contains a code that indicates why the context was revoked. It can be one of the following values.
Reason code | Meaning
CRL_REASON_UNSPECIFIED | No reason was specified for revocation.
CRL_REASON_KEY_COMPROMISE | It is known or suspected that the subject's private key or other aspects of the subject validated in the certificate are compromised.
CRL_REASON_CA_COMPROMISE | It is known or suspected that the CA's private key or other aspects of the CA validated in the certificate are compromised.
CRL_REASON_AFFILIATION_CHANGED | The subject's name or other information in the certificate has been modified but there is no cause to suspect that the private key has been compromised.
CRL_REASON_SUPERSEDED | The certificate has been superseded, but there is no cause to suspect that the private key has been compromised.
CRL_REASON_CESSATION_OF_OPERATION | The certificate is no longer needed for the purpose for which it was issued, but there is no cause to suspect that the private key has been compromised.
CRL_REASON_CERTIFICATE_HOLD | The certificate has been placed on hold.

fHasFreshnessTime
Depending on cbSize, this structure can contain this member. If this member is TRUE, it retrieves the revocation information time.
dwFreshnessTime
Depending on cbSize, this structure can contain this member. If present, this member gives the time in seconds between when the CRL should be refreshed.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CertVerifyRevocation


CERT_SIGNED_CONTENT_INFO

The CERT_SIGNED_CONTENT_INFO structure contains encoded content to be signed and a BLOB to hold the signature. The ToBeSigned member is an encoded CERT_INFO, CRL_INFO, CTL_INFO or CERT_REQUEST_INFO.

typedef struct _CERT_SIGNED_CONTENT_INFO {
  CRYPT_DER_BLOB               ToBeSigned;
  CRYPT_ALGORITHM_IDENTIFIER   SignatureAlgorithm;
  CRYPT_BIT_BLOB               Signature;
} CERT_SIGNED_CONTENT_INFO,     *PCERT_SIGNED_CONTENT_INFO;

Members

ToBeSigned
A DER-encoded BLOB that is to be signed.
SignatureAlgorithm
A CRYPT_ALGORITHM_IDENTIFIER structure that contains the signature algorithm type and any associated additional parameters.
Signature
BLOB containing a signed hash of the encoded data.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB, CRYPT_ALGORITHM_IDENTIFIER, CRYPT_BIT_BLOB


CERT_STORE_PROV_FIND_INFO

The CERT_STORE_PROV_FIND_INFO structure is used by many of the store provider callback functions. It contains find criteria for finding a certificate, CRL, or CTL in a certificate store.

typedef struct _CERT_STORE_PROV_FIND_INFO {
  DWORD               cbSize;
  DWORD               dwMsgAndCertEncodingType;
  DWORD               dwFindFlags;
  DWORD               dwFindType;
  const void          *pvFindPara;
} CERT_STORE_PROV_FIND_INFO, *PCERT_STORE_PROV_FIND_INFO;
typedef const CERT_STORE_PROV_FIND_INFO CCERT_STORE_PROV_FIND_INFO,
*PCCERT_STORE_PROV_FIND_INFO;

Members

cbSize
Size of the structure.
dwMsgAndCertEncodingType
Specifies the encoding type used for messages and certificates. The certificate and message encoding types can be combined with a bitwise-OR operation. Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

dwFindFlags
Used with some dwFindType values to modify the search criteria. For most dwFindType values, dwFindFlags is not used and should be set to zero.
dwFindType
Specifies the type of search being made. The search type determines the data type, contents, and the use of pvFindPara. Currently defined dwFindType values and the data type each requires for pvFindPara are as follows.
Value of dwFindType | Value of pvFindPara | Search Criteria
CERT_FIND_ANY | NULL; pvFindPara not used | No search criteria used. Returns the next certificate in the store.
CERT_FIND_CERT_ID | CERT_ID structure | Find the certificate identified by the specified CERT_ID.
CERT_FIND_CTL_USAGE | CTL_USAGE structure | Searches for a certificate having a szOID_ENHANCED_KEY_USAGE extension or a CERT_CTL_PROP_ID that matches the pszUsageIdentifier member of the CTL_USAGE structure.
CERT_FIND_ENHKEY_USAGE CERT_ENHKEY_USAGE structure Searches for a certificate in the store having either an enhanced key usage extension or an enhanced key usage property and a usage identifier that matches the pszUsageIdentifier member in the CERT_ENHKEY_USAGE structure.

A certificate has an enhanced key usage extension if it has a CERT_EXTENSION structure with the pszObjId member set to szOID_ENHANCED_KEY_USAGE. A certificate has an enhanced key usage property if its CERT_ENHKEY_USAGE_PROP_ID identifier is set.

If pvFindPara is NULL or the cUsageIdentifier member of CERT_ENHKEY_USAGE is zero, any certificate that has either the enhanced key usage extension or the enhanced key usage property meets the selection criteria.

If pvFindPara is NULL or the cUsageIdentifier member of the CERT_ENHKEY_USAGE structure is zero, any certificate having enhanced key usage is a match.

If CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG is set in dwFindFlags, certificates without the key usage extension or property are also matches. Setting this flag takes precedence over passing NULL in pvFindPara.

If CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG is set, a match is done only on the key usage extension.

For details on flag modifications to search criteria, see the Remarks section later in this topic.
CERT_FIND_EXISTING | CERT_CONTEXT structure | Searches for a certificate that is an exact match of the specified certificate context.
CERT_FIND_HASH | CRYPT_HASH_BLOB structure | Searches for a certificate with a SHA1 hash that matches the hash in the CRYPT_HASH_BLOB structure.
CERT_FIND_ISSUER_ATTR CERT_RDN structure Search for a certificate with specified issuer attributes that match attributes in the CERT_RDN structure. If these values are set, the function compares attributes of the issuer in a certificate with elements of the CERT_RDN_ATTR array in this CERT_RDN structure. Comparisons iterate through the CERT_RDN_ATTR attributes looking for a match with the certificate's issuer attributes.

If the pszObjId member of CERT_RDN_ATTR is NULL, the attribute object identifier is ignored.

If the dwValueType member of CERT_RDN_ATTR is CERT_RDN_ANY_TYPE, the value type is ignored.

If the pbData member of CERT_RDN_VALUE_BLOB is NULL, any value is a match.

Currently, only an exact, case-sensitive match is supported. For details on Unicode options, see the Remarks section later in this topic. When these values are set, the search is restricted to certificates whose encoding type matches dwMsgAndCertEncodingType.
CERT_FIND_ISSUER_NAME | CERT_NAME_BLOB structure | Search for a certificate with an exact match of the entire issuer name with the name in CERT_NAME_BLOB. The search is restricted to certificates that match the dwMsgAndCertEncodingType.
CERT_FIND_ISSUER_OF CERT_CONTEXT structure Searches for a certificate with an issuer that matches the issuer in CERT_CONTEXT.

Instead of using CertFindCertificateInStore with this value, use the CertGetCertificateChain function.
CERT_FIND_ISSUER_STR | Null-terminated wide (Unicode) string | Search for a certificate containing the specified issuer name string. The certificate's issuer member is converted to a name string of the appropriate type using the appropriate form of CertNameToStr formatted as CERT_SIMPLE_NAME_STR. Then a case-insensitive substring-within-a-string match is performed. When this value is set, the search is restricted to certificates whose encoding type matches dwMsgAndCertEncodingType.
CERT_FIND_KEY_IDENTIFIER | CRYPT_HASH_BLOB structure | Searches for a certificate with a CERT_KEY_IDENTIFIER_PROP_ID property matching the key identifier in CRYPT_HASH_BLOB.
CERT_FIND_KEY_SPEC | DWORD containing a key specification | Searches for a certificate having a CERT_KEY_SPEC_PROP_ID property matching the key specification in pvFindPara.
CERT_FIND_MD5_HASH | CRYPT_HASH_BLOB structure | Searches for a certificate with an MD5 hash that matches the hash in CRYPT_HASH_BLOB.
CERT_FIND_PROPERTY | DWORD containing a property identifier | Searches for a certificate with a property that matches the property identifier specified by the DWORD in pvFindPara.
CERT_FIND_PUBLIC_KEY CERT_PUBLIC_KEY_INFO structure Searches for a certificate with a public key that matches the public key in the CERT_PUBLIC_KEY
_INFO structure.
CERT_FIND_SHA1_HASH | CRYPT_HASH_BLOB structure | Searches for a certificate with a SHA1 hash that matches the hash in the CRYPT_HASH_BLOB structure.
CERT_FIND_SIGNATURE_HASH | CRYPT_HASH_BLOB structure | Searches for a certificate with a signature hash that matches the signature hash in the CRYPT_HASH_BLOB structure.
CERT_FIND_SUBJECT_ATTR CERT_RDN structure Searches for a certificate with specified subject attributes that match attributes in the CERT_RDN structure If RDN values are set, the function compares attributes of the subject in a certificate with elements of the CERT_RDN_ATTR array in this CERT_RDN structure. Comparisons iterate through the CERT_RDN_ATTR attributes looking for a match with the certificate's subject's attributes.

If the pszObjId member of CERT_RDN_ATTR is NULL, the attribute object identifier is ignored.

If the dwValueType member of CERT_RDN_ATTR is CERT_RDN_ANY_TYPE, the value type is ignored.

If the pbData member of CERT_RDN_VALUE_BLOB is NULL, any value is a match.

Currently, only an exact, case-sensitive match is supported.

For details on Unicode options, see the Remarks section later in this topic. When these values are set, the search is restricted to certificates whose encoding type matches dwMsgAndCertEncodingType.
CERT_FIND_SUBJECT_CERT | CERT_INFO structure | Searches for a certificate with both an issuer and a serial number that match the issuer and serial number in the CERT_INFO structure.
CERT_FIND_SUBJECT_NAME | CERT_NAME_BLOB structure | Searches for a certificate with an exact match of the entire subject name with the name in the CERT_NAME_BLOB structure. The search is restricted to certificates that match the value of dwMsgAndCertEncodingType.
CERT_FIND_SUBJECT_STR | NULL-terminated wide (Unicode) string | Searches for a certificate containing the specified subject name string. The certificate's subject member is converted to a name string of the appropriate type using the appropriate form of CertNameToStr formatted as CERT_SIMPLE_NAME_STR. Then a case-insensitive substring-within-a-string match is performed. When this value is set, the search is restricted to certificates whose encoding type matches dwMsgAndCertEncodingType.

Note There are alternate forms of dwFindType value that pass a string in pvFindPara. One form uses a Unicode string, and the other an ASCII string. Values that end in "_W" or without a suffix use Unicode. Values that end with "_A" use ASCII strings.

pvFindPara
Points to a data item or structure to be used with the find type indicated by the value of dwFindType.

Remarks

The dwFindFlags member is used to modify the criteria of some search types.

The CERT_UNICODE_IS_RDN_ATTRS_FLAG dwFindFlags value is used only with the CERT_FIND_SUBJECT_ATTR and CERT_FIND_ISSUER_ATTR values for dwFindType. CERT_UNICODE_IS_RDN_ATTRS_FLAG must be set if the CERT_RDN_ATTR structure pointed to by pvFindPara was initialized with Unicode strings. Before any comparison is made, the string to be matched is converted by using X509_UNICODE_NAME to provide for Unicode comparisons.

The following dwFindFlags values are used only with the CERT_FIND_ENKEY_USAGE value for dwFindType.

Value | Meaning
CERT_FIND_OR_ENHKEY_USAGE_FLAG | The search criteria can be altered by setting one or more flags. By default, if the pszUsageIdentifer member of the CERT_ENHKEY_USAGE structure pointed to by pvFindPara is to be matched, each identifier must be matched to satisfy the search criteria. However, if CERT_FIND_OR_ENHKEY_USAGE_FLAG is set, a match can be made to all identifiers combined by using a bitwise-OR operation; thus, matching any one of the identifiers is sufficient.
CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG | When this flag is set, in addition to usual matches, any certificate that has neither the enhanced key usage extension nor the enhanced key usage property meets the search criteria.
CERT_FIND_NO_ENHKEY_USAGE_FLAG | When this flag is set, only those certificates that have neither an enhanced key usage nor the enhanced key usage property are matches. This flag setting takes precedence over pvFindPara being NULL.
CERT_FIND_VALID_ENHKEY_USAGE_FLAG | When this flag is set, the function only matches those certificates that are valid for the specified usage. By default, in order to match, a certificate must be valid for all usages. CERT_FIND_OR_ENHKEY_USAGE_FLAG can also be set if the certificate only needs to be valid for one of the specified usages. Note that CertGetValidUsages is called to get the certificate's list of valid usages. Only CERT_FIND_OR_ENHKEY_USAGE_FLAG can also apply when CERT_FIND_VALID_ENHKEY_USAGE_FLAG is set.
CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG | When this flag is set, the matching process involves only the extension usage identifiers. If pvFindPara is NULL or the cUsageIdentifier member of the CERT_ENHKEY_USAGE structure pointed to by pvFindPara is zero, any certificate having an enhanced key usage extension is a match. If CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG is also set, any certificate without the enhanced key usage extension is also a match. If CERT_FIND_NO_ENHKEY_USAGE_FLAG is also set, only certificates without the enhanced key usage extension are matches.
CERT_FIND_EXT_PROP_ENHKEY_USAGE_FLAG | When this flag is set, the matching process involves only usage identifiers that are properties. If pvFindPara is NULL or cUsageIdentifier is set to zero, any certificate having an enhanced key usage property is a match. If CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG is also set, any certificate without the enhanced key usage property is also a match. If CERT_FIND_NO_ENHKEY_USAGE_FLAG is set, only certificates without the enhanced key usage property are matches.
CERT_CASE_INSENSITIVE_IS_RDN_ATTRS_FLAG | Used only with CERT_FIND_SUBJECT_ATTR and CERT_FIND_ISSUER-ATTR values of dwFindType. By default, a case-sensitive, exact match is made. If this flag is set, the match is case-insensitive.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wincrypt.h.


CERT_SYSTEM_STORE_INFO

The CERT_SYSTEM_STORE_INFO structure contains information used by functions that work with system stores. Currently, no essential information is contained in this structure.

typedef struct _CERT_SYSTEM_STORE_INFO {
  DWORD               cbSize;
} CERT_SYSTEM_STORE_INFO, *PCERT_SYSTEM_STORE_INFO;

Members

cbSize
Size of this structure in bytes.

Remarks

Currently, no system store information is persisted.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.


CERT_SYSTEM_STORE_RELOCATE_PARA

The CERT_SYSTEM_STORE_RELOCATE_PARA structure contains data to be passed to CertOpenStore when that function's dwFlags parameter is set to CERT_SYSTEM_STORE_RELOCATE_FLAG. It allows the application to specify not only the name of the store to be opened, but also registry hKey information indicating a registry location other than the default location.

typedef struct _CERT_SYSTEM_STORE_RELOCATE_PARA {
  union {
      HKEY                hKeyBase;
      void                *pvBase;
  };
  union {
      void                *pvSystemStore;
      LPCSTR              pszSystemStore;
      LPCWSTR             pwszSystemStore;
  };
} CERT_SYSTEM_STORE_RELOCATE_PARA, *PCERT_SYSTEM_STORE_RELOCATE_PARA;

Members

hKeyBase
Handle to registry hKey.
pvBase
Pointer to a void to allow the system store location's base to be passed in a number of different forms.
pvSystemStore
Pointer to a void to allow the name of the system store to be passed in various forms.
pszSystemStore
A NULL-terminated ASCII string that names the system store.
pwszSystemStore
A NULL-terminated Unicode string that names the system store.

Remarks

The relocate capability is used to access system stores persisted in the Group Policy Template (GPT). For example, the Group Policy Editor's MMC snap-in extension for managing group policy trust lists and certificates uses the GPT's base HKEY to call CertOpenStore.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CertOpenStore


CERT_TEMPLATE_EXT

[This is preliminary documentation and subject to change.]

The CERT_TEMPLATE_EXT structure is a certificate template.

typedef struct _CERT_TEMPLATE_EXT{
    LPSTR               pszObjId;
    DWORD               dwMajorVersion;
    BOOL                fMinorVersion;
    DWORD               dwMinorVersion;
} CERT_TEMPLATE_EXT, *PCERT_TEMPLATE_EXT;

Members

pszObjId
LPSTR object identifier (OID).
dwMajorVersion
DWORD indicating the major version of the template.
fMinorVersion
BOOL flag set to TRUE if there is a minor version number.
dwMinorVersion
DWORD indicating the minor version of the template.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.


CERT_X942_DH_PARAMETERS

The CERT_X942_DH_PARAMETERS structure contains parameters associated with a Diffie/Hellman public key algorithm.

typedef struct _CERT_X942_DH_PARAMETERS {
  CRYPT_UINT_BLOB     p;
  CRYPT_UINT_BLOB     g;
  CRYPT_UINT_BLOB     q;
  CRYPT_UINT_BLOB     j;
  PCERT_X942_DH_VALIDATION_PARAMS
                      pValidationParams;
} CERT_DSS_PARAMETERS, *PCERT_DSS_PARAMETERS;

Members

p
Prime modulus P. The most significant bit of the most significant byte must always be set to 1.
g
Generator G. Must be the same length as p (must be padded with 0x00 bytes if it is less).
q
Prime Q.

A factor of p-1. The most significant bit of the most significant byte must be set to 1.

j
Optional subgroup factor.
pValidationParams
Optional pointer to a CERT_X942_DH_VALIDATION_PARAMS structure. If the cbData member of the q BLOB is zero, all of the members of pValidationParams must be zero.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CERT_X942_DH_VALIDATION_PARAMS

The CERT_X942_DH_VALIDATION_PARAMS structure is optionally pointed to by a member of the CERT_X492_DH_PARAMS structure and contains additional seed information.

typedef struct _CERT_X942_DH_VALIDATION_PARAMS{
  CRYPT_BIT_BLOB     seed;
  DWORD              pgenCounter;
} CERT_942_DH_VALIDATION_PARAMS, *PCERT942_DH_VALIDATION_PARAMS;

Members

seed
CRYPT_UINT_BLOB containing an unsigned seed value.
pgenCounter
DWORD counter.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CMC_ADD_ATTRIBUTES_INFO

[This is preliminary documentation and subject to change.]

The CMC_ADD_ATTRIBUTES_INFO structure contains certificate attributes to be added to a certificate.

typedef struct _CMC_ADD_ATTRIBUTES_INFO{
    DWORD               dwCmcDataReference;
    DWORD               cCertReference;
    DWORD               *rgdwCertReference;
    DWORD               cAttribute;
    PCRYPT_ATTRIBUTE    rgAttribute;
} CMC_ADD_ATTRIBUTES_INFO, *PCMC_ADD_ATTRIBUTES_INFO;

Members

dwCmcDataReference
DWORD data reference number.
cCertReference
Count of elements in the rgdwCertReference array.
rgdwCertReference
Array of certificate reference numbers.
cAttribute
Count of the elements in the rgAttribute array.
rgAttribute
Array of pointers to the CRYPT_ATTRIBUTE certificate attributes to be added.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.


CMC_ADD_EXTENSIONS_INFO

[This is preliminary documentation and subject to change.]

The CMC_ADD_EXTENSIONS_INFO structure contains certificate extension control attributes to be added to a certificate.

typedef struct _CMC_ADD_EXTENSIONS_INFO{
    DWORD               dwCmcDataReference;
    DWORD               cCertReference;
    DWORD               *rgdwCertReference;
    DWORD               cExtension;
    PCERT_EXTENSION     rgExtension;
} CMC_ADD_EXTENSIONS_INFO, *PCMC_ADD_EXTENSIONS_INFO;

Members

dwCmcDataReference
DWORD data reference number.
cCertReference
DWORD count of elements in the rgdwCertReference array.
rgdwCertReference
Array of certificate reference numbers.
cExtension
DWORD count of the elements in the rgExtension array.
rgExtension
Array of pointers to the CERT_EXTENSION certificate extensions to be added.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.


CMC_DATA_INFO

[This is preliminary documentation and subject to change.]

The CMC_DATA_INFO structure provides a means of communicating different pieces of tagged information.

typedef struct _CMC_DATA_INFO {
    DWORD                       cTaggedAttribute;
    PCMC_TAGGED_ATTRIBUTE       rgTaggedAttribute;
    DWORD                       cTaggedRequest;
    PCMC_TAGGED_REQUEST         rgTaggedRequest;
    DWORD                       cTaggedContentInfo;
    PCMC_TAGGED_CONTENT_INFO    rgTaggedContentInfo;
    DWORD                       cTaggedOtherMsg;
    PCMC_TAGGED_OTHER_MSG       rgTaggedOtherMsg;
} CMC_DATA_INFO, *PCMC_DATA_INFO;

Members

cTaggedAttribute
Count of the number of elements in the rgTaggedAttribute member array.
rgTaggedAttribute
Array of CMC_TAGGED_ATTRIBUTE structures.
cTaggedRequest
Count of the number of elements in the rgTaggedRequest member array.
rgTaggedRequest
Array of CMC_TAGGED_REQUEST structures.
cTaggedContentInfo
Count of the number of elements in the rgTaggedContentInfo member array.
rgTaggedContentInfo
Array of CMC_TAGGED_CONTENT_INFO structures.
cTaggedOtherMsg
Count of the number of elements in the rgTaggedOtherMsg member array.
rgTaggedOtherMsg
Array of CMC_TAGGED_OTHER_MSG structures.

Remarks

All tagged arrays are optional.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.


CMC_PEND_INFO

[This is preliminary documentation and subject to change.]

The CMC_PEND_INFO structure is a possible member of a CMC_STATUS_INFO structure.

typedef struct _CMC_PEND_INFO{
    CRYPT_DATA_BLOB          PendToken;
    FILETIME                 PendTime;
} CMC_PEND_INFO, *PCMC_PEND_INFO;

Members

PendToken
BLOB containing the pending request information.
PendTime
FILETIME containing the request.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.


CMC_RESPONSE_INFO

[This is preliminary documentation and subject to change.]

The CMC_RESPONSE_INFO structure provides a means of communicating different pieces of tagged information.

typedef struct _CMC_RESPONSE_INFO {
    DWORD                       cTaggedAttribute;
    PCMC_TAGGED_ATTRIBUTE       rgTaggedAttribute;
    DWORD                       cTaggedContentInfo;
    PCMC_TAGGED_CONTENT_INFO    rgTaggedContentInfo;
    DWORD                       cTaggedOtherMsg;
    PCMC_TAGGED_OTHER_MSG       rgTaggedOtherMsg;
} CMC_RESPONSE_INFO, *PCMC_RESPONSE_INFO;

Members

cTaggedAttribute
Count of the number of elements in the rgTaggedAttribute member array.
rgTaggedAttribute
Array of CMC_TAGGED_ATTRIBUTE structures.
cTaggedContentInfo
Count of the number of elements in the rgTaggedContentInfo member array.
rgTaggedContentInfo
Array of CMC_TAGGED_CONTENT_INFO structures.
cTaggedOtherMsg
Count of the number of elements in the rgTaggedOtherMsg member array.
rgTaggedOtherMsg
Array of CMC_TAGGED_OTHER_MSG structures.

Remarks

All tagged arrays are optional.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.


CMC_STATUS_INFO

[This is preliminary documentation and subject to change.]

The CMC_STATUS_INFO structure contains status information about Certificate Management Messages over CMS.

typedef struct _CMC_STATUS_INFO{
  DWORD               dwStatus;
  DWORD               cBodyList;
  DWORD               *rgdwBodyList;
  LPWSTR              pwsStatusString;
  DWORD               dwOtherInfoChoice;
  union{
    DWORD             dwFailInfo;
    PCMC_PEND_INFO    pPendInfo;
   };
} CMC_STATUS_INFO, *PCMC_STATUS_INFO;

Members

dwStatus
DWORD indicating the status of the message.
dwStatus value | Defined constant | Meaning of return
0 | CMC_STATUS_SUCCESS | Request was granted.
2 | CMC_STATUS_FAILED | Request failed. There is addition information in other parts of the message.
3 | CMC_STATUS_PENDING | Request body part has not been process. Requester must poll again. This value is returned only on certificate requests.
4 | CMC_STATUS_NO_SUPPORT | Requested operation is not supported.
5 | CMC_STATUS_CONFIRM_REQUIRED | Confirmation using the idConfirmCertAcceptance control is required before the certificate can be used.

cBodyList
DWORD count of the elements in the rgdwBodyList array.
rgdwBodyList
DWORD array.
pwsStatusString
Optional string text indicating message status.
dwOtherInfoChoice
DWORD identifying the union member to be used.
dwFailInfo
DWORD member of the union. This member is used if dwOtherInfoChoice is CMC_OTHER_INFO_FAIL_CHOICE. The following table contains values returned for various failures.
Value | Defined constant | Reason for failure
0 | CMC_FAIL_BAD_ALG | Unrecognized or unsupported algorithm.
1 | CMC_FAIL_BAD_MESSAGE_CHECK | Integrity check failed.
2 | CMC_FAIL_BAD_REQUEST | Transaction not permitted or supported.
3 | CMC_FAIL_BAD_TIME | Message time field was not sufficiently close to the system time.
4 | CMC_FAIL_BAD_CERT_ID | No certificate could be identified matching the provided criteria.
5 | CMC_FAIL_UNSUPORTED_EXT | Requested X.509 extension is not supported by the recipient CA.
6 | CMC_FAIL_MUST_ARCHIVE_KEYS | Private key material must be supplied.
7 | CMC_FAIL_BAD_IDENTITY | Identification attribute failed to verify.
8 | CMC_FAIL_POP_REQUIRED | Server requires a POP proof before issuing certificate.
9 | CMC_FAIL_POP_FAILED | POP processing failed.
10 | CMC_FAIL_NO_KEY_REUSE | Server policy does not allow key re-use.
11 | CMC_FAIL_INTERNAL_CA_ERROR | Certificate authority had an internal failure.
12 | CMC_FAIL_TRY_LATER | Request failed for an unknown reason. The request should be reissued later.

pPendInfo
Pointer to the CMC_PEND_INFO structure member of the union. This member is used if dwOtherInfoChoice is CMC_OTHER_INFO_PEND_CHOICE.

Remarks

Additional members of the union may be defined in future versions.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.


CMC_TAGGED_ATTRIBUTE

[This is preliminary documentation and subject to change.]

The CMC_TAGGED_ATTRIBUTE structure is used in the CMC_DATA_INFO and CMC_RESPONSE_INFO structures.

typedef struct _CMC_TAGGED_ATTRIBUTE{
    DWORD                       dwBodyPartID;
    CRYPT_OBJID_BLOB            Attribute;
} CMC_TAGGED_ATTRIBUTE, *PCMC_TAGGED_ATTRIBUTE;

Members

dwBodyPartID
DWORD identifying the tagged attribute.
Attribute
CRYPT_ATTRIBUTE structure containing the attribute.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.


CMC_TAGGED_CERT_REQUEST

[This is preliminary documentation and subject to change.]

The CMC_TAGGED_CERT_REQUEST structure is used in the CMC_TAGGED_REQUEST structure.

typedef struct _CMC_TAGGED_CERT_REQUEST{
    DWORD                       dwBodyPartID;
    CRYPT_DER_BLOB              SignedCertRequest;
} CMC_TAGGED_CERT_REQUEST, *PCMC_TAGGED_CERT_REQUEST;

Members

dwBodyPartID
DWORD identifying the tagged certificate request.
SignedCertRequest
CRYPT_DER_BLOB containing a signed request for a certificate.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.


CMC_TAGGED_CONTENT_INFO

[This is preliminary documentation and subject to change.]

The CMC_TAGGED_CONTENT_INFO structure is used in the CMC_DATA_INFO and CMC_RESPONSE_INFO structures.

typedef struct _CMC_TAGGED_CONTENT_INFO{
    DWORD                       dwBodyPartID;
    CRYPT_DER_BLOB              EncodedContentInfo;
} CMC_TAGGED_CONTENT_INFO, *PCMC_TAGGED_CONTENT_INFO;

Members

dwBodyPartID
DWORD identifying the tagged other message.
EncodedContentInfo
CRYPT_DER_BLOB containing the encoded content information.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.


CMC_TAGGED_OTHER_MSG

[This is preliminary documentation and subject to change.]

The CMC_TAGGED_OTHER_MSG structure is used in the CMC_DATA_INFO and CMC_RESPONSE_INFO structures.

typedef struct _CMC_TAGGED_OTHER_MSG{
    DWORD                       dwBodyPartID;
    LPSTR                       pszObjId;
    CRYPT_OBJID_BLOB            Value;
} CMC_TAGGED_OTHER_MSG, *PCMC_TAGGED_OTHER_MSG;

Members

dwBodyPartID
DWORD identifying the tagged other message.
pszObjId
Object identifier (OID) of the other message.
Value
CRYPT_OBJID_BLOB structure containing the encoded other message information.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.


CMC_TAGGED_REQUEST

[This is preliminary documentation and subject to change.]

The CMC_TAGGED_REQUEST structure is used in the CMC_DATA_INFO structures to request a certificate. In the future, it may be used for other requests.

typedef struct _CMC_TAGGED_REQUEST{
    DWORD                       dwTaggedRequestChoice;
    union{
      PCMC_TAGGED_CERT_REQUEST  pTaggedCertRequest;
      };
} CMC_TAGGED_REQUEST, *PCMC_TAGGED_REQUEST;

Members

dwTaggedRequestChoice
DWORD identifying the union member to be used.
pTaggedCertRequest
Pointer to a CMC_TAGGED_CERT_REQUEST structure containing the signed certificate request.

Remarks

Additional members of the union may be defined in future versions.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.


CRL_CONTEXT

The CRL_CONTEXT structure contains both the encoded and decoded representations of a CRL. CRL contexts returned by any CryptoAPI function must be freed by calling the CertFreeCRLContext function.

typedef struct _CRL_CONTEXT {
  DWORD           dwCertEncodingType;
  BYTE*           pbCrlEncoded;
  DWORD           cbCrlEncoded;
  PCRL_INFO       pCrlInfo;
  HCERTSTORE      hCertStore;
} CRL_CONTEXT,     *PCRL_CONTEXT;
typedef const CRL_CONTEXT *PCCRL_CONTEXT;

Members

dwCertEncodingType
Type of encoding used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
     X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pbCrlEncoded
Pointer to the encoded CRL information.
cbCrlEncoded
Size, in bytes, of the encoded CRL information.
pCrlInfo
Pointer to CRL_INFO structure containing the CRL information.
hCertStore
Handle to the certificate store.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRL_INFO, CRYPT_SIGN_MESSAGE_PARA, CertAddCRLContextToStore, CertAddEncodedCRLToStore, CertCreateCRLContext, CertFreeCRLContext, CertGetCRLFromStore


CRL_ENTRY

The CRL_ENTRY structure contains information on a single revoked certificate. It is a member of a CRL_INFO structure.

typedef struct _CRL_ENTRY {
  CRYPT_INTEGER_BLOB    SerialNumber;
  FILETIME              RevocationDate;
  DWORD                 cExtension;
  PCERT_EXTENSION       rgExtension;
} CRL_ENTRY,             *PCRL_ENTRY;

Members

SerialNumber
BLOB containing the serial number of a revoked certificate.

Leading 0x00 or 0xFF bytes are removed. See CertCompareIntegerBlob.

RevocationDate
Date that the certificate was revoked. Time is UTC-time encoded as a eight-byte date/time precise to seconds with a two digit year (that is, YYMMDDHHMMSS plus 2 bytes). The date is interpreted as a date between the years 1968 and 2067.
cExtension
Number of elements in the rgExtension array of extensions.
rgExtension
Array of pointers to CERT_EXTENSION structures, each providing information about the revoked certificate.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB, CERT_EXTENSION, CRL_INFO


CRL_INFO

The CRL_INFO structure containing the information of a certificate revocation list (CRL).

typedef struct _CRL_INFO {
  DWORD                        dwVersion;
  CRYPT_ALGORITHM_IDENTIFIER   SignatureAlgorithm;
  CERT_NAME_BLOB               Issuer;
  FILETIME                     ThisUpdate;
  FILETIME                     NextUpdate;
  DWORD                        cCRLEntry;
  PCRL_ENTRY                   rgCRLEntry;
  DWORD                        cExtension;
  PCERT_EXTENSION              rgExtension;
} CRL_INFO,                     *PCRL_INFO;

Members

dwVersion
Version number of the CRL. Currently defined version numbers are shown in the following table.
Certificate Version Name | Value
CRL_V1 | version 1
CRL_V2 | version 2

SignatureAlgorithm
CRYPT_ALGORITHM_IDENTIFIER structure that contains the object identifier (OID) of a signature algorithm and any associated additional parameters.
Issuer
BLOB containing an encoded certificate issuer's name.
ThisUpdate
Indication of the date and time of the CRL's published. If the time is after 1950 and before 2050, it is UTC-time encoded as an 8-byte date/time precise to seconds with a 2-digit year (that is, YYMMDDHHMMSS plus 2 bytes). Otherwise, it is generalized-time encoded as an 8-byte year precise to milliseconds with a 4-byte year.
NextUpdate
Indication of the date and time for the CRL's next available scheduled update. If the time is after 1950 and before 2050, it is UTC-time encoded as an 8-byte date/time precise to seconds with a 2-digit year (that is, YYMMDDHHMMSS plus 2 bytes). Otherwise, it is generalized-time encoded as an 8-byte date time precise to milliseconds with a 4-byte year.
cCRLEntry
Number of elements in the rgCRLEntry array.
rgCRLEntry
Array of pointers to CRL_ENTRY structures. Each of these structures represents a revoked certificate.
cExtension
Number of elements in the rgExtension array.
rgExtension
Array of pointers to CERT_EXTENSION structures, each holding information about the CRL.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB, CERT_EXTENSION, CRL_ENTRY, CRYPT_ALGORITHM_IDENTIFIER, CertVerifyCRLRevocation, CryptSignAndEncodeCertificate


CRL_ISSUING_DIST_POINT

[This is preliminary documentation and subject to change.]

The CRL_ISSUING_DIST_POINT structure contains information about the kinds of certificates listed in a CRL.

typedef struct _CRL_ISSUING_DIST_POINT{
    CRL_DIST_POINT_NAME     DistPointName;
    BOOL                    fOnlyContainsUserCerts;
    BOOL                    fOnlyContainsCACerts;
    CRYPT_BIT_BLOB          OnlySomeReasonFlags; // OPTIONAL
    BOOL                    fIndirectCRL;
} CRL_ISSUING_DIST_POINT, *PCRL_ISSUING_DIST_POINT;

Members

DistPointName
Optional CRL_DIST_POINT_NAME member.
fOnlyContainsUserCerts
BOOL flag. TRUE if only user certificates are contained in the CRL.
fOnlyContainsCACerts
BOOL flag. TRUE if only CA certificates are contained in the CRL.
OnlySomeReasonFlags
Optional CRYPT_BIT_BLOB with bits indicating some reasons for certificate revocation.
fIndirectCRL
BOOL flag. TRUE if this is an indirect CRL.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.


CROSS_CERT_DIST_POINTS_INFO

[This is preliminary documentation and subject to change.]

The CROSS_CERT_DIST_POINTS_INFO structure provides information used to update dynamic cross certificates.

typedef struct _CROSS_CERT_DIST_POINTS_INFO {
    DWORD                   dwSyncDeltaTime;
    DWORD                   cDistPoint;
    PCERT_ALT_NAME_INFO     rgDistPoint;
} CROSS_CERT_DIST_POINTS_INFO, *PCROSS_CERT_DIST_POINTS_INFO;

Members

dwSyncDeltaTime
DWORD indicating seconds between synchronization. If this member is zero, the cline default synchronization time is used.
cDistPoint
Count of the number of elements in the rgDistPoint member array.
rgDistPoint
Array of CERT_ALT_NAME_INFO structures for distribution points for updating cross certificates.

Requirements

Windows NT/2000 or later: Requires Windows Whistler.
Windows 95/98/Me: Unsupported.


CRYPT_ALGORITHM_IDENTIFIER

The CRYPT_ALGORITHM_IDENTIFIER structure specifies an algorithm. The structure includes the object identifier (OID) of the algorithm and any needed parameters for that algorithm. The parameters contained in its CRYPT_OBJID_BLOB are encoded.

typedef struct _CRYPT_ALGORITHM_IDENTIFIER {
  LPSTR                          pszObjId;
  CRYPT_OBJID_BLOB               Parameters;
} CRYPT_ALGORITHM_IDENTIFIER,     *PCRYPT_ALGORITHM_IDENTIFIER;

Members

pszObjId
Object identifier (OID) of an algorithm. Can be any of the following values in the table.
OID | Remark
szOID_RSA | "1.2.840.113549"
szOID_PKCS | "1.2.840.113549.1"
szOID_RSA_HASH | "1.2.840.113549.2"
szOID_RSA_ENCRYPT | "1.2.840.113549.3"
szOID_PKCS_1 | "1.2.840.113549.1.1"
szOID_PKCS_2 | "1.2.840.113549.1.2"
szOID_PKCS_3 | "1.2.840.113549.1.3"
szOID_PKCS_4 | "1.2.840.113549.1.4"
szOID_PKCS_5 | "1.2.840.113549.1.5"
szOID_PKCS_6 | "1.2.840.113549.1.6"
szOID_PKCS_7 | "1.2.840.113549.1.7"
szOID_PKCS_8 | "1.2.840.113549.1.8"
szOID_PKCS_9 | "1.2.840.113549.1.9"
szOID_PKCS_10 | "1.2.840.113549.1.10"
szOID_PKCS_12 | "1.2.840.113549.1.12"
szOID_RSA_MD2 | "1.2.840.113549.1.1.2"
szOID_RSA_MD4 | "1.2.840.113549.1.1.3"
szOID_RSA_MD5 | "1.2.840.113549.1.1.4"
szOID_RSA_RSA | "1.2.840.113549.1.1.1"
szOID_RSA_MD2RSA | "1.2.840.113549.1.1.2"
szOID_RSA_MD4RSA | "1.2.840.113549.1.1.3"
szOID_RSA_MD5RSA | "1.2.840.113549.1.1.4"
szOID_RSA_SHA1RSA | "1.2.840.113549.1.1.5"
szOID_RSA_SETOAEP_RSA | "1.2.840.113549.1.1.5"
szOID_RSA_DH | "1.2.840.113549.1.3.1"
szOID_RSA_data | "1.2.840.113549.1.7.1"
szOID_RSA_signedData | "1.2.840.113549.1.7.2"
szOID_RSA_envelopedData | "1.2.840.113549.1.7.3"
szOID_RSA_signEnvData | "1.2.840.113549.1.7.4"
szOID_RSA_digestedData | "1.2.840.113549.1.7.5"
szOID_RSA_hashedData | "1.2.840.113549.1.7.5"
szOID_RSA_encryptedData | "1.2.840.113549.1.7.6"
szOID_RSA_emailAddr | "1.2.840.113549.1.9.1"
szOID_RSA_unstructName | "1.2.840.113549.1.9.2"
szOID_RSA_contentType | "1.2.840.113549.1.9.3"
szOID_RSA_messageDigest | "1.2.840.113549.1.9.4"
szOID_RSA_signingTime | "1.2.840.113549.1.9.5"
szOID_RSA_counterSign | "1.2.840.113549.1.9.6"
szOID_RSA_challengePwd | "1.2.840.113549.1.9.7"
szOID_RSA_unstructAddr | "1.2.840.113549.1.9.8"
szOID_RSA_extCertAttrs | "1.2.840.113549.1.9.9"
szOID_RSA_SMIMECapabilities | "1.2.840.113549.1.9.15"
szOID_RSA_preferSignedData | "1.2.840.113549.1.9.15.1"
szOID_RSA_RC2CBC | "1.2.840.113549.3.2"
szOID_RSA_RC4 | "1.2.840.113549.3.4"
szOID_RSA_DES_EDE3_CBC | "1.2.840.113549.3.7"
szOID_RSA_RC5_CBCPad | "1.2.840.113549.3.9"
szOID_ANSI_x942 | "1.2.840.10046"
szOID_ANSI_x942_DH | "1.2.840.10046.2.1"
szOID_X957 | "1.2.840.10040"
szOID_X957_DSA | "1.2.840.10040.4.1"
szOID_DATA STRUCTURE | "1.2.840.10040.4.3"
szOId_DS | "2.5"
szOID_DSALG | "2.5.8"
szOID_DSALG_CRPT | "2.5.8.1"
szOID_DSALG_HASH | "2.5.8.2"
szOID_DSALG_SIGN | "2.5.8.3"
szOID_DSALG_RSA | "2.5.8.1.1"
szOID_OIW | "1.3.14"
szOID_OIWSEC | "1.3.14.3.2"
szOID_OIWSEC_md4RSA | "1.3.14.3.2.2"
szOID_OIWSEC_md5RSA | "1.3.14.3.2.3"
szOID_OIWSEC_md4RSA2 | "1.3.14.3.2.4"
szOID_OIWSEC_desECB | "1.3.14.3.2.6"
szOID_OIWSEC_desCBC | "1.3.14.3.2.7"
szOID_OIWSEC_desOFB | "1.3.14.3.2.8"
szOID_OIWSEC_desCFB | "1.3.14.3.2.9"
szOID_OIWSEC_desMAC | "1.3.14.3.2.10"
szOID_OIWSEC_rsaSign | "1.3.14.3.2.11"
szOID_OIWSEC_dsa | "1.3.14.3.2.12"
szOID_OIWSEC_shaDSA | "1.3.14.3.2.13"
szOID_OIWSEC_mdc2RSA | "1.3.14.3.2.14"
szOID_OIWSEC_shaRSA | "1.3.14.3.2.15"
szOID_OIWSEC_dhCommMod | "1.3.14.3.2.16"
szOID_OIWSEC_desEDE | "1.3.14.3.2.17"
szOID_OIWSEC_sha | "1.3.14.3.2.18"
szOID_OIWSEC_mdc2 | "1.3.14.3.2.19"
szOID_OIWSEC_dsaComm | "1.3.14.3.2.20"
szOID_OIWSEC_dsaCommSHA | "1.3.14.3.2.21"
szOID_OIWSEC_rsaXchg | "1.3.14.3.2.22"
szOID_OIWSEC_keyHashSeal | "1.3.14.3.2.23"
szOID_OIWSEC_md2RSASign | "1.3.14.3.2.24"
szOID_OIWSEC_md5RSASign | "1.3.14.3.2.25"
szOID_OIWSEC_sha1 | "1.3.14.3.2.26"
szOID_OIWSEC_dsaSHA1 | "1.3.14.3.2.27"
szOID_OIWSEC_dsaCommSHA1 | "1.3.14.3.2.28"
szOID_OIWSEC_sha1RSASign | "1.3.14.3.2.29"
szOID_OIWDIR | "1.3.14.7.2"
szOID_OIWDIR_CRPT | "1.3.14.7.2.1"
szOID_OIWDIR_HASH | "1.3.14.7.2.2"
szOID_OIWDIR_SIGN | "1.3.14.7.2.3"
szOID_OIWDIR_md2 | "1.3.14.7.2.2.1"
szOID_OIWDIR_md2RSA | "1.3.14.7.2.3.1"
szOID_INFOSEC | "2.16.840.1.101.2.1"
szOID_INFOSEC_sdnsSignature | "2.16.840.1.101.2.1.1.1"
szOID_INFOSEC_mosaicSignature | "2.16.840.1.101.2.1.1.2"
szOID_INFOSEC_sdnsConfidentiality | "2.16.840.1.101.2.1.1.3"
szOID_INFOSEC_mosaicConfidentiality | "2.16.840.1.101.2.1.1.4"
szOID_INFOSEC_sdnsIntegrity | "2.16.840.1.101.2.1.1.5"
szOID_INFOSEC_mosaicIntegrity | "2.16.840.1.101.2.1.1.6"
szOID_INFOSEC_sdnsTokenProtection | "2.16.840.1.101.2.1.1.7"
szOID_INFOSEC_mosaicTokenProtection | "2.16.840.1.101.2.1.1.8"
szOID_INFOSEC_sdnsKeyManagement | "2.16.840.1.101.2.1.1.9"
szOID_INFOSEC_mosaicKeyManagement | "2.16.840.1.101.2.1.1.10"
szOID_INFOSEC_sdnsKMandSig | "2.16.840.1.101.2.1.1.11"
szOID_INFOSEC_mosaicKMandSig | "2.16.840.1.101.2.1.1.12"
szOID_INFOSEC_SuiteASignature | "2.16.840.1.101.2.1.1.13"
szOID_INFOSEC_SuiteAConfidentiality | "2.16.840.1.101.2.1.1.14"
szOID_INFOSEC_SuiteAIntegrity | "2.16.840.1.101.2.1.1.15"
szOID_INFOSEC_SuiteATokenProtection | "2.16.840.1.101.2.1.1.16"
szOID_INFOSEC_SuiteAKeyManagement | "2.16.840.1.101.2.1.1.17"
szOID_INFOSEC_SuiteAKMandSig | "2.16.840.1.101.2.1.1.18"
szOID_INFOSEC_mosaicUpdatedSig | "2.16.840.1.101.2.1.1.19"
szOID_INFOSEC_mosaicKMandUpdSig | "2.16.840.1.101.2.1.1.20"
szOID_INFOSEC_mosaicUpdatedInteg | "2.16.840.1.101.2.1.1.21"

Parameters
BLOB providing encoded algorithm specific values. In many cases, there are no parameters. This is indicated by setting the cbData member of the Parameters BLOB to zero.

The following table lists algorithms that have encoded parameters. For details, see Constants for CryptEncodeObject and CryptDecodeObject.
Algorithm name OID | Predefined constant
szOID_OIWSEC_dsa | X509_DSS_PARAMETERS
szOID_RSA_RC2CBC | PKCS_RC2_CBC_PARAMETERS
szOID_OIWSEC_desCBC | X509_OCTET_STRING
szOID_RSA_DES_EDE3_CBC | X509_OCTET_STRING
szOID_RSA_RC4 | X509_OCTET_STRING

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

ALG_ID, CRYPTOAPI_BLOB, CERT_INFO, CERT_PUBLIC_KEY_INFO, CERT_SIGNED_CONTENT_INFO, CMSG_ENVELOPED_ENCODE_INFO, CMSG_HASHED_ENCODE_INFO, CMSG_SIGNER_ENCODE_INFO, CMSG_SIGNER_INFO, CRL_INFO, CRYPT_ENCRYPT_MESSAGE_PARA, CRYPT_HASH_MESSAGE_PARA, CRYPT_SIGN_MESSAGE_PARA, CryptMsgGetParam


CRYPT_ATTRIBUTE_TYPE_VALUE

The CRYPT_ATTRIBUTE_TYPE_VALUE structure contains a single attribute value. The Value's CRYPT_OBJID_BLOB is encoded.

typedef struct _CRYPT_ATTRIBUTE_TYPE_VALUE {
  LPSTR                       pszObjId;
  CRYPT_OBJID_BLOB            Value;
} CRYPT_ATTRIBUTE_TYPE_VALUE,  *PCRYPT_ATTRIBUTE_TYPE_VALUE;

Members

pszObjId
Object identifier (OID) that specifies the attribute type data contained in the Value BLOB.
Value
BLOB containing the encoded attribute. The cbData member of the CRYPTOAPI_BLOB structure indicates the length of the pbData member. The pbData member contains the attribute information

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB, CERT_ALT_NAME_ENTRY


CRYPT_ATTRIBUTE

The CRYPT_ATTRIBUTE structure specifies an attribute having one or more values.

typedef struct _CRYPT_ATTRIBUTE {
  LPSTR            pszObjId;
  DWORD            cValue;
  PCRYPT_ATTR_BLOB rgValue;
} CRYPT_ATTRIBUTE,  *PCRYPT_ATTRIBUTE;

Members

pszObjId
Object identifier (OID) specifying the type of data contained in the rgValue array.
cValue
Number of elements in the rgValue array.
rgValue
Array of pointers to CRYPTOAPI_BLOB structures The cbData member of the CRYPTOAPI_BLOB structure indicates the length of the pbData member. The pbData member contains the attribute information.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB, CERT_REQUEST_INFO, CMSG_SIGNER_ENCODE_INFO, CRYPT_ATTRIBUTES, CRYPT_SIGN_MESSAGE_PARA, CRYPT_TIME_STAMP_REQUEST_INFO, CertFindAttribute


CRYPT_ATTRIBUTES

The CRYPT_ATTRIBUTES structure contains an array of attributes.

typedef struct _CRYPT_ATTRIBUTES {
  DWORD              cAttr;
  PCRYPT_ATTRIBUTE   rgAttr;
} CRYPT_ATTRIBUTES,   *PCRYPT_ATTRIBUTES
  CMSG_ATTR;

Members

cAttr
Number of elements in the rgAttr array.
rgAttr
Array of CRYPT_ATTRIBUTE structures.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CMSG_SIGNER_INFO, CRYPT_ATTRIBUTE, CryptMsgGetParam


CRYPT_BIT_BLOB

The CRYPT_BIT_BLOB structure contains an array of bytes. In a CRYPT_BIT_BLOB the last byte in the array can contain zero to seven unused bits. Therefore, the number of meaningful bits in the pbData member is cbData * 8 – cUnusedBits.

typedef struct _CRYPT_BIT_BLOB {
  DWORD             cbData;
  BYTE*             pbData;
  DWORD             cUnusedBits;
} CRYPT_BIT_BLOB,    *PCRYPT_BIT_BLOB;

Members

cbData
Number of bytes in the pbData array of bytes.
pbData
Pointer to a block of data bytes.
cUnusedBits
Number of unused bits in the last byte of the array.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CERT_BASIC_CONSTRAINTS_INFO, CERT_INFO, CERT_KEY_ATTRIBUTES_INFO, CERT_KEY_USAGE_RESTRICTION_INFO, CERT_PUBLIC_KEY_INFO, CERT_SIGNED_CONTENT_INFO


CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY

The CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY structure contains information representing the Netscape certificate sequence of certificates.

A Netscape certificate sequence of certificates can be created by setting the pszObjId member to szOID_NETSCAPE_CERT_SEQUENCE and supplying DER-encoded certificates in rgValue.

typedef struct _CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY {
  LPSTR               pszObjId;
  DWORD               cValue;
  PCRYPT_DER_BLOB     rgValue;
} CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY, *PCRYPT_CONTENT_INFO_SEQUENCE_OF_ANY;

Members

pszObjId
Object identifier (OID) specifying the type of data contained in the rgValue array.
cValue
Number of elements in the rgValue array.
rgValue
Array of pointers to CRYPT_DER_BLOB structures. (See CRYPTOAPI_BLOB.)

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.


CRYPT_CONTENT_INFO

The CRYPT_CONTENT_INFO structure contains data encoded in the PKCS #7 ContentInfo data format.

typedef struct _CRYPT_CONTENT_INFO {
  LPSTR               pszObjId;
  CRYPT_DER_BLOB      Content;
} CRYPT_CONTENT_INFO, *PCRYPT_CONTENT_INFO;

Members

pszObjId
Object identifier (OID) of the type of data contained in the Content member. ContentType in PKCS7 defines a set of predefined OIDs. However, additional OIDs can be defined and used.
Content
The data encoded in the PKCS7 ContentInfo data format.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.


CRYPT_KEY_PROV_INFO

The CRYPT_KEY_PROV_INFO structure contains fields that are passed as the arguments to CryptAcquireContext to acquire a handle to a particular key container within a particular cryptographic service provider (CSP), or to create or destroy a key container.

typedef struct _CRYPT_KEY_PROV_INFO {
  LPWSTR                 pwszContainerName;
  LPWSTR                 pwszProvName;
  DWORD                  dwProvType;
  DWORD                  dwFlags;
  DWORD                  cProvParam;
  PCRYPT_KEY_PROV_PARAM  rgProvParam;
  DWORD                  dwKeySpec;
} CRYPT_KEY_PROV_INFO,    *PCRYPT_KEY_PROV_INFO;

Members

pwszContainerName
String naming a key container within a particular CSP.
pwszProvName
String that names a CSP.
dwProvType
CSP type. The dwProvType values are as follows:

PROV_RSA_FULL
PROV_RSA_SIG
PROV_DSS
PROV_FORTEZZA
PROV_MS_EXCHANGE
PROV_SSL
PROV_RSA_SCHANNEL
PROV_DSS_DH
PROV_DH_SCHANNEL

dwFlags
Flags value indicating whether a key container is to be created or destroyed, and whether an application is allowed access to a key container.

The following flags are defined and must not collide with any CryptAcquireContext dwFlags definitions.
Flag value | Description
CERT_SET_KEY_PROV_HANDLE_PROP_ID | Enables the handle to the key provider to be kept open for subsequent calls to the cryptographic functions.
CERT_SET_KEY_CONTEXT_PROP_ID | Enables the handle to the key provider to be kept open for subsequent calls to the cryptographic functions.

See CryptAcquireContext for the list of flags passed through. The above flags are cleared before CryptAcquireContext is called. The cryptographic functions CryptDecryptMessage, CryptSignMessage, CryptDecryptAndVerifyMessageSignature, and CryptSignAndEncryptMessage, internally perform CryptAcquireContext operations using the CRYPT_KEY_PROV_INFO from a certificate. When the CERT_SET_KEY_CONTEXT_PROP_ID or CERT_SET_KEY_PROV_HANDLE_PROP_ID flag is set, these cryptographic functions then can call CertSetCertificateContextProperty (CERT_KEY_CONTEXT_PROP_ID). This call enables the handle to the key provider to be kept open for subsequent calls to the cryptographic functions mentioned that use that same certificate, which eliminates the need to perform another CryptAcquireContext, improving efficiency. Also, since some providers can require that a password be entered for calls to CryptAcquireContext, it is desirable for applications to minimize the number of CryptAcquireContext calls made. Handles to key providers that were kept open are automatically released when the store is closed.

For example, consider an e-mail application where five encrypted messages have been received, all encrypted with the public key from the same certificate. If the handle to the key provider is kept open after the first message is processed, calls to CryptAcquireContext are not required for the four remaining messages.

cProvParam
Number of elements in the rgProvParam array.
rgProvParam
Array of pointers to CRYPT_KEY_PROV_PARAM structures.
dwKeySpec
The specification of the private key to retrieve.

The following dwKeySpec values are defined for the default provider.
Value | Meaning
AT_KEYEXCHANGE | Keys used to encrypt/decrypt session keys.
AT_SIGNATURE | Keys used to create and verify digital signatures.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPT_KEY_PROV_PARAM, CertGetCertificateContextProperty, CertSetCertificateContextProperty


CRYPT_KEY_PROV_PARAM

The CRYPT_KEY_PROV_PARAM structure contains data to be passed as the arguments to CryptSetProvParam. This structure is pointed to by the elements of the rgProvParam array in the CRYPT_KEY_PROV_INFO structure.

typedef struct _CRYPT_KEY_PROV_PARAM {
  DWORD           dwParam;
  BYTE*           pbData;
  DWORD           cbData;
  DWORD           dwFlags;
} CRYPT_KEY_PROV_PARAM, *PCRYPT_KEY_PROV_PARAM;

Members

dwParam
Number of the parameter to set. See CryptSetProvParam for a list of values.
pbData
Pointer to an array of bytes.
cbData
Size in bytes of pbData.
dwFlags
This member is reserved for future use and is zero.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPT_KEY_PROV_INFO


CRYPT_SEQUENCE_OF_ANY

The CRYPT_SEQUENCE_OF_ANY structure contains an arbitrary list of encoded BLOBs.

typedef struct _CRYPT_SEQUENCE_OF_ANY {
  DWORD                 cValue;
  PCRYPT_DER_BLOB       rgValue;
} CRYPT_SEQUENCE_OF_ANY, *PCRYPT_SEQUENCE_OF_ANY;

Members

cValue
Number of elements in the rgValue array.
rgValue
Array of CRYPT_DER_BLOB.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.


CRYPT_TIME_STAMP_REQUEST_INFO

The CRYPT_TIME_STAMP_REQUEST_INFO structure is used for time stamping. To add an authenticated attribute when signing an executable file to verify the date and time of the signature, a signed time stamp is requested from a time stamp server. The CRYPT_TIME_STAMP_REQUEST_INFO structure is used to get a time stamp. It contains the signature bits of the material being time stamped in the Content field.

typedef struct _CRYPT_TIME_STAMP_REQUEST_INFO {
  LPSTR                   pszTimeStampAlgorithm;   // pszObjId
  LPSTR                   pszContentType;          // pszObjId
  CRYPT_OBJID_BLOB        Content;
  DWORD                   cAttribute;
  PCRYPT_ATTRIBUTE        rgAttribute;
} CRYPT_TIME_STAMP_REQUEST_INFO, *PCRYPT_TIME_STAMP_REQUEST_INFO;

Members

pszTimeStampAlgorithm
Object identifier (OID) specifying the desired format of the time stamp, usually UTC.
pszContentType
OID of the Content Type of the content, usually DATA.
Content
BLOB containing the encoded signature bits of the material being time stamped.
cAttribute
Number of elements in the rgAttribute array.
rgAttribute
Array of pointers to CRYPT_ATTRIBUTE structures, each holding an encoded attribute.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB, CRYPT_ATTRIBUTE


CRYPT_X942_OTHER_INFO

The CRYPT_X942_OTHER_INFO structure contains additional key generation information.

typedef struct _CRYPT_X942_OTHER_INFO{
  LPSTER  pszContentEncryptionObjId;
  BYTE    rgbCount[CRYPT_X942_COUNTER_BYTE_LENGTH];
  BYTE    rgbKeyLength[CRYPT_X942_KEY_LENGTH_BYTE_LENGTH];
  CRYPT_DATA_BLOB
          PubInfo;
} CRYPT_X942_OTHER_INFO, *PCRYPT_X942_OTHER_INFO;

Members

pszContentEncryptionObjId
OID of the content encryption algorithm.
rgbCount
Array of BYTES of length CRYPT_X942_COUNTER_BYTE_LENGTH. The value is stored in little-endian order.
rgbKeyLength
Array of BYTES of length RYPT_X942_KEY_LENGTH_BYTE_LENGTH. The value is stored in little-endian order.
PubInfo
Optional CRYPT_DATA_BLOB for additional information.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CTL_ANY_SUBJECT_INFO

The CTL_ANY_SUBJECT_INFO structure contains a SubjectAlgorithm to be matched in the CTL and the SubjectIdentifier to be matched in one of the CTL entries in calls to CertFindSubjectInCTL.

typedef struct _CTL_ANY_SUBJECT_INFO {
  CRYPT_ALGORITHM_IDENTIFIER  SubjectAlgorithm;
  CRYPT_DATA_BLOB             SubjectIdentifier;
} CTL_ANY_SUBJECT_INFO, *PCTL_ANY_SUBJECT_INFO;

Members

SubjectAlgorithm
CRYPT_ALGORITHM_IDENTIFIER structure containing the object identifier (OID) of an algorithm type and any associated additional parameters. The pszObjId can be set to NULL to exclude a SubjectAlgorithm comparison.
SubjectIdentifier
BLOB containing a unique identifier of the subject.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB, CRYPT_ALGORITHM_IDENTIFIER, CTL_FIND_SUBJECT_PARA, CertFindCTLInStore, CertFindSubjectInCTL


CTL_CONTEXT

The CTL_CONTEXT structure contains both the encoded and decoded representations of a CTL. It also contains an opened HCRYPTMSG handle to the decoded, cryptographic-signed message containing the CTL_INFO as its inner content.

CryptoAPI low-level message functions can be used to extract additional signer information.

A CTL_CONTEXT returned by any CryptoAPI function must be freed by calling the CertFreeCTLContext function.

typedef struct _CTL_CONTEXT {
  DWORD           dwMsgAndCertEncodingType;
  BYTE*           pbCtlEncoded;
  DWORD           cbCtlEncoded;
  PCTL_INFO       pCtlInfo;
  HCERTSTORE      hCertStore;
  HCRYPTMSG       hCryptMsg;
  BYTE*           pbCtlContent;
  DWORD           cbCtlContent;
} CTL_CONTEXT,     *PCTL_CONTEXT;
typedef const CTL_CONTEXT *PCCTL_CONTEXT;

Members

dwMsgAndCertEncodingType
Type of encoding used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
     X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pbCtlEncoded
Pointer to the encoded CTL.
cbCtlEncoded
Size, in bytes, of the encoded CTL.
pCtlInfo
Pointer to CTL_INFO structure contain the CTL information.
hCertStore
Handle to the certificate store.
hCryptMsg
Open HCRYPTMSG handle to a decoded, cryptographic-signed message containing the CTL_INFO as its inner content.
pbCtlContent
The encoded inner content of the signed message.
cbCtlContent
Count, in bytes, of pbCtlContent.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CTL_INFO, CertAddCTLContextToStore, CertAddEncodedCTLToStore, CertCreateCTLContext, CertEnumCTLsInStore, CertFindCTLInStore, CertFindSubjectInCTL, CertFreeCTLContext, CryptMsgGetAndVerifySigner, CryptMsgSignCTL


CTL_ENTRY

The CTL_ENTRY structure is an element of a Certificate Trust List (CTL).

typedef struct _CTL_ENTRY {
  CRYPT_DATA_BLOB     SubjectIdentifier;   // For example, its hash
  DWORD               cAttribute;
  PCRYPT_ATTRIBUTE    rgAttribute;         // OPTIONAL
} CTL_ENTRY, *PCTL_ENTRY;

Members

SubjectIdentifier
BLOB containing a unique identifier of a subject. It can be a hash or any unique byte sequence.
cAttribute
Count of elements in the rgAttribute array.
rgAttribute
Array of CRYPT_ATTRIBUTE structures, each holding information about the subject.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB, CTL_INFO, CRYPT_ATTRIBUTE


CTL_FIND_SUBJECT_PARA

The CTL_FIND_SUBJECT_PARA structure contains data used by CertFindCTLInStore with a dwFindType of CTL_FIND_SUBJECT to find a Certificate Trust List (CTL).

typedef struct _CTL_FIND_SUBJECT_PARA {
  DWORD                   cbSize;
  PCTL_FIND_USAGE_PARA    pUsagePara; // optional
  DWORD                   dwSubjectType;
  void                    *pvSubject;
} CTL_FIND_SUBJECT_PARA, *PCTL_FIND_SUBJECT_PARA;

Members

cbSize
Size of this structure in bytes.
pUsagePara
Pointer to a CTL_FIND_USAGE_PARA structure. Can be NULL if there is no need to reference the CTL_FIND_USAGE_PARA parameters when finding a CTL.
dwSubjectType
For CTL_CERT_SUBJECT_TYPE, pvSubject points to a CERT_CONTEXT. The CTL's SubjectAlgorithm is examined to determine the representation of the subject's identity. Initially, only SHA1 or MD5 hash will be supported. The appropriate hash property is obtained from the CERT_CONTEXT.

For CTL_ANY_SUBJECT_TYPE, pvSubject points to the CTL_ANY_SUBJECT_INFO structure that contains the SubjectAlgorithm to be matched in the CTL and the SubjectIdentifer to be matched in one of the CTL entries.

pvSubject
pvSubject depends on the dwSubjectType. See dwSubjectType for details.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CERT_CONTEXT, CTL_ANY_SUBJECT_INFO, CTL_FIND_USAGE_PARA, CertFindCTLInStore


CTL_FIND_USAGE_PARA

The CTL_FIND_USAGE_PARA structure is a member of the CTL_FIND_SUBJECT_PARA structure and it is used by CertFindCTLInStore.

typedef struct _CTL_FIND_USAGE_PARA {
  DWORD               cbSize;
  CTL_USAGE           SubjectUsage;   // optional
  CRYPT_DATA_BLOB     ListIdentifier; // optional
  PCERT_INFO          pSigner;        // optional
} CTL_FIND_USAGE_PARA, *PCTL_FIND_USAGE_PARA;

Members

cbSize
Size of this structure in bytes.
SubjectUsage
CTL_USAGE structure that includes a sequence of object identifiers to be matched when finding a CTL.

A found CTL must contain all the usage object identifiers specified by SubjectUsage.

If the cUsageIdentifier member of this structure is zero, a CTL with any usage can be a match.

ListIdentifier
Specified to restrict a search to a particular signer CTL list. Normally the ListIdentifier will be zero, indicating that any ListIdentifier can be matched. If it is not zero, this ListIdentifier and the ListIdentifier in a CTL must match.

To match only CTLs that have no ListIdentifier, the cbData member of ListIdentifier is set to CTL_FIND_NO_LIST_ID_CBDATA.

A CTL uses a ListIdentifier to distinguish among multiple CTLs created by the same issuer with the same SubjectUsage.

pSigner
Pointer to a CERT_INFO structure that specifies the CTL signer to be matched. Only the issuer and serial number from the CERT_INFO are used to match a signer.

Set pSigner to NULL to match any signer. To match CTLs that do not have any signers, set pSigner to CTL_FIND_NO_SIGNER_PTR.

The CertEncodingType of the signer is obtained from the dwMsgAndCertEncodingType parameter of CertFindCTLInStore.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB, CERT_INFO, CTL_FIND_SUBJECT_PARA, CTL_USAGE, CertFindCTLInStore


CTL_INFO

The CTL_INFO structure contains the information stored in a Certificate Trust List (CTL).

typedef struct _CTL_INFO {
  DWORD                       dwVersion;
  CTL_USAGE                   SubjectUsage;
  CRYPT_DATA_BLOB             ListIdentifier;     // OPTIONAL
  CRYPT_INTEGER_BLOB          SequenceNumber;     // OPTIONAL
  FILETIME                    ThisUpdate;
  FILETIME                    NextUpdate;         // OPTIONAL
  CRYPT_ALGORITHM_IDENTIFIER  SubjectAlgorithm;
  DWORD                       cCTLEntry;
  PCTL_ENTRY                  rgCTLEntry;         // OPTIONAL
  DWORD                       cExtension;
  PCERT_EXTENSION             rgExtension;        // OPTIONAL
} CTL_INFO, *PCTL_INFO;

Members

dwVersion
The CTL's version number. Currently defined version numbers are shown in the following table.
CTL version name | Meaning
CTL_V1 | Version 1

SubjectUsage
CTL_USAGE structure identifying the intended usage of the list as a sequence of object identifiers. This is the same as in the Enhanced Key Usage extension.
ListIdentifier
CRYPTOAPI_BLOB that includes a byte string that uniquely identifies the list. This member is used to augment the SubjectUsage and further specifies the list when desired.
SequenceNumber
BLOB containing a monotonically increasing number for each update of the CTL.
ThisUpdate
Indication of the date and time of the CRLs published. If the time is after 1950 and before 2050, it is UTC-time encoded as an 8-byte date/time precise to seconds with a 2-digit year (that is, YYMMDDHHMMSS plus 2 bytes). Otherwise, it is generalized-time encoded as an 8-byte year precise to milliseconds with a 4-byte year.
NextUpdate
Indication of the date and time for the CRL's next available scheduled update. If the time is after 1950 and before 2050, it is UTC-time encoded as an 8-byte date/time precise to seconds with a 2-digit year (that is, YYMMDDHHMMSS plus 2 bytes). Otherwise, it is generalized-time encoded as an 8-byte date time precise to milliseconds with a 4-byte year.
SubjectAlgorithm
CRYPT_ALGORITHM_IDENTIFIER structure that contains the algorithm type of the SubjectIdentifier in CTL_ENTRY members of the rgCTLEntry array. The structure also includes additional parameters used by the algorithm.
cCTLEntry
Number of elements in the rgCTLEntry array.
rgCTLEntry
Array of CTL_ENTRY structures.
cExtension
Number of elements in the rgExtension array.
rgExtension
Array of CERT_EXTENSION structures.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB, CERT_EXTENSION, CRYPT_ALGORITHM_IDENTIFIER, CTL_CONTEXT, CTL_ENTRY, CTL_USAGE


CTL_USAGE

The CTL_USAGE structure contains an array of Object Identifiers (OIDs) for Certificate Trust List (CTL) extensions. CTL_USAGE structures are used in functions that search for CTLs for specific uses.

typedef struct _CTL_USAGE {
  DWORD               cUsageIdentifier;
  LPSTR               *rgpszUsageIdentifier;
} CTL_USAGE, *PCTL_USAGE,
  CERT_ENHKEY_USAGE, *PCERT_ENHKEY_USAGE;

Members

cUsageIdentifier
Number of elements in the rgpszUsageIdentifier array.
rgpszUsageIdentifier
Array of object identifiers (OIDs) of CTL extensions.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CTL_INFO, CTL_FIND_USAGE_PARA, CertFindCertificateInStore, CertGetCertificateContextProperty, CertVerifyCTLUsage, CryptDecodeObject, CryptEncodeObject


CTL_VERIFY_USAGE_PARA

The CTL_VERIFY_USAGE_PARA structure contains parameters used by CertVerifyCTLUsage to establish the validity of a CTL's usage.

typedef struct _CTL_VERIFY_USAGE_PARA {
  DWORD                   cbSize;
  CRYPT_DATA_BLOB         ListIdentifier;     // OPTIONAL
  DWORD                   cCtlStore;
  HCERTSTORE              *rghCtlStore;       // OPTIONAL
  DWORD                   cSignerStore;
  HCERTSTORE              *rghSignerStore;    // OPTIONAL
} CTL_VERIFY_USAGE_PARA, *PCTL_VERIFY_USAGE_PARA;

Members

cbSize
Size of this structure in bytes.
ListIdentifier
BLOB that specifies a ListIdentifier of a CTL to be found or verified. Normally the cbData member of the ListIdentifier BLOB will be zero, indicating that a CTL with any ListIdentifier can be a match.

To match only CTLs with no ListIdentifier, the cbData member of the ListIdentifier BLOB is set to CTL_FIND_NO_LIST_ID_CBDATA.

If an issuer creates multiple CTLs for the same SubjectUsage, a ListIdentifier can distinguish among them.

cCtlStore
The count of stores to be searched for a matching CTL.
rghCtlStore
Array of handles of stores to be searched to find a matching CTL.
cSignerStore
Count of stores to be searched for acceptable CTL signers.
rghSignerStore
Array of handles of stores to be searched for acceptable CTL signers.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CertVerifyCTLUsage


CTL_VERIFY_USAGE_STATUS

The CTL_VERIFY_USAGE_STATUS structure contains information about a Certificate Trust List (CTL) returned by CertVerifyCTLUsage.

typedef struct _CTL_VERIFY_USAGE_STATUS {
  DWORD                   cbSize;
  DWORD                   dwError;
  DWORD                   dwFlags;
  PCCTL_CONTEXT           *ppCtl;             // IN OUT OPTIONAL
  DWORD                   dwCtlEntryIndex;
  PCCERT_CONTEXT          *ppSigner;          // IN OUT OPTIONAL
  DWORD                   dwSignerIndex;
} CTL_VERIFY_USAGE_STATUS, *PCTL_VERIFY_USAGE_STATUS;

Members

cbSize
Size of the structure in bytes. The application calling CertVerifyCTLUsage sets this parameter. If cbSize is not greater than or equal to the required size of the structure, CertVerifyCTLUsage returns FALSE and GetLastError returns E_INVALIDARG.
dwError
The error status, if any, returned by the call to CertVerifyCTLUsage. This will be the same as LastError reported by CertVerifyCTLUsage. See the Return Values section in CertVerifyCTLUsage for the list of possible error values.
dwFlags
If CERT_VERIFY_UPDATED_CTL_FLAG is returned, CertVerifyCTLUsage updated a time-invalid CTL with a new, time-valid CTL.
ppCtl
Pointer to a pointer to a CTL context containing the matched subject. The calling application can set this pointer to NULL to indicate that a CTL containing the subject is not to be returned.

If ppCtl is not NULL, the calling application must free the returned context using CertFreeCTLContext.

dwCtlEntryIndex
Returns the array location of the matching subject's entry in the CTL's array.
ppSigner
Pointer to a pointer to the certificate context of the signer of the CTL. This pointer can be set to NULL by the calling application indicating that the certificate of the signer of the CTL is not to be returned.

If ppSigner is not NULL, the calling application must free the returned context using CertFreeCTLContext.

dwSignerIndex
Index of the signer actually used. Needed if a message has more than one signer.

Remarks

The members dwError, dwFlags, dwCtlEntryIndex, and dwSignerIndex should be initialized to zero by the calling application.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CERT_CONTEXT, CTL_CONTEXT, CertVerifyCTLUsage


X.509 Certificate Extension Structures

The following structures are associated with X.509 CERT_EXTENSION structures.

  • CERT_ACCESS_DESCRIPTION
  • CERT_ALT_NAME_ENTRY
  • CERT_ALT_NAME_INFO
  • CERT_AUTHORITY_INFO_ACCESS
  • CERT_AUTHORITY_KEY_ID_INFO
  • CERT_AUTHORITY_KEY_ID2_INFO
  • CERT_BASIC_CONSTRAINTS_INFO
  • CERT_BASIC_CONSTRAINTS2_INFO
  • CERT_KEY_ATTRIBUTES_INFO
  • CERT_KEY_USAGE_RESTRICTION_INFO
  • CERT_POLICY_ID
  • CERT_POLICY_INFO
  • CERT_POLICY_QUALIFIER_INFO
  • CERT_POLICIES_INFO
  • CERT_PRIVATE_KEY_VALIDITY
  • CRL_DIST_POINT
  • CRL_DIST_POINT_NAME
  • CRL_DIST_POINTS_INFO

These structures can be encoded into the Value member of a CERT_EXTENSION structure using CryptEncodeObject and CryptEncodeObjectEx. They are created and returned by CryptDecodeObject and CryptDecodeObjectEx when the Value member of a CERT_EXTENSION structure is decoded.

The structure encoded or created depends on the pszObjId string member of the CERT_EXTENSION structure.

Current extension predefined constants and OIDs along with the structure associated with each are shown in the following table.

Note: The predefined constant (column 1) and is corresponding OID (column 2) may be used interchangeably.

Predefined constant | Object identifier (OID) | Data structure
X509_AUTHORITY_INFO_ACCESS | szOID_AUTHORITY_INFO_ACCESS | CERT_AUTHORITY_INFO_ACCESS
X509_AUTHORITY_KEY_ID | szOID_AUTHORITY_KEY_IDENTIFIER | CERT_AUTHORITY_KEY_ID_INFO
X509_KEY_ATTRIBUTES | szOID_KEY_ATTRIBUTES | CERT_KEY_ATTRIBUTES_INFO
X509_KEY_USAGE_RESTRICTION | szOID_KEY_USAGE_RESTRICTION | CERT_KEY_USAGE_RESTRICTION_INFO
None | szOID_POLICY_MAPPINGS | Not implemented
X509_ALTERNATE_NAME | szOID_SUBJECT_ALT_NAME – Or – szOID_ISSUER_ALT_NAME | CERT_ALT_NAME_INFO
None | szOID_SUBJECT_DIR_ATTRS | Not implemented
X509_BASIC_CONSTRAINTS | szOID_BASIC_CONSTRAINTS | CERT_BASIC_CONSTRAINTS_INFO
X509_KEY_USAGE | szOID_KEY_USAGE | CRYPT_BIT_BLOB
X509_BASIC_CONSTRAINTS2 | szOID_BASIC_CONSTRAINTS2 | CERT_BASIC_CONSTRAINTS2_INFO
X509_CERT_POLICIES | szOID_CERT_POLICIES | CERT_POLICIES_INFO


CERT_ACCESS_DESCRIPTION

The CERT_ACCESS_DESCRIPTION structure is a member of a CERT_AUTHORITY_INFO_ACCESS structure. It contains one instance of information on how to access certification authority (CA) information and services for the issuer of the certificate in which the CERT_AUTHORITY_INFO_ACCESS extension appears. Information and services can include online validation services and CA policy data.

typedef struct _CERT_ACCESS_DESCRIPTION {
  LPSTR               pszAccessMethod;        // pszObjId
  CERT_ALT_NAME_ENTRY AccessLocation;
} CERT_ACCESS_DESCRIPTION, *PCERT_ACCESS_DESCRIPTION;

Members

pszAccessMethod
Specifies the object identifier (OID) for the method of access. The following are currently defined PKIX Access Method OIDs.

szOID_PKIX_OCSP
szOID_PKIX_CA_ISSUERS

AccessLocation
CERT_ALT_NAME_ENTRY structure that describes the online status server and the access protocol to obtain current certificate status information for the certificate containing the extension.

For the szOID_PKIX_OCSP access method, AccessLocation describes the online status server and the access protocol needed to obtain status information about the certificate containing this extension.

For the szOID_PKIX_CA_ISSUERS access method, AccessLocation obtains information on the CAs that issued certificates superior to the CA that issued the certificate containing this extension. The CA issuer's description is intended to aid certificate users in the selection of a certification path that terminates at a point trusted by the certificate user.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CERT_AUTHORITY_INFO_ACCESS


CERT_ALT_NAME_ENTRY

The CERT_ALT_NAME_ENTRY structure contains an alternative name in one of a variety of name forms. These names are bound by a certification authority (CA) to a certificate's public key.

A CERT_ALT_NAME_ENTRY structure can be a member of a CERT_ALT_NAME_INFO structure.

typedef struct _CERT_ALT_NAME_ENTRY {
  DWORD    dwAltNameChoice;
  union {
    PCERT_OTHER_NAME              pOtherName;
    LPWSTR                        pwszRfc822Name;
    LPWSTR                        pwszDNSName;
    //Not implemented             x400Address;
    CERT_NAME_BLOB                DirectoryName;
    //Not implemented             pEdiPartyName;
    LPWSTR                        pwszURL;
    CRYPT_DATA_BLOB               IPAddress;
    LPSTR                         pszRegisteredID;
  };
} CERT_ALT_NAME_ENTRY,   *PCERT_ALT_NAME_ENTRY;

Members

dwAltNameChoice
Indicates the union variant used for the alternative name.

The following dwAltNameChoice values are:

CERT_ALT_NAME_OTHER_NAME
CERT_ALT_NAME_RFC822_NAME
CERT_ALT_NAME_DNS_NAME
CERT_ALT_NAME_X400_ADDRESS
CERT_ALT_NAME_DIRECTORY_NAME
CERT_ALT_NAME_EDI_PARTY_NAME
CERT_ALT_NAME_URL
CERT_ALT_NAME_IP_ADDRESS
CERT_ALT_NAME_REGISTERED_ID

pOtherName
Pointer to a CERT_OTHER_NAME structure, which includes an object identifier (OID) and a BLOB containing the name.
pwszRfc822Name
E-mail address as a Unicode string.
pwszDNSName
DNS name as an IA5 string.
x400Address
Not currently implemented.
DirectoryName
BLOB containing a directory name.
pEdiPartyName
Not currently implemented.
pwszURL
URL as a IA5 string.
IPAddress
Octet string that is an Internet Protocol address defined in accordance with Internet RFC 791.
pszRegisteredID
Object identifier (OID) of any registered object.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB, CERT_ALT_NAME_INFO, CRYPT_ATTRIBUTE_TYPE_VALUE


CERT_ALT_NAME_INFO

The CERT_ALT_NAME_INFO structure is used in encoding and decoding extensions for subject or issuer certificates, Certificate Revocation Lists (CRLs), and Certificate Trust Lists (CTLs).

CryptDecodeObject creates an instance of this structure when performed on a CERT_EXTENSION structure's Value member with its structure's pszObjId member set to szOID_SUBJECT_ALT_NAME or szOID_ISSUER_ALT_NAME.

An instance of this structure can be used as input to CryptEncodeObject to create an appropriate CERT_EXTENSION.

typedef struct _CERT_ALT_NAME_INFO {
  DWORD                  cAltEntry;
  PCERT_ALT_NAME_ENTRY   rgAltEntry;
 } CERT_ALT_NAME_INFO,    *PCERT_ALT_NAME_INFO

Members

cAltEntry
Number of elements in the rgAltEntry array.
rgAltEntry
Array of CERT_ALT_NAME_ENTRY structures.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CERT_ALT_NAME_ENTRY


CERT_AUTHORITY_INFO_ACCESS

The CERT_AUTHORITY_INFO_ACCESS structure appears as a certificate extension and indicates how to access certification authority (CA) information and services for the issuer of that certificate. Information and services can include online validation services and CA policy data. This extension can be included in subject or CA certificates. It is always noncritical.

CryptDecodeObject creates an instance of this structure when performed on a CERT_EXTENSION structure's Value member with its the structure's pszObjId member set to szOID_AUTHORITY_INFO_ACCESS.

An instance of this structure can be used as input to CryptEncodeObject to create an appropriate CERT_EXTENSION.

typedef struct _CERT_AUTHORITY_INFO_ACCESS {
  DWORD                       cAccDescr;
  PCERT_ACCESS_DESCRIPTION    rgAccDescr;
} CERT_AUTHORITY_INFO_ACCESS, *PCERT_AUTHORITY_INFO_ACCESS;

Members

cAccDescr
Number of elements in the rgAccDescr array.
rgAccDescr
Array of pointers to CERT_ACCESS_DESCRIPTION structures that describes the format and location of additional information about the CA that issued the certificate. Each CERT_ACCESS_DESCRIPTION structure has as its members a pszAccessMethod string indicating an access method and a CERT_ALT_NAME_ENTRY structure indicating the location of the additional information.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CERT_ACCESS_DESCRIPTION, CERT_ALT_NAME_ENTRY


CERT_AUTHORITY_KEY_ID_INFO

The CERT_AUTHORITY_KEY_ID_INFO structure identifies the key used to sign a certificate or CRL. This structure differentiates among distinct keys used by the same certification authority as, for example, keys changed when an update occurs.

The key can be identified by an explicit key identifier, by giving a certificate's issuer and serial number, or by both. If both are used, the certificate issuer must ensure that the explicit key identifier, the certificate issuer and the serial number are consistent.

CryptDecodeObject creates an instance of this structure when performed on a CERT_EXTENSION structure's Value member with its structure's pszObjId member set to szOID_AUTHORITY_KEY_IDENTIFIER.

An instance of this structure can be used as input to CryptEncodeObject to create an appropriate CERT_EXTENSION.

typedef struct _CERT_AUTHORITY_KEY_ID_INFO {
  CRYPT_DATA_BLOB              KeyId;
  CERT_NAME_BLOB               CertIssuer;
  CRYPT_INTEGER_BLOB           CertSerialNumber;
 } CERT_AUTHORITY_KEY_ID_INFO,  *PCERT_AUTHORITY_KEY_ID_INFO;

Members

KeyId
CRYPT_DATA_BLOB containing a unique identifier of a public key.
CertIssuer
CERT_NAME_BLOB containing the encoded distinguished name of the CA that issued the certificate.
CertSerialNumber
CRYPT_INTEGER_BLOB containing the serial number of the certificate associated with the private key used to sign this certificate. See CERT_INFO for details.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB


CERT_AUTHORITY_KEY_ID2_INFO

The CERT_AUTHORITY_KEY_ID2_INFO structure identifies the key used to sign a certificate or CRL. It differs from the CERT_AUTHORITY_KEY_ID_INFO structure in that the certificate issuer is a CERT_ALT_NAME_INFO instead of a CERT_NAME_BLOB. Otherwise, the structures are used in the same way.

The key can be identified by an explicit key identifier, by giving a certificate's issuer and serial number, or by both. If both are used, the certificate issuer must ensure that the explicit key identifier, the certificate issuer and the serial number are consistent.

CryptDecodeObject creates an instance of this structure when performed on a CERT_EXTENSION structure's Value member with its the structure's pszObjId member set to szOID_AUTHORITY_KEY_IDENTIFIER2.

An instance of this structure can be used as input to CryptEncodeObject to create an appropriate CERT_EXTENSION.

typedef struct _CERT_AUTHORITY_KEY_ID2_INFO {
  CRYPT_DATA_BLOB     KeyId;
  CERT_ALT_NAME_INFO  AuthorityCertIssuer;
  CRYPT_INTEGER_BLOB  AuthorityCertSerialNumber;
} CERT_AUTHORITY_KEY_ID2_INFO, *PCERT_AUTHORITY_KEY_ID2_INFO;

Members

KeyId
CRYPT_DATA_BLOB containing a unique identifier of a public key.
AuthorityCertIssuer
CERT_ALT_NAME_INFO that includes the encoded name of the CA that issued the certificate. The cAltEntry member of the structure may be set to zero if the name is not to be used to identify the CA.
AuthorityCertSerialNumber
CRYPT_INTEGER_BLOB that includes the serial number of the certificate associated with the private key used to sign this certificate. See CERT_INFO for details.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CERT_ALT_NAME_INFO, CERT_AUTHORITY_KEY_ID_INFO


CERT_BASIC_CONSTRAINTS_INFO

The CERT_BASIC_CONSTRAINTS_INFO structure contains information indicating whether the certified subject can act as a CA, an end-entity, or both. If the subject can act as a CA, a certification path length constraint can also be specified, as can a set of subtrees that must contain all subject names of subsequent certificates in a certification chain. This extension is used in validating certificates used to sign other certificates.

CryptDecodeObject creates an instance of this structure when performed on a CERT_EXTENSION structure's Value member with its structure's pszObjId member set to szOID_BASIC_CONSTRAINTS.

typedef struct _CERT_BASIC_CONSTRAINTS_INFO {
  CRYPT_BIT_BLOB               SubjectType;
  BOOL                         fPathLenConstraint;
  DWORD                        dwPathLenConstraint;
  DWORD                        cSubtreesConstraint;
  CERT_NAME_BLOB*              rgSubtreesConstraint;
 } CERT_BASIC_CONSTRAINTS_INFO, *PCERT_BASIC_CONSTRAINTS_INFO;

Members

SubjectType
CRYPT_BIT_BLOB can contain a CERT_CA_SUBJECT_FLAG that when set indicates that the certificate's subject can act as a CA, a CERT_END_ENTITY_SUBJECT_FLAG that when set indicates that the certificate's subject can act as an end entity, or both combined using a bitwise-OR operation.
fPathLenConstraint
Boolean indicating whether the dwPathLenConstraint field sets the maximum length of the certification path.
dwPathLenConstraint
Maximum number of CA certificates that can follow this certificate in a certification validation path. A value of zero indicates that the subject of this certificate can issue certificates only to end entities and not to CAs.
cSubtreesConstraint
Number of elements in the rgSubtreesConstraint array.
rgSubtreesConstraint
Array of CERT_NAME_BLOB structures establishing subtree constraints.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB, CRYPT_BIT_BLOB


CERT_BASIC_CONSTRAINTS2_INFO

The CERT_BASIC_CONSTRAINTS2_INFO structure contains information indicating whether the certified subject can act as a CA or an end entity. If the subject can act as a CA, a certification path length constraint can also be specified.

CryptDecodeObject creates an instance of this structure when performed on a CERT_EXTENSION structure's Value member with its the structure's pszObjId member set to szOID_BASIC_CONSTRAINTS2.

An instance of this structure can be used as input to CryptEncodeObject to create an appropriate CERT_EXTENSION.

typedef struct _CERT_BASIC_CONSTRAINTS2_INFO {
  BOOL                           fCA;
  BOOL                           fPathLenConstraint;
  DWORD                          dwPathLenConstraint;
 } CERT_BASIC_CONSTRAINTS2_INFO,  *PCERT_BASIC_CONSTRAINTS2_INFO;

Members

fCA
Boolean indicating whether the certificate subject can act as a certification authority (CA) or not.
fPathLenConstraint
Boolean indicating whether the dwPathLenConstraint field limits the maximum length of the certification path. Used only if fCA is TRUE.
dwPathLenConstraint
Maximum number of CA certificates that can follow this certificate in a certification path. A value of zero indicates that the subject of this certificate can issue certificates only to end entities and not to other CAs. Used only if both fCA and fPathLenConstraint are TRUE.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.


CERT_KEY_ATTRIBUTES_INFO

The CERT_KEY_ATTRIBUTES_INFO structure contains optional additional information about the public key being certified. It can include a key identifier, an indication of the intended use of that key, or an indication of the period of use of the corresponding private key.

CryptDecodeObject creates an instance of this structure when performed on a CERT_EXTENSION structure's Value member with its the structure's pszObjId member set to szOID_KEY_ATTRIBUTES.

An instance of this structure can be used as input to CryptEncodeObject to create an appropriate CERT_EXTENSION.

typedef struct _CERT_KEY_ATTRIBUTES_INFO {
  CRYPT_DATA_BLOB             KeyId;
  CRYPT_BIT_BLOB              IntendedKeyUsage;
  PCERT_PRIVATE_KEY_VALIDITY  pPrivateKeyUsagePeriod;  // optional
} CERT_KEY_ATTRIBUTES_INFO,    *PCERT_KEY_ATTRIBUTES_INFO;

Members

KeyId
CRYPT_DATA_BLOB with a unique identifier of a key.
IntendedKeyUsage
CRYPT_BIT_BLOB with it pbData member indicating the intended purpose of the key. See the RestrictedKeyUsage member of CERT_KEY_USAGE_RESTRICTION_INFO for a list of usage bit values.

This member can be used to find the correct key or certificate of a user who has multiple keys or certificates. Its indication of usage is advisory field, only, and does not imply that usage of the key is restricted to the purpose indicated. The list of intended uses is not necessarily all-inclusive, and the field can be omitted. If a key is to be restricted to a particular use a CERT_KEY_USAGE_RESTRICTION_INFO extension must be used.

pPrivateKeyUsagePeriod
Pointer to a CERT_PRIVATE_KEY_VALIDITY structure that indicates the period of use of the private key corresponding to the certified public key. This member is optional and can be set to NULL.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB, CERT_PRIVATE_KEY_VALIDITY, CRYPT_BIT_BLOB


CERT_KEY_USAGE_RESTRICTION_INFO

The CERT_KEY_USAGE_RESTRICTION_INFO structure contains restrictions imposed on the usage of a certificate's public key. This includes purposes for use of the key and policies under which the key can be used.

CryptDecodeObject creates an instance of this structure when performed on a CERT_EXTENSION structure's Value member with its structure's pszObjId member set to szOID_KEY_USAGE_RESTRICTION.

An instance of this structure can be used as input to CryptEncodeObject to create an appropriate CERT_EXTENSION.

typedef struct _CERT_KEY_USAGE_RESTRICTION_INFO {
  DWORD                            cCertPolicyId;
  PCERT_POLICY_ID                  rgCertPolicyId;
  CRYPT_BIT_BLOB                   RestrictedKeyUsage;
} CERT_KEY_USAGE_RESTRICTION_INFO,  *PCERT_KEY_USAGE_RESTRICTION_INFO;

Members

cCertPolicyId
Number of elements in the array rgCertPolicyId.
rgCertPolicyId
Array of pointers to CERT_POLICY_ID structures.
RestrictedKeyUsage
CRYPT_BIT_BLOB that includes, as its pbData, a byte indicating the purposes for which the key can be used.

If the cbData member is zero, the key has no usage restrictions.

The following are currently defined values for the pbData member of RestrictedKeyUsage. These can be combined using a bitwise-OR operation.

CERT_DATA_ENCIPHERMENT_KEY_USAGE
CERT_DIGITAL_SIGNATURE_KEY_USAGE
CERT_KEY_AGREEMENT_KEY_USAGE
CERT_KEY_CERT_SIGN_KEY_USAGE
CERT_KEY_ENCIPHERMENT_KEY_USAGE
CERT_NON_REPUDIATION_KEY_USAGE
CERT_OFFLINE_CRL_SIGN_KEY_USAGE

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CERT_POLICY_ID, CRYPT_BIT_BLOB


CERT_POLICY_ID

The CERT_POLICY_ID structure contains a list of certificate policies that the certificate expressly supports, together with optional qualifier information pertaining to these policies.

CERT_POLICY_ID is a component of CERT_KEY_USAGE_RESTRICTION_INFO.

typedef struct _CERT_POLICY_ID {
  DWORD          cCertPolicyElementId;
  LPSTR*         rgpszCertPolicyElementId;
} CERT_POLICY_ID, *PCERT_POLICY_ID;

Members

cCertPolicyElementId
Number of elements in the rgpszCertPolicyElementId array.
rgpszCertPolicyElementId
Array of pointers to policy element identifier strings.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CERT_KEY_USAGE_RESTRICTION_INFO


CERT_POLICY_INFO

The CERT_POLICY_INFO structure contains an object identifier (OID) specifying a policy and an optional array of policy qualifiers.

The CERT_POLICY_INFO structure is a component of CERT_POLICIES_INFO.

typedef struct _CERT_POLICY_INFO {
  LPSTR                        pszPolicyIdentifier;
  DWORD                        cPolicyQualifier;
  CERT_POLICY_QUALIFIER_INFO*  rgPolicyQualifier;
} CERT_POLICY_INFO,            *PCERT_POLICY_INFO;

Members

pszPolicyIdentifier
Object identifier (OID) string specifying the policy.
cPolicyQualifier
Number of elements in the rgPolicyQualifier array.
rgPolicyQualifier
Array of CERT_POLICY_QUALIFIER_INFO structures.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CERT_POLICIES_INFO, CERT_POLICY_QUALIFIER_INFO


CERT_POLICY_QUALIFIER_INFO

The CERT_POLICY_QUALIFIER_INFO structure contains an object identifier (OID) specifying the qualifier and qualifier-specific supplemental information.

The CERT_POLICY_QUALIFIER_INFO structure is a component of CERT_POLICY_INFO.

typedef struct _CERT_POLICY_QUALIFIER_INFO {
  LPSTR                       pszPolicyQualifierId;
  CRYPT_OBJID_BLOB            Qualifier;
} CERT_POLICY_QUALIFIER_INFO,  *PCERT_POLICY_QUALIFIER_INFO;

Members

pszPolicyQualifierId
OID specifying the qualifier.
Qualifier
CRYPT_OBJID_BLOB containing qualifier specific supplemental information.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB, CERT_POLICY_INFO


CERT_POLICIES_INFO

The CERT_POLICIES_INFO structure contains an array of CERT_POLICY_INFO.

CryptDecodeObject creates an instance of this structure when performed on a CERT_EXTENSION structure's Value member with the structure's pszObjId member set to szOID_CERT_POLICIES.

An instance of this structure can be used as input to CryptEncodeObject to create an appropriate CERT_EXTENSION.

typedef struct _CERT_POLICIES_INFO {
  DWORD                cPolicyInfo;
  CERT_POLICY_INFO*    rgPolicyInfo;
} CERT_POLICIES_INFO,  *PCERT_POLICIES_INFO;

Members

cPolicyInfo
Number of elements in the rgPolicyInfo array.
rgPolicyInfo
Array of CERT_POLICY_INFO structures.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CERT_POLICY_INFO


CERT_PRIVATE_KEY_VALIDITY

The CERT_PRIVATE_KEY_VALIDITY structure indicates a valid time span for the private key corresponding to a certificate's public key. If the NotBefore component is zero or not present, no statement is made as to when the validity period of the private key begins. If the NotAfter component is zero or not present, no end date is set on the validity of the private key.

A CERT_PRIVATE_KEY_VALIDITY structure is a member of the CERT_KEY_ATTRIBUTES_INFO structure.

typedef struct _CERT_PRIVATE_KEY_VALIDITY{
  FILETIME                   NotBefore;
  FILETIME                   NotAfter;
} CERT_PRIVATE_KEY_VALIDITY,  *PCERT_PRIVATE_KEY_VALIDITY;

Members

NotBefore
Date and time before which the certificate is not valid. For dates between 1950 and 2049 inclusive, the date and time is encoded UTC-time in the form YYMMDDHHMMSS. This member uses a two-digit year and is precise to seconds. For dates before 1950 or after 2049, encoded generalized-time is used. Encoded generalized time is in the form YYYYMMDDHHSSMMM, using a four-digit year, and is precise to milliseconds. Even though generalized time supports millisecond resolution, the NotBefore time is only precise to seconds.
NotAfter
Date and time after which the certificate is not valid. For dates between 1950 and 2049 inclusive, the date and time is encoded UTC-time in the form YYMMDDHHMMSS. This member uses a two-digit year and is precise to seconds. For dates before 1950 or after 2049, encoded generalized time is used. Encoded generalized time is in the form YYYYMMDDHHSSMMM, using a four digit year, and is precise to milliseconds. Even though generalized time supports millisecond resolution, the NotAfter time is only precise to seconds.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CERT_KEY_ATTRIBUTES_INFO


CRL_DIST_POINT

The CRL_DIST_POINT structure identifies a single CRL distribution point that a certificate user can reference to determine if certificates have been revoked. A certificate user can obtain a CRL from an applicable distribution point or can obtain a current complete CRL from the CA directory entry.

The CRL_DIST_POINT structures are the elements in the array member of a CRL_DIST_POINTS_INFO structure.

typedef struct _CRL_DIST_POINT {
  CRL_DIST_POINT_NAME     DistPointName;      // OPTIONAL
  CRYPT_BIT_BLOB          ReasonFlags;        // OPTIONAL
  CERT_ALT_NAME_INFO      CRLIssuer;          // OPTIONAL
} CRL_DIST_POINT, *PCRL_DIST_POINT;

Members

DistPointName
CRL_DIST_POINT_NAME structure identifying the location of a CRL source. If NULL, the distribution point name defaults to the CRLIssuer name.
ReasonFlags
CRYPT_BIT_BLOB containing a byte indicating the revocation reasons covered by the CRL.

If NULL, the indicated CRL distribution point distributes a CRL that will contain an entry for this certificate if this certificate has been revoked, regardless of the revocation reason.

The following are currently defined ReasonFlags values. For revocations for several reasons, these ReasonFlags may be combined using a bitwise-OR operation.

CRL_REASON_UNUSED_FLAG
CRL_REASON_KEY_COMPROMISE_FLAG
CRL_REASON_CA_COMPROMISE_FLAG
CRL_REASON_AFFILIATION_CHANGED_FLAG
CRL_REASON_SUPERSEDED_FLAG
CRL_REASON_CESSATION_OF_OPERATION_FLAG
CRL_REASON_CERTIFICATE_HOLD_FLAG

CRLIssuer
CERT_ALT_NAME_INFO identifying the authority that issued and signed the CRL. If NULL, the CRL issuer name defaults to the certificate's issuer name.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRL_DIST_POINTS_INFO, CRL_DIST_POINT_NAME


CRL_DIST_POINT_NAME

The CRL_DIST_POINT_NAME structure identifies a location from which the CRL can be obtained. When CRL_DIST_POINT_FULL_NAME is used, different forms of the CRL distribution point name appear in the FullName CERT_ALT_NAME_INFO structure. An application need not be able to process all of the name forms in the structure. It can use a distribution point if at least one name form can be processed.

If no name forms for a distribution point can be processed, an application can still use the certificate, provided requisite revocation information can be obtained from another source such as a distribution point of the CA's directory entry.

typedef struct _CRL_DIST_POINT_NAME {
  DWORD   dwDistPointNameChoice;
  union {
    CERT_ALT_NAME_INFO      FullName;       // 1
    // Not implemented      IssuerRDN;      // 2
  };
} CRL_DIST_POINT_NAME, *PCRL_DIST_POINT_NAME;

Members

dwDistPointNameChoice
Indicates the variant used for the name data contained in the union. The following dwDistPointNameChoice values are defined:
Name choice | Meaning
CRL_DIST_POINT_NO_NAME | No distribution point name is provided.
CRL_DIST_POINT_FULL_NAME | The distribution point name is in the FullName member of the Union.
CRL_DIST_POINT_ISSUER_RDN_NAME | Currently not implemented.

FullName
A CERT_ALT_NAME_INFO structure containing an array of alternative names specifying the CRL distribution point in one of several different forms. One of the most common uses a URL in the form "http://… " to specify the location of the CRL.
IssuerRDN
Not implemented.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRL_DIST_POINT


CRL_DIST_POINTS_INFO

The CRL_DIST_POINTS_INFO structure contains a list of CRL distribution points a certificate user can reference to determine if the certificate has been revoked.

typedef struct _CRL_DIST_POINTS_INFO {
  DWORD                   cDistPoint;
  PCRL_DIST_POINT         rgDistPoint;
} CRL_DIST_POINTS_INFO, *PCRL_DIST_POINTS_INFO;

Members

cDistPoint
Number of elements in the array rgDistPoint.
rgDistPoint
Array of CRL_DIST_POINT structures.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRL_DIST_POINT


Low-Level Message Structures

The following structures are used by Low-Level Message Structures.

  • CMSG_CMS_RECIPIENT_INFO
  • CMSG_CMS_SIGNER_INFO
  • CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA
  • CMSG_CTRL_DECRYPT_PARA
  • CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA
  • CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA
  • CMSG_ENVELOPED_ENCODE_INFO
  • CMSG_HASHED_ENCODE_INFO
  • CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO
  • CMSG_KEY_TRANS_RECIPIENT_INFO
  • CMSG_RC2_AUX_INFO
  • CMSG_RC4_AUX_INFO
  • CMSG_RECIPIENT_ENCRYPTED_KEY_INFO
  • CMSG_SIGNED_ENCODE_INFO
  • CMSG_SIGNER_ENCODE_INFO
  • CMSG_SIGNER_INFO
  • CMSG_STREAM_INFO
  • CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO
  • CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO
  • CMSG_MAIL_LIST_RECIPIENT_ENCODE_INFO
  • CMSG_KEY_AGREE_RECIPIENT_INFO
  • CMSG_MAIL_LIST_RECIPIENT_INFO
  • CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA
  • CMSG_CTRL_KEY_TRANS_DECRYPT_PARA
  • CMSG_CTRL_KEY_AGREE_DECRYPT_PARA
  • CMSG_CTRL_MAIL_LIST_DECRYPT_PARA


CMSG_CMS_RECIPIENT_INFO

The CMSG_CMS_RECIPIENT_INFO structure is used with the CryptMsgGetParam function to get information on a key transport, key agreement, or mail list envelope message recipient. This structure is returned in pvData when CryptMsgGetParam is called with dwParamType set to CMSG_CMS_RECIPIENT_INFO_PARAM.

typedef struct _CMSG_CMS_RECIPIENT_INFO {
  DWORD   dwRecipientChoice;
  union {
    PCMSG_KEY_TRANS_RECIPIENT_INFO   pKeyTrans;
    PCMSG_KEY_AGREE_RECIPIENT_INFO   pKeyAgree;
    PCMSG_MAIL_LIST_RECIPIENT_INFO   pMailList;
  };
} CMSG_CMS_RECIPIENT_INFO, *PCMSG_CMS_RECIPIENT_INFO;

Members

dwRecipientChoice
Indicates the member of the union to be used.

Possible values are:
Value | Choice member indicated
CMSG_KEY_TRANS_RECIPIENT | pKeyTrans
CMSG_KEY_AGREE_RECIPIENT | pKeyAgree
CMSG_MAIL_LIST_RECIPIENT | pMailList

pKeyTrans
Pointer to a CMSG_KEY_TRANS_RECIPIENT_INFO structure identifying a key transport recipient. Used for RSA recipients.
pKeyAgree
Pointer to a CMSG_KEY_AGREE_RECIPIENT_INFO structure identifying a key agreement recipient. Used for Diffie Hellman recipients
pMailList
Pointer to a CMSG_MAIL_LIST_RECIPIENT_INFO structure identifying a recipient using a previously distributed key encryption key for the encryption/decryption of the envelopes message's symmetric key.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CMSG_CMS_SIGNER_INFO

The CMSG_CMS_SIGNER_INFO structure contains the content of the defined SignerInfo in signed or signed and enveloped messages. In decoding a received message, CryptMsgGetParam is called for each signer to get a CMSG_CMS_SIGNER_INFO structure.

typedef struct _CMSG_SIGNER_INFO {
  DWORD                       dwVersion;
  CERT_ID                     SignerId;
  CRYPT_ALGORITHM_IDENTIFIER  HashAlgorithm;
  CRYPT_ALGORITHM_IDENTIFIER  HashEncryptionAlgorithm;
  CRYPT_DATA_BLOB             EncryptedHash;
  CRYPT_ATTRIBUTES            AuthAttrs;
  CRYPT_ATTRIBUTES            UnauthAttrs;
} CMSG_SIGNER_INFO,           *PCMSG_SIGNER_INFO;

Members

dwVersion
The version of this structure.
SignerId
CERT_ID structure identifying the signer's certificate.
HashAlgorithm
CRYPT_ALGORITHM_IDENTIFIER structure specifying the algorithm used in generating the hash of a message.
HashEncryptionAlgorithm
CRYPT_ALGORITHM_IDENTIFIER structure specifying the algorithm used to encrypt the hash.
EncryptedHash
CRYPT_DATA_BLOB containing the encrypted hash of the message, the signature.
AuthAttrs
CRYPT_ATTRIBUTES structure containing authenticated attributes of the signer.
UnauthAttrs
CRYPT_ATTRIBUTES structure containing unauthenticated attributes of the signer.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB, CRYPT_ALGORITHM_IDENTIFIER, CRYPT_ATTRIBUTES


CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA

The CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA structure is used to add an unauthenticated attribute to a signer of a signed message. This structure is passed to CryptMsgControl if the dwCtrlType parameter is set to CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR.

typedef struct _CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA {
  DWORD               cbSize;
  DWORD               dwSignerIndex;
  CRYPT_DATA_BLOB     BLOB;
} CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA, *PCMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA;

Members

cbSize
Size of this structure in bytes.
dwSignerIndex
Index of the signer in the rgSigners array of pointers of CMSG_SIGNER_ENCODE_INFO structures in a signed message's CMSG_SIGNED_ENCODE_INFO structure. The unauthenticated attribute is to be added to this signer's information.
BLOB
CRYPT_DATA_BLOB structure containing the encoded unauthenticated attribute as its pbData member.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB, CryptMsgControl


CMSG_CTRL_DECRYPT_PARA

The CMSG_CTRL_DECRYPT_PARA structure contains information used to decrypt an enveloped message for a key transport recipient. This structure is passed to CryptMsgControl if the dwCtrlType parameter is CMSG_CTRL_DECRYPT.

Important changes affecting the handling of enveloped messages have been made to CryptoAPI to support S/MIME e-mail interoperability. For details, see the Remarks section of CryptMsgOpenToEncode.

typedef struct _CMSG_CTRL_DECRYPT_PARA {
  DWORD                    cbSize;
  HCRYPTPROV               hCryptProv;
  DWORD                    dwKeySpec;
  DWORD                    dwRecipientIndex;
} CMSG_CTRL_DECRYPT_PARA,   *PCMSG_CTRL_DECRYPT_PARA;

Members

cbSize
Size of this structure in bytes.
hCryptProv
Cryptographic service provider (CSP) handle.
dwKeySpec
The private key to be used.

The following dwKeySpec values are defined for the default provider.
Value | Meaning
AT_KEYEXCHANGE | Keys used to encrypt/decrypt session keys.
AT_SIGNATURE | Keys used to create and verify digital signatures.

If dwKeySpec is zero, the default AT_KEYEXCHANGE is used.

dwRecipientIndex
Index of the recipient in the message associated with the hCryptProv private key.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CryptMsgControl


CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA

The CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA structure is used to delete an unauthenticated attribute of a signer of a signed message. This structure is passed to CryptMsgControl if dwCrlType is CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR.

typedef struct _CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA {
  DWORD               cbSize;
  DWORD               dwSignerIndex;
  DWORD               dwUnauthAttrIndex;
} CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA, *PCMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA;

Members

cbSize
Size of this structure in bytes.
dwSignerIndex
Index of the signer in the rgSigners array of pointers to CMSG_SIGNER_ENCODE_INFO structures in a signed message's CMSG_SIGNED_ENCODE_INFO structure. The unauthenticated attribute for this signer is deleted.
dwUnauthAttrIndex
Index of the element in the rgUnauthAttr array of the CMSG_SIGNER_ENCODE_INFO structure holding the unauthenticated attribute to be removed.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CryptMsgControl


CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA

The CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA structure contains information used to verify a message signature. It contains the signer index and signer public key. The signer public key can be the signer's CERT_PUBLIC_KEY_INFO structure, certificate context, or chain context.

typedef struct _CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA {
  DWORD               cbSize;
  HCRYPTPROV          hCryptProv;
  DWORD               dwSignerIndex;
  DWORD               dwSignerType;
  void                *pvSigner;
} CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA, *PCMSG_CTRL_VERIFY_SIGNATURE_EX_PARA;

Members

cbSize
Size of this structure in bytes.
hCryptProv
Handle to the cryptographic provider used to verify the signature. If NULL, the cryptographic provider specified in CryptMsgOpenToDecode is used. If the hCryptProv in CryptMsgOpenToDecode is also NULL, the default provider according to the signer's public key OID is used.
dwSignerIndex
Index of the signer in the message.
dwSignerType
Indication of the structure containing the signer information. The following table shows the predefined values and the structures indicated.
Value | pvSigner structure pointed to
CMSG_VERIFY_SIGNER_PUBKEY | CERT_PUBLIC_KEY_INFO
CMSG_VERIFY_SIGNER_CERT | CCERT_CONTEXT
CMSG_VERIFY_SIGNER_CHAIN | CERT_CHAIN_CONTEXT

pvSigner
Pointer to a CERT_PUBLIC_KEY_INFO structure, a certificate context, or a chain context depending on the value of dwSignerType.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CMSG_ENVELOPED_ENCODE_INFO

The CMSG_ENVELOPED_ENCODE_INFO structure contains information needed to encode an enveloped message. It is passed to CryptMsgOpenToEncode if dwMsgType is CMSG_ENVELOPED.

typedef struct _CMSG_ENVELOPED_ENCODE_INFO {
  DWORD                        cbSize;
  HCRYPTPROV                   hCryptProv;
  CRYPT_ALGORITHM_IDENTIFIER   ContentEncryptionAlgorithm;
  void*                        pvEncryptionAuxInfo;
  DWORD                        cRecipients;
  PCERT_INFO*                  rgpRecipients;
#ifdef CMSG_ENVELOPED_ENCODE_INFO_HAS_CMS_FIELDS
  PCMSG_RECIPIENT_ENCODE_INFO  rgCmsRecipients;
  DWORD                        cCertEncoded;
  PCERT_BLOB                   rgCertEncoded;
  DWORD                        cCrlEncoded;
  PCRL_BLOB                    rgCrlEncoded;
  DWORD                        cAttrCertEncoded;
  PCERT_BLOB                   rgAttrCertEncoded;
  DWORD                        cUnprotectedAttr;
  PCRYPT_ATTRIBUTE             rgUnprotectedAttr;
#endif
} CMSG_ENVELOPED_ENCODE_INFO,  *PCMSG_ENVELOPED_ENCODE_INFO;

Members

cbSize
Size of this structure in bytes.
hCryptProv
Specifies a handle to the cryptographic service provider (CSP) used to do content encryption, recipient key encryption, and export. The hCryptProv's private keys are not used.

Unless there is a strong reason for passing in a specific cryptographic provider in hCryptProv, pass zero to use the default RSA or DSS provider.

ContentEncryptionAlgorithm
CRYPT_ALGORITHM_IDENTIFIER structure containing the signature algorithm type and any associated additional parameters in encoded form.

The pszObjId member of the structure specifies the algorithm used to encrypt the message contents.

The following encryption algorithms require an encoded eight byte initialization vector (IV) in the Parameters member of structure. For details, see CryptSetKeyParam.
Defined value | Algorithm OID
CALG_DES | szOID_OIWSEC_desCBC
CALG_3DES | szOID_RSA_DES_EDE3_CBC

If the cbData member of the Parameters member is zero, an ASN.1 encoded OCTET STRING containing the IV is generated using CryptGenRandom.

The szOID_RSA_RC2CBC (CALG_RC2) algorithm requires the pbData member of Parameters to be an encoded CRYPT_RC2_CBC_PARAMETERS structure. If the cbData member of the Parameters member is zero, an ASN.1 encoded CRYPT_RC2_CBC_PARAMETERS is generated with a default value of 40 for the dwVersion member. This sets the default key length to 40 bits. This default key length can be overridden with pvEncryptionAuxInfo pointing to a CMSG_RC2_AUX_INFO structure containing the desired key length.

Note On decryption, if an IV exists, CryptSetKeyParam is called with the IV before decryption begins.

pvEncryptionAuxInfo
Pointer to a structure depending on the encryption algorithm.
Encryption algorithm | Structure used
RC2 | CMSG_RC2_AUX_INFO
RC4 | CMSG_RC4_AUX_INFO
SP3 or compatible | CMSG_SP3_COMPATIBLE_AUX_INFO
All other encryption algorithms | NULL

cRecipients
Number of elements in the rgpRecipients or rgCmsRecipients array.
rgpRecipients
Array of pointers to CERT_INFO structures, each containing a recipient's certificate Issuer, SerialNumber, and SubjectPublicKeyInfo. This array can only be used for recipients identified by their Issuer and serial number. If rgpRecipients is not NULL, rgCmsRecipients must be NULL.
rgCmsRecipients
This member can optionally be defined with Windows 2000. Array of pointers to CMSG_RECIPIENT_ENCODE_INFO structures containing recipient information. If rgCmsRecipients is not NULL, rgpRecipients must be NULL. CMSG_ENVELOPED_ENCODE_INFO_HAS_CMS_FIELDS must be defined to reference this field.
cCertEncoded
This member can optionally be defined with Windows 2000. DWORD indicating the number of encoded certificates in the rgCertEncoded array. CMSG_ENVELOPED_ENCODE_INFO_HAS_CMS_FIELDS must be defined to reference this field.
rgCertEncoded
This member can optionally be defined with Windows 2000. Array of CERT_BLOB structures. CMSG_ENVELOPED_ENCODE_INFO_HAS_CMS_FIELDS must be defined to reference this field.
cCrlEncoded
This member can optionally be defined with Windows 2000. DWORD indicating the number of encoded CRLs in the rgCRLEncoded array. CMSG_ENVELOPED_ENCODE_INFO_HAS_CMS_FIELDS must be defined to reference this field.
rgCrlEncoded
This member can optionally be defined with Windows 2000. Array of CRL_BLOB structures. CMSG_ENVELOPED_ENCODE_INFO_HAS_CMS_FIELDS must be defined to reference this field.
cAttrCertEncoded
This member can optionally be defined with Windows 2000. DWORD indicating the number of encoded certificate attributes in the rgAttrCertEncoded array. CMSG_ENVELOPED_ENCODE_INFO_HAS_CMS_FIELDS must be defined to reference this field.
rgAttrCertEncoded;
This member can optionally be defined with Windows 2000. Array of CRL_BLOB structures. CMSG_ENVELOPED_ENCODE_INFO_HAS_CMS_FIELDS must be defined to reference this field.
cUnprotectedAttr
This member can optionally be defined with Windows 2000. DWORD indicating the number of unprotected attributes in the rgUnprotectedAttr array. CMSG_ENVELOPED_ENCODE_INFO_HAS_CMS_FIELDS must be defined to reference this field.
rgUnprotectedAttr
This member can optionally be defined Windows 2000. Array of CRYPT_ATTRIBUTE structures. CMSG_ENVELOPED_ENCODE_INFO_HAS_CMS_FIELDS must be defined to reference this field.

Remarks

CMSG_ENVELOPED_ENCODE_INFO_HAS_CMS_FIELDS must be defined to reference the following structure members:

rgCmsRecipients
cCertEncoded
rgCertEncoded
cCrlEncoded
rgCrlEncoded
cAttrCertEncoded
rgAttrCertEncoded
cUnprotectedAttr
rgUnprotectedAttr

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Wincrypt.h.

See Also

CERT_INFO, CRYPT_ALGORITHM_IDENTIFIER


CMSG_HASHED_ENCODE_INFO

The CMSG_ENVELOPED_ENCODE_INFO structure is used with hashed messages. It is passed to CryptMsgOpenToEncode if dwMsgType is CMSG_ENVELOPED.

typedef struct _CMSG_ENVELOPED_ENCODE_INFO {
  DWORD                        cbSize;
  HCRYPTPROV                   hCryptProv;
  CRYPT_ALGORITHM_IDENTIFIER   HashAlgorithm;
  void*                        pvHashAuxInfo;
} CMSG_ENVELOPED_ENCODE_INFO,  *PCMSG_ENVELOPED_ENCODE_INFO;

Members

cbSize
Size of this structure in bytes.
hCryptProv
Specifies a handle to the cryptographic service provider (CSP) used to do the hash. The hCryptProv private keys are not used.

Unless there is a strong reason for passing in a specific cryptographic provider in hCryptProv, pass zero to use the default RSA or DSS provider to be acquired before doing hash, signature verification, or recipient encryption operations.

HashAlgorithm
CRYPT_ALGORITHM_IDENTIFIER structure containing the hash algorithm type and any associated additional parameters.
pvHashAuxInfo
Currently not used and must be set to NULL.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPT_ALGORITHM_IDENTIFIER


CMSG_KEY_AGREE_RECIPIENT_INFO

The CMSG_KEY_AGREE_RECIPIENT_INFO structure contains information used for key agreement algorithms.

typedef struct _CMSG_KEY_AGREE_RECIPIENT_INFO {
  DWORD                       dwVersion;
  DWORD                       dwOriginatorChoice;
  union {
    CERT_ID                     OriginatorCertId;
    CERT_PUBLIC_KEY_INFO        OriginatorPublicKeyInfo;
  };
  CRYPT_DATA_BLOB             UserKeyingMaterial;
  CRYPT_ALGORITHM_IDENTIFIER  KeyEncryptionAlgorithm;
  DWORD                       cRecipientEncryptedKeys;
  PCMSG_RECIPIENT_ENCRYPTED_KEY_INFO
                          *rgpRecipientEncryptedKeys;
} CMSG_KEY_AGREE_RECIPIENT_INFO, *PCMSG_KEY_AGREE_RECIPIENT_INFO;

Members

dwVersion
Indicates the version of the structure. Always set to three (3).
dwOriginatorChoice
Indicates which choice of message originator's key identifier is to be used.
dwOriginatorChoice value | Id type used
CMSG_KEY_AGREE_ORIGINATOR_CERT | OriginatorCertId
CMSG_KEY_AGREE_ORIGINATOR_PUBLIC_KEY | OriginatorPublicKeyInfo

OriginatorCertId
CERT_ID identifying the originator's public key.
OriginatorPublicKeyInfo
CERT_PUBLIC_KEY_INFO structure containing the originator's public key.
UserKeyingMaterial
BLOB. Optional. With some key agreement algorithms, the sender provides the bits of this BLOB to insure that a different key is generated each time the same two parties generate a pair-wise key.
KeyEncryptionAlgorithm
CRYPT_ALGORITHM_IDENTIFIER that identifies the key-encryption algorithm and any associated parameters used to encrypt the content encryption key.
cRecipientEncryptedKeys
Count of the number of recipient keys.
rgpRecipientEncryptedKeys
Array of CMSG_RECIPIENT_ENCRYPTED_KEY_INFO structures. Each structure contains a recipient identifier and an encrypted key for a recipient.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO

The CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO structure contains encoded key transport information for a message recipient.

typedef struct _CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO {
  DWORD                       cbSize;
  CRYPT_ALGORITHM_IDENTIFIER  KeyEncryptionAlgorithm;
  void                        *pvKeyEncryptionAuxInfo;
  HCRYPTPROV                  hCryptProv;
  CRYPT_BIT_BLOB              RecipientPublicKey;
  CERT_ID                     RecipientId;
} CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO, *PCMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO;

Members

cbSize
DWORD indicating the size of the structure.
KeyEncryptionAlgorithm
CRYPT_ALGORITHM_IDENTIFIER that identifies the key-encryption algorithm and any associated parameters used to encrypt the content encryption key.
pvKeyEncryptionAuxInfo
Void pointer to a structure containing additional information on the encryption. The format of the structure is dependent upon the algorithm indicated by KeyEncryptionAlgorithm.
hCryptProv
HCRYPTPROV used to do the recipient key encryption and export. The provider's private keys are not used. If hCryptProv is NULL, the HCRYPTPROV specified in the CMSG_ENVELOPED_ENCODE_INFO is used.

Note that this HCRYPTPROV is not released even if CMSG_CRYPT_RELEASE_CONTEXT_FLAG is set in the dwFlags parameter passed to CryptMsgOpenToEncode.

RecipientPublicKey
CRYPT_BIT_BLOB containing the recipient's public key.
RecipientId
CERT_ID identifying the recipient. CMSsupports the KEY_IDENTIFIER and ISSUER_SERIAL_NUMBER CERT_IDs. PKCS #7 version 1.5 only supports the ISSUER_SERIAL_NUMBER CERT_IDs.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CMSG_KEY_TRANS_RECIPIENT_INFO

The CMSG_KEY_TRANS_RECIPIENT_INFO structure contains information used in key transport algorithms.

typedef struct _CMSG_KEY_TRANS_RECIPIENT_INFO {
  DWORD                       dwVersion;
  CERT_ID                     RecipientId;
  CRYPT_ALGORITHM_IDENTIFIER  KeyEncryptionAlgorithm;
  CRYPT_DATA_BLOB             EncryptedKey;
} CMSG_KEY_TRANS_RECIPIENT_INFO, *PCMSG_KEY_TRANS_RECIPIENT_INFO;

Members

dwVersion
Indicates the version of the structure. If RecipientId uses the ISSUER_SERIAL_NUMBER to identify the recipient, dwVersion is set to zero (0), If RecipientId uses KEYID, dwVersion is set to two (2).
RecipientId
CERT_ID identifying the recipient. Currently, only ISSUER_SERIAL_NUMBER or KEYID choices in the CERT_ID are valid.
KeyEncryptionAlgorithm
CRYPT_ALGORITHM_IDENTIFIER that identifies the key-encryption algorithm and any associated parameters used to encrypt the content encryption key.
EncryptedKey
BLOB containing the bytes of the encrypted session key.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CMSG_MAIL_LIST_RECIPIENT_INFO

The CMSG_MAIL_LIST_RECIPIENT_INFO structure contains information used for previously distributed symmetric key-encryption keys (KEK).

typedef struct _CMSG_MAIL_LIST_RECIPIENT_INFO {
  DWORD                       dwVersion;
  CRYPT_DATA_BLOB             KeyId;
  CRYPT_ALGORITHM_IDENTIFIER  KeyEncryptionAlgorithm;
  CRYPT_DATA_BLOB             EncryptedKey;
  FILETIME                    Date;
  PCRYPT_ATTRIBUTE_TYPE_VALUE pOtherAttr;
} CMSG_MAIL_LIST_RECIPIENT_INFO, *PCMSG_MAIL_LIST_RECIPIENT_INFO;

Members

dwVersion
Indicates the version of the structure. This member is always four (4).
KeyId
BLOB that identifies a symmetric key-encryption key previously distributed to the sender and one or more recipients.
KeyEncryptionAlgorithm
CRYPT_ALGORITHM_IDENTIFIER that identifies the key-encryption algorithm and any associated parameters used to encrypt the content encryption key.
EncryptedKey
BLOB containing the encrypted content encryption key.
Date
Optional. When present, this member specifies a single key-encryption key from a previously distributed set.
pOtherAttr
Optional pointer to a CRYPT_ATTRIBUTE_TYPE_VALUE structure containing additional information.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CMSG_RC2_AUX_INFO

The CMSG_RC2_AUX_INFO structure contains the bit length of the key for RC2 encryption algorithms. The pvEncryptionAuxInfo member in CMSG_ENVELOPED_ENCODE_INFO can be set to point to an instance of this structure.

Note This structure is only used when the other members of a CMSG_ENVELOPED_ENCODE_INFO structure indicate that a default key length of 40 bits is to be used with an RC2 encryption algorithm. See CMSG_ENVELOPED_ENCODE_INFO for details.

typedef struct _CMSG_RC2_AUX_INFO {
  DWORD                       cbSize;
  DWORD                       dwBitLen;
} CMSG_RC2_AUX_INFO, *PCMSG_RC2_AUX_INFO;

Members

cbSize
Size of this structure in bytes.
dwBitLen
Specifies the RC2 effective key length. Currently 40-, 64-, and 128-bit lengths are supported.

Note This value is the actual key bit length to be used. The values of the dwVersion member of a CRYPT_RC2_CBC_PARAMETERS structure to indicate the use of a specific key length is not that specific key length. For example, the dwVersion value that indicates the use of a 128-bit key length is CRYPT_RC2_128BIT_VERSION, which is defined as 58, not 128 bits.

If dwBitLen is set to CMSG_SP3_COMPATIBLE_ENCRYPT_FLAG, SP3 compatible encryption is done and the 40-bit default length is ignored.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CMSG_ENVELOPED_ENCODE_INFO, CRYPT_ALGORITHM_IDENTIFIER


CMSG_RC4_AUX_INFO

The CMSG_RC2_AUX_INFO structure contains the bit length of the key for RC4 encryption algorithms. The pvEncryptionAuxInfo member in CMSG_ENVELOPED_ENCODE_INFO can be set to point to an instance of this structure.

typedef struct _CMSG_RC4_AUX_INFO {
  DWORD                       cbSize;
  DWORD                       dwBitLen;
} CMSG_RC4_AUX_INFO, *PCMSG_RC4_AUX_INFO;

Members

cbSize
Size of this structure in bytes.
dwBitLen
Determines the RC4 salt length. If set to CMSG_RC4_NO_SALT_FLAG, no salt is generated. For any other value, (128 - the length set) /8 bytes of salt are generated and encoded as an OCTET STRING in the algorithm parameters field.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CMSG_RECIPIENT_ENCRYPTED_KEY_INFO

The CMSG_RECIPIENT_ENCRYPTED_KEY_INFO structure contains information used for an individual key agreement recipient.

typedef struct _CMSG_RECIPIENT_ENCRYPTED_KEY_INFO {
  CERT_ID                     RecipientId;
  CRYPT_DATA_BLOB             EncryptedKey;
  FILETIME                    Date;
  PCRYPT_ATTRIBUTE_TYPE_VALUE pOtherAttr;
} CMSG_RECIPIENT_ENCRYPTED_KEY_INFO, *PCMSG_RECIPIENT_ENCRYPTED_KEY_INFO;

Members

RecipientId
CERT_ID identifying the recipient. Currently, only ISSUER_SERIAL_NUMBER or KEYID choices in the CERT_ID are valid.
EncryptedKey
BLOB containing the encrypted content encryption key.
Date
Optional. When present, this member specifies which of the recipient's previously distributed UKMs was used by the sender. Only applicable to KEYID choice in the RecipientId CERT_ID.
pOtherAttr
Optional pointer to a CRYPT_ATTRIBUTE_TYPE_VALUE structure containing additional information. Only applicable to KEYID choice in the RecipientId CERT_ID.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CMSG_SP3_COMPATIBLE_AUX_INFO

The CMSG_SP3_COMPATIBLE_AUX_INFO structure contains information needed for SP3 compatible encryption.

typedef struct _CMSG_SP3_COMPATIBLE_AUX_INFO {
  DWORD                       cbSize;
  DWORD                       dwFlags;
} CMSG_SP3_COMPATIBLE_AUX_INFO, *PCMSG_SP3_COMPATIBLE_AUX_INFO;

Members

cbSize
Size of this structure in bytes.
dwFlags
Setting CMSG_SP3_COMPATIBLE_ENCRYPT_FLAG enables SP3 compatible encryption. Zero salt instead of no salt and the encryption algorithm parameters are NULL instead of containing encoded RC2 parameters or encoded IV octet string. The encrypted symmetric key is encoded little-endian instead of big-endian form.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.


CMSG_SIGNED_ENCODE_INFO

The CMSG_SIGNED_ENCODE_INFO structure contains information to be passed to CryptMsgOpenToEncode if dwMsgType is CMSG_SIGNED.

The last two members of this structure were added with Windows 2000 and can optionally be used with CMS for PKCS #7 processing.

typedef struct _CMSG_SIGNED_ENCODE_INFO {
  DWORD                      cbSize;
  DWORD                      cSigners;
  PCMSG_SIGNER_ENCODE_INFO   rgSigners;
  DWORD                      cCertEncoded;
  PCERT_BLOB                 rgCertEncoded;
  DWORD                      cCrlEncoded;
  PCRL_BLOB                  rgCrlEncoded;
#ifdef CMSG_SIGNED_ENCODE_INFO_HAS_CMS_FIELDS
  DWORD                      cAttrCertEncoded;
  PCERT_BLOB                 rgAttrCertEncoded;
#endif
CMSG_SIGNED_ENCODE_INFO,   *PCMSG_SIGNED_ENCODE_INFO;

Members

cbSize
Size of this structure in bytes.
cSigners
Number of elements in the rgSigners array.
rgSigners
Array of pointers to CMSG_SIGNER_ENCODE_INFO structures each holding signer information.
cCertEncoded
Number of elements in the rgCertEncoded array.
rgCertEncoded
Array of pointers to CERT_BLOB structures, each containing an encoded certificate.
cCrlEncoded
Number of elements in the array rgCrlEncoded.
rgCrlEncoded
Array of pointers to CRL_BLOB structures, each containing an encoded CRL.
cAttrCertEncoded
Count of encoded attribute certificates. Used only if CMSG_SIGNED_ENCODE_INFO_HAS_CMS_FIELDS is defined.
rgAttrCertEncoded
Array of encoded attribute certificates. Used only if CMSG_SIGNED_ENCODE_INFO_HAS_CMS_FIELDS is defined.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB, CMSG_SIGNER_ENCODE_INFO


CMSG_SIGNER_ENCODE_INFO

The CMSG_SIGNER_ENCODE_INFO structure contains signer information. It is passed to CryptMsgCountersign, CryptMsgCountersignEncoded, and optionally to CryptMsgOpenToEncode as a member of CMSG_SIGNED_ENCODE_INFO if dwMsgType is CMSG_SIGNED.

The last three members of this structure were added with Windows 2000 and can be used with CMS for PKCS #7 processing.

typedef struct _CMSG_SIGNER_ENCODE_INFO {
  DWORD                       cbSize;
  PCERT_INFO                  pCertInfo;
  HCRYPTPROV                  hCryptProv;
  DWORD                       dwKeySpec;
  CRYPT_ALGORITHM_IDENTIFIER  HashAlgorithm;
  void*                       pvHashAuxInfo;
  DWORD                       cAuthAttr;
  PCRYPT_ATTRIBUTE            rgAuthAttr;
  DWORD                       cUnauthAttr;
  PCRYPT_ATTRIBUTE            rgUnauthAttr;
  CERT_ID                     SignerId;
  CRYPT_ALGORITHM_IDENTIFIER  HashEncryptionAlgorithm;
  void*                       pvHashEncryptionAuxInfo;
#ifdef CMSG_SIGNER_ENCODE_INFO_HAS_CMS_FIELDS
  CERT_ID                     SignerId;
  CRYPT_ALGORITHM_IDENTIFIER  HashEncryptionAlgorithm;
  void                        *pvHashEncryptionAuxInfo;
#endif
} CMSG_SIGNER_ENCODE_INFO,   *PCMSG_SIGNER_ENCODE_INFO;

Members

cbSize
Size of this structure in bytes.
pCertInfo
Pointer to a CERT_INFO containing:

Issuer
SerialNumber
SubjectPublicKeyInfo

The pbData members of the Issuer and SerialNumber structures combined uniquely identify a certificate. The Algorithm member of the SubjectPublicKeyInfo structure specifies the hash encryption algorithm used.

hCryptProv
Handle to the cryptographic service provider (CSP).
dwKeySpec
Specifies the private key to be used.

The following dwKeySpec values are defined for the default provider.
Value | Meaning
AT_KEYEXCHANGE | Keys used to encrypt/decrypt session keys.
AT_SIGNATURE | Keys used to create and verify digital signatures.

If dwKeySpec is zero, then the default AT_KEYEXCHANGE is used.

HashAlgorithm
CRYPT_ALGORITHM_IDENTIFIER structure specifying the hash algorithm.
pvHashAuxInfo
Currently not used and must be set to NULL.
cAuthAttr
Number of elements in the rgAuthAttr array. If no authenticated attributes are present in rgAuthAttr, then cAuthAttr is zero
rgAuthAttr
Array of pointers to CRYPT_ATTRIBUTE structures, each containing authenticated attribute information.

The PKCS #9 standard dictates that if there are any attributes, there must be at least two—the content type object identifier (OID) and the hash of the message. These attributes are automatically added by the system.

cUnauthAttr
Number of elements in the rgUnauthAttr array. If no unauthenticated attributes, cUnauthAttr is zero.
rgUnauthAttr
Array of pointers to CRYPT_ATTRIBUTE structures, each holding unauthenticated attribute information. Unauthenticated attributes can contain countersignatures among other uses.
SignerId
CERT_ID containing a unique identifier of the signer's certificate. This member can optionally be used with PKCS # 7 with CMS. If this member is present and its dwIdChoice member is not zero, it is used to identify to the certificate instead of the Issuer and SerialNumber members of the CERTINFO structure pointed to by pCertInfo.
HashEncryptionAlgorithm
CRYPT_ALGORITHM_IDENTIFIER optionally used with PKCS #7 with CMS. If this member is not NULL, the algorithm identified is used instead of the SubjectPublicKeyInfo.Algorithm algorithm.
pvHashEncryptionAuxInfo
Currently not used. It must be set to NULL if it is present in the data structure.
SignerId
CERT_ID. If not NULL, its dwIdChoice member is used instead of the Issuer and SerialNumber in pCertInfo. CMS supports the KEY_IDENTIFIER and ISSUER_SERIAL_NUMBER CERT_IDs. PKCS #. Version 1.5 only supports the ISSUER_SERIAL_NUMBER CERT_ID choice. Can be used only if CMSG_SIGNER_ENCODE_INFO_HAS_CMS_FIELDS is defined.
HashEncryptionAlgorithm
CRYPT_ALGORITHM_IDENTIFIER. If present and not NULL, used instead of the PublicKeyInfo.Algorithm. For RSA, the hash encryption algorithm is normally the same as the public key algorithm. For DSA, the hash encryption algorithm is normally a DSS signature algorithm. Can be used only if CMSG_SIGNER_ENCODE_INFO_HAS_CMS_FIELDS is defined.
pvHashEncryptionAuxInfo
Currently not used and, if present, must be set to NULL. This member is present only if CMSG_SIGNER_ENCODE_INFO_HAS_CMS_FIELDS is defined.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CERT_INFO, CRYPT_ALGORITHM_IDENTIFIER, CRYPT_ATTRIBUTE, CryptMsgControl, CryptMsgCountersign


CMSG_SIGNER_INFO

The CMSG_SIGNER_INFO structure contains the content of the PKCS #7 defined SignerInfo in signed messages. In decoding a received message, CryptMsgGetParam is called for each signer to get a CMSG_SIGNER_INFO structure.

typedef struct _CMSG_SIGNER_INFO {
  DWORD                       dwVersion;
  CERT_NAME_BLOB              Issuer;
  CRYPT_INTEGER_BLOB          SerialNumber;
  CRYPT_ALGORITHM_IDENTIFIER  HashAlgorithm;
  CRYPT_ALGORITHM_IDENTIFIER  HashEncryptionAlgorithm;
  CRYPT_DATA_BLOB             EncryptedHash;
  CRYPT_ATTRIBUTES            AuthAttrs;
  CRYPT_ATTRIBUTES            UnauthAttrs;
} CMSG_SIGNER_INFO,           *PCMSG_SIGNER_INFO;

Members

dwVersion
The version of this structure.
Issuer
CERT_NAME_BLOB containing the issuer of a certificate with the public key needed to verify a signature.
SerialNumber
CRYPT_INTEGER_BLOB containing the serial number of the certificate containing the public key needed to verify a signature. See CERT_INFO for details.
HashAlgorithm
CRYPT_ALGORITHM_IDENTIFIER structure specifying the algorithm used in generating the hash of a message.
HashEncryptionAlgorithm
CRYPT_ALGORITHM_IDENTIFIER structure specifying the algorithm used to encrypt the hash.
EncryptedHash
CRYPT_DATA_BLOB containing the encrypted hash of the message, the signature.
AuthAttrs
CRYPT_ATTRIBUTES structure containing authenticated attributes of the signer.
UnauthAttrs
CRYPT_ATTRIBUTES structure containing unauthenticated attributes of the signer.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPTOAPI_BLOB, CRYPT_ALGORITHM_IDENTIFIER, CRYPT_ATTRIBUTES


CMSG_STREAM_INFO

The CMSG_STREAM_INFO structure is used to enable processing stream data rather than single block processing. Stream processing is most often used when processing large messages. Stream-process messages can originate from any serialized source such as a file on a hard disk, a server, or a CD ROM.

This structure is passed to CryptMsgOpenToEncode and CryptMsgOpenToDecode.

Messages can be so large that processing them all at once by storing the whole message in memory can be difficult, if not impossible. It is possible to process large messages without encountering memory limitations by streaming the data that is to be processed into manageable sized blocks. The low-level message functions can be used with streaming to encode or decode a message. Any level of nesting of messages is supported when streaming to encode and streaming to decode.

The input message to be processed as a stream feeds into CryptMsgUpdate one block at a time, with the application determining the size of the block. As the streamed message is processed for encoding or decoding, the resulting output data is passed back to the application through an application specified–callback function specified by the pfnStreamOutput member.

No assumptions can be made about the block size of the output data since the size can vary for several reasons such as the jitter in output block size caused by the block size for the encryption algorithm when processing an enveloped message, or when blocks that contain the message header and the SignerInfo as defined by PKCS # 7 are processed.

The size of the output block is passed to the callback function in its cbData parameter The use of output data is determined in the calling application. Typically, output from stream processing will not be persisted in memory as a whole due to memory limitations, but will be serialized to a disk or server file.

typedef struct _CMSG_STREAM_INFO {
  DWORD                    cbContent;
  PFN_CMSG_STREAM_OUTPUT   pfnStreamOutput;
  void                    *pvArg;
} CMSG_STREAM_INFO, *PCMSG_STREAM_INFO;

Members

cbContent
Specifies the size of the content in bytes. Normal DER encoding is used unless a 0xFFFFFFFF is passed indicating that the application is not specifying the content length. This forces the use of indefinite-length BER encoding.
pfnStreamOutput
Address of a callback function used to read from and write data to a disk when processing large messages.

The callback function must have the following signature and parameters:

BOOL WINAPI CmsgStreamOutputCallback(
  IN const void *pvArg,  //in
  IN BYTE *pbData,       //in
  IN DWORD cbData,       //in
  IN BOOL fFinal         //in
);
pvArg
The arguments specified by CMSG_STREAM_INFO.
pbData
Pointer to a block of processed data that is available to the application.
cbData
Size, in bytes, of the block of processed data at pbData.
fFinal
Specifies that the last block of data is being processed and that this is the last time the callback will be executed.
pvArg
Pointer to the argument to pass to the callback function. Typically, this is used for state data that includes the handle to a more deeply nested message (when decoding) or a less deeply nested message (when encoding).

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.


CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO

The CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO structure contains information on a message receiver used to decrypt the session key needed to decrypt the message contents. This structure is used with CMS low level messages using any of the key management methods.

typedef struct _CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO {
  DWORD                         cbSize;
  CRYPT_BIT_BLOB                RecipientPublicKey;
  CERT_ID                       RecipientId;
  FILETIME                      Date;
  PCRYPT_ATTRIBUTE_TYPE_VALUE   pOtherAttr;
} CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO,
  *PCMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO;

Members

cbSize
Size of this data structure in bytes.
RecipientPublicKey
CRYPT_BIT_BLOB containing the recipient's public key.
RecipientId;
CERT_ID identifying a message recipient's public key.
Date
Optional FILETIME. Applicable only if the CERT_ID identifies the receiver's public key with a KEY_IDENTIFIER.
pOtherAttr;
Optional. Pointer to a CRYPT_ATTRIBUTE_TYPE_VALUE. Applicable only if the CERT_ID identifies the receiver's public key with a KEY_IDENTIFIER.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO

The CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO structure contains information on a message recipient using key agreement key management.

typedef struct _CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO {
  DWORD                       cbSize;
  CRYPT_ALGORITHM_IDENTIFIER  KeyEncryptionAlgorithm;
  void                        *pvKeyEncryptionAuxInfo;
  CRYPT_ALGORITHM_IDENTIFIER  KeyWrapAlgorithm;
  void                        *pvKeyWrapAuxInfo;
  HCRYPTPROV                  hCryptProv;
  DWORD                       dwKeySpec;
  DWORD                       dwKeyChoice;
  union {
    PCRYPT_ALGORITHM_IDENTIFIER pEphemeralAlgorithm;
    PCERT_ID                    pSenderId;
  };
  CRYPT_DATA_BLOB             UserKeyingMaterial;
  DWORD                       cRecipientEncryptedKeys;
  PCMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO
                             *rgpRecipientEncryptedKeys;
} CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO, *PCMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO;

Members

cbSize
Size of this data structure in bytes.
KeyEncryptionAlgorithm
CRYPT_ALGORITHM_IDENTIFIER structure indicating the encryption algorithm used.
pvKeyEncryptionAuxInfo
Pointer to a structure containing any additional encryption information.
KeyWrapAlgorithm
CRYPT_ALGORITHM_IDENTIFIER structure containing information on the algorithm used for key wrapping.
pvKeyWrapAuxInfo
Pointer to a structure containing any additional encryption information.
hCryptProv
HCRYPTPROV must be specified for the CMSG_KEY_AGREE_STATIC_KEY_CHOICE. This member is optional for CMSG_KEY_AGREE_EPHEMERAL_KEY_CHOICE. Specifies the sender's private key.
dwKeySpec
Specifies the sender's private key. Must be specified for the CMSG_KEY_AGREE_STATIC_KEY_CHOICE. It is not applicable for CMSG_KEY_AGREE_EPHEMERAL_KEY_CHOICE.
dwKeyChoice
Indicates the choices of key agreement. Can be either CMSG_KEY_AGREE_EPHEMERAL_KEY_CHOICE to create a temporary public/private key pair to encrypt the content encryption key or CMSG_KEY_AGREE_STATIC_KEY_CHOICE to use the sender's existing private key for encryption of the key.
pEphemeralAlgorithm
Pointer to a CRYPT_ALGORITHM_IDENTIFIER structure. This is the CMSG_KEY_AGREE_EPHEMERAL_KEY_CHOICE. Contains the ephemeral public key algorithm and parameters.
pSenderId;
Pointer to the CERT_ID of the sender's certificate. Used with CMSG_KEY_AGREE_STATIC_KEY_CHOICE.
UserKeyingMaterial
OPTIONAL CRYPT_DATA_BLOB containing user keying material (UKM) provided by the sender to ensure that a different key is generated each time the same two parties generate a pair-wise key.
cRecipientEncryptedKeys
Number of elements in the rgpRecipientEncryptedKeys array.
rgpRecipientEncryptedKeys
Array of CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO structures, one for each recipient to receive this key agreement key.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CMSG_MAIL_LIST_RECIPIENT_ENCODE_INFO

The CMSG_MAIL_LIST_RECIPIENT_ENCODE_INFO structure is used with previously distributed symmetric keys for decrypting the content key encryption key (KEK).

typedef struct _CMSG_MAIL_LIST_RECIPIENT_ENCODE_INFO {
  DWORD                       cbSize;
  CRYPT_ALGORITHM_IDENTIFIER  KeyEncryptionAlgorithm;
  void                        *pvKeyEncryptionAuxInfo;
  HCRYPTPROV                  hCryptProv;
  DWORD                       dwKeyChoice;
  union {
    HCRYPTKEY                   hKeyEncryptionKey;
    void                        *pvKeyEncryptionKey;
  };
  CRYPT_DATA_BLOB             KeyId;
  FILETIME                    Date;
  PCRYPT_ATTRIBUTE_TYPE_VALUE pOtherAttr;
} CMSG_MAIL_LIST_RECIPIENT_ENCODE_INFO, *PCMSG_MAIL_LIST_RECIPIENT_ENCODE_INFO;

Members

cbSize
Size of this data structure in bytes.
KeyEncryptionAlgorithm
CRYPT_ALGORITHM_IDENTIFIER structure indicating the encryption algorithm used.
pvKeyEncryptionAuxInfo
Pointer to a structure containing any additional encryption information.
hCryptProv
The provider used to do the recipient key encryption and export. If NULL, the provider specified in CMSG_ENVELOPED_ENCODE_INFO is used.
dwKeyChoice
Indicate which member of the following union will be used. Currently only CMSG_MAIL_LIST_HANDLE_KEY_CHOICE can be used.
hKeyEncryptionKey
HCRYPTKEY Used with the CMSG_MAIL_LIST_HANDLE_KEY_CHOICE value of dwKeyChoice.
pvKeyEncryptionKey;
Pointer to a void reserve for a future potential pointer choice.
KeyId
CRYPT_DATA_BLOB key identifier of the key-encryption key that was previously distributed to the message sender and one or more recipients.
Date
Optional FILETIME. When present, specifies a single key encryption key (KEK) from a set that was previously distributed.
pOtherAttr
Optional pointer to a CRYPT_ATTRIBUTE_TYPE_VALUE containing encryption attributes.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CMSG_RECIPIENT_ENCODE_INFO

The CMSG_RECIPIENT_ENCODE_INFO structure contains information a message recipient's content encryption key management type.

typedef struct _CMSG_RECIPIENT_ENCODE_INFO {
  DWORD   dwRecipientChoice;
  union {
    PCMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO   pKeyTrans;
    PCMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO   pKeyAgree;
    PCMSG_MAIL_LIST_RECIPIENT_ENCODE_INFO   pMailList;
  };
} CMSG_RECIPIENT_ENCODE_INFO, PCMSG_RECIPIENT_ENCODE_INFO;

Members

dwRecipientChoice
Indicates the union member to be used. The following values are defined.
Value | Description
CMSG_KEY_TRANS_RECIPIENT | Use with key transport key management
CMSG_KEY_AGREE_RECIPIENT | Used with key agreement key management
CMSG_MAIL_LIST_RECIPIENT | Use with previously distributed key encryption key management

pKeyTrans
Pointer to a CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO structure. Used with CMSG_KEY_TRANS_RECIPIENT
pKeyAgree
Pointer to a CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO structure. Used with CMSG_KEY_AGREE_RECIPIENT
pMailList
Pointer to a CMSG_MAIL_LIST_RECIPIENT_ENCODE_INFO structure. Used with CMSG_MAIL_LIST_RECIPIENT

Remark

Only key transport recipients are supported in PKCS #7 version 1.5.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CMSG_CTRL_KEY_TRANS_DECRYPT_PARA

The CMSG_CTRL_KEY_TRANS_DECRYPT_PARA structure containing information about a key transport message recipient.

typedef struct _CMSG_CTRL_KEY_TRANS_DECRYPT_PARA {
  DWORD                           cbSize;
  HCRYPTPROV                      hCryptProv;
  DWORD                           dwKeySpec;
  PCMSG_KEY_TRANS_RECIPIENT_INFO  pKeyTrans;
  DWORD                           dwRecipientIndex;
} CMSG_CTRL_KEY_TRANS_DECRYPT_PARA, *PCMSG_CTRL_KEY_TRANS_DECRYPT_PARA;

Members

cbSize
Size of this data structure in bytes.
hCryptProv
The provider used to do the recipient key encryption and export. If NULL, the provider specified in CMSG_ENVELOPED_ENCODE_INFO is used.
dwKeySpec
Specifies the encrypted key. It is the result of encrypting the content-encryption key for a specific recipient using that recipient's public key.
pKeyTrans
Pointer to a CMSG_KEY_TRANS_RECIPIENT_INFO structure
dwRecipientIndex
Indicates a specific recipient in any array of recipients.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CMSG_CTRL_KEY_AGREE_DECRYPT_PARA

The CMSG_CTRL_KEY_AGREE_DECRYPT_PARA structure contains information about a key agreement recipient.

typedef struct _CMSG_CTRL_KEY_AGREE_DECRYPT_PARA {
  DWORD                   cbSize;
  HCRYPTPROV              hCryptProv;
  DWORD                   dwKeySpec;
  PCMSG_KEY_AGREE_RECIPIENT_INFO
                          pKeyAgree;
  DWORD                   dwRecipientIndex;
  DWORD                   dwRecipientEncryptedKeyIndex;
  CRYPT_BIT_BLOB          OriginatorPublicKey;
} CMSG_CTRL_KEY_AGREE_DECRYPT_PARA, *PCMSG_CTRL_KEY_AGREE_DECRYPT_PARA;

Members

cbSize;
Size of this data structure in bytes.
hCryptProv
The provider used to do the recipient key encryption and export. If NULL, the provider specified in CMSG_ENVELOPED_ENCODE_INFO is used.
dwKeySpec
Specifies the encrypted key. It is the result of encrypting the content-encryption key.
pKeyAgree
Pointer to a CMSG_KEY_AGREE_RECIPIENT_INFO structure
dwRecipientIndex;
Indicates a specific recipient in any array of recipients.
dwRecipientEncryptedKeyIndex
Indicates a specific encrypted key in an array of encrypted keys.
OriginatorPublicKey
CRYPT_BIT_BLOB containing the sender's public key information.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CMSG_CTRL_MAIL_LIST_DECRYPT_PARA

The CMSG_CTRL_MAIL_LIST_DECRYPT_PARA structure contains information on a mail list message recipient.

typedef struct _CMSG_CTRL_MAIL_LIST_DECRYPT_PARA {
  DWORD                           cbSize;
  HCRYPTPROV                      hCryptProv;
  PCMSG_MAIL_LIST_RECIPIENT_INFO  pMailList;
  DWORD                           dwRecipientIndex;
  DWORD                           dwKeyChoice;
  union {
    HCRYPTKEY                       hKeyEncryptionKey;
    void                            *pvKeyEncryptionKey;
  };
} CMSG_CTRL_MAIL_LIST_DECRYPT_PARA, *PCMSG_CTRL_MAIL_LIST_DECRYPT_PARA;

Members

cbSize
Size of this data structure in bytes.
hCryptProv
The provider used to do the recipient key encryption and export. If hCryptProv is NULL, the provider specified in CMSG_ENVELOPED_ENCODE_INFO is used.
pMailList
Pointer to a CMSG_MAIL_LIST_RECIPIENT_INFO structure
dwRecipientIndex
Indicates a specific recipient in any array of recipients.
dwKeyChoice
Indicates the member of the following union that will be used. Currently only CMSG_MAIL_LIST_HANDLE_KEY_CHOICE is defined.
hKeyEncryptionKey
Handle of the key encryption key. Used with dwKeyChoice set to CMSG_MAIL_LIST_HANDLE_KEY_CHOICE.
pvKeyEncryptionKey
Pointer to a void. Reserved for future use.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


Simplified Message Structures

The following structures are used by the Simplified Message Functions.

  • CRYPT_DECRYPT_MESSAGE_PARA
  • CRYPT_ENCRYPT_MESSAGE_PARA
  • CRYPT_HASH_MESSAGE_PARA
  • CRYPT_SIGN_MESSAGE_PARA
  • CRYPT_VERIFY_MESSAGE_PARA


CRYPT_DECRYPT_MESSAGE_PARA

The CRYPT_DECRYPT_MESSAGE_PARA structures contains information for decrypting messages.

typedef struct _CRYPT_DECRYPT_MESSAGE_PARA {
  DWORD                       cbSize;
  DWORD                       dwMsgAndCertEncodingType;
  DWORD                       cCertStore;
  HCERTSTORE*                 rghCertStore;
#ifdef CRYPT_DECRYPT_MESSAGE_PARA_HAS_EXTRA_FIELDS
  DWORD                       dwFlags;
#endif
} CRYPT_DECRYPT_MESSAGE_PARA,  *PCRYPT_DECRYPT_MESSAGE_PARA;

Members

cbSize
Size of this structure in bytes.
dwMsgAndCertEncodingType
Type of encoding used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
     X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

cCertStore
Number of elements in the rghCertStore array.
rghCertStore
Array of certificate store handles.

These certificate store handles are used to obtain the certificate context to use for decrypting a message. See the decryption functions CryptDecryptMessage, and CryptDecryptAndVerifyMessageSignature. An encrypted message can have one or more recipients. The recipients are identified by a unique certificate identifier, often the hash of the certificate issuer and serial number. The certificate stores are searched to find a certificate context corresponding to the unique identifier.

With Windows 2000, recipients can also be identified by their KeyId. Windows 2000 also allows Key Agreement (Diffie Hellman) in addition to Key Transport (RSA) recipients.

Only certificate contexts in the store with one of the following properties, CERT_KEY_PROV_INFO_PROP_ID, or CERT_KEY_CONTEXT_PROP_ID can be used. These properties specify the location of a needed private exchange key.

DwFlags
With Windows Whistler, the CRYPT_MESSAGE_SILENT_KEYSET_FLAG can be set to suppress any UI by the CSP. For more information on the CRYPT_SILENT flag, see CryptAcquireContext.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CryptDecryptAndVerifyMessageSignature, CryptDecryptMessage


CRYPT_ENCRYPT_MESSAGE_PARA

The CRYPT_ENCRYPT_MESSAGE_PARA structure contains information used to encrypt messages.

typedef struct _CRYPT_ENCRYPT_MESSAGE_PARA {
  DWORD                       cbSize;
  DWORD                       dwMsgEncodingType;
  HCRYPTPROV                  hCryptProv;
  CRYPT_ALGORITHM_IDENTIFIER  ContentEncryptionAlgorithm;
  void                        *pvEncryptionAuxInfo;
  DWORD                       dwFlags;
  DWORD                       dwInnerContentType;
} CRYPT_ENCRYPT_MESSAGE_PARA, *PCRYPT_ENCRYPT_MESSAGE_PARA;

Members

cbSize
Size of this structure in bytes.
dwMsgEncodingType
Type of encoding used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
     X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

hCryptProv
Handle to the cryptographic service provider (CSP) to be used for encryption. The CSP identified by hCryptProv is used to do content encryption, recipient key encryption, and recipient key export. Its private key is not used.

Unless there is a strong reason for passing in a specific cryptographic provider in hCryptProv, pass zero to use the default RSA or DSS provider.

ContentEncryptionAlgorithm
CRYPT_ALGORITHM_IDENTIFIER structure containing the object identifier (OID) of the encryption algorithm. The chosen hCryptProv CSP must support the encryption algorithm.

The following encryption algorithms require that the Parameters member of the structure to contain an encoded eight byte Initialization Vector (IV) (see CryptSetKeyParam for more information about the KP_IV parameter).

szOID_OIWSEC_desCBC (CALG_DES)
szOID_RSA_DES_EDE3_CBC (CALG_3DES)

If the cbData member of the Parameters member is zero, an ASN.1 encoded OCTET STRING containing the IV is generated using CryptGenRandom.

The szOID_RSA_RC2CBC(CALG_RC2) algorithm requires the pbData member of Parameters to be a CRYPT_RC2_CBC_PARAMETERS structure. If the cbData member of the Parameters member is zero, an ASN.1 encoded CRYPT_RC2_CBC_PARAMETERS containing the IV is generated as the pbData member. This generated pbData uses the default dwVersion corresponding to the 40 bit key length. To override the default 40 bit key length, pvEncryptionAuxInfo can be set to point to a CMSG_RC2_AUX_INFO structure that contains a key bit length.

If ContentEncryptionAlgorithm is szOID_RSA_RC4, this member points to a CMSG_RC4_AUX_INFO structure specifying the number of salt bytes to be included.

Note When a message is decrypted, if it has an initialization vector parameter, the cryptographic message functions call CryptSetKeyParam with the initialization vector before decrypting.

pvEncryptionAuxInfo
Pointer to a CMSG_RC2_AUX_INFO structure for RC2 encryption or a CMSG_SP3_COMPATIBLE_AUX_INFO structure for SP3 compatible encryption. For other than RC2 or SP3 compatible encryption, the member must be set to NULL.

For szOID_RSA_RC4 points to a CMSG_RC4_AUX_INFO data structure specifying the number of salt bytes to be included.

dwFlags
Normally set to zero. However, if the encoded output is to be a CMSG_ENVELOPED inner content of an outer cryptographic message, such as a CMSG_SIGNED message, the CRYPT_MESSAGE_BARE_CONTENT_OUT_FLAG must be set. If it is not set, content will be encoded as an inner content type of CMSG_DATA.

With Windows 2000 messages, CRYPT_MESSAGE_ENCAPSULATED_CONTENT_OUT_FLAG can be set to encapsulate non-data inner content within an OCTET STRING before encrypting.

With Windows 2000 messages, CRYPT_MESSAGE_KEYID_RECIPIENT_FLAG can be set to identify recipients by their Key Identifier and not their Issuer and Serial Number.

dwInnerContentType
Normally set to zero. It must be set to set the cryptographic message types if the input to be encrypted is the encoded output of another cryptographic message such as CMSG_SIGNED.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPT_ALGORITHM_IDENTIFIER, CryptEncryptMessage, CryptSignAndEncryptMessage


CRYPT_HASH_MESSAGE_PARA

The CRYPT_HASH_MESSAGE_PARA structure contains data for hashing messages.

typedef struct _CRYPT_HASH_MESSAGE_PARA {
  DWORD                      cbSize;
  DWORD                      dwMsgEncodingType;
  HCRYPTPROV                 hCryptProv;
  CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
  void*                      pvHashAuxInfo;
} CRYPT_HASH_MESSAGE_PARA,    *PCRYPT_HASH_MESSAGE_PARA;

Members

cbSize
Size of this structure in bytes.
dwMsgEncodingType
Type of encoding used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
     X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

hCryptProv
Handle to the cryptographic service provider (CSP) to be used.

Unless there is a strong reason for passing in a specific cryptographic provider in hCryptProv, pass zero to use the default RSA or DSS provider.

HashAlgorithm
CRYPT_ALGORITHM_IDENTIFIER containing the algorithm for generating the hash of the message.
pvHashAuxInfo
Not currently used, and must be set to NULL.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPT_ALGORITHM_IDENTIFIER, CryptHashMessage, CryptVerifyDetachedMessageHash, CryptVerifyMessageHash


CRYPT_SIGN_MESSAGE_PARA

The CRYPT_SIGN_MESSAGE_PARA structure contains information for signing messages using a specified signing certificate context.

typedef struct _CRYPT_SIGN_MESSAGE_PARA {
  DWORD                       cbSize;
  DWORD                       dwMsgEncodingType;
  PCCERT_CONTEXT              pSigningCert;
  CRYPT_ALGORITHM_IDENTIFIER  HashAlgorithm;
  void                        *pvHashAuxInfo;
  DWORD                       cMsgCert;
  PCCERT_CONTEXT              *rgpMsgCert;
  DWORD                       cMsgCrl;
  PCCRL_CONTEXT               *rgpMsgCrl;
  DWORD                       cAuthAttr;
  PCRYPT_ATTRIBUTE            rgAuthAttr;
  DWORD                       cUnauthAttr;
  PCRYPT_ATTRIBUTE            rgUnauthAttr;
  DWORD                       dwFlags;
  DWORD                       dwInnerContentType;
#ifdef CRYPT_SIGN_MESSAGE_PARA_HAS_CMS_FIELDS
  CRYPT_ALGORITHM_IDNETIFIER  HashEncryptionAlgorithm;
  void                        pvHashEncryptionAuxInfo;
#endif
} CRYPT_SIGN_MESSAGE_PARA, *PCRYPT_SIGN_MESSAGE_PARA;

Members

cbSize
Size of this structure in bytes.
dwMsgEncodingType
Type of encoding used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
     X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pSigningCert
Pointer to the CERT_CONTEXT to be used in the signing.

Either the CERT_KEY_PROV_INFO_PROP_ID, or CERT_KEY_CONTEXT_PROP_ID property must be set for the context to provide access to the private signature key.

HashAlgorithm
CRYPT_ALGORITHM_IDENTIFIER containing the hashing algorithm used to hash the data to be signed.
pvHashAuxInfo
Not currently used, and must be set to NULL.
cMsgCert
Number of elements in the rgpMsgCert array of CERT_CONTEXT structures. If set to zero no certificates are included in the signed message.
rgpMsgCert
Array of pointers to CERT_CONTEXT structures to be included in the signed message. If the pSigningCert is to be included, a pointer to it must be in the rgpMsgCert array.
cMsgCrl
Number of elements in the rgpMsgCrl array of pointers to CRL_CONTEXT structures. If set to zero, no CRL_CONTEXT structures are included in the signed message.
rgpMsgCrl
Array of pointers to CRL_CONTEXT structures to be included in the signed message.
cAuthAttr
Number of elements in the rgAuthAttr array. If no authenticated attributes are present in rgAuthAttr, this member is set to zero.
rgAuthAttr
Array of pointers to CRYPT_ATTRIBUTE structures, each holding authenticated attribute information. If there are authenticated attributes present, the PKCS #9 standard dictates that there must be at least two attributes present, the content type object identifier (OID), and the hash of the message itself. These attributes are automatically added by the system.
cUnauthAttr
Number of elements in the rgUnauthAttr array. If no unauthenticated attributes are present in rgUnauthAttr, this member is zero.
rgUnauthAttr
Array of pointers to CRYPT_ATTRIBUTE structures each holding an unauthenticated attribute information. Unauthenticated attributes can be used to contain countersignatures, among other uses.
dwFlags
Normally zero. If the encoded output is to be a CMSG_SIGNED inner content of an outer cryptographic message such as a CMSG_ENVELOPED message, the CRYPT_MESSAGE_BARE_CONTENT_OUT_FLAG must be set. If it is not set, the message will be encoded as an inner content type of CMSG_DATA.

With Windows 2000, CRYPT_MESSAGE_ENCAPSULATED_CONTENT_OUT_FLAG can be set to encapsulate non-data inner content into an OCTET STRING. Also, CRYPT_MESSAGE_KEYID_SINGER_FLAG can be set to identify signers by their Key Identifier and not their Issuer and Serial Number.

With Windows Whistler, the CRYPT_MESSAGE_SILENT_KEYSET_FLAG can be set to suppress any UI by the CSP. For more information on the CRYPT_SILENT flag, see CryptAcquireContext.

dwInnerContentType
Normally zero. Set to the encoding type of the input message if that input to be signed is the encoded output of another cryptographic message.
HashEncryptionAlgorithm
A CRYPT_ALGORITHM_IDENTIFIER. If present and not NULL, it is used instead of the signer's certificate PublicKeyInfo.Algorithm member. Note that for RSA, the hash encryption algorithm is normally the same as the public key algorithm. For DSA, the hash encryption algorithm is normally a DSS signature algorithm. This member can only be used if CRYPT_SIGN_MESSAGE_PARA_HAS_CMS_FIELDS is defined.
pvHashEncryptionAuxInfo
Currently not used and must be set to NULL. This member can only be used if CRYPT_SIGN_MESSAGE_PARA_HAS_CMS_FIELDS is defined.

Remarks

The HashEncryptionAlgorithm and pvHashEncryptionAuxInfo members can only be used if CRYPT_SIGN_MESSAGE_PARA_HAS_CMS_FIELDS is defined.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CERT_CONTEXT, CRL_CONTEXT, CRYPT_ALGORITHM_IDENTIFIER, CRYPT_ATTRIBUTE, CryptSignAndEncryptMessage, CryptSignMessage


CRYPT_VERIFY_MESSAGE_PARA

The CRYPT_VERIFY_MESSAGE_PARA structure contains information needed to verify signed messages.

typedef struct _CRYPT_VERIFY_MESSAGE_PARA {
  DWORD                             cbSize;
  DWORD                             dwMsgAndCertEncodingType;
  HCRYPTPROV                        hCryptProv;
  PFN_CRYPT_GET_SIGNER_CERTIFICATE  pfnGetSignerCertificate;
  void*                             pvGetArg;
} CRYPT_VERIFY_MESSAGE_PARA,         *PCRYPT_VERIFY_MESSAGE_PARA;

Members

cbSize
Size of this structure in bytes.
dwMsgAndCertEncodingType
Type of encoding used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
     X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

hCryptProv
Handle to the cryptographic service provider to be used to verify a signed message. The CSP identified by hCryptProv is used for hashing and for signature verification.

Unless there is a strong reason for passing in a specific cryptographic provider in hCryptProv, pass zero to use the default RSA or DSS provider.

pfnGetSignerCertificate
Pointer to the callback function used to get the signer's certificate context. If NULL, the default callback is used. The default callback tries to get the signer certificate context from the message's certificate store.

An application defined–callback function that gets the signer's certificate can be used in place of the default. It gets passed the certificate identifier of the signer (its issuer and serial number) and a handle to its cryptographic signed message's certificate store.

pvGetArg
Argument to pass to the callback function. Typically, this gets and verifies the message signer's certificate.

The callback function uses the following signature and parameters.

PCCERT_CONTEXT WINAPI CryptGetSignerCertificateCallback(
  void *pvGetArg,                  // in
  DWORD dwCertEncodingType,        // in
  PCERT_INFO pSignerId,            // in
  HCERTSTORE hMsgCertStore         // in
);
pvGetArg
Pointer to user-defined data passed on to the verification function, as specified in the CRYPT_VERIFY_MESSAGE_PARA structure.
dwCertEncodingType
Type of encoding used. It is always acceptable to specify both the certificate and message encoding types by combining them with a bitwise-OR operation as shown in the following example:
  X509_ASN_ENCODING | PKCS_7_ASN_ENCODING

Currently defined encoding types are:

X509_ASN_ENCODING
PKCS_7_ASN_ENCODING

pSignerId
Pointer to a CERT_INFO structure that contains the issuer and serial number. It can be NULL if there is no content or signers.
hMsgCertStore
Handle to the certificate store containing all the certificates and CRLs in the signed message.

Remarks

If the message does not contain content or signers, the function is called with pSignerId set to NULL.

Return Values

If a signer certificate is found, the function returns a pointer to a read-only CERT_CONTEXT. The returned CERT_CONTEXT is either obtained from a certificate store or was created with CertCreateCertificateContext. For either case, it is freed with CertFreeCertificateContext.

If no signer certificate was found, NULL is returned.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CERT_CONTEXT, CERT_INFO, CryptDecryptAndVerifyMessageSignature, CryptVerifyDetachedMessageSignature, CryptVerifyMessageSignature


OID Support Structures

The following structures are used by the OID Support Functions.

  • CRYPT_OID_FUNC_ENTRY
  • CRYPT_OID_INFO
  • CRYPT_RC2_CBC_PARAMETERS
  • CRYPT_SMIME_CAPABILITY
  • CRYPT_SMIME_CAPABILITIES


CRYPT_OID_FUNC_ENTRY

The CRYPT_OID_FUNC_ENTRY structure contains an object identifier (OID) and a pointer to its related function. It is used with CryptInstallOIDFunctionAddress.

typedef struct _CRYPT_OID_FUNC_ENTRY {
  LPCSTR  pszOID;
  void    *pvFuncAddr;
} CRYPT_OID_FUNC_ENTRY, *PCRYPT_OID_FUNC_ENTRY;

Members

pszOID
If the high-order word of the OID is nonzero, pszOID is a pointer to either an OID string, such as "2.5.29.1" or an ASCII string, such as "file". If the high-order word of the OID is zero, the low-order word specifies the numeric identifier to be used as the object identifier.
pvFuncAddr
The starting address of the function that the OID identifies.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CryptInstallOIDFunctionAddress


CRYPT_OID_INFO

The CRYPT_OID_INFO structure contains information about an object identifier (OID). These structures give the relationship among an OID identifier, its name, its group, and other information on the OID. These structures can be listed using CryptEnumOIDInfo. New CRYPT_OID_STRUCTURES can be added using CryptRegisterOIDInfo .

typedef struct _CRYPT_OID_INFO {
  DWORD               cbSize;
  LPCSTR              pszOID;
  LPCWSTR             pwszName;
  DWORD               dwGroupId;
  union {
    DWORD               dwValue;
    ALG_ID              Algid;
    DWORD               dwLength;
  };
  CRYPT_DATA_BLOB     ExtraInfo;
} CRYPT_OID_INFO, *PCRYPT_OID_INFO;
typedef const CRYPT_OID_INFO CCRYPT_OID_INFO, *PCCRYPT_OID_INFO;

Members

cbSize
Size of this structure in bytes.
pszOID
Object identifier (OID) associated with this OID information.
pwszName
Friendly name associated with an OID.
dwGroupId
Group identifier value associated with this OID information.

The following are currently defined dwGroupId group identifiers.
dwGroupId | Description
CRYPT_HASH_ALG_OID_GROUP_ID | Hash Algorithms
CRYPT_ENCRYPT_ALG_OID_GROUP_ID | Encryption Algorithms
CRYPT_PUBKEY_ALG_OID_GROUP_ID | Public Key Algorithms
CRYPT_SIGN_ALG_OID_GROUP_ID | Signature Algorithms
CRYPT_RDN_ATTR_OID_GROUP_ID | RDN Attributes
CRYPT_EXT_OR_ATTR_OID_GROUP_ID | Extensions or Attributes
CRYPT_ENHKEY_USAGE_OID_GROUP_ID | Enhanced Key Usages
CRYPT_POLICY_OID_GROUP_ID | Policies

dwValue
Numeric value associated with this OID information. Used with dwGroupId CRYPT_SIGN_ALG_OID_GROUP_ID
Algid
The algorithm identifier associated with this OID information.

Applies for the following values of dwGroupId:

CRYPT_HASH_ALG_OID_GROUP_ID
CRYPT_ENCRYPT_ALG_OID_GROUP_ID
CRYPT_PUBKEY_ALG_OID_GROUP_ID
CRYPT_SIGN_ALG_OID_GROUP_ID

dwLength
Not implemented. Is always set to zero (0).
ExtraInfo
Extra information used to find or register OID information. Applies for the following values of dwGroupId:

CRYPT_PUBKEY_ALG_OID_GROUP_ID
CRYPT_SIGN_ALG_OID_GROUP_ID
CRYPT_RDN_ATTR_OID_GROUP_ID

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CryptFindOIDInfo, CryptRegisterOIDInfo, CryptUnregisterOIDInfo


CRYPT_RC2_CBC_PARAMETERS

The CRYPT_RC2_CBC_PARAMETERS structure contains information used with szOID_RSA_RC2CBC encryption. It is used in calls to CryptEncodeObject, CryptEncodeObjectEx, CryptDecodeObject CryptDecodeObjectEx.

typedef struct _CRYPT_RC2_CBC_PARAMETERS {
  DWORD               dwVersion;
  BOOL                fIV;            // set if has following IV
  BYTE                rgbIV[8];
} CRYPT_RC2_CBC_PARAMETERS, *PCRYPT_RC2_CBC_PARAMETERS;

Members

dwVersion
Specifies the key length. Current usable key lengths are 40, 64, and 128 bits.

Note The numeric value of defined constants for dwVersion are not the same as the key lengths they specified. Currently defined values for dwVersion are shown in the following table.
Version number defined constant | Numeric value | Associated key length
CRYPT_RC2_40BIT_VERSION | 160 | 40 bits
CRYPT_RC2_56BIT_VERSION | 52 | 56 bits
CRYPT_RC2_64BIT_VERSION | 120 | 64 bits
CRYPT_RC2_128BIT_VERSION | 58 | 128 bits

fIV
Boolean specifying whether an 8-byte initialization vector (IV) is contained in rgbIV[8]. Set to TRUE when IV is present.
rgbIV[8]
Eight byte initialization vector. Can be NULL if fIV is FALSE. The IV is encoded as an OCTET_STRING.

Use CryptEncodeObject or CryptEncodeObjectEx with dwCertEncodingType set to X500_OCTET_STRING to create the encoded OCTET_STRING. The ContentEncryptionAlgorithm's Parameters BLOB is updated to point to this encoded OCTET_STRING.

Note When a message is decrypted, if it has an IV parameter, the message functions calls CryptSetKeyParam with the IV before doing the decryption.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CMSG_ENVELOPED_ENCODE_INFO, CRYPT_ENCRYPT_MESSAGE_PARA, CryptEncodeObject, CryptSetKeyParam.


CRYPT_SMIME_CAPABILITY

The CRYPT_SMIME_CAPABILITY structure specifies a single capability and its associated parameters. Single capabilities are grouped together into a list of CRYPT_SMIME_CAPABILITIES which can specify a prioritized list of capability preferences.

Note The CRYPT_SMIME_CAPABILITY is part of an Internet draft proposal. For a complete definition, see "draft-dusse-s/mime-cert-01.txt" dated May 5, 1997.

typedef struct _CRYPT_SMIME_CAPABILITY {
  LPSTR               pszObjId;
  CRYPT_OBJID_BLOB    Parameters;
} CRYPT_SMIME_CAPABILITY, *PCRYPT_SMIME_CAPABILITY;

Members

pszObjId
Object identifier (OID) for a capability. Capabilities include signature algorithms, symmetric algorithms, and key enciphering algorithms. Also included are non-algorithm capabilities, which are the preference for signed data and the preference for unencrypted messages.
Parameters
CRYPTOAPI_BLOB structure containing any parameters associated with the specified capability in pszObjId.

Note For CryptEncodeObject and CryptEncodeObjectEx with dwCertEncodingType set to X509_ASN_ENCODING, if the cbData member of the Parameters member is zero, the encoded parameters are omitted. They are not encoded as a NULL (05 00) as is done when encoding a CRYPT_ALGORITHM_IDENTIFIER. This follows the S/MIME specification for encoding capabilities that requires this omission.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPT_SMIME_CAPABILITIES


CRYPT_SMIME_CAPABILITIES

The CRYPT_SMIME_CAPABILITIES structure contains a prioritized array of supported capabilities. Capabilities include signature algorithms, symmetric algorithms, key enciphering algorithms, and non-algorithm capabilities, which are the preference for signed data and the preference for unencrypted messages.

Note The CRYPT_SMIME_CAPABILITIES are part of an Internet draft proposal. For a complete definition, see "draft-dusse-s/mime-cert-01.txt" dated May 5, 1997.

typedef struct _CRYPT_SMIME_CAPABILITIES {
  DWORD                   cCapability;
  PCRYPT_SMIME_CAPABILITY rgCapability;
} CRYPT_SMIME_CAPABILITIES, *PCRYPT_SMIME_CAPABILITIES;

Members

cCapability
Count of elements in the rgCapability array.
rgCapability
Prioritized array of pointers to CRYPT_SMIME_CAPABILITY structures each indicating a capability or preference of a user.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPT_SMIME_CAPABILITY


Certificate Chain Structures

The following structures are used in building certificate chains. See Certificate Chain Verification Functions.

  • AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_PARA
  • AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_STATUS
  • AUTHENTICODE_TS_EXTRA_CERT_CHAIN_POLICY_PARA
  • CERT_CHAIN_CONTEXT
  • CERT_CHAIN_ELEMENT
  • CERT_CHAIN_ENGINE_CONFIG
  • CERT_CHAIN_FIND_BY_ISSUER_PARA
  • CERT_CHAIN_PARA
  • CERT_CHAIN_POLICY_PARA
  • CERT_CHAIN_POLICY_STATUS
  • CERT_REVOCATION_INFO
  • CERT_SIMPLE_CHAIN
  • CERT_TRUST_LIST_INFO
  • CERT_TRUST_STATUS
  • CERT_USAGE_MATCH
  • CTL_USAGE_MATCH


AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_PARA

The AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_PARA structure holds policy information used in the verification of certificate chains for files.

typedef struct _AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_PARA {
  DWORD               cbSize;
  DWORD               dwRegPolicySettings;
  PCMSG_SIGNER_INFO   pSignerInfo;
} AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_PARA,
  *PAUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_PARA;

Members

cbSize
Size of this structure in bytes.
dwRegPolicySettings
Flags set during installation that can be modified by a user. The SetReg utility found in the Authenticode Tool Pack can be used to select or deselect each value. These flags can be combined using a bitwise-OR operation.
Name | Description
WTPF_TRUSTTEST | Trust any "TEST" certificate.
WTPF_TESTCANBEVALID | Check any "TEST" certificate for validity.
WTPF_IGNOREEXPIRATION | Use expiration date.
WTPF_IGNOREREVOKATION | Do revocation check.
WTPF_OFFLINEOK_IND | If the source is offline, trust any individual certificates.
WTPF_OFFLINEOK_COM | If the source is offline, trust any commercial certificates.
WTPF_OFFLINEOKNBU_IND | If the source is offline, trust any individual certificates. Do not use UI.
WTPF_OFFLINEOKNBU_COM | If the source is offline, trust any commercial certificates. Do not use checking UI.
WTPF_VERIFY_V1_OFF | Turn off verification of v1 certificates.
WTPF_IGNOREREVOCATIONONTS | Ignore TimeStamp revocation checks.
WTPF_ALLOWONLYPERTRUST | Allow only items in personal trust database.

pSignerInfo
Pointer to a CMSG_SIGNER_INFO structure containing information on the signer of the file.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_STATUS

The AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_STATUS structure holds additional Authenticode policy information for chain verification of files.

typedef struct _AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_STATUS {
  DWORD               cbSize;
  BOOL                fCommercial;
} AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_STATUS,
  *PAUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_STATUS;

Members

cbSize
Size of this structure in bytes.
fCommercial
BOOL flag. If TRUE, a signer has been verified by a CA as meeting certain minimum financial standards.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


AUTHENTICODE_TS_EXTRA_CERT_CHAIN_POLICY_PARA

The AUTHENTICODE_TS_EXTRA_CERT_CHAIN_POLICY_PARA structure contains time stamp policy information that can be used in certificate chain verification of files.

typedef struct _AUTHENTICODE_TS_EXTRA_CERT_CHAIN_POLICY_PARA {
  DWORD               cbSize;
  DWORD               dwRegPolicySettings;
  BOOL                fCommercial;
} AUTHENTICODE_TS_EXTRA_CERT_CHAIN_POLICY_PARA,
  *PAUTHENTICODE_TS_EXTRA_CERT_CHAIN_POLICY_PARA;

Members

cbSize
Size of this structure in bytes.
dwRegPolicySettings
Flag set during installation that can be modified by a user. The SETREG.EXE utility found in the Authenticode Tool Pack can be used to select or deselect each value. Flag values can be combined using a bitwise-OR operation.
Name | Description
WTPF_TRUSTTEST | Trust any "TEST" certificate.
WTPF_TESTCANBEVALID | Check any "TEST" certificate for validity.
WTPF_IGNOREEXPIRATION | Use expiration date.
WTPF_IGNOREREVOKATION | Do revocation check.
WTPF_OFFLINEOK_IND | If the source is offline, trust any individual certificates.
WTPF_OFFLINEOK_COM | If the source is offline, trust any commercial certificates.
WTPF_OFFLINEOKNBU_IND | If the source is offline, trust any individual certificates. Do not use UI.
WTPF_OFFLINEOKNBU_COM | If the source is offline, trust any commercial certificates. Do not use checking UI.
WTPF_VERIFY_V1_OFF | Turn off verification of v1 certificates.
WTPF_IGNOREREVOCATIONONTS | Ignore TimeStamp revocation checks.
WTPF_ALLOWONLYPERTRUST | Allow only items in personal trust database.

fCommercial
BOOL flag. If TRUE, a signer has been verified by a CA as meeting certain minimum financial standards.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CERT_CHAIN_CONTEXT

The CERT_CHAIN_CONTEXT structure contains an array of simple certificate chains and a trust status structure that indicates summary validity data on all of the connected simple chains.

typedef struct _CERT_CHAIN_CONTEXT {
  DWORD               cbSize;
  CERT_TRUST_STATUS   TrustStatus;
  DWORD               cChain;
  PCERT_SIMPLE_CHAIN* rgpChain;
  DWORD               cLowerQualityChainContext;
  PCCERT_CHAIN_CONTEXT*   rgpLowerQualityChainContext;
  BOOL                    fHasRevocationFreshnessTime;
  DWORD                   dwRevocationFreshnessTime;
} CERT_CHAIN_CONTEXT, *PCERT_CHAIN_CONTEXT;

Members

cbSize
Size of this structure in bytes.
TrustStatus
Structure that indicates the combined trust status of the simple chains array. The structure includes an error status code and an information status code. See CERT_TRUST_STATUS for information on status code values.
cChain
Number of simple chains in the array.
rgpChain
Array of simple chain structures. rgpChain[0] is the end certificate simple chain, and rgpChain[cChain-1] is the final chain. If the end certificate is to be considered valid, the final chain must begin with a certificate contained in the root store or an otherwise trusted, self-signed certificate. If the original chain begins with a trusted certificate, there will be only a single simple chain in the array.
cLowerQualityChainContext
Number of chains in the array rgpLowerQualityChainContext array.
rgpLowerQualityChainContext
Array of CERT_CHAIN_CONTEXTs. Returned when CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS is set in dwFlags.
fHasRevocationFreshnessTime
Bool set to TRUE if revocation time information can be retrieved for all elements checked for revocation.
dwRevocationFreshnessTime
The largest CurrentTime minus the CRL's ThisUpdate of all elements checked.

Remarks

When a CERT_CHAIN_CONTEXT is built, the first simple chain begins with an end certificate and ends with a self-signed certificate. If that self-signed certificate is not a root or otherwise trusted certificate, an attempt is made to build a new chain. CTLs are used to create the new chain beginning with the self-signed certificate from the original chain as the end certificate of the new chain. This process continues building additional simple chains until the first self-signed certificate is a trusted certificate or until an additional simple chain cannot be built.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.

See Also

CERT_SIMPLE_CHAIN, CERT_TRUST_STATUS, CertGetCertificateChain


CERT_CHAIN_ELEMENT

The CERT_CHAIN_ELEMENT structure is a single element in a simple certificate chain. Each element has a pointer to a certificate context, a pointer to a structure that indicates the error status and information status of the certificate, and a pointer to a structure that indicates the revocation status of the certificate.

typedef struct _CERT_CHAIN_ELEMENT {
  DWORD                 cbSize;
  PCCERT_CONTEXT        pCertContext;
  CERT_TRUST_STATUS     TrustStatus;
  PCERT_REVOCATION_INFO pRevocationInfo;
  PCERT_ENHKEY_USAGE    pIssuanceUsage;
  PCERT_ENHKEY_USAGE    pApplicationUsage;

} CERT_CHAIN_ELEMENT, *PCERT_CHAIN_ELEMENT;

Members

cbSize
Size of this structure in bytes.
pCertContext
Pointer to a certificate context.
TrustStatus
Structure indicating the status of the certificate. The structure includes an error status code and an information status code. See CERT_TRUST_STATUS for information on status code values.
pRevocationInfo
Pointer to a CERT_REVOCATION_INFO structure with information on the revocation status of the certificate. If the certificate is not revoked, pRevocationInfo is NULL.
pIssuanceUsage
Pointer to a CERT_ENHKEY_USAGE structure. If NULL, any enhanced key usage is acceptable.
pApplicationUsage
Pointer to a CERT_ENHKEY_USAGE structure. If NULL, any enhanced key usage is acceptable.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.

See Also

CERT_SIMPLE_CHAIN, CERT_TRUST_STATUS, CERT_REVOCATION_INFO


CERT_CHAIN_ENGINE_CONFIG

The CERT_CHAIN_ENGINE_CONFIG structure sets parameters for building a non-default certificate chain engine. The engine used determines the ways that certificate chains are built.

typedef struct _CERT_CHAIN_ENGINE_CONFIG {
  DWORD       cbSize;
  HCERTSTORE  hRestrictedRoot;
  HCERTSTORE  hRestrictedTrust;
  HCERTSTORE  hRestrictedOther;
  DWORD       cAdditionalStore;
  HCERTSTORE* rghAdditionalStore;
  DWORD       dwFlags;
  DWORD       dwUrlRetrievalTimeout;
  DWORD       MaximumCachedCertificates;
  DWORD       CycleDetectionModulus;
} CERT_CHAIN_ENGINE_CONFIG, *PCERT_CHAIN_ENGINE_CONFIG;

Members

cbSize
Size of this structure in bytes.
hRestrictedRoot
This configuration parameter can be used to restrict the root store. If used, it can be the handle of any HCERTSTORE containing only a proper subset of the certificates in the root store.
hRestrictedTrust
Store handle. If used, restricts the stores searched to find CTLs.
hRestrictedOther
Store handle. If used, restricts the stores searched for certificates and CRLs.
cAdditionalStore
Count of additional stores to be searched for certificates and CRLs needed to build chains.
rghAdditionalStore
Pointer to an array of store handles for any additional stores to be searched in building chains.
dwFlags
The following flags are defined.
Value | Meaning
CERT_CHAIN_CACHE_END_CERT | Information in the end certificate is cached. By default, information in all certificates except the end certificate is cached as a chain is built. Setting this flag extends the caching to the end certificate.
CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL | Use only cached URLs in building a certificate chain. The Internet and Intranet are not searched for URL-based objects.
CERT_CHAIN_USE_LOCAL_MACHINE_STORE | Build the chain using the LocalMachine registry location as opposed to the CurrentUser location.

dwUrlRetrievalTimeout
Number of microseconds before a time-out for network based–URL object retrievals. Can be set to zero to use the default limit.
MaximumCachedCertificates
Limit on the number of certificates that can be cached as a chain is built. Can be set to 0 to use the default limit.
CycleDetectionModulus
Number of certificates added to the chain before a check is made to determine if there is a cycle of certificates in the chain. A cycle may be defined as having the same certificate in two different places in a chain.

The lower the number, the more frequently checks will be made. Extra checking for cycles of certificates will slow the process considerably. This parameter can be set to zero to use the default limit.

Remarks

The chain-building engine uses four certificate stores in building chains. These are hRoot, hWorld, hTrust, and hOther. These stores' handles are established using information in this structure when a chain engine is created.

hRoot is the store handle from hRestrictedRoot or, if hRestructedRoot is NULL, the handle for System Store "Root."

hWorld is a collection certificate store including sibling stores hRoot, "CA," "My," "Trust," and any additional stores whose handles are in the array pointed to by rghAdditionalStore.

hTrust is the store handle from hRestrictedTrust or, if hRestrictedTrust is NULL, hWorld.

hOther is hRestrictedOther plus hRoot or, if hRestrictedTrust is non-NULL, the hWorld collection store plus the store handle from hRestrictedTrust.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.

See Also

CertCreateCertificateChainEngine


CERT_CHAIN_FIND_BY_ISSUER_PARA

The CERT_CHAIN_FIND_BY_ISSUER_PARA structure holds information used in CertFindChainInStore to build certificate chains.

typedef struct _CERT_CHAIN_FIND_BY_ISSUER_PARA {
  DWORD                           cbSize;
  LPCSTR                          pszUsageIdentifier;
  DWORD                           dwKeySpec;
  DWORD                           dwAcquirePrivateKeyFlags;
  DWORD                           cIssuer;
  CERT_NAME_BLOB                  *rgIssuer;
  PFN_CERT_CHAIN_FIND_BY_ISSUER_CALLBACK  pfnFindCallback;
  void                            *pvFindArg;
  DWORD                           *pdwIssuerChainIndex;
  DWORD                           *pdwIssuerElementIndex;
}
CERT_CHAIN_FIND_BY_ISSUER_PARA, *PCERT_CHAIN_FIND_ISSUER_PARA;

Members

cbSize
Size of this structure in bytes.
pszUsageIdentifier
String indicating a usage to be matched. If pszUsageIdentifier is NULL, a certificate with any usage can be a match.
dwKeySpec
Key specification value to be matched. If dwKeySpec is zero, any certificate with a KeySpec property can be a match.
dwAcquirePrivateKeyFlags
This flag can be set to enable caching of the hCryptProv specifying the key container for the private key. This caching avoids extra user dialogues when CERT_CHAIN_FIND_BY_ISSUER_COMPARE_KEY_FLAG is set in dwFindFlags of the CertFindChainInStore function. CryptAcquireCertificatePrivateKey is called to do the public key comparison.
cIssuer
Count of issuer names in the rgIssuer array. If cIssuer is zero, any issuer can be match.
rgIssuer
Array of X.509, ASN.1 encoded issuer name BLOBs. If there are no elements in the array (that is, rgIssuer is NULL) or if the callback function returns TRUE, adds a new chain element to the chain for the end certificate having a private key with the specified KeySpec and enhanced key usage.
pfnFindCallback
Pointer to a callback function that filters certificates that might be added to the certificate chain. If this parameter is NULL or if the callback function returns TRUE, a chain is built for the certificate. If the function is called and returns FALSE the certificate is skipped.
typedef BOOL (WINAPI *PFN_CERT_CHAIN_FIND_BY_ISSUER_CALLBACK)(
    IN PCCERT_CONTEXT pCert,
    IN void *pvFindArg);
pvFindArg
Currently unused and is set to NULL.
pdwIssuerChainIndex
If this and the following member are both nonNull, returns the index of the matching issuer certificate at:
pChainContext->rgpChain[*pdwIssuerChainIndex]->
rgpElement[*pdwIssuerElementIndex].

The issuer name BLOB is compared to the Issuer field in the certificate. *pdwIssuerElementIndex is set to the index of this subject certificate + 1. Therefore, a partial chain or a self signed certificate matching the name BLOB, where *pdwIssuerElementIndex points past the last certificate in the chain is possible.

Note that this is not updated if the above cIssuer is equal to zero.

pdwIssuerElementIndex
If not NULL, used with pdwIssureChainIndex.

Remarks

The pdwIssurerChainIndex and pdwIssuerElement are used only if CERT_CHAIN_FIND_BY_ISSUER_PARA_HAS_EXTRA_FIELDS is defined. If CERT_CHAIN_FIND_BY_ISSUER_PARA_HAS_EXTRA_FIELDS is defined, the application must zero all unused fields.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.

See Also

CertFindChainInStore


CERT_CHAIN_PARA

The CERT_CHAIN_PARA structure establishing the searching and matching criteria to be used in building a certificate chain.

typedef struct _CERT_CHAIN_PARA {
  DWORD            cbSize;
  CERT_USAGE_MATCH RequestedUsage;
  CERT_USAGE_MATCH RequestedIssuancePolicy;
  DWORD            dwUrlRetrievalTimeout;
  BOOL             fCheckRevocationFreshnessTime;
  DWORD            dwRevocationFreshnessTime;

#endif
} CERT_CHAIN_PARA, *PCERT_CHAIN_PARA;

Members

cbSize
Size of this structure in bytes.
RequestedUsage
Structure indicating the kind of matching necessary to find issuer certificates for building a certificate chain. The structure pointed to indicates whether AND or OR logic is to be used in the matching process. The structure also includes an array of OIDs to be matched.
RequestedIssuancePolicy
CERT_USAGE_MATCH structure.
dwUrlRetrievalTimeout
Time before the revocation checking times out in seconds.
fCheckRevocationFreshnessTime
Bool set to TRUE if revocation time information is to be checked for all elements.
dwRevocationFreshnessTime
The largest CurrentTime minus the CRL's ThisUpdate of all elements checked.

Remarks

The RequestedIssuancePolicy, dwUrlRetrievalTimeout, fCheckRevocationFreshnessTime, and dwRevocationFreshnessTime members are used only if CERT_CHAIN_PARA_HAS_EXTRA_FIELDS is defined. If CERT_CHAIN_PARA_HAS_EXTRA_FIELDS is defined, the application must zero all unused fields.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.

See Also

CERT_USAGE_MATCH


CERT_CHAIN_POLICY_PARA

The CERT_CHAIN_POLICY_PARA structure contains information used in CertVerifyCertificateChainPolicy to establish policy criteria for the verification of certificate chains.

typedef struct _CERT_CHAIN_POLICY_PARA {
  DWORD                   cbSize;
  DWORD                   dwFlags;
  void                    *pvExtraPolicyPara;
} CERT_CHAIN_POLICY_PARA, *PCERT_CHAIN_POLICY_PARA;

Members

cbSize
Size of this structure in bytes.
dwFlags
Flags indicating potential non-valid conditions to be ignored in building certificate chains. The following common chain policy flags are defined. They can be combined using bitwise-OR operators.

CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG
CERT_CHAIN_POLICY_IGNORE_CTL_NOT_TIME_VALID_FLAG
CERT_CHAIN_POLICY_IGNORE_NOT_TIME_NESTED_FLAG
CERT_CHAIN_POLICY_IGNORE_ALL_NOT_TIME_VALID_FLAGS
CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG
CERT_CHAIN_POLICY_IGNORE_WRONG_USAGE_FLAG
CERT_CHAIN_POLICY_IGNORE_END_REV_UNKNOWN_FLAG
CERT_CHAIN_POLICY_IGNORE_CTL_SIGNER_REV_UNKNOWN_FLAG
CERT_CHAIN_POLICY_IGNORE_CA_REV_UNKNOWN_FLAG
CERT_CHAIN_POLICY_IGNORE_ROOT_REV_UNKNOWN_FLAG
CERT_CHAIN_POLICY_IGNORE_ALL_REV_UNKNOWN_FLAGS
CERT_CHAIN_POLICY_ALLOW_TESTROOT_FLAG
CERT_CHAIN_POLICY_TRUST_TESTROOT_FLAG

pvExtraPolicyPara
Pointer to a pszPolicyOID-specific structure that provides additional validity policy conditions.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CERT_CHAIN_POLICY_STATUS

The CERT_CHAIN_POLICY_STATUS structure holds certificate chain status information returned by CertVerifyCertificateChainPolicy from the verification of certificate chains.

typedef struct _CERT_CHAIN_POLICY_STATUS {
  DWORD           cbSize;
  DWORD           dwError;
  LONG            lChainIndex;
  LONG            lElementIndex;
  void           *pvExtraPolicyStatus;
} CERT_CHAIN_POLICY_STATUS, *PCERT_CHAIN_POLICY_STATUS;

Members

cbSize
Size of this structure in bytes.
dwError
Code indicating any error or nonvalid condition found. Currently defined dwError codes are shown in the following table.
Error code | Meaning
TRUST_E_CERT_SIGNATURE | The signature of the certificate cannot be verified.
CERT_E_UNTRUSTEDROOT | A certification chain processed correctly but terminated in a root certificate not trusted by the trust provider.
CERT_E_UNTRUSTEDTESTROOT | The root certificate is a testing certificate and policy settings disallow test certificates.
CERT_E_CHAINING | A chain of certificates was not correctly created.
CERT_E_WRONG_USAGE | The certificate is not valid for the requested usage.
CERT_E_EXPIRED | A required certificate is not within its validity period.
CERT_E_VALIDITYPERIODNESTING | The validity periods of the certification chain do not nest correctly.
CERT_E_PURPOSE | A certificate is being used for a non permitted purpose.
TRUST_E_BASIC_CONSTRAINTS | The certificate's basic constraints are invalid or missing.
CERT_E_ROLE | A certificate that can only be used as an end-entity is being used as a CA or visa versa.
CERT_E_CN_NO_MATCH | The certificate's CN name does not match the passed value.
CRYPT_E_REVOKED | The certificate or signature has been revoked.
CRYPT_E_REVOCATION_OFFLINE | Since the revocation server was offline, the called function was not able to complete the revocation check.
CERT_E_REVOKED | A certificate in the chain has been explicitly revoked by its issuer.
CERT_E_REVOCATION_FAILURE | The revocation process could not continue. The certificates could not be checked.

lChainIndex
Index indicating the chain in which an error or nonvalid condition was found. See Remarks for further details.
lElementIndex
Index indicating the element in a chain where an error or nonvalid condition was found. See Remarks for further details.
pvExtraPolicyStatus
Pointer to a pszPolicyOID-specific structure. In addition to dwError errors, policy OID specific extra status can also be returned here to provide additional chain status information. This pointer can be optionally set to point to an AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_STATUS structure.

Remarks

If both lChainIndex and lElementIndex are set to –1, the error or nonvalid condition applies to the whole chain context. If only lElementIndex is set to –1, the error or nonvalid condition applies to the chain indexed by lChainIndex. Otherwise, the error or nonvalid condition applies to the certificate element at pChainContext->rgpChain[lChainIndex]->rgpElement[lElementIndex].

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CERT_REVOCATION_INFO

The CERT_REVOCATION_INFO structure indicates the revocation status of a certificate in a CERT_CHAIN_ELEMENT.

typedef struct _CERT_REVOCATION_INFO {
  DWORD  cbSize;
  DWORD  dwRevocationResult;
  LPCSTR pszRevocationOid;
  LPVOID pvOidSpecificInfo;
  BOOL   fHasFreshnessTime;
  DWORD  dwFreshnessTime;
  PCERT_REVOCATION_CRL_INFO   pCrlInfo;
} CERT_REVOCATION_INFO, *PCERT_REVOCATION_INFO;

Members

cbSize
Size of this structure in bytes.
dwRevocationResult
Currently defined values are:

CERT_TRUST_IS_REVOKED
CERT_TRUST_REVOCATION_STATUS_IS_UNKNOWN

pszRevocationOid
Not currently used and is set to NULL.
pvOidSpecificInfo
Not currently used and is set to NULL.
fHasFreshnessTime
BOOL set to TRUE to retrieve revocation freshness information.
dwFreshnessTime
If FHasFreshnessTime is TRUE, holds the CurrentTime minus the CRL's ThisUpdate time in seconds.
pCrlInfo
For CRL base revocation checking, a non-NULL pointer to a CERT_REVOCATION_CRL_INFO structure.

Remarks

As a simple chain is built, if any certificate in that chain has been revoked or if its revocation status cannot be determined, a CERT_REVOCATION_INFO structure is allocated and its cbSize and dwRevocationResult members are set.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CERT_CHAIN_ELEMENT


CERT_SIMPLE_CHAIN

The CERT_SIMPLE_CHAIN structure contains an array of chain elements and a summary trust status for the chain that the array represents.

typedef struct _CERT_SIMPLE_CHAIN {
  DWORD                   cbSize;
  CERT_TRUST_STATUS       TrustStatus;
  DWORD                   cElement;
  PCERT_CHAIN_ELEMENT*    rgpElement;
  PCERT_TRUST_LIST_INFO   pTrustListInfo;
  BOOL                    fHasRevocationFreshnessTime;
  DWORD                   dwRevocationFreshnessTime;

} CERT_SIMPLE_CHAIN, *PCERT_SIMPLE_CHAIN;

Members

cbSize
Size of this structure in bytes.
TrustStatus
Structure that indicates the trust status of the whole chain. The structure includes an error status code and an information status code. See CERT_TRUST_STATUS for information on status code values.
cElement
Number of CERT_CHAIN_ELEMENT structures in the array.
rgpElement
Pointer to an array of CERT_CHAIN_ELEMENT structures. rgpElements[0] is the end certificate chain element. rgpElements[cElement-1] is the self-signed "root" certificate element.
pTrustListInfo
Pointer to a CERT_TRUST_LIST_INFO structure that contains a pointer to a CTL connecting this chain to a next certificate chain. If the current chain is the final chain, pTrustListInfo is NULL.
fHasRevocationFreshnessTime
BOOL. If TRUE revocation time information for all elements checked for revocation can be retrieved..
dwRevocationFreshnessTime
Age of elements in a CRL in seconds calculated as the CurrentTime minus the CRL's ThisUpdate time. This values is the largest time across all elements checked.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CERT_CHAIN_CONTEXT, CERT_CHAIN_ELEMENT, CERT_TRUST_STATUS, CERT_TRUST_LIST_INFO


CERT_TRUST_LIST_INFO

The CERT_TRUST_LIST_INFO structure that indicates valid usage of a CTL.

typedef struct _CERT_TRUST_LIST_INFO {
  DWORD         cbSize;
  PCTL_ENTRY    pCtlEntry;
  PCCTL_CONTEXT pCtlContext;
} CERT_TRUST_LIST_INFO, *PCERT_TRUST_LIST_INFO;

Members

cbSize
Size of this structure in bytes.
pCtlEntry
Pointer to a structure that includes a subject identifier, the count of attributes associated with a CTL, and an array of those attributes.
pCtlContext
Pointer to a CTL context.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CERT_CHAIN_ELEMENT, CTL_ENTRY


CERT_TRUST_STATUS

The CERT_TRUST_STATUS structure contains trust information about a certificate in a certificate chain, summary trust information about a simple chain of certificates, or summary information about an array of simple chains.

typedef struct _CERT_TRUST_STATUS {
  DWORD dwErrorStatus;
  DWORD dwInfoStatus;
} CERT_TRUST_STATUS, *PCERT_TRUST_STATUS;

Members

dwErrorStatus
The following error status codes are defined for certificates and chains.
Error status code | Meaning
CERT_TRUST_NO_ERROR | No error found for this certificate or chain.
CERT_TRUST_IS_NOT_TIME_VALID | This certificate or one of the certificates in the certificate chain is not time valid.
CERT_TRUST_IS_NOT_TIME_NESTED | Certificates in the chain are not properly time nested.
CERT_TRUST_IS_REVOKED | Trust for this certificate or one of the certificates in the certificate chain has been revoked.
CERT_TRUST_IS_NOT_SIGNATURE_VALID | The certificate or one of the certificates in the certificate chain does not have a valid signature.
CERT_TRUST_IS_NOT_VALID_FOR_USAGE | The certificate or certificate chain is not valid for its proposed usage.
CERT_TRUST_IS_UNTRUSTED_ROOT | The certificate or certificate chain is based on an untrusted root.
CERT_TRUST_REVOCATION_STATUS_UNKNOWN | The revocation status of the certificate or one of the certificates in the certificate chain is unknown.
CERT_TRUST_IS_CYCLIC | One of the certificates in the chain was issued by a certification authority that the original certificate had certified.
CERT_TRUST_INVALID_EXTENSION | One of the certificates has an invalid extension.
CERT_TRUST_INVALID_POLICY_CONSTRAINTS
CERT_TRUST_INVALID_BASIC_CONSTRAINTS
CERT_TRUST_INVALID_NAME_CONSTRAINTS
CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT
CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT
CERT_TRUST_HAS_NOT_PERMITTED_NAME_
CONSTRAINTCERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT
CERT_TRUST_IS_OFFLINE_REVOCATION
CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY

The following codes are defined for chains only.
Error status code | Meaning
CERT_TRUST_IS_PARTIAL_CHAIN | The certificate chain is not compete.
CERT_TRUST_CTL_IS_NOT_TIME_VALID | A CTL used to create this chain was not time valid.
CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID | A CTL used to create this chain did not have a valid signature.
CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE | A CTL used to create this chain is not valid for this usage.

dwInfoStatus
The following information status codes are defined.
Information status codes | Meaning
CERT_TRUST_HAS_EXACT_MATCH_ISSUER | An exact match issuer certificate has been found for this certificate.
CERT_TRUST_HAS_KEY_MATCH_ISSUER | A key match issuer certificate has been found for this certificate.
CERT_TRUST_HAS_NAME_MATCH_ISSUER | A name match issuer certificate has been found for this certificate.
CERT_TRUST_IS_SELF_SIGNED | This certificate is self-signed.
CERT_TRUST_IS_COMPLEX_CHAIN | The certificate chain created is a complex chain.
CERT_TRUST_HAS_PREFERRED_ISSUER
CERT_TRUST_HAS_ISSUANCE_CHAIN_POLICY
CERT_TRUST_HAS_VALID_NAME_CONSTRAINTS

CERT_TRUST_IS_COMPLEX_CHAIN is defined for chains only: All others are defined for certificates only.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CERT_CHAIN_CONTEXT, CERT_SIMPLE_CHAIN


CERT_USAGE_MATCH

The CERT_USAGE_MATCH structure provides parameters for finding issuer certificates used to build a certificate chain.

typedef struct _CERT_USAGE_MATCH {
  DWORD             dwType;
  CERT_ENHKEY_USAGE Usage;
} CERT_USAGE_MATCH, *PCERT_USAGE_MATCH;

Members

dwType
Determines the kind of issuer matching to be done. In AND logic, the certificate must meet all criteria. In OR logic, the certificate must meet at least one of the criteria. The following codes are defined to determine the logic used in the match.
Code | Meaning
USAGE_MATCH_TYPE_AND | AND logic
USAGE_MATCH_TYPE_OR | OR logic

Default usage match logic is USAGE_MATCH_TYPE_AND.

Usage
CERT_ENHKEY_USAGE structure, which is the same as a CTL_USAGE structure, that includes an array of certificate object identifiers (OIDs) that a certificate must match in order to be valid.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later (or Windows NT 4.0 with Internet Explorer 3.02 or later).
Windows 95/98/Me: Requires Windows 98/Me (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.


CTL_USAGE_MATCH

The CTL_USAGE_MATCH structure provides parameters for finding certificate trust lists (CTL) used to build a certificate chain.

typedef struct _CERT_USAGE_MATCH {
  DWORD             dwType;
  CERT_ENHKEY_USAGE Usage;
} CERT_USAGE_MATCH, *PCERT_USAGE_MATCH;

Members

dwType
Determines the kind of issuer matching to be done. In AND logic, the certificate must meet all criteria. In OR logic, the certificate must meet at least one of the criteria. The following codes are defined to determine the logic used in the match.
Code | Meaning
USAGE_MATCH_TYPE_AND | AND logic
USAGE_MATCH_TYPE_OR | OR logic

Default usage match logic is USAGE_MATCH_TYPE_AND.

Usage
CERT_ENHKEY_USAGE structure that includes an array of OIDs a CTL must match in order to be valid.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.


CryptoAPI Data Types

The following data types are used by the functions contained in CryptoAPI version 2.0.

Data type | Description
ALG_ID | Specifies algorithm identifiers.
HCRYPTHASH | Handles to a hash object.
HCRYPTKEY | Handles to cryptographic keys.
HCRYPTPROV | Handles to CSPs.


ALG_ID

The ALG_ID data type specifing algorithm identifiers. Parameters of this data type are passed to most of the functions in CryptoAPI. This data type is defined in the Wincrypt.h header file as:

typedef unsigned int ALG_ID;

The following table lists the algorithm identifiers that are currently defined. Authors of custom CSPs can define new values. Also, the ALG_ID used by custom CSPs for the key specs AT_KEYEXCHANGE and AT_SIGNATURE are provider dependent. Current mappings follow the table.

Constant | Description
CALG_HMAC† | HMAC keyed hash algorithm.
CALG_MD2† | MD2 hashing algorithm.
CALG_MD4 | MD4 hashing algorithm.
CALG_MD5† | MD5 hashing algorithm.
CALG_SHA† | SHA hashing algorithm.
CALG_SHA1† | Same as CALG_SHA.
CALG_MAC† | MAC keyed-hash algorithm.
CALG_SSL3_SHAMD5 | SSL3 client authentication.
CALG_RSA_SIGN† | RSA public-key signature algorithm.
CALG_DSS_SIGN | DSA public-key signature algorithm.
CALG_RSA_KEYX† | RSA public-key key exchange algorithm.
CALG_DES | DES encryption algorithm.
CALG_3DES_112 | Triple DES encryption algorithm using two 112 bit keys
CALG_3DES | Triple DES encryption algorithm
CALG_RC2† | RC2 block encryption algorithm.
CALG_RC4† | RC4 stream encryption algorithm.
CALG_SEAL | SEAL encryption algorithm.
CALG_DH_SF | Diffie-Hellman store and forward key exchange algorithm.
CALG_DH_EPHEM | Diffie-Hellman ephemeral key exchange algorithm.
CALG_AGREEDKEY_ANY | Temporary algorithm identifier for handles of Diffie-Hellman–agreed keys.
CALG_KEA_KEYX | KEA key exchange algorithm (FORTEZZA).
CALG_SKIPJACK | Skipjack block encryption algorithm (FORTEZZA).
CALG_TEK | TEK (FORTEZZA).
CALG_CYLINK_MEK† | An algorithm to create a 40-bit DES key that has parity bits and zeroed key bits to make its key length 64 bits
CALG_SSL3_SHAMD5 | Used by the schannel.dll operations system. This ALG_ID should not be used by applications.
CALG_SSL3_MASTER | Used by the schannel.dll operations system. This ALG_ID should not be used by applications.
CALG_SCHANNEL_MASTER_HASH | Used by the schannel.dll operations system. This ALG_ID should not be used by applications..
CA;G_SCHANNEL_MAC_KEY | Used by the schannel.dll operations system. This ALG_ID should not be used by applications.
CALG_SCHANNEL_ENC_KEY | Used by the schannel.dll operations system. This ALG_ID should not be used by applications.
CALG_PCT1_MASTER | Used by the schannel.dll operations system. This ALG_ID should not be used by applications.
CALG_SSL2_MASTER | Used by the schannel.dll operations system. This ALG_ID should not be used by applications.
CALG_TLS1_MASTER | Used by the schannel.dll operations system. This ALG_ID should not be used by applications.
CALG_TLS1PRF | Used by the schannel.dll operations system. This ALG_ID should not be used by applications.
† Algorithms supported by the Microsoft Base Cryptographic Provider.

For the Microsoft Base Cryptographic Provider and the Microsoft Enhanced Cryptographic Provider, the ALG_IDs used for the key specs AT_KEYEXCHANGE and AT_SIGNATURE are as follows:

CALG_RSA_KEYX is used for AT_KEYEXCHANGE

CALG_RSA_SIGN is used for AT_SIGNATURE

For the Microsoft DSS Cryptographic Provider and the Diffie-Hellman Provider, the ALG_IDs used for the key specs AT_KEYEXCHANGE and AT_SIGNATURE are as follows:

CALG_DH_SF is used for AT_KEYEXCHANGE

CALG_DSS_SIGN is used for AT_SIGNATURE

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CRYPT_ALGORITHM_IDENTIFIER, CryptEncodeObject/CryptDecodeObject Functions, CryptFindOIDInfo


HCRYPTHASH

The HCRYPTHASH data type is used to represent handles to hash objects. These handles are used to indicate to the CSP module which hash is being used in a particular operation. The CSP module does not enable direct manipulation of the hash values. Instead, the user manipulates the hash values through the hash handle.

HCRYPTHASH is defined in the Wincrypt.h header file as:

typedef unsigned long HCRYPTHASH;

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.


HCRYPTKEY

The HCRYPTKEY data type is used to represent handles to cryptographic keys. These handles are used to indicate to the CSP module which key is being used in a specific operation. The CSP module does not enable direct access to the key values. Instead, the user performs functions by using the key value through the key handle.

HCRYPTKEY is defined in the Wincrypt.h header file as:

typedef unsigned long HCRYPTKEY;

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.


HCRYPTPROV

The HCRYPTPROV data type is used to represent handles to CSPs. These handles are used to indicate which CSP module performs specific operations.

HCRYPTPROV is defined in the Wincrypt.h header file as:

typedef unsigned long HCRYPTPROV;

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.


CryptoAPI Constants

The following are some of the constants used by the functions contained in CryptoAPI version 2.0.

Constant | Description
Constants for CryptEncodeObject and CryptDecodeObject | Predefined constants used with ASN.1 encode and decode operations.
Constants for Netscape Extensions | Predefined constants used for Netscape certificate extensions. This section provides details on the use of these extensions with ASN.1 encoding and decode operations.
Cryptographic Provider Names | Predefined string constants for the names of common Cryptographic Service Providers.
ASN1 Encoding/Decoding Error Codes | Predefined constants that are returned as error codes by functions that do ASN.1 encoding or decoding.
Other CryptoAPI Constants. | Other constants defined in Wincrypt.h.


Constants for CryptEncodeObject and CryptDecodeObject

[This is preliminary documentation and subject to change.]

The CryptEncodeObject, CryptEncodeObjectEx, CryptSignAndEncodeCertificate, CryptDecodeObject, and CryptDecodeObjectEx functions are generalized encoding and decoding functions, capable of encoding and decoding ASN.1 encoded certificates, certificate revocation lists (CRL), certificate trust lists (CTL), and certificate requests.

The following table lists the predefined constants, extensions, and attributes used with encode and decode operations and the data structure to be pointed to by the pvStructInfo parameter.

Note Some predefined constants and OID strings have the same meaning. When they do, either can be used as the lpszStuctType.

LpszStructType | Corresponding pvStructInfo points to:
PKCS_ATTRIBUTE | CRYPT_ATTRIBUTE
PKCS_CONTENT_INFO | CRYPT_CONTENT_INFO See Remarks for further details.
PKCS_CONTENT_INFO_SEQUENCE_OF_ANY | CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY See Remarks for further details.
PKCS_CTL | CTL_INFO
PKCS_RC2_CBC_PARAMETERS | CRYPT_RC2_CBC_PARAMETERS
PKCS_TIME_REQUEST | CRYPT_TIME_STAMP_REQUEST_INFO
PKCS7_SIGNER_INFO | CMSG_SIGNER_INFO
RSA_CSP_PUBLICKEYBLOB | Public Key BLOB See Remarks for further details.
X509_ANY_STRING | CERT_NAME_VALUE
X509_BITS | CRYPT_BIT_BLOB
X509_CERT | CERT_SIGNED_CONTENT_INFO See Remarks for further details.
X509_CERT_CRL_TO_BE_SIGNED | CRL_INFO
X509_CERT_REQUEST_TO_BE_SIGNED | CERT_REQUEST_INFO
X509_CERT_TO_BE_SIGNED | CERT_INFO
X509_CHOICE_OF_TIME | FILETIME See Remarks for further details.
X509_DSS_PARAMETERS | CERT_DSS_PARAMETERS
szOID_OIWSEC_dsa | CERT_DSS_PARAMETERS
X509_DSS_PUBLICKEY | CRYPT_UINT_BLOB See Remarks for further details.
X509_DSS_SIGNATURE | An array of 40 BYTEs. See Remarks for further details.
X509_ENUMERATED | An integer containing the enumerated value. See Remarks for further details.
X509_INTEGER | A signed integer of 32 bits or less.
X509_KEYGEN_REQUEST_TO_BE_SIGNED | CERT_KEYGEN_REQUEST_INFO See Remarks for further details.
X509_MULTI_BYTE_INTEGER | CRYPT_INTEGER_BLOB. in little-endian order.
X509_MULTI_BYTE_UINT | CRYPT_UINT_BLOB See Remarks for further details.
X509_NAME | CERT_NAME_INFO See Remarks for further details.
X509_NAME_VALUE | CERT_NAME_VALUE See Remarks for further details.
X509_OCTET_STRING | CRYPT_DATA_BLOB See Remarks for further details.
X509_PUBLIC_KEY_INFO | CERT_PUBLIC_KEY_INFO
X509_SEQUENCE_OF_ANY | CRYPT_SEQUENCE_OF_ANY See Remarks for further details.
X509_UNICODE_ANY_STRING | CERT_NAME_VALUE See Remarks for further details.
X509_UNICODE_NAME | CERT_NAME_INFO See Remarks for further details.
X509_UNICODE_NAME_VALUE | CERT_NAME_VALUE See Remarks for further details.
PKCS_SMIME_CAPABILITIES | CRYPT_SMIME_CAPABILITIES See Remarks for additional details.
szOID_RSA_SMIMECapabilities | CRYPT_SMIME_CAPABILITIES See Remarks for additional details.
PKCS_UTC_TIME | FILETIME See Remarks for additional details.
szOID_RSA_signingTime | FILETIME See Remarks for additional details.
X509_ALTERNATE_NAME | CERT_ALT_NAME_INFO See Remarks for additional details.
szOID_SUBJECT_ALT_NAME | CERT_ALT_NAME_INFO See Remarks for additional details.
szOID_ISSUER_ALT_NAME | CERT_ALT_NAME_INFO See Remarks for additional details.
szOID_SUBJECT_ALT_NAME2 | CERT_ALT_NAME_INFO
szOID_ISSUER_ALT_NAME2 | CERT_ALT_NAME_INFO
X509_AUTHORITY_INFO_ACCESS | CERT_AUTHORITY_INFO_ACCESS See Remarks for additional details.
szOID_AUTHORITY_INFO_ACCESS | CERT_AUTHORITY_INFO_ACCESS See Remarks for additional details.
X509_AUTHORITY_KEY_ID | CERT_AUTHORITY_KEY_ID_INFO See Remarks for additional details.
szOID_AUTHORITY_KEY_IDENTIFIER | CERT_AUTHORITY_KEY_ID_INFO See Remarks for additional details.
X509_AUTHORITY_KEY_ID2 | CERT_AUTHORITY_KEY_ID2_INFO See Remarks for additional details.
szOID_AUTHORITY_KEY_IDENTIFIER2 | CERT_AUTHORITY_KEY_ID2_INFO See Remarks for additional details.
X509_BASIC_CONSTRAINTS | CERT_BASIC_CONSTRAINTS_INFO structure. See Remarks for additional details.
szOID_BASIC_CONSTRAINTS | CERT_BASIC_CONSTRAINTS_INFO See Remarks for additional details.
X509_BASIC_CONSTRAINTS2 | CERT_POLICIES_INFO
szOID_BASIC_CONSTRAINTS2 | CERT_POLICIES_INFO
X509_CERT_POLICIES | CERT_POLICY_QUALIFIER_INFO
szOID_CERT_POLICIES | CERT_POLICY_QUALIFIER_INFO
X509_CRL_DIST_POINTS | CRL_DIST_POINTS_INFO See Remarks for additional details.
szOID_CRL_DIST_POINTS | CRL_DIST_POINTS_INFO See Remarks for additional details.
X509_CRL_REASON_CODE | An integer containing the enumerated value. See Remarks for additional details.
szOID_CRL_REASON_CODE | An integer containing the enumerated value. See Remarks for additional details.
X509_ENUMERATED | An integer containing the enumerated value. See Remarks for additional details.
X509_ENHANCED_KEY_USAGE | CERT_ENHKEY_USAGE or CTL_USAGE (structures are the same but are known by different names).
szOID_ENHANCED_KEY_USAGE | CERT_ENHKEY_USAGE or CTL_USAGE (structures are the same but are known by different names).
X509_KEY_ATTRIBUTES | CERT_KEY_ATTRIBUTES_INFO
szOID_KEY_ATTRIBUTES | CERT_KEY_ATTRIBUTES_INFO
X509_KEY_USAGE | CRYPT_BIT_BLOB. See Remarks for additional details.
szOID_KEY_USAGE | CRYPT_BIT_BLOB. See Remarks for additional details.
X509_KEY_USAGE_RESTRICTION | CERT_KEY_USAGE_RESTRICTION_INFO
szOID_KEY_USAGE_RESTRICTION | CERT_KEY_USAGE_RESTRICTION_INFO
X509_EXTENSIONS | CERT_EXTENSIONS
szOID_CERT_EXTENSIONS | CERT_EXTENSIONS See Remarks for additional details.
szOID_NEXT_UPDATE_LOCATION | CERT_ALT_NAME_INFO See Remarks for additional details.
szOID_SUBJECT_KEY_IDENTIFIER | CRYPT_DATA_BLOB See Remarks for additional details.
CMS_SIGNER_INFO | CMSG_CMS_SIGNER_INFO
X509_CERT_PAIR | CERT_PAIR
X509_ISSUING_DIST_POINT | CRL_ISSUING_DIST_POINT
szOID_ISSUING_DIST_POINT | CRL_ISSUING_DIST_POINT
X509_NAME_CONSTRAINTS | CERT_NAME_CONSTRAINTS_INFO
szOID_NAME_CONSTRAINTS | CERT_NAME_CONSTRAINTS_INFO
X509_POLICY_MAPPINGS | CERT_POLICY_MAPPINGS_INFO
szOID_POLICY_MAPPINGS | CERT_POLICY_MAPPINGS_INFO
X509_POLICY_CONSTRAINTS | CERT_POLICY_CONSTRAINTS_INFO
szOID_POLICY_CONSTRAINTS | CERT_POLICY_CONSTRAINTS_INFO
X509_CROSS_CERT_DIST_POINTS | CROSS_CERT_DIST_POINTS_INFO
szOID_CROSS_CERT_DIST_POINTS | CROSS_CERT_DIST_POINTS_INFO
CMC_DATA | CMC_DATA_INFO
CMC_RESPONSE | CMC_RESPONSE_INFO
CMC_STATUS | CMC_STATUS_INFO
CMC_ADD_EXTENTSIONS | CMC_ADD_EXTENSIONS_INFO
CMC_ADD_ATTRIBUTES | CMC_ADD_ATTRIBUTES_INFO
X509_CERTIFICATE_TEMPLATE | CERT_TEMPLATE_EXT
szOID_CERTIFICATE_TEMPLATE | CERT_TEMPLATE_EXT
szOID_CRL_NUMBER | int
szOID_DELTA_CRL_INDICATOR | int
szOID_FRESHEST_CRL | CRL_DIST_POINTS_INFO
szOID_CRL_VIRTUAL_BASE | int
szOID_CRL_NEXT_PUBLISH | FILETIME
szOID_APPLICATION_CERT_POLICIES | CERT_POLICY_QUALIFIER_INFO
szOID_APPLICATION_POLICY_MAPPINGS | CERT_POLICY_MAPPINGS_INFO
szOID_APPLICATION_POLICY_CONSTRAINTS | CERT_POLICY_CONSTRAINTS_INFO

Remarks

The following lpszStructType values can be used with Windows Whistler and later only:

X509_CERT_PAIR
X509_ISSING_DIST_POINT
szOID_ISSING_DIST_POINT
X509_NAME_CONSTRAINTS
szOID_NAME_CONSTRAINTS
X509_POLICY_MAPPINGS
szOID_POLICY_MAPPINGS
X509_POLICY_CONSTRAINTS
szOID_POLICY_CONSTRAINTS, X509_CROSS_CERT_DIST_POINTS, szOID_CROSS_CERTS_DIST_POINTS
CMC_DATA
CMC_RESPONSE
CNC_STATUS
CMC_ADD_EXTENTIONS
CMC_ADD_ATTRIBUTES
X509_CERTIFICATE_TEMPLATE
szOID_CERTIFICATE_TEMPLATE
szOID_CRL_NUMBER
szOID_DELTA_CRL_INDICATOR
szOID_FRESHEST_CRL

Further details are provided here for specific lpszStructType values:

PKCS_CONTENT_INFO_SEQUENCE_OF_ANY
For X509_ASN_ENCODING, encoded as a PKCS #7 ContentInfo structure wrapping a sequence of ANY. The value of the contentType member is pszObjId, while the content field is the following structure

SequenceOfAny ::= SEQUENCE OF ANY

The CRYPT_DER_BLOBs points to the already encoded ANY content.

PKCS_CONTENT_INFO
For X509_ASN_ENCODING, encoded as a PKCS #7 ContentInfo structure. The CRYPT_DER_BLOB points to already encoded ANY content
RSA_CSP_PUBLICKEYBLOB
The CryptExportKey function outputs the above pvStructInfo value for a dwBlobType of PUBLICKEYBLOB. The CryptImportKey function expects the above pvStructInfo value when importing a public key.

If dwCertEncodingType is X509_ASN_ENCODING, the RSA_CSP_PUBLICKEYBLOB is encoded as a PKCS #1 RSAPublicKey consisting of a SEQUENCE of a modulus INTEGER and a publicExponent INTEGER. The modulus is encoded as being an unsigned integer.

For the decode functions, pvStructInfo points to a Public Key BLOB immediately followed by a RSAPUBKEY and the modulus bytes. The CryptExportKey outputs the pvStructInfo value for a dwBlobType of PUBLICKEYBLOB. The CryptImportKey function expects the pvStructInfo value when importing a public key.

If dwCertEncodingType is X509_ASN_ENCODING, the RSA_CSP_PUBLICKEYBLOB is encoded as a PKCS #1 RSAPublicKey consisting of a SEQUENCE of a modulus INTEGER and a publicExponent INTEGER. When decoded, if the modulus was encoded as an unsigned integer with a leading 0 byte, the 0 byte is removed before converting to the CSP modulus bytes. Because PKCS #1 does not have any intended key usage information, the aiKeyAlg field of the PUBLICKEYSTRUC structure is always set to CALG_RSA_KEYX.

X509_CERT
The CERT_SIGNED_CONTENT_INFO contains the encoded content to be signed, its signature, and signature algorithm. The ToBeSigned member is an encoded CERT_INFO, CRL_INFO, CERT_REQUEST_INFO, or CERT_KEYGEN_REQUEST_INFO output from a previous call to CryptEncodeObject for one of the following lpszStructType values:
  • X509_CERT_TO_BE_SIGNED
  • X509_CERT_CRL_TO_BE_SIGNED
  • X509_CERT_REQUEST_TO_BE_SIGNED
  • X509_KEYGEN_REQUEST_TO_BE_SIGNED
X509_CHOICE_OF_TIME
For X509_ASN_ENCODING, if the time is after 1950 and before 2050, it is UTC time encoded with a two-digit year. Otherwise, it is Generalized time encoded with a four-digit year, The date is precise to seconds.
X509_DSS_PUBLICKEY
The bytes are ordered as output by the DSS CSP's CryptSignHash where the lower 20 bytes are the R value, and the higher 20 bytes are the S value. The R and S values are treated as unsigned integers and encoded as a sequence of them
X509_ENUMERATED
Is used when encoding any arbitrary enumeration such as the X509_CRL_REASON_CODE.
X509_KEYGEN_REQUEST_TO_BE_SIGNED
For the decode functions, the pbEncoded member is the output of one of the encode functions using the X509_CERT lpszStructType. This output includes the "to be signed" data plus its signature.

For the encode functions, the pbEncoded member is the "to be signed" data only.

X509_MULTI_BYTE_UINT
Before encoding, a leading 0x00 is inserted. After decoding, the leading 0x00 is removed.
X509_NAME
Used to decode/encode the Issuer and Subject members in a CERT_INFO structure.
X509_NAME_VALUE, X509_UNICODE_ANY_STRING, and X509_UNICODE_NAME_VALUE
For the encode functions, the pbData member of the structure pointed to points to the Unicode string. If the cbData member is zero, the Unicode string is NULL terminated, otherwise, cbData is the Unicode string byte count. The byte count is twice the character count.

If the Unicode string contains an invalid character for the specified dwValueType, *pcbEncoded is updated with the Unicode character index of the first invalid character. LastError is set to:

CRYPT_E_INVALID_NUMERIC_STRING

CRYPT_E_INVALID_PRINTABLE_STRING

CRYPT_E_INVALID_IA5_STRING.

The Unicode string is converted before being encoded according to the specified dwValueType. If dwValueType is set to 0, LastError is set to E_INVALIDARG.

If the dwValueType does not indicate a character strings, CryptEncodeObject returns FALSE with LastError set to CRYPT_E_NOT_CHAR_STRING.

For the decode functions, the pbData member points to a NULL terminated Unicode string and the cbData members contains the byte count of the Unicode string excluding the NULL terminator. dwValueType contains the type used to encoded the object. It is not forced to CERT_RDN_UNICODE_STRING. The encoded value is converted to the Unicode string according to the dwValueType.

If the encoded object is not one of the character string types, the decode function returns FALSE with LastError set to CRYPT_E_NOT_CHAR_STRING.

Decode non character strings using lpszStructType X509_NAME_VALUE or X509_ANY_STRING.

X509_OCTET_STRING
The structure contains a sequence of bytes. It is used with some encryption algorithms that require an initialization vector in the form of an octet string.
X509_SEQUENCE_OF_ANY
The CRYPT_DER_BLOBs point to the already encoded ANY content.
X509_UNICODE_NAME
For decode functions, the RDN attribute values are Unicode strings except for the dwValueTypes of CERT_RDN_ENCODED_BLOB or CERT_RDN_OCTET_STRING. These dwValueTypes are the same as for a X509_NAME. These values are not converted to Unicode.

The RDN attribute value's pbData member points to a NULL terminated Unicode string. The RDN attribute value's cbData member contains the byte count of the Unicode string excluding the NULL terminator. The RDN attribute value's dwValueType member contains the type used in the encoded object. It is not forced to CERT_RDN_UNICODE_STRING. The encoded value is converted to the Unicode string according to the dwValueType.

For the encode functions, the RDN attribute values are Unicode strings except for the dwValueTypes of CERT_RDN_ENCODED_BLOB or CERT_RDN_OCTET_STRING. These dwValueTypes are the same as for a X509_NAME. These values are not expected to be Unicode.

For the remaining string dwValueTypes, the RDN attribute value's pbData member points to the Unicode string. If the RDN attribute value's cbData member is zero, the Unicode string is NULL terminated. Otherwise, the RDN attribute value's cbData member is the Unicode string byte count. The byte count is twice the character count, and it excludes the NULL terminator.

If the RDN attribute value's dwValueType member is CERT_RDN_ANY_TYPE, the pszObjId is used to find an acceptable dwValueType. If the Unicode string contains an invalid character for the found or specified dwValueType, *pcbEncoded is updated with the error location of the invalid character. For an invalid character, LastError is set to:

CRYPT_E_INVALID_NUMERIC_STRING

CRYPT_E_INVALID_PRINTABLE_STRING

CRYPT_E_INVALID_IA5_STRING

The Unicode string is converted before being encoded according to the specified dwValueType or the object identifier's dwValueType.

The encode functions error location indices are returned in *pcbEncoded as follows:

The VALUE_INDEX of the error is located in bits 0 through 15.

The ATTR_INDEX of the error is located in bits 16 through 21.

The RDN_INDEX of the error is located in bits 22 through 31.

Bit 0 is the least significant bit of the double word.

The GET_CERT_UNICODE_RDN_ERR_INDEX(X), GET_CERT_UNICODE_ATTR_ERR_INDEX(X), and GET_CERT_UNICODE_VALUE_ERR_INDEX(X) defined macros provide easy reading of the bit mapped fields for VALUE_INDEX, ATTR_INDEX, and RDN_INDEX from the double word that contains them.

PKCS_SMIME_CAPABILITIES and szOID_RSA_SMIMECapabilities
For the encode functions, because of the S/MIME specifications, if the Parameters.cbData is zero, the encoded parameters are omitted and not encoded as a NULL (05 00).
PKCS_UTC_TIME and szOID_RSA_signingTime
For X509_ASN_ENCODING, UTC time encoded precise to seconds and using a two-digit year.
X509_ALTERNATE_NAME, szOID_SUBJECT_ALT_NAME, and szOID_ISSUER_ALT_NAME
Before encoding, the LPWSTR name choices are converted to IA5 strings. If the string contains an invalid IA5 string, LastError is set to CRYPT_E_INVALID_IA5_STRING and *pcbEncoded is updated with the error location of the invalid character.

Error location indices are returned in *pcbEncoded as follows:

Bit 0 is the least significant bit of the double word.

The VALUE_INDEX of the error is located in bits 0 through 15. This is the Unicode character index.

The ENTRY_INDEX of the error is located in bits 16 through 23.

Macros GET_CERT_ALT_NAME_VALUE_ERR_INDEX(X) and GET_CERT_ALT_NAME_ENTRY_ERR_INDEX(X) are defined to provide for easy reading of the bit mapped fields for VALUE_INDEX and ENTRY_INDEX from the double word that contains them:

The szOID_SUBJECT_ALT_NAME has been superseded by szOID_SUBJECT_ALT_NAME2. New certificate servers are implementing the latter.

X509_AUTHORITY_INFO_ACCESS, szOID_AUTHORITY_INFO_ACCESS, X509_AUTHORITY_KEY_ID2 and szOID_AUTHORITY_KEY_IDENTIFIER2
If an encode function returns CRYPT_E_INVALID_IA5_STRING as LastError, the error location is returned in *pcbEncoded consists of:

ENTRY_INDEX - 8 bits << 16

VALUE_INDEX - 16 bits (Unicode character index)

Error location indices are returned in *pcbEncoded as follows:

Bit 0 is the least significant bit of the double word.

The VALUE_INDEX of the error is located in bits 0 through 15. This is the Unicode character index.

The ENTRY_INDEX of the error is located in bits 16 through 23.

Macros GET_CERT_ALT_NAME_VALUE_ERR_INDEX(X) and GET_CERT_ALT_NAME_ENTRY_ERR_INDEX(X) are defined to provide for easy reading of the bit mapped fields for VALUE_INDEX and ENTRY_INDEX from the double word that contains them.

X509_AUTHORITY_KEY_ID and szOID_AUTHORITY_KEY_IDENTIFIER
The X509_AUTHORITY_KEY_ID has been superseded by X509_AUTHORITY_KEY_ID2. New certificate servers are implementing the latter.
X509_BASIC_CONSTRAINTS and szOID_BASIC_CONSTRAINTS
The X509_BASIC_CONSTRAINTS has been superseded by X509_BASIC_CONSTRAINTS2. New certificate servers are implementing the latter.
X509_CRL_DIST_POINTS and szOID_CRL_DIST_POINTS
If the encode function fails with LastError set to CRYPT_E_INVALID_IA5_STRING, *pcbEncoded is updated with the error location of the invalid character:

CRL_ISSUER_BIT - 1 bit << 31 (0 for FullName, 1 for CRLIssuer)

POINT_INDEX - 7 bits << 24

ENTRY_INDEX - 8 bits << 16

VALUE_INDEX - 16 bits (Unicode character index)

Error location indices are returned in *pcbEncoded as follows:

Bit 0 is the least significant bit of the double word.

The VALUE_INDEX of the error is located in bits 0 through 15. This is the Unicode character index.

The ENTRY_INDEX of the error is located in bits 16 through 23.

Macros GET_CERT_ALT_NAME_VALUE_ERR_INDEX(X) and GET_CERT_ALT_NAME_ENTRY_ERR_INDEX(X) are defined to provide for easy reading of the bit mapped fields for VALUE_INDEX and ENTRY_INDEX from the double word that contains them:

X509_CRL_REASON_CODE, X509_ENUMERATED, and szOID_CRL_REASON_CODE
The Integer can be set to one of the following enumerated values.
Reason code | Value
CRL_REASON_UNSPECIFIED | 0
CRL_REASON_KEY_COMPROMISE | 1
CRL_REASON_CA_COMPROMISE | 2
CRL_REASON_AFFILIATION_CHANGED | 3
CRL_REASON_SUPERSEDED | 4
CRL_REASON_CESSATION_OF_OPERATION | 5
CRL_REASON_CERTIFICATE_HOLD | 6
CRL_REASON_REMOVE_FROM_CRL | 8

X509_KEY_USAGE and szOID_KEY_USAGE
The bit definitions used for CERT_KEY_ATTRIBUTES_INFO's IntendedKeyUsage member are used.
szOID_CERT_EXTENSIONS
May be used for one of the attribute types in a certificate request.
szOID_NEXT_UPDATE_LOCATION
Used with certificate trust lists to get the location for the most recent, time valid CTL. Commonly, the choice used in the CERT_ALT_NAME_INFO is a URL indicating the location.
szOID_SUBJECT_KEY_IDENTIFIER
The CRYPTOAPI_BLOB structure contains an octet string, an arbitrary sequence of bytes.
X509_ISSUING_DIST_POINT and szOID_ISSUING_DIST_POINT
For CRYPT_E_INVALID_IA5_STRING, the error location is returned in *pcbEncoded by CryptEncodeObject(X509_ISSUING_DIST_POINT)
Error location consists of:

ENTRY_INDEX - 8 bits << 16

VALUE_INDEX - 16 bits (Unicode character index)

For more information on ENTRY_INDEX and VALUE_INDEX error location defined constants, see X509_ALTERNATE_NAME.

X509_NAME_CONSTRAINTS and szOID_NAME_CONSTRAINTS
For CRYPT_E_INVALID_IA5_STRING, the error location is returned in *pcbEncoded by CryptEncodeObject(X509_NAME_CONSTRAINTS)
Error location consists of:

EXCLUDED_SUBTREE_BIT - 1 bit << 31
(0 for permitted, 1 for excluded)

ENTRY_INDEX - 8 bits << 16

VALUE_INDEX - 16 bits (Unicode character index)

For more information on ENTRY_INDEX and VALUE_INDEX error location defined constants, see X509_ALTERNATE_NAME.

X509_CROSS_CERT_DIST_POINTS and szOID_CROSS_CERT_DIST_POINTS
For CRYPT_E_INVALID_IA5_STRING, the error location is returned in *pcbEncoded by CryptEncodeObject(X509_CRL_DIST_POINTS)
Error location consists of:

POINT_INDEX - 8 bits << 24

ENTRY_INDEX - 8 bits << 16

VALUE_INDEX - 16 bits (Unicode character index)

For more information on ENTRY_INDEX and VALUE_INDEX error location defined constants, see X509_ALTERNATE_NAME.

szOID_CRL_NUMBER
Used with base CRLs only. This is a monotonically increasing sequence number for each CRL issued by a CA.
szOID_DELTA_CRL_INDICATOR
Used with Delta CRLs only. This is marked critical and contains the minimum base CRL Number that can be used with a delta CRL.
szOID_FRESHEST_CRL
Used with base CRLs only. This is formatted identically to a CDP extension holding URLs to fetch the delta CRL.
szOID_CRL_VIRTUAL_BASE
Used with Delta CRLs only. It contains the base CRL Number of the corresponding base CRL.
szOID_CRL_NEXT_PUBLISH
Contains the time when the next CRL is expected to be published. This can be earlier than the CRL's NextUpdate field.


Constants for Netscape Extensions

The following table lists the Netscape extensions used with encode and decode operations. The Netscape predefined constants and object identifier strings are not be used directly with the encoding or decoding functions, CryptEncodeObject, CryptEncodeObjectEx,
CryptSignAndEncodeCertificate,
CryptDecodeObject, or CryptDecodeObjectEx. Instead, these extensions require the use of the lpszStructType indicated in the table.

Additional details that apply to some Netscape extensions follow the table.

Predefined constant | lpszStructType | Corresponding pvStructInfo
szOID_NETSCAPE_BASE_URL | X509_ANY_STRING or X509_UNICODE_ANY_STRING | CERT_NAME_VALUE. The dwValueType member is set to CERT_RDN_IA5_STRING. The Value member's pbData member points to an IA5_STRING added to the beginning of all relative URL addresses in a certificate. This extension can be considered an optimization to reduce the size of the URL extensions.
szOID_NETSCAPE_CA_POLICY_URL | X509_ANY_STRING or X509_UNICODE_ANY_STRING | CERT_NAME_VALUE. The dwValueType member is set to CERT_RDN_IA5_STRING. The Value member's pbData member points to an IA5_STRING, the relative or absolute URL of the Web page describing the policies under which the certificate was issued.
szOID_NETSCAPE_CA_REVOCATION_URL | X509_ANY_STRING or X509_UNICODE_ANY_STRING | CERT_NAME_VALUE. The dwValueType member is set to CERT_RDN_IA5_STRING. The Value member's pbData member points to an IA5_STRING that is the relative or absolute URL used to check the revocation status of certificates signed by the CA that the current certificate belongs to.
szOID_NETSCAPE_CERT_RENEWAL_URL | X509_ANY_STRING or X509_UNICODE_ANY_STRING | CERT_NAME_VALUE.The dwValueType member is set to CERT_RDN_IA5_STRING. The Value member's pbData member points to an IA5_STRING that is the relative or absolute URL of a certificate renewal form,
szOID_NETSCAPE_CERT_SEQUENCE | PKCS_CONTENT _INFO_SEQUENCE _OF_ANY | CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY
szOID_NETSCAPE_CERT_TYPE | X509_BITS | CRYPT_BIT_BLOB
szOID_NETSCAPE_COMMENT | X509_ANY_STRING or X509_UNICODE_ANY_STRING | CERT_NAME_VALUE. The dwValueType member is set to CERT_RDN_IA5_STRING. The Value member's pbData member points to an IA5_STRING that5 is a comment to be display when the certificate is viewed.
szOID_NETSCAPE_REVOCATION_URL | X509_ANY_STRING or X509_UNICODE_ANY_STRING | CERT_NAME_VALUE. The dwValueType member is set to CERT_RDN_IA5_STRING. The Value member's pbData member points to an IA5_STRING that is a relative or absolute URL used to check the revocation status of the certificate.
szOID_NETSCAPE_SSL_SERVER_NAME | X509_ANY_STRING or X509_UNICODE_ANY_STRING | CERT_NAME_VALUE. The dwValueType member is set to CERT_RDN_IA5_STRING. The Value member's pbData member points to an IA5_STRING that is a shell expression used to match the host name off the SSL server using this certificate.

For all encoding functions that use either the X509_ANY_STRING or the X5O9_UNICODE_ANY_STRING lpszStructType, X509_ANY_STRING is used if the string format in the Value member's pbData member is ASCII, and X509_UNICODE_ANY_STRING is used if the string format is UNICODE. In the Unicode case, the string must be converted to an IA5_STRING before encoding by setting the dwValueType member of the CERT_NAME_VALUE structure to CERT_RDN_IA5_STRING.

For decoding functions, the user selects the format of the output string. Use X509_ANY_STRING if the desired string format is ASCII, and X509_UNICODE_ANY_STRING if the desired string format is Unicode.

For the szOID_NETSCAPE_CERT_RENEWAL_URL extension, the data structure contains a relative or absolute URL points to a certificate renewal form. The renewal form will be accessed with an HTTP GET method using a URL that is the concatenation of renewal-URL and certificate-serial-number. The certificate-serial-number is encoded as a string of ASCII hexadecimal digits. For example, if the netscape-base-url is https://<certificate authority URL>/, the netscape-cert-renewal-url is cgi-bin/check-renew.cgi?, and the certificate serial number is 173420, the resulting URL would be: https://<certificate authority URL>/cgi-bin/check-renew.cgi?02a56c The document returned should be an HTML form that will allow the user to request a renewal of their certificate.

For the szOID_NETSCAPE_CERT_SEQUENCE extension using X509_ASN_ENCODING, the certificate is encoded as a PKCS_CONTENT_INFO structure wrapping a sequence of ANY. The value of the contentType member is pszObjId, while the content field is the following structure:

SequenceOfAny ::= SEQUENCE OF ANY

The CRYPT_DER_BLOBs in the CRYPT_CONTENT_INFO_SEQUENCE_OF_ANY's rgValue member point to encoded X509 certificates.

For szOID_NETSCAPE_CERT_TYPE extensions, the following bits are defined:

Bit value | Corresponding type
0x08 | NETSCAPE_SSL_CLIENT_AUTH_CERT_TYPE
0x04 | NETSCAPE_SSL_SERVER_AUTH_CERT_TYPE
0x04 | NETSCAPE_SSL_CA_CERT_TYPE

For the szOID_NETSCAPE_REVOCATION_URL extensions, a relative or absolute URL can be used to check the revocation status of a certificate. The revocation check will be performed as an HTTP GET method using a URL that is the concatenation of revocation-URL and certificate-serial-number. The certificate-serial-number is encoded as a string of ASCII hexadecimal digits. For example, if the netscape-base-url is https://www.certs-r-us.com/, the netscape-revocation-url is cgi-bin/check-rev.cgi?, and the certificate serial number is 173420, the resulting URL would be: https://www.certs-r-us.com/cgi-bin/check-rev.cgi?02a56c.

The server should return a document with a Content-Type of application/x-netscape-revocation. The document should contain a single ASCII digit, '1' if the certificate is not currently valid, and '0' if it is currently valid.

Note that for all of the URLs that include the certificate serial number, the serial number will be encoded as a string that consists of an even number of hexadecimal digits. If the number of significant digits is odd, the string will have a single leading zero to ensure an even number of digits is generated.


Cryptographic Provider Names

The following cryptographic service provider (CSP) names are defined: These constants are used with the CryptAcquireContext and CryptSetProvider functions.

Defined name | Value
MS_DEF_PROV | "Microsoft Base Cryptographic Provider v1.0"
MS_ENHANCED_PROV | "Microsoft Enhanced Cryptographic Provider "
MS_STRONG_PROV | "Microsoft Strong Cryptographic Provider"
MS_DEF_RSA_SIG_PROV | "Microsoft RSA Signature Cryptographic Provider"
MS_DEF_RSA_SCHANNEL_PROV | "Microsoft RSA SChannel Cryptographic Provider"
MS_DEF_DSS_PROV | "Microsoft Base DSS Cryptographic Provider"
MS_DEF_DSS_DH_PROV | "Microsoft Base DSS and Diffie-Hellman Cryptographic Provider"
MS_ENH_DSS_DH_PROV | "Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider"
MS_DEF_DH_SCHANNEL_PROV | "Microsoft DH SChannel Cryptographic Provider"
MS_SCARD_PROV | "Microsoft Base Smart Card Cryptographic Provider"


ASN1 Encoding/Decoding Error Codes

Platform SDK: Security

ASN.1 Encoding/Decoding Error Codes

The following table contains error codes that may be returned by functions performing ASN.1 encoding or decoding. The ASN.1 error codes are returned in Windows 2000 and later. The OSS error codes are returned in by Windows 95, Windows 98, and Windows NT version 4.0 and earlier. For more information, see Winerror.h.

Defined constant | Text message | Hex value
CRYPT_E_ASN1_ERROR | ASN.1 Certificate encode/decode error code base | 0x80093100
CRYPT_E_ASN1_INTERNAL | ASN.1 internal encode or decode error | 0x80093101
CRYPT_E_ASN1_EOD | ASN.1 unexpected end of data | 0x80093102
CRYPT_E_ASN1_CORRUPT | ASN.1 corrupted data | 0x80093103
CRYPT_E_ASN1_LARGE | ASN.1 value too large | 0x80093104
CRYPT_E_ASN1_CONSTRAINT | ASN.1 constraint violated | 0x80093105
CRYPT_E_ASN1_MEMORY | ASN.1 out of memory | 0x80093106
CRYPT_E_ASN1_OVERFLOW | ASN.1 buffer overflow | 0x80093107
CRYPT_E_ASN1_BADPDU | ASN.1 function not supported for this PDU | 0x80093108
CRYPT_E_ASN1_BADARGS | ASN.1 bad arguments to function call | 0x80093109
CRYPT_E_ASN1_BADREAL | ASN.1 bad real value | 0x8009310A
CRYPT_E_ASN1_BADTAG | ASN.1 bad tag value met | 0x8009310B
CRYPT_E_ASN1_CHOICE | ASN.1 bad choice value | 0x8009310C
CRYPT_E_ASN1_RULE | ASN.1 bad encoding rule | 0x8009310D
CRYPT_E_ASN1_UTF8 | ASN.1 bad Unicode (UTF8) | 0x8009310E
CRYPT_E_ASN1_PDU_TYPE | ASN.1 bad PDU type | 0x80093133
CRYPT_E_ASN1_NYI | ASN.1 not yet implemented | 0x80093134
CRYPT_E_ASN1_EXTENDED | ASN.1 skipped unknown extension(s) | 0x80093201
CRYPT_E_ASN1_NOEOD | ASN.1 end of data expected | 0x80093202


Other CryptoAPI Constants

Another constant used by CryptoAPI constants includes MAXUIDLEN.


MAXUIDLEN

MAXUIDLEN is a numeric constant that specifies the maximum size for CSP names and key container names. No CSP or key container name can be longer than MAXUIDLEN characters, including the terminating zero.

MAXUIDLEN is defined in the Wincrypt.h header file as:

#define MAXUIDLEN 64


CAPICOM

Version 1.0

Purpose

CAPICOM is a COM client, supporting Automation, that performs cryptographic functions using Microsoft® ActiveX® and COM objects.

Where Applicable

The CAPICOM interface can be used to perform fundamental cryptographic tasks including signing data, verifying signatures. enveloping messages, decrypting enveloped messages, encryption of data, decryption of data, and checking the validity of digital certificates.

Developer Audience

CAPICOM is intended for use by developers of Microsoft® Visual Basic®, Visual Basic Scripting Edition, and C++ applications.

Run-time Requirements

CAPICOM requires Microsoft® Windows® 95 or later, with Microsoft® Internet Explorer version 5.0 or later, or Microsoft® Windows NT® version 4.0 with Service Pack 4 or later.

See Also

CryptoAPI

About CAPICOM

Provides key cryptography concepts and a high-level view of the CAPICOM interface.

Using CAPICOM

Presents samples of Visual Basic programs that use CAPICOM objects to perform cryptographic operations.

CAPICOM Reference

Documentation of CAPICOM objects, their properties, and methods, and enumerated types used.

Feedback

Make error reports and feature requests directly to Microsoft.


About CAPICOM

[This is preliminary documentation and subject to change.]

CAPICOM is a COM client, supporting Automation, that performs cryptographic functions using Microsoft® ActiveX® and COM objects. CAPICOM can be used in applications created in a many programming languages including Microsoft® Visual Basic®, Visual Basic Scripting Edition, and C++ to perform fundamental cryptographic tasks. A Visual Basic application, for instance, can use CAPICOM objects to digitally sign data, verify digital data signatures, envelop data for privacy, and encrypt and decrypt arbitrary data.

CAPICOM is built on CryptoAPI (an application programming interface) which enables developers to add cryptography-based security to their applications. CryptoAPI includes functionality for encrypting and decrypting data, for simple and complex message handling, for creating and verifying digital signatures, and for authentication using digital certificates. CAPICOM-based applications use the most common parameters as default property settings but can set properties for sophisticated signing or encryption.

For more information on cryptography in general and CryptoAPI, see the following sections of the CryptoAPI documentation:

  • Cryptography and CryptoAPI
  • Data Encryption and Decryption

For more information on specific cryptographic concepts, see the CryptoAPI topics listed in the following table.

Topic | Description
Cryptographic Keys | Cryptographic keys are used to encrypt plaintext into ciphertext and to decrypt ciphertext back into plaintext. CAPICOM uses both symmetric cryptographic keys and the Public Key Infrastructure (PKI).
Hashes and Digital Signatures | A digital signature uses the Public Key Infrastructure (PKI) to associate a signer with a specific version of a document. As long as a document signer's private key has not been compromised, a digital signature, verified using the signers public key from a trusted certificate, confirms the identify of the signer and guarantees that the document was not changed after the signature was created.
Encoding Enveloped Data | Enveloped data consists of encrypted content of any type and encrypted content-encryption session keys for one or more recipients. Enveloped messages keep the contents of the message secret and allow only specified persons or entities to retrieve the contents. For more information, see Digital Messages.
Digital Certificates | The digital certificate is a common credential that provides a means to verify identity.


Using CAPICOM

[This is preliminary documentation and subject to change.]

This section includes scenarios using CAPICOM procedures and Microsoft® Visual Basic® code examples to demonstrate the CAPICOM objects. The code uses CAPICOM objects, methods, and properties described in CAPICOM Reference.

Note Creating digital signatures and un-enveloping messages with CAPICOM is done using Public Key Infrastructure (PKI) cryptography and can only be done if the signer or user decrypting an enveloped message has access to a certificate with an available, associated private key. To decrypt an enveloped message, a certificate with access to the private key must be in the MY store.

Task-based scenarios discussions and code examples have been separated into the following sections:

  • Getting Ready to Use CAPICOM
  • Using Certificate Stores
  • Signing Data and Verifying Digital Signatures
  • Creating and Receiving Enveloped Data Messages
  • Encrypting and Decrypting Data


Getting Ready to Use CAPICOM

[This is preliminary documentation and subject to change.]

Applications using CAPICOM objects must be created using CAPICOM.dll. CAPICOM.dll must also be present and registered at runtime to use CAPICOM objects. CAPICOM.dll should be added to Microsoft® Visual Basic® projects references to use CAPICOM objects. CAPICOM.dll is available with the PSDK.

To register CAPICOM.dll

At the command prompt, change directories to the directory where CAPICOM.dll is stored, and enter the command:

regsvr32 CAPICOM.dll

Except where noted, the code examples in this section include everything needed necessary to compile and run the programs. The following topics document these specific areas:

  • Example Code Limitations
  • Necessary Key Containers, Keys, and Certificates

Example Code Limitations

Principles of good programming practice are not always followed in these code examples to provide more concise, more readable code. In particular, only limited error responses are shown. Working applications should always check returned error codes and perform appropriate actions when an error is encountered.

Necessary Key Containers, Keys, and Certificates in CAPICOM

While some operations with CAPICOM objects can be done on any computer by any user, creating digital signatures and retrieving the clear text content of an enveloped message using CAPICOM objects are certificate-based operations. The user creating digital signature and the user retrieving the encrypted contents of an enveloped message must have a digital certificate with an available associated private key. If a certificate with an associated private key is not present, the cryptographic operation will fail. Users of CAPICOM applications must ensure that they have the appropriate certificate and available private key when the applications are running.

Some code examples in the following sections perform operations that require an available public/private key pair for encrypting and decrypting files, messages, and signatures. Many of these programs will compile and run but fail at run time without the existence of proper key containers, keys, certificate stores, and certificates in those stores.

To create a self-signed certificate

  1. Download the signing tools from http://msdn.microsoft.com/downloads/default.asp?URL=/code/sample.asp?url=/msdn-files/027/000/219/msdncompositedoc.xml.
  2. After makecert.exe is downloaded, run the following command at the command prompt, substituting a user name for xxx, an organization name for yyy, and a company name for zzz
    makecert -r -n "cn=xxx, ou=yyy, o=zzz" -ss my
  3. The certificate can be placed in the current user's MY store. Import the certificate created into the root store so that it is trusted.


Using Certificate Stores

[This is preliminary documentation and subject to change.]

CAPICOM uses digital certificates to create signatures, encrypt session encryption keys when creating enveloped messages, and decrypt encrypted session keys when an enveloped message is received. By default, CAPICOM uses certificates in the MY store that have an associated private key for both digital signatures creation and session key decryption. In most cases, an application would never need to open or otherwise directly deal with a certificate store.

However, applications creating enveloped messages use the public key of each intended recipient of an enveloped message. These keys are retrieved from the certificates of the intended recipients. Thus, to create enveloped messages for a group of intended recipients, the certificates of those recipients would be collected in a certificate store.

The following table lists the standard certificate stores normally persisted on a user station.

Store | Description
MY | Contains personal certificates. These certificates will usually have an associated private key.
Other | Contains the certificates of those that the user normally sends enveloped messages to or receives signed messages from.
CA and ROOT | Contains the certificates of certificate authorities that the user trusts to issue certificates to others. Certificates in these stores are normally supplied with the operating system or by the user's network administrator. Certificates in the ROOT store are typically self-signed.

Additional CAPICOM_CURRENT_USER stores can be created, opened, and persisted by giving a different store name as a string. If a store by that name does not exist, an empty store is created and opened. If a store does exist, it is opened and any certificates currently in the store are made available.

The following sections show code examples for certificate store tasks:

  • Opening the Active Directory Store and Retrieving Certificates
  • Adding Certificates to a Certificate Store
  • Using Stores in Different Locations
  • Collecting and Verifying Certificates


Opening the Active Directory Store and Retrieving Certificates

[This is preliminary documentation and subject to change.]

Certificates can be retrieved from an Active Directory™ (AD) store where the certificates of users of a domain are stored. An AD store can only be opened in the read-only mode and applications cannot added certificates to or remove certificates from an AD store using CAPICOM.

On any CAPICOM error, a negative decimal value of Err.Number is returned. For more information, see CAPICOM Exception and Error Codes. For information on positive decimal values of Err.Number, see Winerror.h.

The following code example shows opening an AD store and retrieving certificates from that store.

    Sub OpenADStore()
    On Error goto ErrorHandler
        Dim mystore as Store
        set mystore = New Store

        ' Put a string representing the name of a certificate subject
        ' in SubjectNameCn. In the example below, the * wild card
        ' is used in the string so that the AD store will be searched
        ' for all certificate with a subject name beginning with 'S.'

        Dim SubjectNameCn as String
        ' The following uses 'cn=' and the * wild card symbol.
        ' Using this sting, all certificates in the AD store with a subject
        ' name beinning with an 'S' would be returned.

        SubjectNameCn = "CN=S*"

        ' Active Directory stores can only be opened with read-only
        ' access.

         mystore.open CAPICOM_ACTIVE_DIRECTORY_USER_STORE,
              SubjectNameCN, CAPICOM_STORE_OPEN_READ_ONLY

        if mystore.certificates.count < 1 then
               msgbox "A certificate for " & SubjectNameCn & " was
                   not found "
        else
               msgbox "The certificate has been retrieved."
        end if
        set myStore = nothing
        Exit Sub
    ErrorHandler:
         if err.number > 0 then
               MsgBox "VB Error found:" & err.description
         else
               MsgBox "CAPICOM error found : " & err.number
          end if
    End Sub


Adding Certificates to a Certificate Store

[This is preliminary documentation and subject to change.]

Certificates can be added to or removed from certificate stores if the store is opened with read/write access. Read/write access is not granted to Active Directory (AD) stores. While certificates can be added to or removed from memory stores, changes in memory stores are not persisted between sessions.

Certificates can be added to a certificate store that is opened with read/write access using the Add method. Certificate can be removed from a certificate store that is opened with read/write access using the Remove method. New stores can be created and saved in the CAPICOM_CURRENT_USER_STORE and CAPICOM_LOCAL_MACHINE_STORE locations. Newly-created stores in either of these locations can be opened with read/write access.

In the following code example, two certificate stores are opened. Certificates of subjects with last names beginning with 'F' are retrieved from the AD store. The CAPICOM_CURRENT_USER_STORE, CAPICOM_CA_STORE store is then opened as a read/write store and the first certificate from the collection of certificates in the AD store is added to the certificates in the CAPICOM_CA_STORE.

For demonstration purposes, the code example that follows shows the opening of stores in the CAPICOM_MEMORY_STORE, CAPICOM_CURRENT_USER_STORE, and CAPICOM_LOCAL_MACHINE_STORE locations. The code example shows exporting all certificates from an open store, writing the exported certificates to a file, reading them back in and importing them into a different store. The newly-imported certificates are them enumerated and displayed.

On any CAPICOM error, a negative decimal value of Err.Number is returned. For more information, see CAPICOM Exception and Error Codes. For information on positive decimal values of Err.Number, see Winerror.h.

The following code example shows opening certificate stores using early binding in the declaration of the Store objects and in creating and instance of those objects.

Sub AddCert()
On Error goto Errorhandler
' The following shows two different ways to declare and
' create a store object.

Dim myADstore as New store

Dim myCAstore as Store
Set myCAstore = New store

' In this example, the AD store will be searched for a certificate
' with a subject name that begins with the letter F. This is done by
' using the string "sn=F*" as the name of the store

Dim SubjectNameCn as String
SubjectNameSn = "SN=F*"

' AD stores can only be opened with read-only
' access.

myADstore.open CAPICOM_ACTIVE_DIRECTORY_USER_STORE,
                SubjectNameSN, CAPICOM_STORE_OPEN_READ_ONLY

'  This code fragment assumes that the store opened and that
'  at least one certificate was returned.
'  A complete application would make sure that at least one certificate
'  was in the store before proceeding, and would
'  also select one or more of the certificates returned
'  to be added instead of using the first certificate
'  in the collection.

'   Open the MY store so that a certificate can be added.

myCAstore.open CAPICOM_CURRENT_USER_STORE, CAPICOM_MY_STORE,
                    CAPICOM_STORE_OPEN_READ_WRITE

myCAStore.add myADstore.certificates.item(1)

' Release the two store objects.

set myCAstore = nothing
set myADstore = nothing
Exit sub

ErrorHandler:
if err.number > 0 then
    MsgBox "VB Error found:" & err.description
else
    MsgBox "CAPICOM error found : " & err.number
end if
End Sub


Using Stores in Different Locations

[This is preliminary documentation and subject to change.]

The code example that follows demonstrates aspects of working with the Store object. It shows opening stores in the CAPICOM_MEMORY_STORE, CAPICOM_CURRENT_USER_STORE, and CAPICOM_LOCAL_MACHINE_STORE locations.

The code example shows exporting certificates from an open store, writing the exported certificates to a file, reading them back in and importing them into a different store. The newly-imported certificates are then enumerated and displayed.

On any CAPICOM error, a negative decimal value of Err.Number is returned. For more information, see CAPICOM Exception and Error Codes. For information on positive decimal values of Err.Number, see Winerror.h.

Sub OpenStores()

On Error GoTo ErrorHandler

'Open Memory, current user, and local machine stores
Dim MemoryStore As New Store
Dim CurrentUserStore As New Store
Dim LocalMachineStore As New Store
Dim NumCerts As Integer

MemoryStore.Open CAPICOM_MEMORY_STORE, "MemStore", CAPICOM_STORE_OPEN_READ_WRITE
CurrentUserStore.Open CAPICOM_CURRENT_USER_STORE, CAPICOM_MY_STORE, CAPICOM_STORE_OPEN_READ_ONLY
LocalMachineStore.Open CAPICOM_LOCAL_MACHINE_STORE, CAPICOM_CA_STORE, CAPICOM_STORE_OPEN_READ_ONLY

' Check the number of certificates in the stores.
NumCerts = MemoryStore.Certificates.Count
MsgBox "There are " & NumCerts & " certificates in the memory store. "
NumCerts = CurrentUserStore.Certificates.Count
MsgBox "There are " & NumCerts & " certificates in the current user store. "
NumCerts = LocalMachineStore.Certificates.Count
MsgBox "There are " & NumCerts & " certificates in the local machine store. "

'  Export the certificates in the current user MY store to a file.
Dim ExportString As String
ExportString = CurrentUserStore.Export
Open "Exportcerts.txt" For Output As #1
Write #1, ExportString
Close #1

' Read the store the file.
Dim importString As String
Open "exportcerts.txt" For Input As #2
Input #2, importString
Close #2
MemoryStore.Import importString

' Check the number of certificates in the memory store after import
NumCerts = MemoryStore.Certificates.Count
MsgBox "There are " & NumCerts & " certificates now in the memory store. "

' Enumerate the certificates in the memory store and display each
' certificate
Dim i As Long
For i = 1 To NumCerts
    MemoryStore.Certificates.Item(i).Display
Next i

' Release the store objects
Set MemoryStore = Nothing
Set CurrentUserStore = Nothing
Set LocalMachineStore = Nothing
Exit Sub
ErrorHandler:
If Err.Number > 0 Then
    MsgBox "VB Error found:" & Err.Description
Else
    MsgBox "CAPICOM error found : " & Err.Number
End If
End Sub


Collecting and Verifying Certificates

[This is preliminary documentation and subject to change.]

Often a group of certificates needs to be collected and verified. This would often be done to prepare a group of recipients for an enveloped message. In the code example that follows, the certificates in a local store are enumerated and checked for validity.

Next, an Active Directory store is opened to retrieve and add to the local store new certificates. The certificates retrieved from the active directory store are checked for validity and, if valid, are added to the local store. Both stores are then closed.

On any CAPICOM error, a negative decimal value of Err.Number is returned. For more information, see CAPICOM Exception and Error Codes. For information on positive decimal values of Err.Number, see Winerror.h.

In this example, the name of the local store is passed in as a string parameter. A string indicating the search criteria for certificates in the Active Directory store is also passed in as a parameter.

Sub CollectValidCerts(storename As String, certname As String)

On Error GoTo ErrorHandler

' Prepare a local certificate store to contain valid
' certificates for the recipients of an enveloped
' message.

' Open the local store and go to the certificates in the store
'   1. Display the certificate
'   2. Check the validity of the certificate
'   3. Remove invalid certificates from the store

Dim LocalStore As New Store
Dim ADStore As New Store
Dim i As Long

LocalStore.Open CAPICOM_CURRENT_USER_STORE, storename, CAPICOM_STORE_OPEN_READ_WRITE

MsgBox "There are " & LocalStore.Certificates.Count & " certificates in this store "
For i = 1 To LocalStore.Certificates.Count
    If LocalStore.Certificates.Item(i).IsValid Then
        LocalStore.Certificates.Item(i).Display
    Else
        MsgBox "An invalid certificate was found."
    End If
Next i

' Open the AD store and retrieve a certificate based
' on a string passed into the function. Add any valid
' certificates found to the local store.

ADStore.Open CAPICOM_ACTIVE_DIRECTORY_USER_STORE, certname, CAPICOM_STORE_OPEN_READ_ONLY
MsgBox "There are " & ADStore.Certificates.Count & " certificates in the AD store."

For i = 1 To ADStore.Certificates.Count
    If ADStore.Certificates.Item(i).IsValid Then
        ADStore.Certificates.Item(i).Display
        LocalStore.Add ADStore.Certificates.Item(i)
    Else
        MsgBox "the certificate from the AD store is invalid."
    End If
Next i

Set LocalStore = Nothing
Set ADStore = Nothing
MsgBox "Sub finished without error "
Exit Sub
errorhandler:
If Err.Number > 0 Then
    MsgBox "VB Error found:" & Err.Description
Else
    MsgBox "CAPICOM error found : " & Err.Number
End If
End Sub


Signing Data and Verifying Digital Signatures

[This is preliminary documentation and subject to change.]

Signing data and verification of signatures on data are among the most important tasks done with cryptography. The following sections show code examples for digital signature tasks:

  • Signing a Document
  • Cosigning a Document
  • Verifying the Signature on a Document


Signing a Document

[This is preliminary documentation and subject to change.]

A standard use of a signature is to sign a text and save that signed text to a file. The signed text could also be sent over the Internet.

In this example, the signature is created for detached content (when the content is not included with the signature). A detached signature would most often be used if the recipient of the signature has a copy of the exact signed text. In the example below, the original message and the detached signature are written to separate files.

On any CAPICOM error, a negative decimal value of Err.Number is returned. For more information, see CAPICOM Exception and Error Codes. For information on positive decimal values of Err.Number, see Winerror.h.

Note Creating a signature uses the signer's private key. A signature can only be created if the signer's certificate with an associated private key is available. This example of the Sign method does not specify a signer. If a signer is not specified and no certificate in CAPICOM_MY_STORE has an associated private key, the Sign method fails. If one and only one certificate in CAPICOM_MY_STORE has an associated private key, that certificate and its private key is used to create the signature. If more than one certificate in the CAPICOM_MY_STORE store has an associated private key, UI is displayed to allow the user to choose the certificate to be used to create the signature.

When a Web-based application uses the Sign method, a prompt is always displayed and the user's permission is required before a signature is created using that signer's private key.

Sub SignContent( ByVal InputFileName as string, ByVal OutputFileName as string)
On Error goto ErrorHandler
Dim c As String
Dim s As String

' Declare and create an instance of a SignedData object/
Dim Signobj As New SignedData

' Read the content to be signed from a text file.

Open InputFileName for input as #1
Input #1, C
Close #1

Signobj.Content = c
'
' Sign the content using the default signer's private key.
' The 'True' parameter indicates that the content signed is not
' included in the signature string.

s = Signobj.Sign( , True)

Open OutputFileName for output as #2
Write #2, s
Close #2

MsgBox "Signature done - Saved to file" & OutputFileName
set signobj = nothing
Exit Sub
ErrorHandler:
if err.number > 0 then
    MsgBox "VB Error found:" & err.description
else
    MsgBox "CAPICOM error found : " & err.number
end if
End Sub


Cosigning a Document

[This is preliminary documentation and subject to change.]

A document can be signed by more than one signer. This happens when, for instance, two or more parties sign a contract or an expense report. In the following example, a document already signed is received by a second signer. This signer uses the CoSign method to attach an additional signature to the document.

On any CAPICOM error, a negative decimal value of Err.Number is returned. For more information, see CAPICOM Exception and Error Codes. For information on positive decimal values of Err.Number, see Winerror.h.

In this code example, files containing the document to be signed and the current signatures on that document are read, the signature is cosigned, and the new signature is written to a file. The example uses a detached signature with the data signed and the signature in separate files.

Sub CoSignContent(  ByVal InputFile1Name as string, ByVal InputFile2Name as string, ByVal OutputFileName as string)
On Error goto ErrorHandler
Dim c As String
Dim s As String
Dim CS As String
Dim Signobj As New SignedData
Open InputFile1Name for Input as #1
Input #1, s
close #1
Open InputFile2 for input as #2
input #2, c
Close #2

Signobj.Content = c
Signobj.Verify s
CS = Signobj.CoSign
Open OutputFoleName for output as #3
Write #3, CS
Close # 3
set Signobj = nothing
MsgBox "Co sign finished. Co-Signature saved to a file."
Exit Sub
ErrorHandler:
if err.number > 0 then
    MsgBox "VB Error found:" & err.description
else
    MsgBox "CAPICOM error found : " & err.number
end if
End Sub

Note Cosigning a document also requires that the cosigner have an available certificate with a private key to create the signature. If a signer is not specified in the call of the Sign method and there is no certificate in CAPICOM_MY_STORE with an associated private key, the method fails. If there is one and only one certificate in CAPICOM_MY_STORE with an associated private key, that key and certificate are used. If there is more than one usable certificate, a prompt is displayed to allow the user to choose the desired certificate.

If the CoSign method is used in a Web-based application, a prompt is always displayed to get the user's permission before a signature is created using that signer's private key.


Verifying the Signature on a Document

[This is preliminary documentation and subject to change.]

When a signed document is received, the validity of the signature or signatures on the document can be checked. A signature on a document can be checked for:

  • Validity of the signature hash
  • Validity of the signer's certificate

The signature hash is decrypted using the public key of the signer found on the signer's certificate, included as part of the signature. If the decrypted signature matches a new hash of the original document, then the signature was created by the owner of the private key associated with the public key used to decrypt the hash. In addition, the document upon which the signature is based is guaranteed not to have been changed after the signature was created.

The certificate that provided the public key and the identity of the signer can also be checked for validity including such issues as whether the certificate has been revoked, whether the certificate is out of date, or whether the certificate was issued by a trusted certificate issuer.

In the following code example, the content signed and the SignedData object are read in from a file and the signature and the validity of the certificate used to create the signature are checked.

Note If the signature is cryptographically invalid or the certificate of the signer is invalid, an exception is raised and the verifying program must handle the exception. On any CAPICOM error, a negative decimal value of Err.Number is returned. For more information, see CAPICOM Exception and Error Codes. For information on positive decimal values of Err.Number, see Winerror.h.

Sub Verifysig( ByVal InputFile1Name as String, ByVal InputFile2Name as String)
On Error Goto ErrorHandler

Dim c As String
Dim s As String
Dim sig As SignedData
Set sig = New SignedData

' Open a file and read the signature
Open InputFile1Name for input as #1
Input #1, s
Close #1

' This example verifies a detached signature.
' It opens a file
' and inputs the plaintext content that was signed.
Open InputFile2Name for input as #2
input #2, c
close #1

' Set the detached content upon which the signature is based.

sig.Content = c

' Verify the signature
On Error resume next
    sig.Verify s, True
if Err.number <> 0 then
    Msgbox"Signature verification failed."
else
    MsgBox "verification complete"
End if

' Release the SignedData object.
set Sig = Nothing

Exit Sub
ErrorHandler:
    if err.number > 0 then
        MsgBox "VB Error found:" & err.description
    else
        MsgBox "CAPICOM error found : " & err.number
    end if
End Sub


Creating and Receiving Enveloped Data Messages

[This is preliminary documentation and subject to change.]

An enveloped message is a message that is encrypted for a set of recipients. In the envelopment process, a session encryption key is generated and the message is encrypted with that key. The encryption key itself is then encrypted separately for each recipient using the public keys from each intended recipient's certificate. The enveloped message consists of the encrypted message, the certificates of the intended recipients, and the set of encrypted keys, one for each recipient.

The following sections show code examples for enveloped message tasks:

  • Sending an Enveloped Data Message
  • Receiving an Enveloped Data Message


Sending an Enveloped Data Message

[This is preliminary documentation and subject to change.]

In the following code example, a plaintext message is read in from a file, and a certificate store containing the certificates of the intended message recipients is opened. All of the certificates in the store are added as recipients of the message, the message is enveloped, and the enveloped message is written to a file.

Additional code can be added to display the certificates being added as message recipients, to verify those certificates before they are added as intended recipients, or to otherwise choose those that are to be added.

On any CAPICOM error, a negative decimal value of Err.Number is returned. For more information, see CAPICOM Exception and Error Codes. For information on positive decimal values of Err.Number, see Winerror.h.

Sub Envelope(ByVal InFile As String, ByVal OutFile As String, ByVal StoreName As String)

On Error GoTo ErrorHandler

'Open the input file and read the message to be
'enveloped.
Dim Text As String
Open InFile For Input As #1
Input #1, Text
Close #1
If Len(Text) < 1 Then
    MsgBox "No message to be enveloped."
    Exit Sub
End If

'Open the store containing the certificates of
'the message recipients.

Dim CertStore As New Store
CertStore.Open CAPICOM_CURRENT_USER_STORE, StoreName, CAPICOM_STORE_OPEN_READ_ONLY

' Check for an empty certificate store

If CertStore.Certificates.Count < 1 Then
    MsgBox "There are no recipient certificates available."
    Set CertStore = Nothing
    Exit Sub
End If

' Declare and initialize an EnvelopedData object

Dim EnvMessage As New EnvelopedData
EnvMessage.Content = Text
Dim I As Integer
For I = 1 To CertStore.Certificates.Count
    EnvMessage.Recipients.Add CertStore.Certificates.Item(I)
    ' The following line can be uncommented to see a prompt
    ' for each certificate in the store.
    ' CertStore.Certificates.Item(I).Display
Next I

'  Set the encryption algorithm and key length. Comment out
'  or remove the following lines to use the default algorithm
'  and key length. The triple DES algorithm and 128 bit key
'  length may not be supported.
Envmessage.Algorithm.Name = ENCRYPTION_ALGORITHM_RC4
Envmessage.Algorithm.KeyLength = KEY_LENGTH_128_BITS

'Declare the string that will hold the enveloped message.

Dim EnvelopedMessage As String

'Encrypt the message into EnvelopedMessage. The enveloped message
'string contains everything that an intended recipient will need to
'decrypt the message, including information on the encryption algorithm 'key length.
EnvelopedMessage = EnvMessage.Encrypt

' Optionally, check the length of the encrypted string to make sure
' that the encrypt method worked.

If Len(EnvelopedMessage) < 1 Then
    MsgBox "no message encrypted. "
Else
    MsgBox " Message is " & Len(EnvelopedMessage) & " characters"

    ' Open an output file and write the encrypted message to the file.
    ' The file is not opened if there is no message to write.
    Open OutFile For Output As #2
    Write #2, EnvelopedMessage
    Close #2
    MsgBox "The message written to file "
End If

' Release the EncryptedData object and the Store object.
Set Envmessage = Nothing
Set CertStore = Nothing

Exit Sub

ErrorHandler:
If Err.Number > 0 Then
    MsgBox "VB Error found:" & Err.Description
Else
    MsgBox "CAPICOM error found : " & Err.Number
End If
End Sub


Receiving an Enveloped Data Message

[This is preliminary documentation and subject to change.]

To decrypt an enveloped message, the recipient matches a certificate from the MY store that has an available private key with a certificate in the enveloped message. If a match is found, the encrypted key associated with that certificate is decrypted and that decrypted key is used to decrypt the enveloped message. A message recipient that does not have a matching certificate with an available private key cannot decrypt the message.

In the code example that follows, a file name is passed into the subroutine, that file is opened and an enveloped message is read in. The enveloped message is then decrypted. The steps of matching a user certificate with a certificate in the enveloped message, of decrypting the encryption key, and finally of decrypting the message are all done behind the scenes. An error is raised if a certificate match is not found or if the decryption fails.

On any CAPICOM error, a negative decimal value of Err.Number is returned. For more information, see CAPICOM Exception and Error Codes. For information on positive decimal values of Err.Number, see Winerror.h.

Sub ReceiveMessage(ByVal InFile As String)
On Error GoTo ErrorHandler

'Declare an EnvelopedData object

Dim Envmessage As New EnvelopedData

'Declare a string variable to hold the encrypted message.

Dim Encrypted As String

' Open an input file and read in the encrypted message
Open InFile For Input As #1
Input #1, Encrypted
Close #1

' If the length of the input string is greater than 0,
' an encrypted message string is available. Decrypt the message.
' Note: to decrypt the message, a certificate with access to
' a user's private key must be available, and that certificate must
' match one of the certificates in the Recipients collection of
' certificates.
If Len(Encrypted) > 0 Then
    ' Receive and decrypt the message
    Envmessage.Decrypt encrypted

    ' Display the decrypted message.
    MsgBox Envmessage.Content
Else
    MsgBox "No enveloped message was read in."
End If
' Release the EncryptedData object.
Set Envmessage = Nothing
Exit Sub

ErrorHandler:
If Err.Number > 0 Then
    MsgBox "VB Error found:" & Err.Description
Else
    MsgBox "CAPICOM error found : " & Err.Number
End If
End Sub.


Encrypting and Decrypting Data

[This is preliminary documentation and subject to change.]

When a document or text needs to have privacy protected by a single user or when the document is to be shared among a small group of people who all have access to the same secret password, simple encryption/decryption can be done.

The following sections show code examples for encryption and decryption tasks:

  • Encrypting a Message in CAPICOM
  • Decrypting a Message in CAPICOM


Encrypting a Message in CAPICOM

[This is preliminary documentation and subject to change.]

This subroutine take a string to be encrypted, a password string to be used to generate an encryption key, and the name of a file where the encrypted message will be written. All parameters are passed into the subroutine by values. To decrypt the message, the same password string must be used. If the password is lost, the text cannot be decrypted. The privacy of the message is lost if an unintended recipient gains access to the password.

On any CAPICOM error, a negative decimal value of Err.Number is returned. For more information, see CAPICOM Exception and Error Codes. For information on positive decimal values of Err.Number, see Winerror.h.

Sub EncryptMessage(ByVal TobeEncrypted As String, ByVal hidden As String, ByVal filename As String)

On Error GoTo errorhandler

' Declare and initialize an EncryptedData object.
' Algorithm.Name and KeyLength do not need to be set.

Dim message As New EncryptedData
message.Content = Tobeencrypted
message.SetSecret hidden
' Optionally, the encryption algorithm and key length can be set.
' If these properties are not set, the default algorithm and key
' length are used.
' Information about the algorithm and key length is saved with the
' encrypted string and the individual decrypting the message does not
' need to set these properties.

message.Algorithm.Name = CAPICOM_ENCRYPTION_ALGORITHM_DES

'Declare the string that will hold the encrypted message.

Dim encryptedmessage As String

'Encrypt the message storing the result in the encryptedmessage string
encryptedmessage = message.Encrypt

' Optionally, check the length of the encrypted string to make sure that the
' encrypt method worked.

If Len(encryptedmessage) < 1 Then
    MsgBox "no message encrypted. "
Else
    MsgBox " Message is " & Len(encryptedmessage) & " characters"

    ' Open an output file and write the encrypted message to the file.
    ' The file is not opened if there is no message to write.
    Open filename For Output As #1
    Write #1, encryptedmessage
    Close #1
    MsgBox "Encrypted message written to file "
End If

' Release the EncryptedData object.
Set message = Nothing

Exit Sub

ErrorHandler:
If Err.Number > 0 Then
    MsgBox "VB Error found:" & Err.Description
Else
    MsgBox "CAPICOM error found : " & Err.Number
End If
End Sub


Decrypting a Message in CAPICOM

[This is preliminary documentation and subject to change.]

This subroutine take a password string to be used to generate a session encryption key, and the name of a file from which an encrypted message will be read. All parameters are passed into the subroutine by values.

If decryption fails, the Err.Number value is checked to see if the error was caused by the use of a password that did not match the password used to encrypt the message. In this case, the NTE_BAD_DATA error is returned.

On any CAPICOM error, a negative decimal value of Err.Number is returned. For more information, see CAPICOM Exception and Error Codes. For information on positive decimal values of Err.Number, see Winerror.h.

Sub DecryptMessage(ByVal hidden As String, ByVal filename As String)
On Error goto ErrorHandler

'Declare an EncryptedData object

Dim message As New EncryptedData

'Declare a string variable to hold the encrypted message.
Dim encrypted As String

' Open an input file and read in the encrypted message
Open filename For Input As #1
Input #1, encrypted
Close #1

' If a message was read in (the length of the input string is
' greater than 0), set the password and decrypt the message.
If Len(encrypted) > 0 then
    ' Set the password used to generate the key
    ' used to decrypt the message. If the password
    ' not the same as the password used when the message
    ' was encrypted, decryption will fail.
    ' The algorithm name and key length set in the encrypting
    ' process are automatically used to decrypt the message.
    message.SetSecret hidden
    message.Decrypt encrypted
    ' Display the decrypted message.
    MsgBox message.Content
else
    msgbox "No encrypted message was read in.
endif

' Release the EncryptedData object and exit the subroutine.
Set message = Nothing
Exit Sub

ErrorHandler:
If Err.Number > 0 Then
    MsgBox "VB Error found:" & Err.Description
Else
'    Check for a bad password error.
    If Err.Number = -2146893819 Then
        MsgBox "Error. The password may not be correct."
    Else
        MsgBox "CAPICOM error found : " & Err.Number
    End If
End If
End Sub


CAPICOM Reference

[This is preliminary documentation and subject to change.]

The CAPICOM COM client provides services that enable application developers to add security based on cryptography to applications. CryptoAPI includes functionality for authentication using digital signatures, for enveloping messages, and for encrypting and decrypting data.

This reference contains the following sections discussing CAPICOM features.

Section | Description
CAPICOM Objects | Defined CAPICOM objects (including properties and methods).
CAPICOM Exception and Error Codes | Error codes returned by function in failure of the function.
CAPICOM Enumerated Types | Enumerated type values used in CAPICOM objects.


CAPICOM Objects

[This is preliminary documentation and subject to change.]

The defined CAPICOM objects can be divided into categories.

Object category | Description
Certificate Store Objects | Objects available for using certificate stores and the certificates in those stores.
Digital Signature Objects | Objects used to digitally sign data and to verify digital signatures.
Enveloped Data Objects | Objects used to create enveloped data messages for privacy and to decrypt data in enveloped messages.
Data Encryption Objects | Objects used to encrypt data and to decrypt encrypted data.
Auxiliary Objects | Objects used to change default behaviors and to manage certificates, certificate stores, and user interface (UI) messages.

Certificate Store Objects

The following objects work with certificate stores and the certificates in those stores. CAPICOM supports the use of Current User, Local Machine, Memory, and Active Directory™ certificate stores.

Object | Description
Certificate | A single digital certificate.
Certificates | Collection of Certificate objects.
CertificateStatus | Provides status information on a certificate.
Chain | Creates and checks a certificate validation chain based on a digital certificate.
Store | Provides the properties and methods to choose, manage, and use certificate stores and the certificates in those stores.

Digital Signature Objects

The following objects are exported to digitally sign data and to verify digital signatures.

Object | Description
SignedData | Object used to sign data and to verify the signature on signed data.
Signer | Information on a single data signer, including the signer's certificate.
Signers | Collection of Signer objects.

Enveloped Data Objects

The following objects are exported to create enveloped data messages for privacy and to decrypt data in enveloped messages.

Object | Description
EnvelopedData | Objects used to create, send, and receive enveloped data. Enveloped data is encrypted so that only the intended recipients can decrypt it.
Recipients | Collection of the Certificate objects of the intended recipients of an enveloped message.

Data Encryption Objects

The following object is exported to encrypt arbitrary data for privacy and to decrypt encrypted data.

Object | Description
EncryptedData | Objects used to encrypt data. Encrypted data in an EncryptedData object can be decrypted.

Auxiliary Objects

The following objects are exported to change default behaviors of other objects and to manage certificates, certificate stores, and messages.

Object | Description
Algorithm | Sets the algorithm and key length to be used in cryptographic operations.
Attribute | Provides a single piece of added information about a signature, such as the time of signing.
Attributes | Collection of Attribute objects.
BasicConstraints | Provides read-only access to basic constraints on the uses of a certificate.
EKU | Provides access to EKU properties of certificates.
EKUS | Collection of EKU objects.
ExtendedKeyUsage | Provides read-only access to the extended key usage properties of certificates.
KeyUsage | Provides read-only access to key usage properties of certificates.
Settings | Enables or disables dialog boxes to prompt for signer or sender identity if that identity is not specified.


Algorithm

[This is preliminary documentation and subject to change.]

The Algorithm object sets the algorithm and key length used for signing, enveloping, and encrypting operations.

Note CAPICOM attempts to use the system default cryptographic service provider (CSP). If that CSP cannot provide the requested algorithm or key length, CAPICOM searches for an available Microsoft-provided CSP that can handle the requested algorithm and key length, in this order of availability: Microsoft Enhanced Cryptographic Provider, Microsoft Strong Cryptographic Provider, Microsoft Base Cryptographic Provider.

Properties

Name (Default)
Data type: CAPICOM_ENCRYPTION_ALGORITHM
Access type: Read/write

Enumerated type indicating the encryption algorithm. This is the default property. When the value of this property is reset, directly or indirectly, the whole state of the object is reset.

KeyLength
Data type: CAPICOM_ENCRYPTION_KEY_LENGTH
Access type: Read/write

Enumerated type indicating the length of the key.

Note Key lengths for DES and 3DES encryption are standard and the key length property is ignored when these algorithms are used.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects


Attribute

[This is preliminary documentation and subject to change.]

The Attribute object contains a single, authenticated attribute giving information about a signer's signature, such as signing time, the name of the document signed, or a description of the document signed.

Properties

Name (Default)
Data type: CAPICOM_ATTRIBUTE
Access type: Read/write

Name of the attribute. This is the default property. When the value of this property is reset, directly or indirectly, the whole state of the object is reset.

Value
Data type: VARIANT
Access type: Read/write

Value of the attribute. For CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME, the data type is DATE. For all others, it is String.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects


Attributes

[This is preliminary documentation and subject to change.]

The Attributes collection object is a collection of Attribute objects.

Properties

All Attributes collection objects have the default collection object properties: Item, Count, and _NewEnum.

Methods

The following table lists the methods of Attributes collection objects.

Method | Description
Add | Adds an Attribute object to the collection.
Clear | Removes all Attribute objects from the collection.
Remove | Removes an Attribute object from the collection.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects


Attributes.Add

[This is preliminary documentation and subject to change.]

The Add method adds an Attribute object to an Attributes collection object.

[Visual Basic]
ObjectName.Add(
  Attribute as Attribute
)

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of an Attributes collection object.
[Visual Basic] Attribute
[in] Reference to the Attribute object to be added to the collection.

Return Values

[Visual Basic] This method does not return a value. An application using this method must contain code to handle an exception raised by this method.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, Attributes


Attributes.Clear

[This is preliminary documentation and subject to change.]

The Clear method removes all Attribute objects from an Attributes collection object.

[Visual Basic]
ObjectName.Clear(
)

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of an Attributes collection object.

Return Values

[Visual Basic] This method does not return a value. An application using this method must contain code to handle an exception raised by this method.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, Attributes


Attributes.Remove

[This is preliminary documentation and subject to change.]

The Remove method removes an Attribute object from an Attributes collection object.

[Visual Basic]
ObjectName.Remove(
  Attribute as Long
)

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of an Attributes collection object.
[Visual Basic] Attribute
[in] Index number of the Attribute object to be removed from the collection.

Return Values

[Visual Basic] This method does not return a value. An application using this method must contain code to handle an exception raised by this method.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, Attributes


BasicConstraints

[This is preliminary documentation and subject to change.]

The BasicConstraints object provides read-only access to basic constraints on the use of a certificate.

Properties

IsPresent (Default)
Data type: Boolean
Access type: Read-only

If TRUE, the BasicConstraints extension is present. This is the default property.

IsCritical
Data type: Boolean
Access type: Read-only

If TRUE, the BasicConstraints extension is marked critical.

IsCertificateAuthority
Data type: Boolean
Access type: Read-only

If TRUE, the certificate is for a certificate authority.

IsPathLenConstraintPresent
Data type: Boolean
Access type: Read-only

If TRUE, a path-length constraint is present.

PathLenConstraint
Data type: Long
Access type: Read-only

Path length constraint value.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects


Certificate

[This is preliminary documentation and subject to change.]

The Certificate object contains a single digital certificate.

Properties

Version
Data type: Long
Access type: Read-only

Version number of the certificate.

SerialNumber
Data type: String
Access type: Read-only

Certificate serial number.

SubjectName
Data type: String
Access type: Read-only

Name of the certificate subject.

IssuerName
Data type: String
Access type: Read-only

Issuer of the certificate.

ValidFromDate
Data type: Date
Access type: Read-only

Beginning date for the validity of the certificate.

ValidToDate
Data type: Date
Access type: Read-only

Ending date for the validity of the certificate.

Thumbprint
Data type: String
Access type: Read-only

SHA1 hash of the certificate.

Methods

The following table lists the methods of the Certificate object.

Method | Description
BasicConstraints | Returns the BasicConstraints object associated with a certificate.
Display | Displays a certificate.
Export | Exports a certificate to a BLOB.
ExtendedKeyUsage | Returns the ExtendedKeyUsage object associated with a certificate.
GetInfo | Retrieve information from a certificate.
HasPrivateKey | Checks access to a private key for the certificate.
Import | Imports a certificate from a BLOB.
IsValid | Checks the validity status of the certificate.
KeyUsage | Returns the KeyUsage object associated with a certificate.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects


Certificate.BasicConstraints

[This is preliminary documentation and subject to change.]

The BasicConstraints method returns a BasicConstraints object that indicates any such constraints on the use of the certificate.

[Visual Basic]
ObjectName.BasicConstraints(
) as BasicConstraints

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a Certificate object.

Return Values

[Visual Basic] This method returns the BasicConstraints object associated with the certificate.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, Certificate


Certificate.Display

[This is preliminary documentation and subject to change.]

The Display method displays a certificate.

[Visual Basic]
ObjectName.Display()

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a Certificate object.

Return Values

[Visual Basic] None.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, Certificate


Certificate.Export

[This is preliminary documentation and subject to change.]

The Export method copies a certificate to an encoded string. The encoded string can be written to a file or imported into a new Certificate object.

[Visual Basic]
ObjectName.Export(
  EncodingType as CAPICOM_ENCODING_TYPE
) as String

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a Certificate object.
[Visual Basic] EncodingType
[in] CAPICOM_ENCODING_TYPE enumerated type indicating the encoding type for the export operation. The default value is CAPICOM_ENCODE_BASE64.

Return Values

[Visual Basic] This method returns a String containing the exported certificate in the specified encoding form.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, Certificate


Certificate.ExtendedKeyUsage

[This is preliminary documentation and subject to change.]

The ExtendedKeyUsage method returns a ExtendedKeyUsage object that indicates the valid uses of the certificate.

[Visual Basic]
ObjectName.ExtendedKeyUsage(
) as ExtendedKeyUsage

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a Certificate object.

Return Values

[Visual Basic] This method returns the ExtendedKeyUsage object associated with the certificate.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, Certificate


Certificate.GetInfo

[This is preliminary documentation and subject to change.]

The GetInfo method checks retrieves information from the certificate.

[Visual Basic]
ObjectName.GetInfo(
  InfoType as CAPICOM_CERT_INFO_TYPE
) as String

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a Certificate object.
[Visual Basic] InfoType
[in] CAPICOM_CERT_INFO_TYPE enumerated type indicating the information to be returned from the certificate.

Return Values

[Visual Basic] This method returns a String containing the requested information.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, Certificate


Certificate.HasPrivateKey

[This is preliminary documentation and subject to change.]

The HasPrivateKey method checks for the access availability of a certificate subject's private key.

[Visual Basic]
ObjectName.HasPrivateKey(
) as Boolean

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a Certificate object.

Return Values

[Visual Basic] This method returns TRUE if access is available to the certificate subject's private key.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, Certificate


Certificate.Import

[This is preliminary documentation and subject to change.]

The Import method copies the contents of an encoded String containing a previously encoded certificate into the Certificate object. Calling this method resets the state of this object.

[Visual Basic]

ObjectName.Import(
  EncodedCertificate as String
)

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a Certificate object.
[Visual Basic] EncodedCertificate
[in] String containing the encoded certificate to be imported.

Return Values

[Visual Basic] None.

Remarks

A dialog will be displayed before this method is executed, if this method is called from a Web-based application.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, Certificate


Certificate.IsValid

[This is preliminary documentation and subject to change.]

The IsValid method builds a certificate verification chain for a certificate and returns a CertificateStatus object that contains the validity status of the certificate.

[Visual Basic]
ObjectName.IsValid(
) as CertificateStatus

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a Certificate object.

Return Values

[Visual Basic] This method returns the CertificateStatus object associated with a certificate. If a certificate is invalid, use the Chain.Build method to determine why the validity check failed.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, Certificate


Certificate.KeyUsage

[This is preliminary documentation and subject to change.]

The KeyUsage method returns a KeyUsage object that indicates the valid key usage of the certificate.

[Visual Basic]
ObjectName.KeyUsage(
) as KeyUsage

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a Certificate object.

Return Values

[Visual Basic] This method returns the KeyUsage object associated with the certificate.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, Certificate


Certificates

[This is preliminary documentation and subject to change.]

The Certificates collection object is a collection of Certificate objects.

Properties

All Certificates collection objects have the default collection object properties: Item, Count, and _NewEnum.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects


CertificateStatus

[This is preliminary documentation and subject to change.]

The CertificateStatus object contains status information about a certificate. Applications do not create instances of this object directly.

Properties

Result
Data type: Boolean
Access type: Read-only

If TRUE, the certificate is valid. The certificate's validity is checked using the current setting of the CheckFlag property and the EKU setting of the certificate. This is the default property.

CheckFlag
Data type: CAPICOM_CHECK_FLAG
Access type: Read/write

Validity check flag. Values can be joined with a logical OR. The default check flag is CAPICOM_CHECK_SIGNATURE_VALIDITY, CAPICOM_CHECK_TIME_VALIDITY, and CAPICOM_CHECK_TRUSTED_ROOT.

Methods

The following table lists the method of the CertificateStatus object.

Method | Description
EKU | Returns the EKU object used to set the EKU elements to be checked in establishing a certificate's validity status.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects


CertificateStatus.EKU

[This is preliminary documentation and subject to change.]

The EKU method returns the EKU object used to set the EKU elements to be checked in establishing a certificate's validity status.

[Visual Basic]
ObjectName.EKU(
) as EKU

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a CertificateStatus object.

Return Values

[Visual Basic] This method returns an EKU object indicating the extended key usage setting of the certificate. The EKU setting establishes a certificate's valid use. Currently, only a single EKU object can be set for each certificate.

Remarks

By default, no extended key usage settings are checked in establishing a certificate's validity status.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, EKU


Chain

[This is preliminary documentation and subject to change.]

The Chain object provides properties and methods to build a certificate trust chain to check the validity of certificates. The chain is built using the CertificateStatus.CheckFlag property value and the EKU setting of each certificate to check validity.

Properties

Certificates (Default)
Data type: Certificates
Access type: Read-only

Ordered Certificates collection object representing the chain. The first certificate in the collection, Item(1), is the end certificate and Item(Count()) is the root certificate. This is the default property.

Status
Data type: Long
Access type: Read-only

Validity status of the chain or of a particular certificate. This property takes an index parameter to indicate which certificate in the chain is to be checked for validity:

  • For the status of the entire chain, specify the index, 0.
  • For the status of the end certificate, specify 1.
  • For the status of the nth certificate in the chain, specify the value of n.
  • For the status of the root of the chain, specify "certificates.count''.

This property returns the status of the whole chain as the default. The following chain status values are used.
Constant/hex value Description
CRYPTCOM_TRUST_IS_NOT_TIME_VALID

0x00000001

 The current date is not within a certificate's valid period.
CRYPTCOM_TRUST_IS_NOT_TIME_NESTED

0x00000002

 The time validity of a certificate in the chain falls outside the time validity of one or more of its verifying certificates.
CRYPTCOM_TRUST_IS_REVOKED

0x00000004

 One or more of the certificates in the chain has been revoked.
CRYPTCOM_TRUST_IS_NOT_SIGNATURE_VALID

0x00000008

 One or more of the certificates in the chain does not have a valid signature.
CRYPTCOM_TRUST_IS_NOT_VALID_FOR_USAGE

0x00000010

 One or more of the certificates in the chain is not valid for its usage.
CRYPTCOM_TRUST_IS_UNTRUSTED_ROOT

0x00000020

 The root certificate of the chain is not trusted.
CRYPTCOM_TRUST_REVOCATION_STATUS_UNKNOWN

0x00000040

 The revocation status of one or more of the certificates in the chain cannot be determined.
CRYPTCOM_TRUST_IS_CYCLIC

0x00000080

 A certificate in the chain is used to certify a certificate that was used in its own certification.
CRYPTCOM_TRUST_IS_PARTIAL_CHAIN

0x00010000

 The truest chain cannot be completed to a certificate in the Root store.
CRYPTCOM_TRUST_CTL_IS_NOT_TIME_VALID

0x00020000

 The chain depends upon a CTL that is not time-valid.
CRYPTCOM_TRUST_CTL_IS_NOT_SIGNATURE_VALID

0x00040000

 The chain depends upon a CTL that does not have a valid signature.
CRYPTCOM_TRUST_CTL_IS_NOT_VALID_FOR_USAGE

0x00080000

 The chain depends upon a CTL that is not valid for its usage in the chain.

Methods

The following table lists the method of Chain objects.

Method | Description
Build | Builds the certificate chain and establishes the chain's overall validity. Use of this method resets the state of the object.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects


Chain.Build

[This is preliminary documentation and subject to change.]

The Build method builds a certificate verification chain from an end certificate to the trusted root certificate. It returns a Boolean value indicating the overall validity of the chain. Each time the Build method is called, the state of the Chain object is reset.

[Visual Basic]
ObjectName.Build(
  Certificate as Certificate
) as Boolean

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a Chain object.
[Visual Basic] Certificate
[in] Expression that resolves to the Certificate object representing the end certificate upon which the verification chain is to be built.

Return Values

[Visual Basic] This method returns a Boolean indicating the overall validity of the chain built upon the input end certificate. Overall validity is based on the validity checking policy in place.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, Chain


EKU

[This is preliminary documentation and subject to change.]

The EKU object provides access to the extended key usage (EKU) properties of certificates. Currently, only a single EKU object can be set.

Properties

Name (Default)
Data type: CAPICOM_EKU
Access type: Read/write

EKU enumeration name. This is the default property. When the value of this property is reset, directly or indirectly, the whole state of the object is reset.

OID
Data type: String
Access type: Read/write

EKU OID string value as defined in Wincrypt.h.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects


EKUS

[This is preliminary documentation and subject to change.]

The EKUS collection object is a collection of EKU objects.

Properties

All EKUS collection objects have the default collection object properties: Item, Count, and _NewEnum.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects


EncryptedData

[This is preliminary documentation and subject to change.]

The EncryptedData object provides properties and methods to encrypt and decrypt data using a session key derived from a secret.

Properties

Content (Default)
Data type: String
Access type: Read/write

Clear text content to be encrypted or the result of a decryption. Setting this property must be done before the Encrypt method is called. This is the default property. When the value of this property is reset, directly or indirectly, the whole state of the object is reset and any encrypted content in the object is lost.

Algorithm
Data type: Algorithm
Access type: Read/write

Algorithm used for encryption/decryption.

Methods

The following table lists the methods of EncryptedData objects.

Method | Description
Decrypt | Decrypts encrypted content using the secret.
Encrypt | Encrypts the content using the current secret and encryption algorithm.
SetSecret | Sets the secret from which the encryption/decryption session key is derived.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects


EncryptedData.Decrypt

[This is preliminary documentation and subject to change.]

The Decrypt method decrypts an encrypted and encoded data string. The resulting clear text data become the Content property of the EncryptedData object. Decryption of the content fails unless the secret is exactly the same as the secret used to derive the key used to encrypt the content.

[Visual Basic]
ObjectName.Decrypt(
  EncryptedMessage as String
)

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of an EncryptedData object.
[Visual Basic] EncryptedMessagel
[in] String containing the encoded, encrypted data to be decrypted.

Return Values

[Visual Basic] None.

Remarks

The session key derived from the current secret is used for the decryption. This method will not produce the correct clear text unless the current secret exactly matches the secret used to encrypt the message.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, EncryptedData


EncryptedData.Encrypt

[This is preliminary documentation and subject to change.]

The Encrypt method derives a session key from the secret and encrypts the Content property value using that key. It returns the encrypted content as an encoded String.

[Visual Basic]
ObjectName.Encrypt(
  EncodingType as CAPICOM_ENCODING_TYPE
) as String

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of an EncryptedData object.
[Visual Basic] EncodingType
[in] CAPICOM_ENCODING_TYPE enumerated type indicating the encoding type used to encode the encrypted data. The default value is CAPICOM_ENCODE_BASE64.

Return Values

[Visual Basic] This method returns a String containing the encrypted, encoded data.

Remarks

The Content and Secret properties of an EncryptedData object must be set before its Encrypt method can be called.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, EncryptedData


EncryptedData.SetSecret

[This is preliminary documentation and subject to change.]

The SetSecret method sets the value of the secret used to derive the cryptographic session key used to encrypt and decrypt data.

[Visual Basic]
ObjectName.SetSecret(
  newVal as String,
  SecretType as CAPICOM_SECRET_TYPE
)

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of an EncryptedData object.
[Visual Basic] newVal
[in] String containing a secret used to create a session cryptographic key.
[Visual Basic] SecretType
[in] CAPICOM_SECRET_TYPE enumerated type indicating the kind of secret used to generate the session key. The default value is CAPICOM_SECRET_PASSWORD.

Return Values

[Visual Basic] None.

Remarks

The secret is used to create the session key for encryption or decryption. The same secret must be used for both operations. If the secret used to encrypt data is lost, the encrypted data cannot be decrypted.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, EncryptedData


EnvelopedData

[This is preliminary documentation and subject to change.]

The EnvelopedData object provides properties and methods to envelop data for privacy by encryption. To envelop data, a session cryptographic key is generated. That session key is then encrypted for each intended recipient using the public key of that intended recipient from the recipient's certificate. The encrypted data and the set of encrypted session keys can be sent to all intended recipients.

Properties

Content (Default)
Data type: String
Access type: Read/write

Clear text content of a message to be enveloped. Setting this property must be done before the Encrypt method is called. When the value of this property is reset, directly or indirectly, the whole state of the object is reset and any encrypted content in the object is lost. This is the default property.

Algorithm
Data type: Algorithm
Access type: Read/write

Encryption algorithm and key length.

Recipients
Data type: Recipients
Access type: Read-only

Collection of the recipients of the enveloped message.

Methods

The following table lists the methods of EnvelopedData objects.

Method | Description
Decrypt | Decrypts enveloped content.
Encrypt | Encrypts the content, encrypts a session key for each recipient, and return the encrypted BLOB.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects


EnvelopedData.Decrypt

[This is preliminary documentation and subject to change.]

The Decrypt method decrypts enveloped content. Decryption is done if the recipient of the message has access to the private key paired with one of the public keys used to envelop the message. Calling the Decrypt method resets the state of the object. If the Decrypt method succeeds, the Content property of the EnvelopedData object is set to the clear text message.

[Visual Basic]
ObjectName.Decrypt(
  EnvelopedMessage as String
)

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a EnvelopedData object.
[Visual Basic] EnvelopedMessage
[in] String containing the enveloped data to be decrypted.

Return Values

[Visual Basic] None.

Remarks

The decrypted data becomes the Content property value for the EnvelopedData object.

If the user of this method does not have access to a private key that matches one of the public keys used to envelop the message, the method fails.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, EnvelopedData


EnvelopedData.Encrypt

[This is preliminary documentation and subject to change.]

The Encrypt method generates a session key, uses that key to encrypt the contents, envelops the encrypted content for each recipient by encrypting the session key with each recipient's public key, and returns the BLOB containing the encrypted contents and the encrypted session keys as an encoded String.

[Visual Basic]
ObjectName.Encrypt(
  EncodingType as CAPICOM_ENVELOP_ENCODING_TYPE
) as String

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a EnvelopedData object.
[Visual Basic] EncodingType
[in] CAPICOM_ENCODING_TYPE enumerated type indicating the encoding type used to encode the enveloped data. The default encoding value is CAPICOM_ENCODE_BASE64.

Return Values

[Visual Basic] This method returns a String-encoded BLOB containing the enveloped data.

Remarks

The returned BLOB contains the encrypted content and an encrypted session key for each intended recipient. These session keys are encrypted using the public key of each recipient. The encrypted session keys can be decrypted only with a recipient's private key.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, EnvelopedData


ExtendedKeyUsage

[This is preliminary documentation and subject to change.]

The ExtendedKeyUsage object provides read-only access to the extended key usage (EKU) properties of a certificate.

Properties

IsPresent (Default)
Data type: Boolean
Access type: Read-only

If TRUE, the EKU extension is present. This is the default property.

IsCritical
Data type: Boolean
Access type: Read-only

If TRUE, the EKU extension is marked critical.

EKUs
Data type: EKUS
Access type: Read-only

Expression that resolves to an EKUS collection object.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects


KeyUsage

[This is preliminary documentation and subject to change.]

The KeyUsage object provides read-only access to key usage properties of a certificate.

Properties

IsPresent (Default)
Data type: Boolean
Access type: Read-only

If TRUE, the KeyUsage extension is present. This is the default property.

IsCritical
Data type: Boolean
Access type: Read-only

If TRUE, the KeyUsage extension is marked critical.

IsDigitalSignatureEnabled
Data type: Boolean
Access type: Read-only

If TRUE, the digitalSignature bit is set.

IsNonRepudiationEnabled
Data type: Boolean
Access type: Read-only

If TRUE, the nonRepudiationEnabled bit is set.

IsKeyEnciphermentEnabled
Data type: Boolean
Access type: Read-only

If TRUE, the keyEncipherment bit is set.

IsDataEnciphermentEnabled
Data type: Boolean
Access type: Read-only

If TRUE, the dataEncipherment bit is set.

IsKeyAgreementEnabled
Data type: Boolean
Access type: Read-only

If TRUE, the keyAgreement bit is set.

IsKeyCertSignEnabled
Data type: Boolean
Access type: Read-only

If TRUE, the keyCertSign bit is set.

IsCRLSignEnabled
Data type: Boolean
Access type: Read-only

If TRUE, the CRLSign bit is set.

IsEncipherOnlyEnabled
Data type: Boolean
Access type: Read-only

If TRUE, the encipherOnly bit is set.

IsDecipherOnlyEnabled
Data type: Boolean
Access type: Read-only

If TRUE, the decipherOnly bit is set.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects


Recipients

[This is preliminary documentation and subject to change.]

The Recipients collection object is a collection of Certificate objects. Each certificate in the collection represents an intended recipient of the enveloped message. Data in an EnvelopedData object is encrypted with a symmetric session key and that symmetric session key is then itself encrypted for each recipient with the public key from that intended recipient's certificate. A recipient with access to the private key associated with a certificate's public key can decrypt the session key and used the decrypted session key to decrypt the actual data.

Properties

All Recipients collection objects have the default collection object properties: Item, Count, and _NewEnum.

Methods

The following table lists the methods of Recipients objects.

Method | Description
Add | Add a Certificate object to the collection.
Clear | Removes all Certificate objects from the collection.
Remove | Remove a Certificate object from the collection.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects


Recipients.Add

[This is preliminary documentation and subject to change.]

The Add method adds a Certificate object to a Recipients collection object.

[Visual Basic]
ObjectName.Add(
  Val as Certificate
)

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a Recipients object.
[Visual Basic] Val
[in] Expression that resolves to the Certificate object to be added to the collection.

Return Values

[Visual Basic] None.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, Recipients


Recipients.Clear

[This is preliminary documentation and subject to change.]

The Clear method removes all Certificate objects from a Recipients collection object.

[Visual Basic]
ObjectName.Clear(
)

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a Recipients collection object.

Return Values

[Visual Basic] This method does not return a value. An application using this method must contain code to handle an exception raised by this method.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, Recipients


Recipients.Remove

[This is preliminary documentation and subject to change.]

The Remove method removes a Certificate object from a Recipients collection object.

[Visual Basic]
ObjectName.Remove(
  Val as long
)

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a Recipients collection object.
[Visual Basic] Val
[in] Index of the Certificate object to be removed from the collection.

Return Values

[Visual Basic] None.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, Recipients


Settings

[This is preliminary documentation and subject to change.]

The Settings object is used to configure CAPICOM components.

Properties

EnablePromptForCertificateUI
Data type: Boolean
Access type: Read/write

If TRUE, UI prompts for a signer or sender's identity can be used.

Note Setting this property will not disable user interface (UI) dialogs that warn a user before any private key usage is done from a Web-based application.

ActiveDirectorySearchLocation
Data type: CAPICOM_ACTIVE_DIRECTORY_SEARCH_LOCATION
Access type: Read/write

Active Directory search location. The initial location is unspecified by default. When the location is unspecified, the global catalog is searched to see if the user certificate attribute is published there; otherwise, the default domain is searched.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects


SignedData

[This is preliminary documentation and subject to change.]

The SignedData object provides properties and methods to establish the content to be signed with a digital signature, to sign or cosign data digitally, and to verify the digital signature of signed data.

A data signature, if verified, proves the association between a signer and data and shows that the data was not changed in any way after the signature was created.

Properties

Content (Default)
Data type: String
Access type: Read/write

Data to be signed. This property must be initialized before the Sign method is called. When the value of this property is reset, directly or indirectly, the whole state of the object is reset and any signature associated with the object before the property was changed is lost. This is the default property.

Signers
Data type: Signers
Access type: Read-only

Expression that resolves to a Signers collection object representing the signature creators of the data.

Methods

The following table lists the methods of SignedData objects.

Method | Description
Certificates | Retrieves the Certificates collection object of the signed data.
CoSign | Co-signs an already signed message.
Sign | Creates a digital signature on the content to be signed.
Verify | Determines the validity of a signature or signatures.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects


SignedData.Certificates

[This is preliminary documentation and subject to change.]

The Certificates method retrieves the Certificates collection object associated with the SignedData object. After being retrieved, the individual Certificate objects in the collection can be enumerated.

[Visual Basic]
ObjectName.Certificates(
) as Certificates

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a SignedData object.

Return Values

[Visual Basic] This method returns the Certificates collection object of the SignedData object.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, SignedData


SignedData.CoSign

[This is preliminary documentation and subject to change.]

The CoSign method creates a digital signature on previously signed content.

A dialog is displayed before this method is executed if this method is called from a Web-based application. This may cause a program running on a remote computer to hang; therefore, Web-based applications should use this method with care.

[Visual Basic]
ObjectName.CoSign(
  Signer as Signer,
  EncodingType as CAPICOM_ENCODING_TYPE
) as String

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a SignedData object.
[Visual Basic] Signer
[in] Reference to the Signer object of the signer of the data. The Signer object must have access to the private key of the certificate used to sign. This parameter can be NULL. For more information, see Remarks.
[Visual Basic] EncodingType
[in] CAPICOM_ENCODING_TYPE enumerated type indicating how the signed data is to be encoded. The default value is CAPICOM_ENCODE_BASE64.

Return Values

[Visual Basic] This method returns a String containing the encoded, cosigned data.

Remarks

Because creating a digital signature requires the use of a private key, Web-based applications attempting to use this method will require user interface prompts that allow the user to approve the use of the private key, for security reasons.

The following results apply to the Signer parameter value:

  • If Signer is not NULL, this method uses the private key pointed to by the associated certificate to encrypt the co-signature. If the private key pointed to by the certificate is not available, the method fails.
  • If Signer is NULL and there is one and only one certificate in the CURRENT_USER MY store that has access to a private key, that certificate is used to create the co-signature.
  • If Signer is NULL, the Settings.EnablePromptForCertifiicateUI property value is TRUE, and there is more than one certificate in the user's MY store with an available private key, a dialog allows the user to select the certificate to be used.
  • If Signer is NULL, there is more than one certificate in the user's MY store with an available private key, and the Settings.EnablePromptForCertificateUI property is FALSE, the method fails.
  • If Signer is NULL and there is no certificate in the CURRENT_USER MY store with an available private key, the method fails.
  • If Signer is NULL and there is no certificate in the CURRENT_USER MY store with an available private key, the method fails.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, SignedData


SignedData.Sign

[This is preliminary documentation and subject to change.]

The Sign method creates a digital signature on the content to be signed. A digital signature consists of a hash of the content to be signed that is encrypted using the private key of the signer. This method can only be used after the Content property of the SignedData object has been initialized. If the Sign method is called on an object that already has a signature, the old signature is replaced.

[Visual Basic]
ObjectName.Sign(
  Signer as Signer,
  bDetached as Boolean,
  EncodingType as CAPICOM_ENCODING_TYPE
) as String

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a SignedData object.
[Visual Basic] Signer
[in] Reference to the Signer object of the signer of the data. The Signer object must have access to the private key of the certificate used to sign. This parameter can be NULL. For more information, see Remarks.
[Visual Basic] bDetached
[in] If TRUE, the data to be signed is detached; that is, the content that is signed is not included as part of the signed object. To verify the signature on detached content, an application must have a copy of the original content. Detached content is often used to decrease the size of a signed object to be sent across the Web, if the recipient of the signed message has an original copy of the signed data.
[Visual Basic] EncodingType
[in] CAPICOM_ENCODING_TYPE enumerated type indicating how the signed data is to be encoded. The default value is CAPICOM_ENCODE_BASE64.

Return Values

[Visual Basic] This method returns a String containing the encoded, signed data.

Remarks

Because creating a digital signature requires the use of a private key, Web-based applications attempting to use this method will require user interface prompts that allow the user on a remote computer to approve of the use of the private key, for security reasons. This may cause a program running on a remote computer to hang; therefore, Web-based applications should use this method with care.

A dialog is displayed before this method is executed, if this method is called from a Web-based application.

The following results apply to the Signer parameter value:

  • If Signer is not NULL, this method uses the private key pointed to by the associated certificate to encrypt the co-signature. If the private key pointed to by the certificate is not available, the method fails.
  • If Signer is NULL and there is one and only one certificate in the CURRENT_USER MY store that has access to a private key, that certificate is used to create the co-signature.
  • If Signer is NULL, the Settings.EnablePromptForCertifiicateUI property value is TRUE, and there is more than one certificate in the user's MY store with an available private key, a dialog allows the user to select the certificate to be used.
  • If Signer is NULL, there is more than one certificate in the user's MY store with an available private key, and the Settings.EnablePromptForCertificateUI property is FALSE, the method fails.
  • If Signer is NULL and there is no certificate in the CURRENT_USER MY store with an available private key, the method fails.
  • If Signer is NULL and there is no certificate in the CURRENT_USER MY store with an available private key, the method fails.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, SignedData


SignedData.Verify

[This is preliminary documentation and subject to change.]

The Verify method determines whether the signatures on signed data in the SignedData object are valid. To verify a signature, the encrypted hash of the contents is decrypted using the signer's public key from the signer's certificate. The decrypted hash is compared to a new hash of the data content. A signature is valid if the hashes match. In addition, this method also builds a certificate chain to determine the validity of the certificate that provides the public key used to decrypt the hash.

[Visual Basic]
ObjectName.Verify(
  SignedMessage as String,
  bDetached as VARIENT_BOOL,
  VerifyFlag as CAPICOM_SIGNED_DATA_VERIFY_FLAG
)

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a SignedData object.
[Visual Basic] SignedMessage
[in] String containing the signed message to be verified.
[Visual Basic] bDetached
[in] If TRUE, the data to be signed is detached; that is, the content that is signed is not included as part of the signed object. To verify the signature on detached content, an application must have a copy of the original content. Detached content is often used to decrease the size of a signed object to be sent across the Web, if the recipient of the signed message has an original copy of the signed data.
[Visual Basic] VerifyFlag
[in] CAPICOM_SIGNED_DATA_VERIFY_FLAG enumerated type indicating the verification policy. The default value is CAPICOM_VERIFY_SIGNATURE_AND_CERTIFICATE. Using this value, both the validity of the certificate and the validity of the signature are checked. This parameter may be set to verify the signature and not the certificate.

Return Values

[Visual Basic] This method does not return a value. If the signature or the certificate is invalid, an exception is raised. Any application using this method must contain code to handle an exception raised by this method.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects, SignedData


Signer

[This is preliminary documentation and subject to change.]

The Signer object establishes the signer of a SignedData object. The Signer object's certificate must have an available private key that can be used to sign data.

Properties

Certificate (Default)
Data type: Certificate
Access type: Read/write

Expression that resolves to a Certificate object representing the certificate of a signer of the data. This is the default property. When the value of this property is reset, directly or indirectly, the whole state of the object is reset.

AuthenticatedAttributes
Data type: Attributes
Access type: Read-only

Property used to add and remove authenticated attributes.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects


Signers

[This is preliminary documentation and subject to change.]

The Signers collection object is a collection of Signer objects.

Properties

All Signers collection objects have the default collection object properties: Item, Count, and _NewEnum.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects


Store

[This is preliminary documentation and subject to change.]

The Store object provides properties and methods to choose, manage, and use certificate stores and the certificates in those stores. CAPICOM can use Current-User, Local-Machine, memory, and Active Directory stores. Developers should be aware that some methods may fail with some stores if operations are attempted for which the user does not have access rights.

Properties

Certificates (Default)
Data type: Certificates
Access type: Read-only

Collection object that includes all of the certificates in the store. This is the default property.

Methods

The following table lists the methods of the Store object.

Method | Description
Add | Adds a certificate to the open store.
Export | Exports the store of an encoded BLOB.
Import | Imports a previously exported store.
Open | Opens a certificate store.
Remove | Removes a certificate from an open store.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.

See Also

CAPICOM Objects


Store.Add

[This is preliminary documentation and subject to change.]

The Add method adds a Certificate object to an open certificate store. This method can only be used with a store that has been opened with read/write access.

[Visual Basic]
ObjectName.Add(
  Certificate as Certificate
)

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a Store object.
[Visual Basic] Certificate
[in] Expression that resolves to an instance of a Certificate object to be added to the store.

Return Values

[Visual Basic] None.

Remarks

This method fails if the store is not open in read/write mode. While this method can be used with MEMORY stores, any changes made to a MEMORY store are not persisted when the store is closed.

A dialog is displayed before any change is made to a store, if this method is called from a Web-based application.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.


Store.Export

[This is preliminary documentation and subject to change.]

The Export method copies the contents of an open certificate store to an encoded String.

[Visual Basic]
ObjectName.Export(
  SaveAs as CAPICOM_STORE_SAVE_AS_TYPE,
  EncodingType as CAPICOM_ENCODING_TYPE
) as String

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a Store object.
[Visual Basic] SaveAs
[in] CAPICOM_STORE_SAVE_AS_TYPE enumerated type indicating the format for the export operation. The default value is CAPICOM_STORE_SAVE_AS_SERIALIZED.
[Visual Basic] EncodingType
[in] CAPICOM_ENCODING_TYPE enumerated type indicating the encoding type of the exported store. The default encoding value is CAPICOM_ENCODE_BASE64.

Return Values

[Visual Basic] This method returns a String containing the certificates in the store in the specified encoding form.

Remarks

A dialog is displayed before this method is executed, if this method is called from a Web-based application.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.


Store.Import

[This is preliminary documentation and subject to change.]

The Import method copies into an open certificate store the contents of a previously exported certificate store. This method can only be used with a store that has been opened with read/write access.

[Visual Basic]
ObjectName.Import(
  EncodedStore as String
)

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a Store object.
[Visual Basic] EncodedStore
[in] String containing the encoded certificates to be imported.

Return Values

[Visual Basic] None.

Remarks

This method fails if the store is not opened in read/write mode. While this method can be used with MEMORY stores, any changes made to a MEMORY store are not persisted when the store is closed.

A dialog is displayed before any change is made to a store, if this method is called from a Web-based application.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.


Store.Open

[This is preliminary documentation and subject to change.]

The Open method opens a specified certificate store. By default, the CAPICOM_CURRENT_USER_STORE location and CAPICOM_MY_STORE store are opened as read-only.

[Visual Basic]
ObjectName.Open( _
  StoreLocation as CAPICOM_STORE_LOCATION,
  StoreName as String, _
  OpenMode as CAPICOM_STORE_OPEN_MODE _
)

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a Store object.
[Visual Basic] StoreLocation
[in] CAPICOM_STORE_LOCATION enumerated type value indicating the location of the store to be opened. The default value is CURRENT_USER_STORE.
[Visual Basic] StoreName
[in] String containing the name of the certificate store to be opened. The default value is CAPICOM_MY_STORE.
Value | Description
CAPICOM_MY_STORE | My store. This store is used for a user's personal certificates.
CAPICOM_CA_STORE | CA store. This store is used to store intermediate CA certificates.
CAPICOM_ROOT_STORE | Root store. This store is used to store the root CA, and self-signed, trusted certificates.
CAPICOM_OTHER_STORE | AddressBook store. This store is used to keep the certificates of others.

[Visual Basic] OpenMode
[in] CAPICOM_STORE_OPEN_MODE enumerated type indicating the open mode of the store. By default, the store is open as read-only.

Note Stores in some locations can only be opened in read-only mode. These include all Active Directory (AD) stores, and all stores in CAPICOM_LOCAL_MACHINE_STORE for which the user does not have write permissions. Attempts to open a store as a read/write store without proper access and permissions will result in the failure of the Open method.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.


Store.Remove

[This is preliminary documentation and subject to change.]

The Remove method removes a certificate from an open certificate store. This method can only be used with a store that has been opened with read/write access.

[Visual Basic]
ObjectName.Remove(
  Certificate as Certificate
)

Parameters

[Visual Basic] ObjectName
Expression that resolves to an instance of a Store object.
[Visual Basic] Certificate
[in] Expression that resolves to an instance of a Certificate object to be removed from the store.

Return Values

[Visual Basic] None.

Remarks

This method fails if the store is not open in read/write mode. While this method can be used with MEMORY stores, any changes made to a MEMORY store are not persisted when the store is closed.

A dialog is displayed before any change is made to a store if this method is called from a Web-based application.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later (or Windows NT 4.0 SP4 or later).
Windows 95/98/Me: Requires Windows 95 or later (with Internet Explorer 5 or later).
Library: Included as a resource in Capicom.dll.


CAPICOM Exception and Error Codes

[This is preliminary documentation and subject to change.]

Microsoft® Visual Basic® errors return an Err.number value greater than 0. For those errors, Err.Description values provide information on the cause of the error. In addition to Visual Basic errors, CAPICOM errors and exceptions return the codes listed in the following table.

Error code/value | Description
CAPICOM_E_ENCODE_INVALID_TYPE 0x80880100 | An invalid encoding type was used. The valid encoding types are CAPICOM_ENCODE_BASE64 or CAPICOM_ENCODE_BINARY.
CAPICOM_E_EKU_INVALID_OID 0x80880200 | The OID property of the EKU object cannot be set because the Name property is not set to CAPICOM_EKU_OTHER. To correct, set the Name property to CAPICOM_EKU_OTHER before setting the OID property.
CAPICOM_E_EKU_OID_NOT_INITIALIZED 0x80880201 | The OID value of the EKU object has not been initialized. To initialize it, either set the Name property to anything other than CAPICOM_EKU_OTHER, or set the Name property to CAPICOM_EKU_OTHER and the OID property to a value.
CAPICOM_E_CERTIFICATE_NOT_INITIALIZED 0x80880210 | The Certificate object has not been initialized. Usually, this happens when a Certificate object is instantiated, but somehow the object is not associated to a digital certificate. To associate the object to a digital certificate, either assign it to an existing Certificate object or call the Import method.
CAPICOM_E_CERTIFICATE_NO_PRIVATE_KEY 0x80880211 | The Certificate object does not have an associated private key. This error code is returned when an attempt is made to sign data using the signer's private key. This usually means the Certificate object associated with the Signer object cannot be used for the signing operation.
CAPICOM_E_CHAIN_NOT_BUILT 0x80880220 | The Chain object has not been initialized. To initialize, call the Build method.
CAPICOM_E_STORE_NOT_OPENED 0x80880230 | The Store object has not been initialized. To initialize, call the Open method.
CAPICOM_E_STORE_EMPTY 0x80880231 | The Store object does not contain any Certificate objects.
CAPICOM_E_STORE_INVALID_SAVE_AS_TYPE 0x80880232 | Invalid SaveAs value for saving the store. Valid SaveAs values are CAPICOM_STORE_SAVE_AS_SERIALIZED or CAPICOM_STORE_SAVE_AS_PKCS7.
CAPICOM_E_ATTRIBUTE_NAME_NOT_INITIALIZED 0x80880240 | The Name property of the Attribute object has not been initialized. To initialize, set the Name property.
CAPICOM_E_ATTRIBUTE_VALUE_NOT_INITIALIZED 0x80880241 | The Value property of the Attribute object has not been initialized. To initialize, set the Value property.
CAPICOM_E_ATTRIBUTE_INVALID_NAME 0x80880242 | The Name property of the Attribute object is invalid. The valid attribute names are: CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME CAPICOM_AUTHENTICATED_ATTRIBUTE_DOCUMENT_NAME CAPICOM_AUTHENTICATED_ATTRIBUTE_DOCUMENT_DESCRIPTION
CAPICOM_E_ATTRIBUTE_INVALID_VALUE 0x80880243 | The Value property of the Attribute object is invalid because the data type does not match what is intended to be stored, as indicated by the Name property. For example, if the Name property is set to CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME, the data type must be a DATE type.
CAPICOM_E_SIGNER_NOT_INITIALIZED 0x80880250 | The Signer object has not been initialized. To initialize, set the Certificate property.
CAPICOM_E_SIGNER_NOT_FOUND 0x80880251 | The signer cannot be found in the SignedData object. This usually does not happen with SignedData object that was created by CAPICOM; however, if the SignedData object was created by a third-party product, the signer's certificate may not be included in the PKCS #7 structure.
CAPICOM_E_SIGN_NOT_INITIALIZED 0x80880260 | The SignedData object has not been initialized. To initialize, set the Content property or call the Verify method.
CAPICOM_E_SIGN_INVALID_TYPE 0x80880261 | The SignedData object contains an invalid type. This usually happen when trying to verify an enveloped message with a SignedData object or vice versa.
CAPICOM_E_SIGN_NOT_SIGNED 0x80880262 | The SignedData object has not been signed. To sign, call the Sign method.
CAPICOM_E_INVALID_ALGORITHM 0x80880270 | Invalid algorithm value for the Name property of the Algorithm object. Valid algorithm values for the Name property are: CAPICOM_ENCRYPTION_ALGORITHM_RC2 CAPICOM_ENCRYPTION_ALGORITHM_RC4 CAPICOM_ENCRYPTION_ALGORITHM_DES CAPICOM_ENCRYPTION_ALGORITHM_3DES
CAPICOM_E_INVALID_KEY_LENGTH 0x80880271 | Invalid key length value for the KeyLength property of the Algorithm object. Valid key length values for the KeyLength property are: CAPICOM_ENCRYPTION_KEY_LENGTH_MAXIMUM CAPICOM_ENCRYPTION_KEY_LENGTH_40_BITS CAPICOM_ENCRYPTION_KEY_LENGTH_56_BITS CAPICOM_ENCRYPTION_KEY_LENGTH_128_BITS
CAPICOM_E_ENVELOP_NOT_INITIALIZED 0x80880280 | The EnvelopedData object has not been initialized. To initialize, set the Content property or call the Decrypt method.
CAPICOM_E_ENVELOP_INVALID_TYPE 0x80880281 | The EnvelopedData object contains an invalid type. This usually happen when trying to verify a signed message with an EnvelopedData object or vice versa.
CAPICOM_E_ENVELOP_NO_RECIPIENT 0x80880283 | There is no recipient specified in the EnvelopedData object when the Encrypt method of an EnvelopedData object is called. To add a recipient, call the Recipients.Add method.
CAPICOM_E_ENVELOP_RECIPIENT_NOT_FOUND 0x80880284 | The recipient cannot be found in the EnvelopedData object. This usually does not happen with EnvelopedData object that was created by CAPICOM; however, if the EnvelopedData object was created by a third-party product, the recipient's certificate may not be included in the PKCS #7 structure.
CAPICOM_E_ENCRYPT_NOT_INITIALIZED 0x80880290 | The EncryptedData object has not been initialized. To initialize, set the Content property or call the Decrypt method.
CAPICOM_E_ENCRYPT_INVALID_TYPE 0x80880291 | The EncryptedData object is not a valid type. This usually means the data is corrupted.
CAPICOM_E_ENCRYPT_NO_SECRET 0x80880292 | The secret of an EncryptedData object has not been initialized. To initialize, call the SetSecret method.
CAPICOM_E_NOT_SUPPORTED 0x80880900 | The requested operation is not supported in the current platform.
CAPICOM_E_UI_DISABLED 0x80880901 | When signing, the Certificate property of the Signer object has not been set, but the prompt for the user certificate has been disabled. Either enable the prompt by setting the EnablePromptForCertificateUI property of the Settings object, or set the Certificate property of the Signer object.
CAPICOM_E_CANCELLED 0x80880902 | The operation has been canceled by the user. This happens when the user is prompted for permission to carry out certain operation, such as accessing the private key, and the user cancels the operation.
CAPICOM_E_INTERNAL 0x80880911 | An internal error has occurred. Contact Microsoft Technical Support for assistance.
CAPICOM_E_UNKNOWN 0x80880999 | An unknown error has occurred. Collect as much information as possible and contact your vendor.


CAPICOM Enumerated Types

[This is preliminary documentation and subject to change.]

The following enumerated types are defined:

  • CAPICOM_ACTIVE_DIRECTORY_SEARCH_LOCATION
  • CAPICOM_ATTRIBUTE
  • CAPICOM_CERT_INFO_TYPE
  • CAPICOM_CHECK_FLAG
  • CAPICOM_EKU
  • CAPICOM_ENCODING_TYPE
  • CAPICOM_ENCRYPTION_ALGORITHM
  • CAPICOM_ENCRYPTION_KEY_LENGTH
  • CAPICOM_SECRET_TYPE
  • CAPICOM_SIGNED_DATA_VERIFY_FLAG
  • CAPICOM_STORE_LOCATION
  • CAPICOM_STORE_OPEN_MODE
  • CAPICOM_STORE_SAVE_AS_TYPE


CAPICOM_ACTIVE_DIRECTORY_SEARCH_LOCATION

[This is preliminary documentation and subject to change.]

The CAPICOM_ACTIVE_DIRECTORY_SEARCH_LOCATION enumerated type indicates the location to be searched for an Active Directory certificate store. It has the values defined in the following table.

Enumeration/value | Description
CAPICOM_SEARCH_ANY 0 | Search all available locations.
CAPICOM_SEARCH_GLOBAL_CATALOG 1 | Search only the global catalog.
CAPICOM_SEARCH_DEFAULT_DOMAIN 2 | Search only the default domain.


CAPICOM_ATTRIBUTE

[This is preliminary documentation and subject to change.]

The CAPICOM_ATTRIBUTE enumerated type indicates the kind of attribute being associated with a signature. It has the values defined in the following table.

Enumeration/value | Description
CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME 0 | The attribute contains the time that the signature was created.
CAPICOM_AUTHENTICATED_ATTRIBUTE_DOCUMENT_NAME 1 | The attribute contains the name of the signed document.
CAPICOM-AUTHENTICATED_ATTRIBUTE_DOCUMENT_DESCRIPTION 2 | The attribute contains a description of the signed document.


CAPICOM_CERT_INFO_TYPE

[This is preliminary documentation and subject to change.]

The CAPICOM_CERT_INFO_TYPE enumerated type indicates what information is to be queried from a certificate. It has the values defined in the following table.

Enumeration/value | Description
CAPICOM_INFO_SUBJECT_SIMPLE_NAME 0 | Return the friendly subject name from the certificate.
CAPICOM_INFO_ISSUER_SIMPLE_NAME 1 | Return the friendly issuer name from the certificate.
CAPICOM_INFO_SUBJECT_EMAIL_NAME 2 | Return the e-mail address of the certificate subject.
CAPICOM_INFO_ISSUER_EMAIL_NAME 3 | Return the e-mail address of the certificate issuer.


CAPICOM_CHECK_FLAG

[This is preliminary documentation and subject to change.]

The CAPICOM_CHECK_FLAG enumerated type is used to indicate conditions for which a certificate chain is to be checked. This flag has the following defined values that can be combined using an OR operator. It has the values defined in the following table.

Enumeration/value | Description
CAPICOM_CHECK_NONE 0 | No validity checking is done.
CAPICOM_CHECK_TRUSTED_ROOT 1 | Check for a trusted root of the certificate chain.
CAPICOM_CHECK_TIME_VALIDITY 2 | Check the time validity of all certificates in the chain.
CAPICOM_CHECK_SIGNATURE_VALIDITY 4 | Check for valid signatures on all certificates in the chain.
CAPICOM_CHECK_ONLINE_REVOCATION_STATUS 8 | Check the revocation status of all certificates in the chain using CRLs available online.
CAPICOM_CHECK_OFFLINE_REVOCATION_STATUS 16 | Check the revocation status of all certificates in the chain using any offline CRLs.


CAPICOM_EKU

[This is preliminary documentation and subject to change.]

The CAPICOM_EKU enumerated type indicates the enumerated key usage settings. It has the values defined in the following table.

Enumeration/value | Description
CAPICOM_EKU_OTHER 0 | Certificate has uses defined in local policy. This is used if the EKU needed is not predefined and the OID value must be set by the application.
CAPICOM_EKU_SERVER_AUTH 1 | Certificate can be used to authenticate a server.
CAPICOM_EKU_CLIENT_AUTH 2 | Certificate can be used to authenticate a client.
CAPICOM_EKU_CODE_SIGNING 3 | Certificate can be used to create a digital signature.
CAPICOM_EKU_EMAIL_PROTECTION 4 | Certificate can be used for e-mail protection.


CAPICOM_ENCODING_TYPE

[This is preliminary documentation and subject to change.]

The CAPICOM_ENCODING_TYPE enumerated type indicates the encoding type used. It has the values defined in the following table.

Enumeration/value | Description
CAPICOM_ENCODE_BASE64 0 | Data is saved as a base64-encoded string.
CAPICOM_ENCODE_BINARY 1 | Data is saved as a pure binary sequence.


CAPICOM_ENCRYPTION_ALGORITHM

[This is preliminary documentation and subject to change.]

The CAPICOM_ENCRYPTION_ALGORITHM enumerated type indicates the algorithm to be used in encryption/decryption. It has the values defined in the following table.

Enumeration/value | Description
CAPICOM_ENCRYPTION_ALGORITHM_RC2 0 | Use RSA RC2 encryption.
CAPICOM_ENCRYPTION_ALGORITHM_RC4 1 | Use RSA RC4 encryption.
CAPICOM_ENCRYPTION_ALGORITHM_DES 2 | Use DES encryption.
CAPICOM_ENCRYPTION_ALGORITHM_3DES 3 | Use triple DES encryption.


CAPICOM_ENCRYPTION_KEY_LENGTH

[This is preliminary documentation and subject to change.]

The CAPICOM_ENCRYPTION_KEY_LENGTH enumerated type indicates the key length to be used in encryption. It has the values defined in the following table.

Enumeration/value | Description
CAPICOM_KEY_LENGTH_MAXIMUM 0 | Use the maximum key length available with the indicated encryption algorithm.
CAPICOM_KEY_LENGTH_40_BITS 1 | Use 40-bit keys.
CAPICOM_KEY_LENGTH_56_BITS 2 | Use 56-bit keys if available.
CAPICOM_KEY_LENGTH_128_BITS 3 | Use 128-bit keys if available.

Note A standard key length is set for DES or Triple DES encryption. If DES or Triple DES encryption is indicated, any key length property is ignored.


CAPICOM_SECRET_TYPE

[This is preliminary documentation and subject to change.]

The CAPICOM_SECRET_TYPE enumerated type indicates the kind of 'secret' used to derive a key to be used for encryption/decryption of data. It has the value defined in the following table.

Enumeration/value | Description
CAPICOM_SECRET_PASSWORD 0 | The encryption key is to be derived from a password.


CAPICOM_SIGNED_DATA_VERIFY_FLAG

[This is preliminary documentation and subject to change.]

The CAPICOM_SIGNED_DATA_VERIFY_FLAG enumerated type indicates what is checked when a digital signature is verified. It has the values defined in the following table.

Enumeration/value | Description
CAPICOM_VERIFY_SIGNATURE_ONLY 0 | Only the signature is checked.
CAPICOM_VERIFY_SIGNATURE_AND_CERTIFICATE 1 | Both the signature and the validity of the certificate used to create the signature are checked.


CAPICOM_STORE_LOCATION

[This is preliminary documentation and subject to change.]

The CAPICOM_STORE_LOCATION enumerated type indicates the location of a certificate store. It has the values defined in the following table.

Enumeration/value | Description
CAPICOM_MEMORY_STORE 0 | The store is a memory store. Any changes in the contents of the store are not persisted.
CAPICOM_LOCAL_MACHINE_STORE 1 | The store is a local machine store. Local machine stores can be read/write stores only if the user has read/write permission. If the user has read/write permissions and if the store is opened read/write, then changes in the contents of the store are persisted.
CAPICOM_CURRENT_USER_STORE 2 | The store is a current user store. A current user store may be a read/write store. If it is, changes in the contents of the store are persisted.
CAPICOM_ACTIVE_DIRECTORY_USER_STORE 3 | The store is an Active Directory store. Active Directory stores can be opened only in read-only mode. Certificates cannot be added to or removed from Active Directory stores.


CAPICOM_STORE_OPEN_MODE

[This is preliminary documentation and subject to change.]

The CAPICOM_STORE_OPEN_MODE enumerated type indicates how a certificate store is to be opened. It has the values defined in the following table.

Enumeration/value | Description
CAPICOM_STORE_OPEN_READ_ONLY 0 | Open the store in read-only mode.
CAPICOM_STORE_OPEN_READ_WRITE 1 | Open the store in read/write mode.
CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED 2 | Open the store in read/write mode if the user has read/write permissions. If not, open the store in read-only mode.


CAPICOM_STORE_SAVE_AS_TYPE

[This is preliminary documentation and subject to change.]

The CAPICOM_STORE_SAVE_AS_TYPE enumerated type indicates the encoding of a store. It has the values defined in the following table.

Enumeration | Description
CAPICOM_STORE_SAVE_AS_SERIALIZED 0 | The store is saved is saved in serialized format.
CAPICOM_STORE_SAVE_AS_PKCS7 1 | The store is saved in PKCS #7 format.


Cryptographic Service Providers

Purpose

A Cryptographic Service Provider (CSP) contains implementations of cryptographic standards and algorithms.

Developer Audience

This documentation is written for CSP developers. It defines the CSP interfaces, describes the procedures a CSP writer must use, and the requirements that a CSP writer must fulfill to create a custom CSP. While information in this documentation is primarily intended for a person writing a CSP, it can also be of interest to advanced application developers.

See Also

CryptoAPI

About Cryptographic Service Providers

General information. Examines the elements and requirement of CSPs and presents key terms and concepts using language familiar to C/C++ application developers.

Using a Cryptographic Service Provider

Presents processes, procedures, and extended C program and function code that implement sample CSP elements.

Cryptographic Service Provider Reference

Documentation of Cryptographic Service Providers functions, structures, types, and constants.

Feedback

Make error reports and feature requests directly to Microsoft.


About Cryptographic Service Providers

A Cryptographic Service Provider (CSP) contains implementations of cryptographic standards and algorithms. At a minimum, a CSP consists of a dynamic-link library (DLL) that implements the functions in CryptoSPI (a system program interface). Most CSPs contain the implementation of all of their own functions; however, some CSPs implement their functions mainly in a Microsoft® Win32®-based service program managed by the Win32 service control manager. Others implement functions in hardware, such as a smart card or secure coprocessor. If a CSP does not implement its own functions, the DLL acts as a pass-through layer, facilitating the communication between the operating system and the actual CSP implementation.

This documentation is written for CSP developers. It defines the CSP interfaces, describes the procedures a CSP writer must use, and the requirements that a CSP writer must fulfill to create a custom CSP. While information in this documentation is primarily intended for a person writing a CSP, it can also be of interest to advanced cryptography application developers.

This documentation maintains a focus on creating a CSP and assumes familiarity with CryptoAPI in the Microsoft Platform SDK. The following related subjects, which a CSP developer must be familiar with to implement a CSP, are not covered:

  • Cryptography
  • Cryptographic protocols and standards
  • Cryptographic application programming
  • Microsoft® Windows® programming

For more reading on the above topics, see Additional Documentation on Cryptography.

This section includes the following topics.

Topic | Contents
Architecture of a Cryptographic Service Provider (CSP) | Describes the internal structure of a typical CSP and explains some of the assumptions implicit in the CryptoAPI/CryptoSPI design.
Writing a CSP | Outlines the steps used to write, test, and implement a custom CSP.
CSP Interoperability | Presents information on implementation requirements that a CSP must meet to work with other cryptography providers.


Architecture of a Cryptographic Service Provider (CSP)

This section describes the internal structure of a typical CSP and explains some of the assumptions implicit in the CryptoAPI/CryptoSPI design. Although each CSP is structured differently, the material in this section is general and applies to all cryptographic service providers.

Topics covered in this section are:

  • CSP Architectural Overview
  • Entry Points
  • Persistent Data Objects
  • Volatile Data Objects


CSP Architectural Overview

Applications do not communicate directly with a CSP. Instead, applications call CryptoAPI functions exposed by the operating system's Advapi32.dll and Crypt32.dll files. The operating system filters these function calls and passes them on to the appropriate CSP functions through CryptoSPI (a system program interface).

The CSP writer must know the nature, order, and meaning of parameters passed by the operating system to the CSP functions and must return the values as expected to the operating system.

Applications use handles to refer to data objects within the CSP. Objects that are referenced by their handles include key containers, hash objects, session key objects, and public/private key pair objects. These handles are opaque from both sides; that is, the handle that the application uses to access a data object is not the same one that the CSP uses. For various reasons, the operating system layer always accesses data objects indirectly using handles.


Entry Points

All custom CSPs must support all of the following DLL entry points:

  • CPAcquireContext
  • CPCreateHash
  • CPDecrypt
  • CPDeriveKey
  • CPDestroyHash
  • CPDestroyKey
  • CPEncrypt
  • CPExportKey
  • CPGenKey
  • CPGenRandom
  • CPGetHashParam
  • CPGetKeyParam
  • CPGetProvParam
  • CPGetUserKey
  • CPHashData
  • CPHashSessionKey
  • CPImportKey
  • CPReleaseContext
  • CPSetHashParam
  • CPSetKeyParam
  • CPSetProvParam
  • CPSignHash
  • CPVerifySignature

All PROV_RSA_SCHANNEL and PROV_DH_SCHANNEL CSPs must also support all of the following DLL entry points: These entry points are optional for other custom CSPs):

  • CPDuplicateHash
  • CPDuplicateKey

These functions compose the CryptoSPI system program interface. Each function corresponds directly to a CryptoAPI cryptographic function.

Note All of these functions must be declared with the WINAPI keyword.


Persistent Data Objects

The CSP stores public/private key pairs from session to session in persistent memory. A CSP implemented completely in software can store these keys, in encrypted form, in the system registry. CSPs with a hardware component might store the key pairs in tamper-resistant hardware.

The key pairs are stored in logical data objects called key containers. The CSP maintains one key container for each user or client that uses that CSP. Each key container can store one key pair of each type that the CSP supports. For example, the Microsoft® Base Cryptographic Provider supports two key pair types: the key exchange key pair and the digital signature key pair.

Several key containers can be open at any given time (either by a single application or multiple ones). Each call to a CryptoSPI function specifies the key container to be used with one of the parameters of the function. This is illustrated by the following drawing.

Note In the CryptoSPI context, the HCRYPTPROV data type is a handle to a particular key container within the CSP. In the CryptoAPI context, the HCRYPTPROV data type is a handle for both a key container and the CSP to be used.


Volatile Data Objects

A CSP maintains session key objects and hash objects in volatile memory. These objects are created using the CPGenKey and CPCreateHash functions, respectively. These objects are destroyed using CPDestroyKey and CPDestroyHash. They must be destroyed when their associated key container or user context is released by CPReleaseContext.

The objects maintained in volatile memory are accessed using their handles as shown below.

The CRYPT_VERIFYCONTEXT flag can be passed as the dwFlags parameter to CPAcquireContext to enable that function to create volatile private keys. Volatile private keys are required for PROV_RSA_SCHANNEL and PROV_DH_SCHANNEL CSPs.


Writing a CSP

This section outlines the steps used to write, test, and implement a custom CSP.

Before writing a CSP, a writer must accomplish two tasks:

  • Select the cryptographic algorithms and data formats to be included.
  • Obtain implementations for each algorithm and data format.

Once these tasks have been accomplished, a custom CSP can be created. The creation procedure is as follows:

  1. Creating the CSP DLL that exposes the CryptoSPI functions.
  2. Writing the CSP setup program that creates the appropriate registry entries.
  3. Test signing the CSP.
  4. Testing the CSP.
  5. Getting the CSP signed to enable the CSP to be used with the released versions of Microsoft® Windows® 2000, Microsoft® Windows NT®, or Windows 95 and later.
  6. Test the officially signed CSP. This is the same as step 4, except that the official signature and the release version of Windows are used.


Creating the CSP DLL

A CSP DLL is created like any other DLL. This procedure is explained in the MSDN documentation.

For a CSP with hardware components, the DLL might involve writing a smart card device driver or the embedded code that runs on the card. For information on writing any needed device drivers, see the Microsoft Device Developer Kit (DDK).

Every custom CSP DLL must expose all of the CryptoSPI functions listed in Entry Points. If a CSP does not actually support a particular function, a call to that function must at least return the E_NOTIMPL error code. A CSP that does not perform all of the cryptographic processes can be created; for example, a CSP specializing in signature verification that does not support data encryption functions.

Custom CSPs may involve more than one DLL; however, this is discouraged because it can create run-time complications. For more information, see CPAcquireContext. Regardless of the number of DLLs used for a custom CSP, all of them must be signed by Microsoft to enable the CSP to be used with the released versions of Windows 2000, Windows NT, or Windows 95 and later.


Writing the CSP Setup Program

Part of creating a CSP is providing for its installation. At a minimum, a CSP must include a setup program that:

  • Copies the CSP DLL to a directory pointed to by the PATH environment variable.
  • Creates the appropriate registry entries.

The following topics discuss the steps that must be included in writing a CSP setup program:

  • Registering the CSP
  • Setting the Machine Default CSP
  • Setting the User Default CSP


Registering the CSP

A CSP is registered under the following registry key:

HKEY_LOCAL_MACHINE
SOFTWARE
Microsoft
Cryptography
Defaults
Provider

The following registry entries under the above hKey register the CSP with the operating system.

<CSP name>
>Image Path:REG_SZ:<CSP DLL name>
>Signature:REG_BINARY:<digital signature>
 >Type:REG_DWORD:<CSP type>

The <CSP name> entry is the text name of the CSP. If the CSP has been signed by Microsoft Corporation, this name must exactly match the CSP name that was specified in the Export Compliance Certificate (ECC).

The <CSP DLL name> (Image Path) entry is the name of the CSP DLL. If a fully qualified path, such as C:\Myx\Rsabase.dll is specified, the CSP DLL need not be placed in a directory pointed to by the PATH environment variable.

The <digital signature> (Signature) entry is the digital signature file for the CSP DLL. This signature file can be either the debug signature created with the Sign.exe utility or the release signature obtained from Microsoft. With Windows 2000, the signature can be in a resource within the CSP. Sign.exe is discussed in Test Signing the CSP.

The <CSP type> entry is in decimal format and exactly 3 digits in length. For example, if the CSP type is 25, the key name is Type 025.


Setting the Machine Default CSP

One machine default CSP can be specified for each CSP type. The machine default CSP is used if an application calls CryptAcquireContext with only a CSP type specified and no user default CSP registry entry exists.

Unless there are important reasons for setting up a custom CSP as the machine default CSP, the normal default CSP should not be changed. If a custom CSP must be used, the setup program can install its CSP as the machine default. If the normal default is to be changed, the following registry entry sets the machine default CSP:

HKEY_LOCAL_MACHINE
SOFTWARE
Microsoft
Cryptography
Defaults
Provider Type
Type <CSP type>
 >Name:REG_SZ:<CSP name>

The <CSP type> entry is in decimal format and exactly 3 digits in length. For example, if the CSP type is 25, the key name is Type 025.

The <CSP Name> entry must be set to the textual name of the CSP. This must exactly match the <CSP Name> registry key discussed in Registering the CSP.


Setting the User Default CSP

One user default CSP can be specified for each CSP type. The user default CSP is used when an application calls CryptAcquireContext with only a CSP type specified. Unless there are important reasons for setting up a custom CSP as the user default CSP, the normal default CSP should not be changed.

If the user default CSP must be changed, user defaults are stored in the registry's HKEY_CURRENT_USER window and can only be set if the actual end user is currently logged on to the computer. In any case, the end user should be consulted or informed whenever the user default CSP is changed. The user default CSP is set using the CryptSetProvider function, which internally sets the following registry entry:

HKEY_CURRENT_USER
Software
Microsoft
Cryptography
Provider Type<CSP type>
 >Name:REG_SZ:<CSP name>

The <CSP type> entry is in decimal format and exactly 3 digits in length. For example, if the CSP type is 25, the key name is Type 025.

The <CSP name> entry must be set to the textual name of the CSP. This must exactly match the <CSP name> registry key discussed in Registering the CSP.


Test Signing the CSP

A CSP DLL must be signed each time it is built. This includes each build of the CSP that is made for testing purposes. Prior to Windows 2000, the signature is placed appropriately in the registry. Windows 2000 introduces signing a CSP digitally in a resource in the CSP DLL. This eliminates problems with signatures in the registry getting out of synchronization with the CSP binaries on the system.

Old signature checking in the registry is still supported in Windows 2000 so CSPs with signatures in that form continue to work. To support the same CSP binary on Windows 2000 computers and Windows NT 4.0 and Windows 95 and later computers, some CSPs may need to be signed both in the resource and in the registry using the old signature form.

Windows 2000 continues to support CSPs verifying signatures on loaded DLLs using the FuncVerifyImage callback function from the VTableProvStuc structure passed to the CSP with CPAcquireContext. To use the callback in this way, the pointer to the signature, parameter 1, must be set to NULL.

To support the new signature format, the CSP must provide a 144 byte binary resource numbered 0x29A (decimal 666). The signature is placed in this resource.

A makefile can be used for the creation process of a CSP to incorporate this signing and registering procedure so that no steps are forgotten.

Sign Utility

The Sign.exe utility signs CSP DLLs. Given a DLL file, the utility produces a signature file whose contents can be placed into the registry as discussed above and in Setting the User Default CSP. Sign.exe takes three arguments:

sign {s|v} <filename> <signature file>

The first argument must be s if a signature file is to be generated and v if an existing signature file is to be verified against the DLL file. The second argument must be the fully qualified file name of the DLL file. The third argument must be the fully qualified file name of the signature file.

For the CSP DLL file Myxcsp.dll, the following command generates a signature file. The signature file will be named Myxcsp.sig.

sign s myxcsp.dll myxcsp.sig


Testing the CSP

In accordance with the U.S. Department of Commerce's export restrictions concerning cryptography, Microsoft must digitally sign a CSP so that it will run on Microsoft operating systems. The Microsoft Cryptographic Service Provider Developer's Kit (CSPDK) is designed to help test a CSP. After the CSP has been tested and it is ready for signing, send e-mail to cspsign@microsoft.com.

Note that Microsoft can only distribute the CSPDK to legal residents of the U.S. and Canada.

Information on how to obtain the CSPDK can be found at http://www.microsoft.com/security/tech/cryptoapi/cspdkintrocontent.asp.

CSP testing involves the following steps:

  1. Sign the CSP with the Sign.exe utility to produce a debug signature (.sig) file. For more information, see Test Signing the CSP.
  2. Install the CSP using the setup program written for the CSP
  3. Run test code that calls CryptoAPI functions to test the CSP's implementations of those functions.

Developers of CSPs for Microsoft® Windows CE must develop and test their CSP using the x86 emulator from the CSPDK using Windows CE running natively on a PC.


Getting the CSP Signed

A CSP must be digitally signed by Microsoft to be used with the released versions of Windows 2000, Windows NT, or Windows 95 and later. The digital signature separates applicable legal export controls on the CSP from the host operating system and applications, thereby allowing broader distribution of encryption-enabled products than would be possible under other circumstances. Generally, U.S. export law limits the export outside the U.S. or Canada of products that host strong encryption or an open cryptographic interface. The digital signature requirement effectively prevents arbitrary use of CryptoAPI, and allows export of the host operating system and CryptoAPI-enabled applications. By removing encryption services from host systems and applications, CryptoAPI places the burden of U.S. encryption export restrictions squarely on the CSP vendor, who is subject to those controls regardless.

In addition, the operating system validates this signature periodically to ensure that the CSP has not been changed.

Microsoft's interests in applying signatures to CSPs are

  • To ensure the exportability of CryptoAPI-enabled systems and applications
  • To exercise due diligence under prevailing U.S. and other national export controls.
  • To help maintain the integrity of the CSP

Any disclosure requested by Microsoft is used solely to determine whether export approval is required, or if sufficient export approval exists, for Microsoft to sign a vendor's CSP. Vendors must complete and return an Export Compliance Certificate (ECC) to Microsoft. A copy of the ECC is included at the end in Export Compliance Certificate (ECC).

Vendors developing a CSP for distribution only in the U.S. and Canada only need to compete and return the EEC.

Vendors who expect to export a CSP outside the U.S. and Canada must obtain export approval from a U.S. or Canadian export licensing authority or claim an exemption under U.S. export law. The completed ECC must contain evidence of export approval or exemption, and certify that the CSP is intended for export outside the U.S. or Canada. Microsoft independently confirms export approval, and when confirmation is complete, will return information on arrangements to sign the CSP.

Microsoft makes every effort to review the ECC and sign CSPs as expeditiously as possible. Exact time frames for review and signing depend on the circumstances of each request.

Vendors should consult legal counsel or U.S. export authorities to determine whether an export approval or exemption applies to their CSP.

Questions and comments about the CSP signing mechanism, signing procedures and CryptoAPI licensing policy can be sent by email to cspsign@microsoft.com.

CSP Vendors can also consult

U.S. Commerce Department,
Bureau of Export Administration
Office of Exporter Services

for assistance in the classification and/or export licensing of CSPs for export from the U.S. The US Commerce Department's export license process, encryption export controls, and points of contact are described on their Web site at http://www.bxa.doc.gov/encstart.htm.

Microsoft will sign CSPs subject only to the limitations of U.S. export controls. Microsoft will sign CSPs from competitors. At present, CSPs are signed at the Microsoft facilities in Redmond, Washington, USA.

For further information, see Microsoft's CSP Signing Policy.


Extending CryptoAPI

CryptoAPI has been designed to be easily extensible. New types and parameters can be defined by any CSP author to make CryptoAPI bend to the requirements of a wide variety of situations.

Extensible items | Comment
Provider types | A provider type represents a particular family or type of cryptographic services. New provider types can be defined, each serving a particular niche.
Provider parameters | Provider parameters are sent and received using CPSetProvParam and CPGetProvParam, respectively. New provider parameters could allow a CSP to be configured in ways not foreseen by the CryptoAPI designers.
Algorithm identifiers | The enumeration facilities of CPGetProvParam allow applications to list algorithm identifiers dynamically. New symmetric, public-key, and hash algorithms can be defined at any time.
Public/private key pair types | While new key pair types can be defined as needed, currently only signature and key exchange key pairs are used.
Key BLOB types | New key BLOB types could permit session keys, public keys, and public/private key pairs to be exchanged in a flexible manner using the CPExportKey and CPImportKey functions.
Key parameters | Key parameters are sent and retrieved using CPSetKeyParam and CPGetKeyParam. New key parameters could enable support for many different types of keys.
Hash object parameters | Hash object parameters are sent and retrieved using CPSetHashParam and CPGetHashParam. New hash object parameters could enable support for many different types of hashes.
Flag values | Most CryptoAPI/CryptoSPI functions have a dwFlags parameter. New dwFlags values could modify the behavior of functions as necessary.

Extensions to CryptoAPI must be made in a responsible manner. Before defining new parameters and algorithm types, a CSP developer should consult Microsoft Corporation, so that:

  • Common CryptoAPI extensions can be identified and placed into the standard Microsoft® Win32® Wincrypt.h file.
  • Namespace collisions can be avoided.
  • It can be determined if the extension is required, or whether a particular operation can be achieved with the current API.

Note For a CSP to be compatible with applications developed for the Microsoft Base Cryptographic Provider, it must support all of the preceding items as described in CryptoAPI Reference and in Cryptographic Service Provider Reference.


CSP Interoperability

To provide for interoperability with other cryptographic service providers (CSPs), any PROV_RSA_FULL CSP must conform to specific implementation requirements. The PROV_RSA_SIG provider type is a subset of PROV_RSA_FULL and not all of the implementation requirements discussed apply to PROV_RSA_SIG providers.

Major areas that must conform to implementation requirements are listed in the following table.

Major requirement | Description
Supported algorithms | The minimum set of algorithms that must be supported by all PROV_RSA_FULL and PROV_RSA_SIG providers.
Key BLOB formats | The standard encoding schemes for key BLOBs. Using standard encoding schemes enables keys to be exchanged between CSPs even if the CSPs come from different vendors.
Deriving session keys | The procedure for deriving session keys from hash values so that given the same base data, every CSP generates exactly the same session key.
Hashing session keys | The procedure for hashing session keys so that given the same session key, every CSP generates exactly the same hash value.
Digital signature mechanics | The mechanics of digital signatures and signature format so that different CSPs can verify each other's signatures.


Supported Algorithms

All PROV_RSA_FULL or PROV_RSA_SIG providers must support a minimum set of algorithms. Additional algorithms can be implemented, but for security reasons this is discouraged.

The following cryptographic service providers (CSP) are currently available from Microsoft.

Provider | Description
Microsoft Base Cryptographic Provider | A broad set of basic cryptographic functionality that can be exported to other countries.
Microsoft Strong Cryptographic Provider | An extension of the Microsoft Base Cryptographic Provider available with Microsoft® Windows® 2000 and later. It is currently available only within the United States and Canada.
Microsoft Enhanced Cryptographic Provider | Microsoft Base Cryptographic Provider with through longer keys and additional algorithms. It is currently available only within the United States and Canada.
Microsoft DSS Cryptographic Provider | Provides hashing, data signing, and signature verification capability using the Secure Hash Algorithm (SHA) and Digital Signature Standard (DSS) algorithms.
Microsoft Base DSS and Diffie-Hellman Cryptographic Provider | A superset of the DSS Cryptographic Provider that also supports Diffie-Hellman key exchange, hashing, data signing, and signature verification using the Secure Hash Algorithm (SHA) and Digital Signature Standard (DSS) algorithms.
Microsoft DSS and Diffie-Hellman/Schannel Cryptographic Provider | Supports hashing, data signing with DSS, generating Diffie-Hellman (D-H) keys, exchanging D-H keys, and exporting a D-H key. This CSP supports key derivation for the SSL3 and TLS1 protocols.
Microsoft RSA/Schannel Cryptographic Provider | Supports hashing, data signing, and signature verification. The algorithm identifier CALG_SSL3_SHAMD5 is used for SSL 3.0 and TLS 1.0 client authentication. This CSP supports key derivation for the SSL2, PCT1, SSL3 and TLS1 protocols.

Supported algorithms are specifically enumerated under the following topics:

  • Public Key Algorithms
  • Symmetric Encryption Algorithms
  • Hashing Algorithms


Public-Key Algorithms

All PROV_RSA_FULL and PROV_RSA_SIG CSPs use the RSA Public-Key Cipher for both digital signatures and key exchange. Two public/private key pairs are defined: the signature key pair and the exchange key pair. The exchange key pair can be used both to exchange session keys and to verify digital signatures.

Although the Microsoft Base Cryptographic Provider uses 512-bit public/private keys, this is not a requirement. A new CSP is free to use larger keys, although using larger keys makes a CSP subject to controls on exports outside the United States and Canada. For more information on export control, see Microsoft's CSP Signing Policy.

The CPVerifySignature function of all CSPs must be able to verify signatures of up to 2048 bits, regardless of the size of the signatures produced by CPSignHash. This ensures that the CSP will be able to validate all compatible certificates, even those signed with large keys. This requirement may be difficult for CSPs implemented in hardware packages with limited memory. It may be necessary for some hardware CSPs to implement a software signature verification algorithm within the primary DLL.


Symmetric Encryption Algorithms

Every PROV_RSA_FULL or PROV_RSA_SIG CSP must provide an implementation of the RC2 block cipher and the RC4 stream cipher encryption. These algorithms are used to create session keys for bulk data encryption and decryption.

The Microsoft Base Cryptographic Provider uses 40-bit session keys with 88-bit salt values (128 bits total). New CSPs are free to use larger keys, although using longer keys can make exporting the CSP outside the USA and Canada more difficult. For more information on export control, see Microsoft's CSP Signing Policy. In addition, using a session key larger than 40-bits makes key exchange with a Microsoft Base Cryptographic Provider more difficult.


Hashing Algorithms

Every PROV_RSA_FULL or PROV_RSA_SIG CSP must provide implementations of both the MD5 and the SHA hash functions. In addition, supporting the MD2 algorithm is helpful if compatibility is important. To be interoperable with the Microsoft Cryptographic Service Providers, a CSP must also support the SSL3 Client Authentication algorithm.


Key BLOB Formats

Key BLOBs are structures that store keys outside a CSP key container. Every key BLOB consists of one or more fixed-length header structures followed by the key data itself. The key data is variable in length and is often encrypted.

Key BLOBs consist of binary data. The size of a key BLOB varies depending on the BLOB type and the key size.

Unless stated otherwise, all multibyte numbers are stored in little-endian format; that is, the first byte of a number is the least significant and the last byte is the most significant. For example, the four byte hexadecimal number 0x12345678 will be stored as:

        78 56 34 12

This is the most common format for computers running versions of Microsoft® Windows®.

Standard structure formats include the following.

Structure format | Description
BLOBHEADER | Structure used at the beginning of all key BLOB structures.
Simple Key BLOBs | BLOB format for an encrypted session key.
Public Key BLOBs | BLOB format for a public key.
Private Key BLOBs | BLOB format for a private key in encrypted form.
Symmetric Wrapped Key Blobs | BLOB format for exporting a symmetric key wrapped with another symmetric key.


Simple Key BLOBs

Simple key BLOBs (type SIMPLEBLOB) are used to store and transport session keys. These are always encrypted with a key exchange public key. They have the following format:

BLOBHEADER blobheader;
ALG_ID algid;
BYTE encryptedkey[rsapubkey.bitlen/8];

The algorithm identifier that immediately follows the BLOBHEADER structure specifies the encryption algorithm that was used to encrypt the session key data. This typically has a value of CALG_RSA_KEYX, indicating that the session key data was encrypted with a key exchange public key, using the RSA Public-Key algorithm.

The encrypted session key data is in the form of a PKCS #1, type 2 encryption block. For details on this data format, see The Public-Key Cryptography Standards (PKCS), published by RSA Data Security, Inc.

This data is always the same size as the public key's modulus. For example, public keys generated by the Microsoft Base Cryptographic Provider are always 512 bits (64 bytes) in length, so the encrypted session key data is also always 64 bytes.

Sample Simple Key BLOB

Two data items are required before a SIMPLEBLOB structure can be built: the session key to be transported and the public key used to encrypt the session key. This example shows a typical 40-bit RC4 session key and a public key used to encrypt it. In this example, the hexadecimal value of the session key material is:

74 4f 06 35 3f

The first step is building the PKCS #1, type 2 encryption block. This is always the same size as the public key's modulus (64 bytes) and contains the following fields.

Field | Bytes | Description
Key material | 1 to 5 | Session key material. The size of this field varies depending on the size of the session key. The bytes in the session key data are reversed before they are placed in the encryption block because the operating system formats data in little-endian format, and the encryption block must be built in big-endian format.
Reserved | 6 | Zero value.
Padding | 7 to 56 | Random padding data. The size of this field is adjusted as necessary so that the encryption block's overall length is correct. It can be longer than the 50 bytes indicated here if a longer RSA key is used. None of these bytes are allowed to be zero.
Block type | 57 | The PKCS block type (0x02).
Reserved | 58 | Zero value.

The order of this table is reversed from the diagram found in the PKCS documentation because the encryption block is built in big-endian format on a little-endian computer.

After the encryption block has been built, its sixty-four byte hexadecimal value could look something like this:

3f 35 06 4f 74 00 c9 db
b1 74 b0 de 8e d4 aa c5
99 8a 4d 19 4f 0f ed 24
b0 2e 93 fe e9 f4 d4 93
dc ac 9e 9f 3a 62 be f1
e4 1d 44 5c 33 e5 2f 4f
58 01 95 16 36 f7 86 65
68 6c 2a 28 79 55 02 00

Next, the block is encrypted with the appropriate public key. After this is done, the encrypted block might look like this:

e3 c1 78 62 c4 1f 51 4f
e9 50 89 fd 0d 58 bd 9d
74 c7 54 19 bd 97 3b a0
f0 6c ee 86 05 74 16 62
27 a5 99 63 c4 6f 95 ed
3e 93 ba 9a ea 36 cc 96
92 e8 aa 15 2c 50 a1 3c
38 d3 1f 08 e2 82 cd 90

Finally, the BLOBHEADER structure and the algorithm identifier are tacked onto the front of the encryption block, resulting in a complete SIMPLEBLOB data structure:

01 02 00 00 01 68 00 00
00 a4 00 00 e3 c1 78 62
c4 1f 51 4f e9 50 89 fd
0d 58 bd 9d 74 c7 54 19
bd 97 3b a0 f0 6c ee 86
05 74 16 62 27 a5 99 63
c4 6f 95 ed 3e 93 ba 9a
ea 36 cc 96 92 e8 aa 15
2c 50 a1 3c d3 1f 08 e2
82 cd 90 2b

Note The encrypted block begins at byte 13.

The BLOBHEADER structure and the algorithm identifier have been assigned the following values:

blobheader.bType    = SIMPLEBLOB;         // 0x01     in byte number 1
blobheader.bVersion = CUR_BLOB_VERSION;   // 0x02     in byte number 2
blobheader.Reserved = 0;                  // 0x0000   in bytes 3 and 4
blobheader.aiKeyAlg = CALG_RC4;           // 0x00006801 in reverse
                                          // order in bytes 5, 6, 7,
                                          // and 8
algid               = CALG_RSA_KEYX;      // 0x0000a400  in reverse
                                          // order in bytes 9, 10, 11,
                                          // and 12

When filling in the BLOBHEADER structure, the two Reserved field bytes are set to zero.


Public Key BLOBs

Public key BLOBs (type PUBLICKEYBLOB) are used to store RSA public keys. They have the following format:

BLOBHEADER blobheader;
RSAPUBKEY rsapubkey;
BYTE modulus[rsapubkey.bitlen/8];

Notice that public key BLOBs are not encrypted, but contain public keys in plaintext form.

The RSAPUBKEY structure contains information specific to the particular public key contained in the key BLOB. It is defined as follows:

typedef struct _RSAPUBKEY {
    DWORD magic;
    DWORD bitlen;
    DWORD pubexp;
} RSAPUBKEY;

The following table describes each of the fields in the RSAPUBKEY structure.

Field | Description
magic | This is set to "RSA1" (0x31415352) for public keys and to "RSA2" (0x32415352) for private keys. These hex values are an ASCII encoding of "RSA1" and "RSA2."
bitlen | Number of bits in the modulus. In practice, this must always be a multiple of 8.
pubexp | The public exponent.

The public key modulus data is located directly after the RSAPUBKEY structure. The size of this data will vary depending on the size of the public key. The number of bytes can be determined by dividing the value of the bitlen field of RSAPUBKEY by 8.

Sample Public Key BLOB

The following hex dump shows a sample public key BLOB, generated by the Microsoft Base Cryptographic Provider. This contains a key exchange public key.

0x00000000 06 02 00 00 00 a4 00 00  ........
0x00000008 52 53 41 31 00 02 00 00  RSA1....
0x00000010 01 00 01 00 e1 94 84 7a  .......z
0x00000018 27 4c 7b da db c5 99 dd  'L{.....
0x00000020 ed 20 1a b8 66 44 21 dc  . ..fD!.
0x00000028 10 e5 ee 48 62 39 ae 8f  ...Hb9..
0x00000030 cf 17 81 f0 37 8b b5 46  ....7..F
0x00000038 a9 65 b7 4e 75 83 84 4e  .e.Nu..N
0x00000040 4f ce f1 f2 ad a0 b1 22  O......"
0x00000048 09 ec c2 30 96 f8 27 2b  ...0..'+
0x00000050 33 cf a4 be              3...

Notice that the BLOBHEADER and RSAPUBKEY structures have been assigned the following values, and the last 64 bytes of the BLOB contain the public key's modulus data.

blobheader.bType    = PUBLICKEYBLOB;      // 0x06
blobheader.bVersion = CUR_BLOB_VERSION;   // 0x02
blobheader.reserved = 0;                  // 0x0000
blobheader.aiKeyAlg = CALG_RSA_KEYX;      // 0x0000a400
rsapubkey.magic     = 0x31415352;         // "RSA1"
rsapubkey.bitlen    = 512;                // 0x00000200
rsapubkey.pubexp    = 65537;              // 0x00010001

When filling in the BLOBHEADER structure, place zero in the reserved field.


Private Key BLOBs

Private key BLOBs (type PRIVATEKEYBLOB) are used to store RSA public/private key pairs. They have the following format:

BLOBHEADER blobheader;
RSAPUBKEY rsapubkey;
BYTE modulus[rsapubkey.bitlen/8];
BYTE prime1[rsapubkey.bitlen/16];
BYTE prime2[rsapubkey.bitlen/16];
BYTE exponent1[rsapubkey.bitlen/16];
BYTE exponent2[rsapubkey.bitlen/16];
BYTE coefficient[rsapubkey.bitlen/16];
BYTE privateExponent[rsapubkey.bitlen/8];

If the key BLOB is encrypted, then everything but the BLOBHEADER portion of the BLOB is encrypted. Note that the encryption algorithm and encryption key parameters are not stored along with the private key BLOB. It is the responsibility of the application to manage this information.

The following table describes each private key BLOB component. Note that these fields largely correspond to the ones described in section 7.2 of PKCS #1: RSA Encryption Standard.

Field | Description
blobheader | A BLOBHEADER structure as described in a previous section. The bType field must always have a value of PRIVATEKEYBLOB.
rsapubkey | A RSAPUBKEY structure as described in Public Key BLOBs. The magic field must always have a value of 0x32415352 ("RSA2").
modulus | The modulus. This has a value of "prime1 * prime2" and is often known as "n".
prime1 | Prime number 1, often known as "p".
prime2 | Prime number 2, often known as "q".
exponent1 | Exponent 1. This has a numeric value of "d mod (p - 1)".
exponent2 | Exponent 2. This has a numeric value of "d mod (q - 1)".
coefficient | Coefficient. This has a numeric value of "(inverse of q) mod p".
privateExponent | Private exponent, often known as "d".

Sample Private Key BLOB

The following hex dump shows a sample private key BLOB, generated by the Microsoft Base Cryptographic Provider. This contains a key exchange public/private key pair. Note that this sample contains a public key that is different than the one discussed in Public Key BLOBs.

0x00000000  07 02 00 00 00 a4 00 00  ........
0x00000008  52 53 41 32 00 02 00 00  RSA2....
0x00000010  01 00 01 00 6b df 51 ef  ....k.Q.
0x00000018  db 6f 10 5c 32 bf 87 1c  .o.\2...
0x00000020  d1 4c 24 7e e7 2a 14 10  .L$~.*..
0x00000028  6d eb 2c d5 8c 0b 95 7b  m.,....{
0x00000030  c7 5d c6 87 12 ea a9 cd  .]......
0x00000038  57 7d 3e cb e9 6a 46 d0  W}>..jF.
0x00000040  e1 ae 2f 86 d9 50 f9 98  ../..P..
0x00000048  71 dd 39 fc 0e 60 a9 d3  q.9..`..
0x00000050  f2 38 bb 8d 5d 2c bc 1e  .8..],..
0x00000058  c3 38 fe 00 5e ca cf cd  .8..^...
0x00000060  b4 13 89 16 d2 07 bc 9b  ........
0x00000068  e1 20 31 0b 81 28 17 0c  . 1..(..
0x00000070  c7 73 94 ee 67 be 7b 78  .s..g.{x
0x00000078  4e c7 91 73 a8 34 5a 24  N..s.4Z$
0x00000080  9d 92 0d e8 91 61 24 dc  .....a$.
0x00000088  b5 eb df 71 66 dc e1 77  ...qf..w
0x00000090  d4 78 14 98 79 44 b0 19  .x..yD..
0x00000098  f6 f0 7d 63 cf 62 67 78  ..}c.bgx
0x000000a0  d0 7b 10 ae 6b db 40 b3  .{..k.@.
0x000000a8  b2 eb 2e 9f 31 34 2d cb  ....14-.
0x000000b0  bf a2 6a a6 1f e9 03 42  ..j....B
0x000000b8  f2 63 9b b7 33 d0 fe 20  .c..3..
0x000000c0  83 26 1f 56 a8 24 f5 6d  .&.V.$.m
0x000000c8  19 51 a5 92 31 e4 2b bc  .Q..1.+.
0x000000d0  11 c8 26 75 a0 51 e9 83  ..&u.Q..
0x000000d8  ca ee 4b f0 59 eb a4 81  ..K.Y...
0x000000e0  d6 1f 49 42 2b 75 89 a7  ..IB+u..
0x000000e8  9f 84 7f 1f c3 8f 70 b6  ......p.
0x000000f0  7e 06 5e 8b c9 53 65 80  ~.^..Se.
0x000000f8  b7 16 f2 5e 5e de 0b 57  ...^^..W
0x00000100  47 43 86 85 8a fb 37 ac  GC....7.
0x00000108  66 34 ba 09 1a b1 21 0b  f4....!.
0x00000110  aa fa 6c b7 75 a7 3e 23  ..l.u.>#
0x00000118  18 58 95 90 b5 29 a4 1e  .X...)..
0x00000120  15 76 52 56 bb 3d 6b 1d  .vRV.=k.
0x00000128  2a d1 9f 5c 8a c0 55 ea  *..\..U.
0x00000130  c3 29 a2 1e              .)..

Notice that the BLOBHEADER and RSAPUBKEY structures have been assigned the following values:

blobheader.bType    = PRIVATEKEYBLOB;     // 0x07
blobheader.bVersion = CUR_BLOB_VERSION;   // 0x02
blobheader.reserved = 0;                  // 0x0000
blobheader.aiKeyAlg = CALG_RSA_KEYX;      // 0x0000a400
rsapubkey.magic     = 0x32415352;         // "RSA2"
rsapubkey.bitlen    = 512;                // 0x00000200
rsapubkey.pubexp    = 65537;              // 0x00010001

The following table shows the numeric values of each of the large numeric fields contained by the sample private key BLOB. As with all of the numbers in the public and private key BLOBs, these are in little-endian byte order.

Field name Value
modulus 6b df 51 ef db 6f 10 5c 32 bf 87 1c d1 4c 24 7e
e7 2a 14 10 6d eb 2c d5 8c 0b 95 7b c7 5d c6 87
12 ea a9 cd 57 7d 3e cb e9 6a 46 d0 e1 ae 2f 86
d9 50 f9 98 71 dd 39 fc 0e 60 a9 d3 f2 38 bb 8d
prime1 5d 2c bc 1e c3 38 fe 00 5e ca cf cd b4 13 89 16
d2 07 bc 9b e1 20 31 0b 81 28 17 0c c7 73 94 ee
prime2 67 be 7b 78 4e c7 91 73 a8 34 5a 24 9d 92 0d e8
91 61 24 dc b5 eb df 71 66 dc e1 77 d4 78 14 98
exponent1 79 44 b0 19 f6 f0 7d 63 cf 62 67 78 d0 7b 10 ae
6b db 40 b3 b2 eb 2e 9f 31 34 2d cb bf a2 6a a6
exponent2 1f e9 03 42 f2 63 9b b7 33 d0 fe 20 83 26 1f 56
a8 24 f5 6d 19 51 a5 92 31 e4 2b bc 11 c8 26 75
coefficient a0 51 e9 83 ca ee 4b f0 59 eb a4 81 d6 1f 49 42
2b 75 89 a7 9f 84 7f 1f c3 8f 70 b6 7e 06 5e 8b
+privateExponent c9 53 65 80 b7 16 f2 5e 5e de 0b 57 47 43 86 85
8a fb 37 ac 66 34 ba 09 1a b1 21 0b aa fa 6c b7
75 a7 3e 23 18 58 95 90 b5 29 a4 1e 15 76 52 56
bb 3d 6b 1d 2a d1 9f 5c 8a c0 55 ea c3 29 a2 1e


Symmetric Wrapped Key BLOBs

The Symmetric Wrapped Key BLOB format is used to export and import a symmetric key wrapped with another symmetric key. The actual wrapped key is in the format specified in the IETF SMIME X9.42 standard.

BLOBHEADER blobheader;
ALG_ID WrapAlgid;
BYTE Blob[variable length];

This BLOB format is exported when the SYMMETRICWRAPKEYBLOB type is used with CryptExportKey. When exporting a BLOB of this type, both the hKey and hExpKey parameters to the CryptExportKey call must contain valid symmetric key handles. When calling CryptImportkey and using a BLOB of this type, the hImpKey parameter must contain a valid and correct handle to a symmetric key.

The following table describes each component of the key BLOB.

Field | Description
Blobheader | BLOBHEADER structure. The bType member must have a value of SYMMETRICWRAPKEYBLOB, bVersion must be 2 and aiKeyAlgid must be the algorithm identifier for the wrapped key.
WrapAlgid | Algorithm identifier for the wrapping key.
Blob | BLOB value. This needs to be in the symmetric key wrapping format specified in the IETF SMIME X9.42 standard.


Deriving Session Keys

Applications derive session keys from hash values by using the CryptDeriveKey function. The underlying mechanism is: The required number of bytes from the beginning of the hash value become the session key material. If the CRYPT_CREATE_SALT flag is specified, additional bytes from the hash are used. The remaining bytes of the hash value are not used.

For example, from a 160-bit SHA hash value, a 40-bit session key with an 88-bit salt value can be created. The first five bytes (40 bits) of the hash are the session key material and the next 11 bytes are the salt. The last four bytes of the hash are unused.

Note Hash values and session keys are viewed as blocks of binary data, not large integers; therefore, byte ordering (that is, big-endian versus little-endian format) is not relevant.


Key Derivation Sample

The example data in this section was generated using the Microsoft Base Cryptographic Provider. In a particular instance with another provider, the session key length and salt length can be different, but the basic process is the same.

Assume an application will derive a session key from a hash of the password, "124-kelp". The password is hashed using CryptHashData specifying the MD5 hash algorithm. The following sixteen-byte hash value is generated.

73 40 e6 e2 74 b8 ea 39
93 95 aa 29 d6 38 b5 2a

The application calls CryptDeriveKey to create the session key, which in this case is an RC4 stream cipher key. The CSP uses the first five bytes of the previous hash value, 73 40 e6 e2 74, as the key itself.

If the CRYPT_CREATE_SALT flag is not specified, the key is given a salt value of zero.

Using this session key to encrypt the following plaintext buffer:

00 01 02 03 04 05 06 07
08 09 0a 0b 0c 0d 0e 0f
10 11 12 13 14 15 16 17
18 19 1a 1b 1c 1d 1e 1f

generates the following ciphertext data:

26 59 de 24 44 fa 36 9c
11 0c bb 9d b6 a2 bd 24
04 2e e3 ba 72 76 f3 27
8d d5 b4 2f 56 cf f8 c9

If the application specifies the CRYPT_CREATE_SALT flag during the CryptDeriveKey function call, the key is given the following 11-byte salt value:

b8 ea 39 93 95 aa 29 d6
38 b5 2a

Using the key with the added salt value to encrypt the plaintext generates the following ciphertext:

47 f4 5d e2 cc 3b 87 1b
95 bc fc 39 fb 86 d3 05
da a2 91 fb 80 f1 2a 22
c3 b9 ec 91 dd 9f af 50


Hashing Session Keys

When an application uses the CryptHashSessionKey function to hash a session key, only the base key material must be hashed. For a 40-bit key, this will be 5 bytes of data.

The key should be hashed in big-endian byte order. For example, if the Microsoft Base Cryptographic Provider is used to create and hash a session key with a value of 4a 3a ee 77 37, the bytes need to be reversed before the hashing operation is performed. In this example, the following hash values are produced:

For an MD5 hash

0b 15 55 0a a0 03 f9 3f 75 82 f7 e7 91 32 bc 8c

For an SHA hash

3c 37 72 93 53 ff 2a 4f ef 12 54 18 5b 3a c4 63 03 fd 07 5d


Digital Signature Mechanics

An application signs or verifies hash values by using the CryptSignHash and CryptVerifySignature functions. The application often specifies a description string, which must be added to the hash object before it is signed or verified.

The following is a typical signature process:

  1. The application creates a hash object by using CryptCreateHash.
  2. The application adds data to the hash object by using CryptHashData, CryptHashSessionKey, or both.
  3. The application calls the CryptSignHash function to sign the hash value, specifying a description string.
  4. The operating system layer accepts the CryptSignHash invocation. If the descriptive string is not already in Unicode, the system converts it to Unicode and hands off the task to the CSP using the CPSignHash function.
  5. The CSP adds the Unicode description string to the hash object, using the CPHashData function. The terminating NULL character is not hashed in.
  6. The CSP completes the hash and obtains the hash value to be signed by using the CPGetHashParam function.
  7. The CSP takes the hash value, pads it out to the size of the public key modulus, and encrypts it by using the signature private key.

    The padding around the hash value must be in the format specified by the Public-Key Cryptography Standards (PKCS), available from RSA Data Security. The hash algorithm used must be encoded as described in PKCS #1, Section 6.3.

  8. The signature block is returned to the application, using the operating system layer.


Signature Sample

This section steps through the signature process. It uses the hash value from the Key Derivation Sample, the MD5 hash of the "124-kelp" string. This hash value is as follows:

73 40 e6 e2 74 b8 ea 39
93 95 aa 29 d6 38 b5 2a

This example uses "Test Signature" as the description string.

First, the CSP adds this string to the hash object being signed. The description string, "Test Signature," is received by the CSP in Unicode format as the following hexadecimal bytes:

54 00 65 00 73 00 74 00
20 00 53 00 69 00 67 00.
6e 00 61 00 74 00 75 00
18 72 00 65 00

After the description string has been added to the hash, the hash value is:

a8 2b df c2 c9 f1 bb 62
38 78 d4 60 fa ce 5c 2a

Next, a PKCS signature block is built. Details of the PKCS standards can be found on the RSA Security Standards Web page. The signature block is always the same size as the public key's modulus (64 bytes) and contains the following fields.

Field | Bytes | Description
To be signed | 1 to 16 | Hash of data to be signed. The size of this field varies depending on the hash algorithm used. The bytes in the hash value are reversed before they are placed in the encryption block because the operating system formats data in little-endian format, and the encryption block must be built in big-endian format.
Algorithm specifier | 17 to 34 | ASN.1 encoded hash algorithm specifier. The size of this field depends on the hash algorithm used. Note that this data is also reversed. For more information on ASN.1, see the PKCS documentation.
Reserved | 35 | Zero value.
Padding | 36 to 62 | Padding data (0xff's). The size of this field is adjusted as necessary so that the signature block's overall length is correct.
Block type | 63 | The PKCS block type (0x01).
Reserved | 64 | Zero value.

The order of this table is reversed from the diagram found in the PKCS documentation because the signature block is built in big-endian on a little-endian computer.

The completed signature block in this example is:

2a 5c ce fa 60 d4 78 38
62 bb f1 c9 c2 df 2b a8
10 04 00 05 05 02 0d f7
86 48 86 2a 08 06 0c 30
20 30 00 ff ff ff ff ff
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff 01 00

Next, the block is encrypted with the appropriate private key. This example uses a typical but unspecified private key. This encryption results in a completed digital signature:

64 f6 46 3a 97 2e 83 38
09 57 43 cb ca 41 59 0d
03 35 d6 e4 36 6f 2c fc
63 43 95 c4 fd e2 c4 ed
06 da 9a 21 98 fc 0a 6e
3f 1c ad 3a db 7c 83 2f
14 d0 58 80 02 df dc 96
70 09 00 e3 5b bd 2b 45


PKCS Hash Algorithm Encoding

All RSA digital signature blocks contain an ASN.1 encoded hash algorithm identification string. The following table lists the encoding for the algorithms supported by the Microsoft Base Cryptographic Provider. These algorithms are also supported by most other RSA CSPs.

Algorithm Encoding
MD2 10 04 00 05 02 02 0d f7
86 48 86 2a 08 06 0c 30
20 30
MD4 10 04 00 05 04 02 0d f7
86 48 86 2a 08 06 0c 300
20 30
MD5 10 04 00 05 05 02 0d f7
86 48 86 2a 08 06 0c 30
20 30
SHA 14 04 00 05 1a 02 03 0e
2b 05 06 09 30 21 30

The encoded object identifier (OID) strings shown in the previous table include wrapper bytes. For example, the encoded string shown for SHA contains the following information (for clarity, the bytes are in reverse order).


Using a Cryptographic Service Provider

This section contains two parts:

  • Using CSPs: General Processes
  • Using Schannel CSPs


Using CSPs: General Processes

To provide more concise, more readable code, some principles of good programming practice are not always followed in the following example programs. In particular:

  • Only limited error responses are shown. Well-written, complete programs check returned error codes and perform appropriate actions when an error is encountered.
  • Only limited memory and resource management is done. Well-written, complete programs destroy all keys and hashes, free all allocated memory, close all files, and release all handles. These example programs provide only limited demonstrations of the use of functions that perform these tasks. These example programs perform no memory or resource management tasks in the case of program termination due to errors.

The following topics present general information about procedure examples and sample code.

  • Retrieving Data of Unknown Length
  • Enumerating Supported Protocols


Retrieving Data of Unknown Length

Many functions return a potentially large amount of data to an address provided as one of the parameters by the application. In all these cases, the operation is performed in a similar, if not identical, fashion. The parameter that points to the location of the returned data will use the notation convention where pb or pv are the first two characters of the parameter name. Another parameter will have pcb as the first three characters of the parameter name. This parameter represents the size, in bytes, of the data that will be returned to the pb or pv location. For example, consider the following function specification:

BOOL WINAPI SomeFunction(
  PCCRL_CONTEXT pCrlContext,  // in
  DWORD dwPropId,             // in
  BYTE *pbData,               // out
  DWORD *pcbData              // in/out
);

In this example pbData is a pointer to the location where the data will be returned, and pcbData is the size, in bytes, of the returned data.

Note The companion parameter to the pcb parameter may sometimes carry a slightly different prefix, such as p or pv. Also, for companion parameters using the combination of prefixes pwsz and pcch, the pcch parameter is the count in characters (Unicode or ASCII, as applicable), of the returned data.

If the buffer specified by the pbData parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code (which can be seen by calling GetLastError), and stores the required buffer size, in bytes, in the variable pointed to by pcbData.

If NULL is input for pbData and pcbData is non-NULL, no error is returned and the function returns the size in bytes of the needed memory buffer in the variable pointed to by pcbData. This lets an application determine the size of, and the best way to allocate, a buffer for the returned data.

Note When NULL is input for pbData to determine the size needed to ensure that the returned data fits in the specified buffer, the second call to the function which populates the buffer with the desired data may not use the whole buffer. After the second call, the actual size of the data returned is contained in pcbData. Use this size when processing the data.

The following example code demonstrates how input and output parameters might be implemented for this purpose:

//--------------------------------------------------------------------

#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

void HandleError(char *s);

void main()
{
//--------------------------------------------------------------------
// Set up SomeFunction variables.

PCCRL_CONTEXT pCrlContext; // Initialized elsewhere.
DWORD dwPropId;            // Initialized elsewhere.
DWORD cbData;
BYTE  *pbData;

//--------------------------------------------------------------------
// Call SomeFunction to set cbData, the size of
// the buffer needed for pbData.

if(SomeFunction(
     pCrlContext,
     dwPropId,
     NULL,
     &cbData))
{
       printf("The function succeeded.\n");
}
else
{
// The function call failed. Handle the error.
       HandleError("Function call failed.");
}

//--------------------------------------------------------------------
// The call succeeded; the size for the needed buffer, in bytes,
// now resides in cbData.

//--------------------------------------------------------------------
// Malloc memory for the size of the message.

if(pbData = (BYTE*)malloc(cbData))
{
   printf("Memory has been allocated.\n");
}
else
{
   // The allocation failed. Write an error message and exit.
   HandleError("Malloc operation failed. ");
}

//--------------------------------------------------------------------
// The space for the buffer has been allocated.
// Call SomeFunction to fill the buffer with the data.

if(SomeFunction(
      pCrlContext,
      dwPropId,
      pbData,
      &cbData))
{
       printf("The function succeeded.\n");
}
else
{
   // The second function call failed. Handle the error.
   HandleError("The second call to the function failed.");
}
//--------------------------------------------------------------------
// The function succeeded; the data is now in the buffer
// pointed to by pbData. Note that cbData is
// updated with the actual size of the data returned. Use this size
// to process bytes of pbData.
} // End of main

//--------------------------------------------------------------------
//  This example uses the function HandleError, a simple error
//  handling function, to print an error message to the standard error
//  (stderr) file and exit the program.
//  For most applications, replace this function with one
//  that does more extensive error reporting.

void HandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program.\n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr,"Error number %x.\n",GetLastError());
    fprintf(stderr,"Program terminating.\n");
    exit(1);
}


Enumerating Supported Protocols

Supported protocols and cipher suites can be listed by calls to CryptGetProvParam with PP_ENUMALGS or PP_ENUMALGS_EX. The PP_ENUMALGS_EX value works like PP_ENUMALGS but returns a PROV_ENUMALGS_EX structure that holds more extensive information on the algorithms supported by the provider.

For more information on defined protocol flags and their values, see Protocol Flags.

Given that hCryptProv is the handle of an open cryptographic context acquired using CryptAcquireContext with its dwProvType parameter set to PROV_RSA_SCHANNEL, the following code lists the names of all algorithms available in the CSP:

PROV_ENUMALGS_EX EnumAlgs;     //   Structure to hold information on
                               //   a supported algorithm
DWORD dFlag = CRYPT_FIRST;     //   Flag indicating that the first
                               //   supported algorithm is to be
                               //   enumerated. Changed to 0 after the
                               //   first call to the function.
cbData = sizeof(PROV_ENUMALGS_EX);

while( CryptGetProvParam(
    hCryptProv,          // handle to an open cryptographic provider
    PP_ENUMALGS_EX,
    (BYTE *)&EnumAlgs,  // information on the next algorithm
    &cbData,            // number of bytes in the PROV_ENUMALGS_EX
    dFlag))             // flag to indicate whether this is a first or
                        // subsequent algorithm supported by the
                        // CSP.
{
    printf("Supported Algorithm name %s\n", EnumAlgs.szName);
    dFlag = 0;          // Set to 0 after the first call,
} //  end of while loop. When all of the supported algorithms have
  //  been enumerated, the function returns FALSE.

The following table lists some algorithms returned by a typical domestic PROV_RSA_SCHANNEL CSP. Notice that neither SSL2 SHA MACs nor SSL2 DES encryption is supported by the CSP in this example.

Algorithm identifier | Minimum Key Length | Maximum Key Length | Protocols | Algorithm Name
CALG_RSA _KEYX | 512 | 2048 | 0x0007 | "RSA_KEYX"
CALG_MD5 | 128 | 128 | 0x0007 | "MD5"
CALG_SHA | 160 | 160 | 0x0005 | "SHA"
CALG_RC4 | 40 | 128 | 0x0007 | "RC4"
CALG_DES | 56 | 56 | 0x0005 | "DES"

To prepare to send ClientHello or ServerHello messages, the Schannel protocol engine enumerates the algorithms and key sizes supported by the CSP and builds a list internally of supported cipher suites.


Using Schannel CSPs

Beginning with Microsoft® Windows® 2000, the SSL protocol engine (Schannel) uses cryptographic service provider when performing cryptographic operations. Previous versions of Schannel performed cryptographic operations internally. Cryptographic applications can call CryptAcquireContext using the PROV_RSA_SCHANNEL and PROV_DH_SCHANNEL providers. This section defines the RSA and Diffie-Hellman Schannel CSP types and describes the functionality that a CSP must support to be compatible with Schannel.dll, the Microsoft cryptographic protocol engine. A protocol engine is a program that establishes a secure communications channel between a client and server application.

Applications should not attempt to use information in this documentation to use PROV_RSA_SCHANNEL or PROV_DH_SCHANNEL directly. Rather, this documentation explains how CSP developers and vendors must write Schannel CSPs that are compatible with Microsoft Schannel providers.

This documentation is intended to help CSP developers implement compatible RSA or Diffie-Hellman Schannel CSPs. Developers are assumed to be familiar with the Secure Socket Layer protocol (SSL) version 3.0, public-key cryptography, digital certificates, and the CryptoAPI function set. Developers new to these topics are advised to read the SSL Protocol 3.0 specification and the CryptoAPI documentation in this SDK. In addition, RSA and Diffie-Hellman CSP developers must know Transport Layer Security protocol (TLS) specifications along with the relevant RSA and Diffie-Hellman algorithms.

See Creating the Master Key for code used by a Microsoft protocol engine. The calls to cryptography functions in this code result in calls to CP functions a CSP must implement. To write a compatible CSP, a developer must understand the SSL 3.0 specification and combine that knowledge with an understanding of the protocol engine code similar to this example code.

Because usage of the Private Communication Technology (PCT) protocol is expected to be minimal in the future, developers of new CSPs need not support this protocol. The Schannel protocol engine supports it strictly for backward compatibility.


Public/Private Key Pair Usage

All normal RSA/Schannel and Diffie-Hellman/Schannel operations use the AT_KEYEXCHANGE public/private key pair. To provide server authentication, the server-side of Schannel operations must have access to its X.509 certificate containing its public key and access to the matching private key. The client-side of Schannel needs its certificate with its public key and access to its private key if client authentication is implemented.

Since Schannel protocol engines never use the AT_SIGNATURE public/private key pair, that key pair need not be supported by a new CSP supporting only RSA/Schannel or Diffie-Hellman/Schannel.

If a protocol engine uses an SSL 3.0 export cipher suite with an AT_KEYEXCHANGE key pair larger than 512 bits, the server must use an additional RSA key pair. This additional key pair is always exactly 512 bits and it can be ephemeral. The pair is stored as an AT_KEYEXCHANGE element in a key container owned by the protocol engine. A handle to this key container is typically acquired at protocol engine startup.

Diffie-Hellman supports only CALG_DH_EPHEM and uses normal RSA or DSS public keys.


SHA/MD5 RSA Signature Type

CSPs for PROV_RSA_SCHANNEL must support the CALG_SSL3_SHAMD5 hash that is compatible with the Microsoft Base Cryptographic Provider used in SSL 3.0 and TLS 1.0 client authentication. This hash consists of a concatenation of an MD5 hash and an SHA hash signed with an RSA or Diffie-Hellman private key. A handle to a hash value of this type is created with the CryptCreateHash or CPCreateHash function using CALG_SSL3_SHAMD5 as the Algid parameter. Example code using hash functions can be seen in Example C Program: Creating and Hashing a Session Key and Example C Program: Signing a Hash and Verifying the Hash Signature.


Creating the Master Key

A master key is key data material from which other keys are derived. Depending on the protocol and cipher suite used, the master key can be from 5 to 48 bytes in length. For the RSA/Schannel CSP, the master key is created by the client-side and transferred to the server in an RSA envelope. For a Diffie-Hellman/Schannel CSP, the master key is created by performing a Diffie-Hellman key exchange.

Code for creating and exchanging master keys is demonstrated in:

  • Creating a Master Key: The RSA Client
  • Creating a Master Key: The Diffie-Hellman Client
  • Creating a Master Key: The RSA Server
  • Creating a Master Key: The Diffie-Hellman Server
  • Specifying the Algorithms


Creating a Master Key: The RSA Client

The following is typical RSA/Schannel client-side code for creating a master key:

//--------------------------------------------------------------------
//   Define and initialize local variables.

HCRYPTPROV hProv      = <protocol engine's key container>;
HCRYPTKEY  hPublicKey = <server's public key>;
HCRYPTKEY  hMasterKey;       // handle for master key to be created.
ALG_ID     Algid;
DWORD      dwGenFlags =CRYPT_EXPORTABLE;
DWORD          dwExportFlags =0;
BYTE       rgbBlob[<max BLOB size>];
DWORD      cbBlob;

//--------------------------------------------------------------------
// The method for creating the master key depends upon the protocol
// in use. Schannel protocols include:
//           PCT 1.0
//           SSL 2.0
//           SSL 3.0
//           TLS 1.0

//--------------------------------------------------------------------
// Select the master key type.

switch(<protocol being used>)
{
    case <PCT 1.0>:
        Algid = CALG_PCT1_MASTER;
        break;

    case <SSL 2.0>:
        Algid = CALG_SSL2_MASTER;
        dwGenFlags |=,key size. << 16;
        if(<SSL3 or TLS is supported>)
            dwExportFlags |= CRYPT_SSL2_FALLBACK;
        break;

    case <SSL 3.0>:
        Algid = CALG_SSL3_MASTER;
        break;

    case <TLS 1.0>:
        Algid = CALG_TLS1_MASTER;
        break;
}

//--------------------------------------------------------------------
// Generate the master key.

CryptGenKey(
         hProv,
         Algid,
         dwGenFlags,
          &hMasterKey);

//--------------------------------------------------------------------
// Export the master key.

cbBlob = sizeof(rgbBlob);
CryptExportKey(
         hMasterKey,
         hPublicKey,
         SIMPLEBLOB,
         dwExportFlags,
         rgbBlob,
         &cbBlob);


Creating a Master Key: The Diffie-Hellman Client

The following is typical Diffie-Hellman/Schannel client-side code for creating a master key:

//--------------------------------------------------------------------
//   Define and initialize local variables.

HCRYPTPROV hProv      = <protocol engine's key container>;
HCRYPTKEY  hClientDHKey;  // handle to the client's DH key
HCRYPTKEY  hMasterKey;
ALG_ID     Algid;
PBYTE      pbServerPub = <pointer to Server Public Key>;
DWORD      cbServerPub = <size of Server Public Key>;
BYTE       rgbServerBlob[<max BLOB size>];
DWORD      cbServerBlob;
PBYTE      pbG = <pointer to generator G from Server>;
DWORD      cbG = <size of generator G from Server>;
PBYTE      pbP = <pointer to prime P from Server>;
DWORD      cbP = <size of prime P from Server>;
CRYPT_DATA_BLOB Data;
BYTE       rgbClientPubBlob[size of the client public key BLOB];
DWORD      cbClientPubBlob;

//--------------------------------------------------------------------
// Generate and set the parameters on the client DH key
// Schannel specifies the key size and [regen flag when generating
// a client DH key.

CryptGenKey(
      hProv,
      CALG_DH_EPHEM,
      ((cbP * 8) << 16)|CRYPT_PREGEN,
      &hClientDHKey);

Data.pbData = pbP;
Data.cbData = cbP;
CryptSetKeyParam(
         hClientDHKey,
         KP_P,
         (BYTE*)&Data,
         0);

Data.pbData = pbG;
Data.cbData = cbG;
CryptSetKeyParam(
          hClientDHKey,
          KP_G,
          (BYTE*)&Data,
          0);

//--------------------------------------------------------------------
// Create the client private DH key

CryptSetKeyParam(
     hClientDHKey,
     KP_X,
     NULL,
     0);

//--------------------------------------------------------------------
// Build PUBLICKEYBLOB around the server's public key
{
     BLOBHEADER *pBlobHeader = (BLOBHEADER *)rgbServerBlob;
     DHPUBKEY   *pDHPubKey   = (DHPUBKEY *)(pBlobHeader + 1);
     BYTE       *pData       = (BYTE *)(pDHPubKey + 1);

     pBlobHeader->bType    = PUBLICKEYBLOB;
     pBlobHeader->bVersion = CUR_BLOB_VERSION;
     pBlobHeader->reserved = 0;
     pBlobHeader->aiKeyAlg = CALG_DH_EPHEM;

     pDHPubKey->magic = 0x31484400;
     pDHPubKey->bitlen = dwServerPub * 8;

     ReverseMemCopy(pData, pbServerPub, cbServerPub);
     cbServerBlob = sizeof(BLOBHEADER) + sizeof(DHPUBKEY) +
       cbServerPub;
}

//--------------------------------------------------------------------
// Import the server's public key and get an agreed key

CryptImportKey(
        hProv,
        rgbServerBlob,
        cbServerBlob,
        hClientDHKey,
        0,
        &hMasterKey);

//--------------------------------------------------------------------
// Select the master key type.

switch(<protocol being used>)
{
    case <SSL 3.0>:
        Algid = CALG_SSL3_MASTER;
        break;

    case <TLS 1.0>:
        Algid = CALG_TLS1_MASTER;
        break;
}

//--------------------------------------------------------------------
// Convert the agreed key to the appropriate master key

CryptSetKeyParam(
        hMasterKey,
        KP_ALGID,
        (BYTE*)&Algid,
        0);

//--------------------------------------------------------------------
// Export the client Diffie-Hellman public key.

cbClientPubBlob = sizeof(rgbClientPubBlob);
CryptExportKey(
           hClientDHKey,
           0,
           PUBLICKEYBLOB,
           0,
           rgbClientPubBlob,
           & cbClientPubBlob);

CryptDestroyKey(hClientDHKey);


Creating a Master Key: The RSA Server

The following is typical RSA/Schannel server-side code for creating a master key:

//--------------------------------------------------------------------
//   Define and initialize local variables.

HCRYPTPROV hProv         = <server's key container>;
PBYTE      pbKeyExchange = <pointer to RSA envelope>;
DWORD      dwKeyExchange = <size of RSA envelope>;
HCRYPTKEY  hPublicKey;
HCRYPTKEY  hMasterKey;
ALG_ID     Algid;
DWORD      dwFlags =0 ;
BYTE       rgbBlob[<max BLOB size>];
DWORD      cbBlob;

//--------------------------------------------------------------------
// Select the master key type.

switch(<protocol being used>)
{
    case <PCT 1.0>:
        Algid = CALG_PCT1_MASTER;
        break;

    case <SSL 2.0>:
        Algid = CALG_SSL2_MASTER;
        if(<we support SSL3>)
            dwFlags = CRYPT_SSL2_FALLBACK;
        break;

    case <SSL 3.0>:
        Algid = CALG_SSL3_MASTER;
        break;

    case <TLS 1.0>:
        Algid = CALG_TLS1_MASTER;
        break;
}

//--------------------------------------------------------------------
// Build a SIMPLEBLOB around the RSA envelope.
{
     BLOBHEADER *pBlobHeader = (BLOBHEADER *)rgbBlob;
     ALG_ID     *pAlgid      = (ALG_ID *)(pBlobHeader + 1);
     BYTE       *pData       = (BYTE *)(pAlgid + 1);

     pBlobHeader->bType    = SIMPLEBLOB;
     pBlobHeader->bVersion = CUR_BLOB_VERSION;
     pBlobHeader->reserved = 0;
     pBlobHeader->aiKeyAlg = Algid;

     *pAlgid = CALG_RSA_KEYX;

     ReverseMemCopy(
         pData,
         pbKeyExchange,
         cbKeyExchange);
}

//--------------------------------------------------------------------
// Decrypt the master key.

CryptGetUserKey(
         hProv,
         AT_KEYEXCHANGE,
         &hPublicKey);

CryptImportKey(
          hProv,
          rgbBlob,
          cbBlob,
          hPublicKey,
          dwFlags,
          &hMasterKey);

CryptDestroyKey(hPublicKey);


Creating a Master Key: The Diffie-Hellman Server

The following is typical Diffie-Hellman/Schannel server-side code for creating a master key:

//--------------------------------------------------------------------
//   Define and initialize local variables.

HCRYPTPROV hProv      = <protocol engine's key container>;
HCRYPTKEY  hServerDHKey;  // handle to the client's DH key
HCRYPTKEY  hMasterKey;    // handle for the master key to be created.
ALG_ID     Algid;
PBYTE      pbClientPub = <pointer to client public key>;
DWORD      cbServerPub = <size of client public key>;
BYTE       rgbClientBlob[<max BLOB size>];
DWORD      cbClientBlob = <size of the client key BLOB>;
CRYPT_DATA_BLOB Data;

//--------------------------------------------------------------------
// Build a PUBLICKEYBLOB around the client's public key
{
     BLOBHEADER *pBlobHeader = (BLOBHEADER *)rgbClientBlob;
     DHPUBKEY   *pDHPubKey   = (DHPUBKEY *)(pBlobHeader + 1);
     BYTE       *pData       = (BYTE *)(pDHPubKey + 1);

     pBlobHeader->bType    = PUBLICKEYBLOB;
     pBlobHeader->bVersion = CUR_BLOB_VERSION;
     pBlobHeader->reserved = 0;
     pBlobHeader->aiKeyAlg = CALG_DH_EPHEM;

     pDHPubKey->magic = 0x31484400;
     pDHPubKey->bitlen = dwClientPub * 8;

     ReverseMemCopy(pData, pbClientPub, cbClientPub);
     cbClientBlob = sizeof(BLOBHEADER) + sizeof(DHPUBKEY) +
        cbClientPub;
}

//--------------------------------------------------------------------
// Import the client's public key and get an agreed key

CryptImportKey(
      hProv,
      rgbClientBlob,
      cbClientBlob,
      hServerDHKey,
      0,
      &hMasterKey);

//--------------------------------------------------------------------
// Select the master key type.

switch(<protocol being used>)
{
    case <SSL 3.0>:
        Algid = CALG_SSL3_MASTER;
        break;

    case <TLS 1.0>:
        Algid = CALG_TLS1_MASTER;
        break;
}

//--------------------------------------------------------------------
// Convert the agreed key to the appropriate master key

CryptSetKeyParam(
         hMasterKey,
         KP_ALGID,
         (BYTE*)&Algid,
         0);


Specifying the Algorithms

After a master key is created or imported, both RSA/Schannel and Diffie-Hellman/Schannel inform the CSP of the type of bulk encryption keys and MAC keys that will be derived from the master key. The following code specifies these algorithms. The same code is used for both client and server.

//--------------------------------------------------------------------
// Algorithms for the SCHANNEL_ALG structure

#define SCHANNEL_MAC_KEY   0x00000000
#define SCHANNEL_ENC_KEY   0x00000001

//--------------------------------------------------------------------
// dwFlags for the SCHANNEL_ALG structure
// This flag will be set when the SSL cipher suite is exportable
// outside the United States and Canada. The use of this flag notifies
// the CSP that it must perform the extra export steps when deriving
// the key.

#define INTERNATIONAL USAGE   0x00000001

typedef struct _SCHANNEL_ALG
{
    DWORD  dwUse;
    ALG_ID Algid;
    DWORD  cBits;
    DWORD  dwFlags;
    DWORD  dwReserved;
} SCHANNEL_ALG, *PSCHANNEL_ALG;

SCHANNEL_ALG Algorithm;

//--------------------------------------------------------------------
// Specify the bulk encryption algorithm.

Algorithm.dwUse = SCHANNEL_ENC_KEY;
Algorithm.Algid = CALG_RC4;    // or CALG_RC2, CALG_DES, etc.
Algorithm.cBits = 40;          // or 64, 128, 192, etc.
CryptSetKeyParam(
         hMasterKey,
         KP_SCHANNEL_ALG,
         (PBYTE)&Algorithm,
         0);

//--------------------------------------------------------------------
// Specify hash algorithm.

Algorithm.dwUse = SCHANNEL_MAC_KEY;
Algorithm.Algid = CALG_MD5;    // or CALG_SHA, etc.
Algorithm.cBits = 128;         // or 160...
CryptSetKeyParam(
          hMasterKey,
          KP_SCHANNEL_ALG,
          (PBYTE)&Algorithm,
          0);

Note An Schannel protocol engine must not specify algorithms and key sizes not supported by the CSP. For more information, see Enumerating Supported Protocols. If unsupported algorithms or key sizes are specified, the CSP function must fail and return the NTE_BAD_DATA error code.


Deriving Bulk Encryption and MAC Keys

Bulk encryption and MAC keys are derived from a master key but can include other sources depending on the protocol and cipher suite used.

The process of deriving bulk encryption and MAC keys is the same for both client and server:

  1. The protocol engine calls CryptSetKeyParam on the master key one or more times to provide the CSP with the information needed to build the keys.
  2. Because CryptoAPI keys cannot be derived directly from other keys, a hash object is created from the master key using CryptCreateHash. This hash is used to create the new keys.
  3. The two bulk encryption keys and the two MAC keys are created from the "master hash" object using four calls to CryptDeriveKey.

Note When performing SSL reconnects, a protocol engine can perform the above procedure several times using the same master key. This enables the client and server to have multiple, often simultaneous connections, each using different bulk encryption and MAC keys without additional RSA or Diffie-Hellman operations.

All CSPs must use good thread-safe practices. Thread counts of several dozen are not unusual.

The following is typical source code for the protocol engine:

//--------------------------------------------------------------------
//   Define and initialize local variables.

BOOL fClient = <TRUE if this is code for the client?>;
CRYPT_DATA_BLOB Data;
HCRYPTHASH hMasterHash;

//--------------------------------------------------------------------
// Finish creating the master_secret.

switch(<protocol being used>)
{
    case <PCT 1.0>:

//------------------------------------------------------------
// Specify clear key value.

        Data.pbData = pClearKey;
        Data.cbData = cbClearKey;
        CryptSetKeyParam(
                   hMasterKey,
                   KP_CLEAR_KEY,
                   (PBYTE)&Data,
                   0);

//------------------------------------------------------------
// Specify the CH_CHALLENGE_DATA.

        Data.pbData = pChallenge;
        Data.cbData = cbChallenge;
        CryptSetKeyParam(
                    hMasterKey,
                    KP_CLIENT_RANDOM,
                    (PBYTE)&Data,
                    0);

//------------------------------------------------------------
// Specify the SH_CONNECTION_ID_DATA.

        Data.pbData = pConnectionID;
        Data.cbData = cbConnectionID;
        CryptSetKeyParam(
                    hMasterKey,
                    KP_SERVER_RANDOM,
                    (PBYTE)&Data,
                    0);

//------------------------------------------------------------
// Specify the SH_CERTIFICATE_DATA.
        Data.pbData = pbServerCertificate;
        Data.cbData = cbServerCertificate;
        CryptSetKeyParam(
                    hMasterKey,
                    KP_CERTIFICATE,
                    (PBYTE)&Data,
                    0);
        break;

    case <SSL 2.0>:

//------------------------------------------------------------
// Specify clear key value.

        Data.pbData = pClearKey;
        Data.cbData = cbClearKey;
        CryptSetKeyParam(
                 hMasterKey,
                 KP_CLEAR_KEY,
                 (PBYTE)&Data,
                 0);

//------------------------------------------------------------
// Specify the CH_CHALLENGE_DATA.

        Data.pbData = pChallenge;
        Data.cbData = cbChallenge;
        CryptSetKeyParam(
                 hMasterKey,
                 KP_CLIENT_RANDOM,
                 (BYTE*)&Data,
                 0);

//------------------------------------------------------------
// Specify the SH_CONNECTION_ID_DATA.

        Data.pbData = pConnectionID;
        Data.cbData = cbConnectionID;
        CryptSetKeyParam(
                   hMasterKey,
                   KP_SERVER_RANDOM,
                   (BYTE*)&Data,
                   0);
        break;

case <SSL 3.0>:
case <TLS 1.0>:

//------------------------------------------------------------
// Specify client_random.

        Data.pbData = pClientRandom;
        Data.cbData = cbClientRandom;
        CryptSetKeyParam(
                hMasterKey,
                KP_CLIENT_RANDOM,
                (PBYTE)&Data,
                 0);

//------------------------------------------------------------
// Specify server_random.

        Data.pbData = pServerRandom;
        Data.cbData = cbServerRandom;
        CryptSetKeyParam(
                  hMasterKey,
                  KP_SERVER_RANDOM,
                  (PBYTE)&Data,
                  0);
}

//------------------------------------------------------------
// Create the master hash object from the master key.

CryptCreateHash(
            hProv,
            CALG_SCHANNEL_MASTER_HASH,
            hMasterKey,
            0,
            &hMasterHash);

//------------------------------------------------------------
// Derive read key from the master hash object.

CryptDeriveKey(hProv,
               CALG_SCHANNEL_ENC_KEY,
               hMasterHash,
               fClient ? CRYPT_SERVER : 0,
               &hReadKey);

//------------------------------------------------------------
// Derive write key from the master hash object.

CryptDeriveKey(
           hProv,
           CALG_SCHANNEL_ENC_KEY,
           hMasterHash,
           fClient ? 0 : CRYPT_SERVER,
           &hWriteKey);

if(<protocol being used> != <SSL 2.0>)   // for SSL 2.0, the master
                                         // key is also the MAC.
{
//------------------------------------------------------------
// Derive read MAC from the master hash object.

    CryptDeriveKey(
              hProv,
              CALG_SCHANNEL_MAC_KEY,
              hMasterHash,
              fClient ? CRYPT_SERVER : 0,
              &hReadMAC);

//------------------------------------------------------------
// Derive write MAC from the master hash object.

    CryptDeriveKey(
             hProv,
             CALG_SCHANNEL_MAC_KEY,
             hMasterHash,
             fClient ? 0 : CRYPT_SERVER,
             &hWriteMAC);
}

CryptDestroyHash(hMasterHash);


Finish Messages (TLS 1.0)

A finish message is sent immediately after a change cipher spec message to verify the success of key exchange and authentication processes. The finish messages in the TLS 1.0 protocol are calculated using Pseudo-Random Function (PRF) with the master key, a label, and a seed as input. PRF produces an output of arbitrary length. The following method is used to generate the PRF output used in TLS 1.0 finish messages.

A PRF hash handle is generated using CryptCreateHash with the ALG_ID value set to CALG_TLS1PRF and the handle to the master key passed in the hKey parameter. The label and seed values are set on the hash handle using the values HP_TLS1PRF_LABEL and HP_TLS1PRF_SEED, respectively, in the dwParam parameter with the CryptSetHashParam function. Finally, the protocol engine calls the function CryptGetHashParam with the value HP_HASHVAL in the dwParam parameter to retrieve the PRF data to be included in the finish message. When making the call to CryptGetHashParam, the protocol engine must specify how many bytes of data PRF will produce. This is done in the pdwDataLen parameter, and the resulting data is placed in the buffer pointed to by the pbData parameter.

The following is typical source code for this protocol engine:

CRYPT_DATA_BLOB Data;
HCRYPTHASH hFinishHash;
BYTE rgbFinishPRF[12];
BYTE rgbCliHashOfHandshakes[36];

//------------------------------------------------------------
// get client finish message

CryptCreateHash(
         hProv,
         CALG_TLS1PRF,
         hMasterKey,
         0,
         &hFinishHash);

Data.pbData = (BYTE*)"client finished";
Data.cbData = 15;
CryptSetHashParam(
         hFinishHash,
         HP_TLS1PRF_LABEL,
         (BYTE*)&Data,
         0);

Data.pbData = rgbCliHashOfHandshakes;
Data.cbData = sizeof(rgbCliHashOfHandshakes);
CryptSetHashParam(
          hFinishHash,
          HP_TLS1PRF_SEED,
          (BYTE*)&Data,
          0);

cbFinishPRF = sizeof(rgbFinishPRF);
CryptGetHashParam(
          hFinishHash,
          HP_HASHVAL,
          rgbFinishPRF,
          &cbFinishPRF,
          0);

CryptDestroyHash(hFinishHash);


Bulk Data Encryption

A bulk encryption key is generated by hashing one of the MAC keys using CryptHashSessionKey together with the message contents and other data. The message is encrypted/decrypted with one of the bulk encryption keys in the usual manner.

When using a block cipher, the Schannel protocol engine does all necessary block cipher padding. When CryptEncrypt and CryptDecrypt are called, the Final flag is always FALSE and the data length is a multiple of whole block lengths.

Note The CSP must never buffer data internally. Once the data has been encrypted (or decrypted), the size of the plaintext must always exactly match the size of the ciphertext.


Crossing Process Boundaries

The Schannel protocol engine in Windows 2000 performs the handshaking and authentication in a secure process and the bulk encryption/message passing in the application process. This means that the bulk encryption keys and MAC keys must be copied from one process to another. To do this, use the CryptExportKey and CryptImportKey functions as follows:

The secure process exports each key into an OPAQUEKEYBLOB using CryptExportKey, then destroys the key using CryptDestroyKey. Note that if the key is stored in hardware, the CSP must recognize this and must not attempt to destroy the key.

The secure process passes the OPAQUEKEYBLOBs to the application process in a manner beyond the scope of this document.

The application process imports each OPAQUEKEYBLOB back into the CSP using CryptImportKey. At this point, the key must be in exactly the same state as when it was exported.


Opaque BLOB Type

Opaque BLOBs, also known as OPAQUEKEYBLOBs, are used to store session keys. They contain the base key material and all current state information. This includes information such as the salt value, the initialization vector, and the key table. The format of opaque BLOBs is unpublished. Each CSP vendor determines its own BLOB format which should include encrypting the opaque BLOBs with some sort of symmetric key.

Because a key is exported into an opaque BLOB in CSP-specific format, it can only be imported into the CSP from which it was originally exported.

When two processes are involved, each process calls CryptAcquireContext independently. Each process gets a handle to a key container. It is possible for both processes to have handles to the same key container. One process creates the keys and exports them into opaque BLOBs, then passes the BLOBs to the second process. The second process imports the keys from the BLOB into its key container.

If a hardware CSP does not support exporting keys, the BLOB might only contain the index of a key register, or something similar. In this case, the rest of the procedure is ignored.

<secure process>
cbBlob = sizeof(rgbBlob);
CryptExportKey(
          hKey,
          0,
          OPAQUEKEYBLOB,
          0,
          rgbBlob,
          &cbBlob);
hKey = 0;

<BLOB is transferred to other process>

<user process>
CryptImportKey(
            hProv,
            pbBlob,
            cbBlob,
            0,
            0,
            &hKey);


Cryptographic Service Provider Reference

This section contains the following topics:

  • CSP Functions
  • CSP Structures and Types
  • CSP Constants
  • Schannel CSP Reference


CSP Functions

CSP functions are divided into the following function categories:

  • CSP Connection Functions
  • Key Generation and Exchange Functions
  • Data Encryption Functions
  • Hashing and Digital Signature Functions
  • CSP Auxiliary Functions


CSP Connection Functions

CSP connection functions work with the characteristics of a cryptographic service provider (CSP) and connect to and disconnect from key containers with a CSP. The following table briefly describes each function.

Function | Description
CPAcquireContext | Acquires a handle to a particular key container within the CSP.
CPGetProvParam | Retrieves attributes of the CSP.
CPReleaseContext | Releases the handle acquired by CPAcquireContext.
CPSetProvParam | Sets specific attributes of a CSP.


CPAcquireContext

The CPAcquireContext function acquires a handle to the key container specified by the pszContainer parameter.

BOOL CPAcquireContext(
  HCRYPTPROV *phProv,       // out
  CHAR *pszContainer,       // in, out
  DWORD dwFlags,            // in
  PVTableProvStruc pVTable  // in
);

Parameters

phProv
Address to which the function copies a handle to the CSP.
pszContainer
A NULL-terminated string of no more than MAX_PATH characters containing a key container name. The function ignores this parameter if CRYPT_VERIFYCONTEXT is set in dwFlags.

If pszContainer is NULL or a zero length string on input, a default key container name is used. The Microsoft RSA Base Provider, for example, uses the logon name of the current user as the default key container name. Other CSPs can use different default key container names.

dwFlags
Can be zero or one of the following flags.
Flag value Meaning
CRYPT_VERIFYCONTEXT The application has no access to the private keys and the return pszContainer parameter must be set to NULL. This option is used with applications that do not use private keys.

When CryptAcquireContext is called, many CSPs require input from the user before granting access to the private keys in the key container. For example, private keys might be encrypted, requiring a password from the user before being used. However, if CRYPT_VERIFYCONTEXT is specified and access to the private keys is not required, the user interface can be bypassed.

When this flag is used and a public/private key pair is created or imported, that pair of keys is treated as treated as ephemeral; that is, the keys are kept only in memory and are automatically destroyed when CPReleaseContext is called.
CRYPT_NEWKEYSET A new key container is created with the name specified by pszContainer. If pszContainer is NULL on input, a key container with the default name is created.

While a CSP is not required to create key pairs at this point; at the CSP author's discretion, a CSP can generate key pairs at this time. Keys are created through calls to CPGenKey, either within this call to CPAcquireContext or later as a separate step.
CRYPT_MACHINE_KEYSET By default, key containers and their keys are stored as keys associated with a specific user. For the CSP currently provided by Microsoft, user key containers are stored in the user's profile. The CRYPT_MACHINE_KEYSET flag is useful when access is being performed from a service or user account that did not log on interactively.

The CRYPT_MACHINE_KEYSET flag can be combined with other flags indicating that the key container of interest is a machine key container and the CSP will treat it as such. For Microsoft CSPs, this means the keys are stored locally on the computer that created the key container.

The CRYPT_MACHINE_KEYSET flag is used for keys that are machine keys, keys that must be accessible to applications not associated with a user account. UI cannot be associated with these keys because they can be used by unattended server applications. With Microsoft CSPs, ACLs can be set on these keys by using CPGetProvParam and CPSetProvParam with the PP_KEYSET_SEC_DESCR value. CSP writers can consider setting ACLs on keys as well.

If a key container is to be a machine key container, the CRYPT_MACHINE_KEYSET flag must be used with all calls to CryptAcquireContext that reference the container.

CRYPT_MACHINE_KEYSET applies specifically to the Microsoft provider types. For a list of these types, see Cryptographic Provider Types. Other provider types can store keys differently, and can ignore this flag. All compatible CSPs must implement the CRYPT_MACHINE_KEYSET flag; however, this implementation can be done by simply ignoring the flag.
CRYPT_DELETEKEYSET Deletes the key container specified by pszContainer or, if pszContainer is NULL, the key container with the default name. All key pairs in the key container are also destroyed.

After a key container has been deleted, the value returned in phProv is undefined; therefore, the context has been released and the application does not need to call CryptReleaseContext.
CRYPT_SILENT This flag directs the CSP to not display user interface (UI) for this context. If any future function call using this acquired CSP context requires UI to operate, the function call must fail and the function must set the last error to NTE_SILENT_CONTEXT. If CRYPT_SILENT is set and a later call is made to CPGenKey using CRYPT_USER_PROTECTED, that call will fail and the function must set the last error to NTE_SILENT_CONTEXT.

This flag is intended for use with applications that cannot tolerate UI being displayed by the CSP. It is only supported with Microsoft® Windows® 2000 or later.

pVTable
Pointer to a VTableProvStruc structure containing a list of callback functions provided by the operating system for use by the CSP.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
NTE_BAD_FLAGS | The dwFlags parameter has an illegal value.
NTE_BAD_KEYSET | The key container could not be opened and might not exist.
NTE_BAD_KEYSET_PARAM | The pszContainer parameter is set to an illegal value.
NTE_BAD_SIGNATURE | The digital signature of an auxiliary DLL did not verify correctly. Either the DLL or the digital signature has been tampered with.
NTE_EXISTS | The dwFlags parameter is CRYPT_NEWKEYSET, but the key container already exists.
NTE_KEYSET_ENTRY_BAD | The pszContainer key container was found but is corrupt.
NTE_KEYSET_NOT_DEF | The key container specified by pszContainer does not exist.
NTE_NO_MEMORY | The CSP ran out of memory during the operation.
NTE_PROVIDER_DLL_FAIL | An auxiliary DLL file could not be loaded and might not exist. If it exists, the file is not a valid DLL.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPReleaseContext, CryptAcquireContext, CryptSetProvParam


CPGetProvParam

The CPGetProvParam function returns data about a cryptographic service provider (CSP).

BOOL CPGetProvParam(
  HCRYPTPROV hProv,  // in
  DWORD dwParam,     // in
  BYTE *pbData,      // out
  DWORD *pdwDataLen, // in, out
  DWORD dwFlags      // in
);

Parameters

hProv
Handle to a particular key container within the CSP. This handle is obtained by a previous call to CPAcquireContext.
dwParam
A DWORD value that determines the nature of the query. The following queries are defined.
dwParam value | Contents returned in pbData
PP_CONTAINER | The name of the current key container as a NULL-terminated CHAR string. The returned string is identical to the one passed in the pszContainer parameter of the CryptAcquireContext function to specify the key container to use. pszContainer can be read to determine the name of the default key container.
PP_ENUMALGS Information about an algorithm supported by the CSP being queried. PP_ENUMALGS values must be read repeatedly to list all of the supported algorithms (not enumerated in any particular order). The first time that PP_ENUMALGS is read, the CRYPT_FIRST flag must be specified in dwFlags. Doing so ensures that information about the first algorithm in the enumeration list is returned. PP_ENUMALGS can then be repeatedly read with dwFlags set to 0 to retrieve the information about the rest of the supported algorithms. When the CPGetProvParam function fails with the ERROR_NO_MORE_ITEMS error code, the end of the enumeration list has been reached.

This function is not thread-safe and all of the available algorithms may not be enumerated if this function is used in a multithread context.
PP_ENUMALGS_EX Information about an algorithm supported by the CSP. The structure returned contains more information about the algorithm than the structure returned for PP_ENUMALGS.

The PP_ENUMALGS_EX value must be read repeatedly to enumerate all the supported algorithms (not enumerated in any particular order). The first time that PP_ENUMALGS is read, the CRYPT_FIRST flag must be specified in dwFlags. Doing so ensures that information about the first algorithm in the enumeration list is returned. PP_ENUMALGS can then be repeatedly read with dwFlags set to 0 to retrieve the information about the rest of the supported algorithms. When the CryptGetProvParam function fails with the ERROR_NO_MORE_ITEMS error code, the end of the enumeration list has been reached.

PP_ENUMALGS_EX is supported in Microsoft® Internet Explorer version 4.0 or later, Microsoft® Windows NT® version 4.0 SP4, Windows 98 or later, and Windows 2000.

This function is not thread-safe and all of the available algorithms may not be enumerated if this function is used in a multithread context.
PP_ENUMCONTAINERS The name of one of the key containers maintained by the CSP in the form of a NULL-terminated CHAR string. The PP_ENUMCONTAINERS value can be read repeatedly to enumerate all the container names. Container names are enumerated in the same way as the CSP's supported algorithms.

This function is not thread-safe and all of the available container names mayt not be enumerated if this function is used in a multithread context.
PP_IMPTYPE | A DWORD value indicating how the CSP is implemented. Predefined implementation types CRYPT_IMPL_HARDWARE, CRYPT_IMPL_SOFTWARE, CRYPT_IMPL_MIXED, and CRYPT_IMPL_UNKNOWN are supported.
PP_NAME | The name of the CSP in the form of a NULL-terminated CHAR string. This string is identical to the one passed in the pszProvider parameter of the CryptAcquireContext function to specify that the current CSP be used.
PP_VERSION The version number of the CSP. The least significant byte contains the minor version number and the next most significant byte contains the major version number. Version 1.0 is represented as 0x00000100.

To maintain backward compatibility with earlier versions of the Microsoft Base Cryptographic Provider and Microsoft Enhanced Cryptographic Provider, the provider names retain the "v1.0" designation in later versions. Version 2.0 of these providers is included in Windows 2000.

PP_SIG_KEYSIZE_INC The number of bits for the increment length of AT_SIGNATURE keys. This information is used with information returned with PP_ENUMALGS_EX to determine valid AT_SIGNATURE key lengths. These key lengths can then be used with CPGenKey.

For example, if a CSP enumerated CALG_RSA_SIGN (AT_SIGNATURE) with a minimum key length of 512 bits, a maximum of 1024 bits, and returned the increment length as 64 bits, then valid key lengths would be 512, 576, 640, and other lengths at 512-bit intervals up to 1024 bits.
PP_KEYX_KEYSIZE_INC The number of bits for the increment length of AT_KEYEXCHANGE keys. This information is used with information returned with PP_ENUMALGS_EX to determine valid AT_KEYEXCHANGE key lengths. These key lengths can then be used with CPGenKey.

For example, if a CSP enumerated CALG_RSA_SIGN (AT_KEYEXCHANGE) with a minimum key length of 512 bits, a maximum of 1024 bits, and returned the increment length as 64 bits, then valid key lengths would be 512, 576, 640, and other lengths at 512-bit intervals up to 1024 bits.
PP_KEYSET_SEC_DESCR | The security descriptor of the registry entry where the key set is stored. This flag is supported in Windows 98 and later and Windows NT 4.0 and later.
PP_UNIQUE_CONTAINER | The unique container name of the current key container in the form of a NULL-terminated CHAR string. For many CSPs, this name is the same as the name returned when PP_CONTAINER is used. The CryptAcquireContext function must work with this container name.
PP_PROVTYPE | A DWORD value indicating the provider type of the CSP.

pbData
Pointer to a data buffer. The dwParam parameter specifies the type of data to be copied to this buffer.

It is not an error if this parameter is NULL. If pbData is NULL, no parameter data is copied. Instead, the required buffer size (in bytes) is returned in pdwDataLen and a second call to the function with the correct number of bytes allocated for the pbData buffer is expected. For a detailed discussion and examples, see Retrieving Data of Unknown Length.

pdwDataLen
Pointer to a buffer to hold length of pbData. Upon function entry, it points to a DWORD value indicating the number of bytes allocated for the pbData buffer. Upon exit, the DWORD value must be set to the number of bytes needed to hold pbData. When one of the enumeration parameters is being read, the value returned in pdwDataLen must indicate the size of the largest item in the enumeration list.

If the buffer specified by pbData is not large enough to hold the requested data, the ERROR_MORE_DATA error code is returned by the SetLastError function. In this case, the required buffer size must be returned in pdwDataLen.

If this function fails with any error code other than ERROR_MORE_DATA, this parameter returns zero.

dwFlags
The following flags are defined for this function:
CRYPT_FIRST
Used only with an enumeration parameter such as PP_ENUMALGS, PP_ENUMALGS_EX, or PP_ENUMCONTAINERS. If this flag is set, the first item in the enumeration list is to be returned. Otherwise, the next item in the list is returned.

If this flag is set when a non-enumeration parameter is being read, the NTE_BAD_FLAGS error code is returned.

CRYPT_MACHINE_KEYSET
Can be set along with PP_ENUMCONTAINERS. If set, the key containers associated with a computer are enumerated, rather than those associated with the logged in user.

This flag value is used by the Microsoft CSPs. Other CSPs may ignore this flag.

SECURITY_INFORMATION
If dwParam is set to PP_KEYSET_SEC_DESCR, the security descriptor of the key container is retrieved. For this case, dwFlags is used to pass in bit flags that can be combined with a bitwise OR operation. The pointer to the security descriptor is returned in the pbData parameter and the length of the security descriptor is returned in the pcbData parameter. This flag value is used only by RSA base CSPs. A hardware-based CSP will not use this flag value. For more information, see RegGetKeySecurity and RegSetKeySecurity.

The following table contains bit flags indicating the requested security information.
Value | Meaning
OWNER_SECURITY_INFORMATION | Indicates the owner identifier of the object being referenced.
GROUP_SECURITY_INFORMATION | Indicates the primary group identifier of the object being referenced.
DACL_SECURITY_INFORMATION | Indicates the discretionary ACL of the object being referenced.
SACL_SECURITY_INFORMATION | Indicates the system ACL of the object being referenced.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
ERROR_MORE_DATA | The pbData buffer is not large enough to hold the requested data.
ERROR_NO_MORE_ITEMS | The end of the enumeration list has been reached. No valid data has been placed in the pbData buffer. This error is returned only when dwParam equals PP_ENUMALGS, PP_ENUMALGS_EX, or PP_ENUMCONTAINERS.
NTE_BAD_FLAGS | The value of the dwFlags parameter is invalid.
NTE_BAD_TYPE | The dwParam parameter specifies an unknown parameter number.
NTE_BAD_UID | The context specified by hProv is invalid.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPAcquireContext, CPSetProvParam, CryptGetProvParam


CPReleaseContext

The CPReleaseContext function releases a context created by CPAcquireContext.

BOOL CPReleaseContext(
  HCRYPTPROV hProv,  // in
  DWORD dwFlags      // in
);

Parameters

hProv
Handle of a key container within the CSP. This handle is obtained by a call to CPAcquireContext.
dwFlags
No flags are currently defined.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
NTE_BAD_FLAGS | The value of the dwFlags parameter is invalid.
NTE_BAD_UID | The context specified by hProv is invalid.

Remarks

After this function has been executed, the hProv handle becomes invalid. All session keys and hash objects previously created by using the hProv handle can be destroyed at this time. Ideally, the application already did this using CryptDestroyKey and CryptDestroyHash , but a CSP cannot depend upon the keys and hashes being destroyed.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPAcquireContext, CryptReleaseContext


CPSetProvParam

The CPSetProvParam function customizes the operations of a cryptographic service provider (CSP).

BOOL CPSetProvParam(
  HCRYPTPROV hProv,  // in
  DWORD dwParam,     // in
  BYTE *pbData,      // in
  DWORD dwFlags      // in
);

Parameters

hProv
Handle to a key container within the CSP. This handle is obtained by a call to CPAcquireContext.
dwParam
Customizable parameter to set. The only currently defined parameter value is:
PP_KEYSET_SEC_DESCR
Sets the security descriptor of a registry entry where the key set is stored. The new value is contained in pbData. For details on manipulating ACLs, see Secperf.c in the Microsoft Platform SDK.

Windows 95 does not support this flag.

Customizable parameters can be added as needed. General-purpose parameters can be defined in coordination with Microsoft Corporation to promote cross-vendor standardization and allow the new parameter numbers to be added to the standard Microsoft® Win32® header files.

pbData
On entry to the function, this buffer contains data as specified by the dwParam parameter. The form and length of this data varies depending on dwParam.
dwFlags
If pdParam is PP_KEYSET_SEC_DESCR, dwFlags contains the SECURITY_INFORMATION applicable bit flags. These can be combined with a bitwise OR operation. The following table lists defined SECURITY_INFORMATION flags.
Value | Meaning
OWNER_SECURITY_INFORMATION | Indicates the owner identifier of the object being referenced.
GROUP_SECURITY_INFORMATION | Indicates the primary group identifier of the object being referenced.
DACL_SECURITY_INFORMATION | Indicates the discretionary ACL of the object being referenced.
SACL_SECURITY_INFORMATION | Indicates the system ACL of the object being referenced.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
NTE_BAD_FLAGS | The value of the dwFlags parameter is invalid.
NTE_BAD_TYPE | The dwParam parameter specifies an unknown parameter number.
NTE_BAD_UID | The context specified by hProv is invalid.
NTE_FAIL | The function failed in an unexpected way.

Remarks

Applications can call CryptSetProvParam with the dwParam parameter set to PP_CLIENT_HWND to specify the window handle the CSP is to use when interacting with the user. The call to CryptSetProvParam passes in the window handle as a DWORD value in the pbData buffer.

Applications call CryptSetProvParam before calling CryptAcquireContext; therefore, calls to CPSetProvParam with the PP_CLIENT_HWND parameter are not made. The CSP obtains this window handle using a virtual function pointer obtained from the CPAcquireContext function call.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPAcquireContext, CPGetProvParam, CryptSetProvParam


Key Generation and Exchange Functions

Key generation and exchange functions exchange keys with other users and create, configure, and destroy cryptographic keys. The following table briefly describes each function.

Function | Description
CPDeriveKey | Creates a key derived from a password.
CPDestroyKey | Destroys a key.
CPDuplicateKey | Makes an exact copy of a key, including the state of the key.
CPExportKey | Transfers a key from the CSP into a key BLOB in the application's memory space.
CPGenKey | Creates a random key.
CPGenRandom | Generates random data.
CPGetKeyParam | Retrieves a key's parameters.
CPGetUserKey | Gets a handle to the key exchange or signature key.
CPImportKey | Transfers a key from a key BLOB to a CSP.
CPSetKeyParam | Specifies a key's parameters.


CPDeriveKey

The CPDeriveKey function generates a cryptographic session key using a hash of base data. This function guarantees that all keys generated from the same base data using the same algorithms will be identical. The base data can be a password or other user-supplied data.

BOOL CPDeriveKey(
  HCRYPTPROV  hProv,        // in
  ALG_ID      Algid,        // in
  HCRYPTHASH  hBaseData,    // in
  DWORD       dwFlags,      // in
  HCRYPTKEY   *phKey        // out
);

Parameters

hProv
Handle to a particular key container within the CSP. This handle is obtained with a call to CPAcquireContext.
Algid
Identifier of the encryption algorithm for which the key is to be generated. This algorithm must be one of those supported by the CSP.

The following Algid values are used with Schannel providers.
Algid | Meaning
CALG_SCHANNEL_ENC_KEY Generates a bulk encryption key. The key generation algorithm and key size must have been previously specified with a call to the CPSetKeyParam function. The initialization vector (IV) is typically set using CPSetKeyParam with KP_IV. Some protocol and cipher suite combinations insist on building the IV from the key block. In this case, the CSP derives the IV automatically.

For SSL 2, this key is also used as the MAC key.
CALG_SCHANNEL_MAC_KEY | Generates a MAC key. The key generation algorithm has previously been specified with a call to CPSetKeyParam.

hBaseData
Handle to a hash object that contains a hash of the base data.
dwFlags
Attributes of the session key generated. Not all CSPs support all flags. Currently defined flags are listed below.
Flag value | Meaning
CRYPT_EXPORTABLE The session key can be transferred out of the CSP into a key BLOB using CPExportKey. Because keys generally must be exportable, this flag is usually set.

If this flag is not set, the session key is not exportable. The session key is available only within the current session and can only be used by the application that created it.

This flag does not apply to public/private key pairs.
CRYPT_CREATE_SALT Typically, a number of extra bits are left over when a session key is created from a hash value. There are 88 bits left over when a 40-bit session key is created from a 128- bit hash value.

If this flag is set, the key is assigned a salt value based on the unused hash value bits. This salt value can be retrieved by calling CPGetKeyParam with the dwParam parameter set to KP_SALT.

If this flag is not set, the key is given a salt value of zero.

When keys with nonzero salt values are exported using CPExportKey, the salt value must also be obtained and kept with the key BLOB.
CRYPT_NO_SALT | No salt value is allocated for a 40-bit symmetric key.
CRYPT_USER_PROTECTED The user is notified through a dialog box or another method when this key is used to attempt certain actions. The precise behavior is specified by the CSP being used.

If the provider context is opened with the CRYPT_SILENT flag set, using this flag causes a failure with the last error set to NTE_SILENT_CONTEXT.

Microsoft cryptographic providers support this flag in Internet Explorer 4.0 and later, Windows 98, and Windows 2000. Prior to Internet Explorer 4.0, this flag was ignored.
CRYPT_UPDATE_KEY Some CSPs use session keys derived from multiple hash values. When this is the case, CPDeriveKey must be called multiple times.

If this flag is set, a new session key is not generated. Instead, the key specified by phKey is modified. The precise behavior of this flag is dependent on the type of key being generated and on the particular CSP being used.

Microsoft cryptographic providers ignore this flag.
CRYPT_SERVER | This flag is used only with Schannel providers. If this flag is set, the key to be generated is a server-write key; otherwise, it is a client-write key.

phKey
Address to which the function copies the handle of the newly-generated key.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
NTE_BAD_ALGID | The Algid parameter specifies an algorithm that this CSP does not support.
NTE_BAD_FLAGS | The dwFlags parameter contains an invalid value.
NTE_BAD_HASH | The hBaseData parameter does not contain a valid handle to a hash object.
NTE_BAD_HASH_STATE | An attempt was made to add data to a hash object that is already marked as finished.
NTE_FAIL | The function failed in an unexpected way.
NTE_BAD_UID | The hProv parameter does not contain a valid context handle.
NTE_SILENT_CONTEXT | The provider could not perform the action because the context was acquired as silent.

Remarks

The CPDeriveKey function completes the hash of the hash object passed in as hBaseData. After CPDeriveKey has been called, no more data can be added to that hash object. Additional calls to CPHashData or CPHashSessionKey with that hash object fail. However, additional calls to CPDeriveKey, CPGetHashParam, CPSignHash, and CPVerifySignature use the completed hash object and succeed.

If CSP interoperability is important, session keys must be derived in the precise manner specified by the CSP's type. For information on how the key derivation must be performed, see Deriving Session Keys.

If interoperability is not a concern, a CSP is free to derive session keys in any manner.

For a description of the master hash object, see CPCreateHash.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPDestroyKey, CPGenKey, CryptDeriveKey


CPDestroyKey

The CPDestroyKey function releases the handle referenced by the hKey parameter. After a key handle has been released, it becomes invalid and can no longer be used.

BOOL CPDestroyKey(
  HCRYPTPROV hProv,  // in
  HCRYPTKEY  hKey    // in
):

Parameters

hProv
Handle to a particular key container within the CSP. This handle is obtained by a call to CPAcquireContext.
hKey
Handle to the key to be destroyed.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
NTE_BAD_KEY | The hKey parameter does not contain a valid handle to a key.
NTE_BAD_UID | The hProv parameter does not contain a valid context handle.

Remarks

If the handle refers to a session key or to a public key imported into the CSP with CryptImportKey, this function destroys the key and frees the memory that the key occupied. A CSP typically scrubs the memory where the key was held before freeing it.

On the other hand, if the handle refers to a public/private key pair (obtained from CryptGetUserKey), the underlying key pair is not destroyed by this function. Only the handle is destroyed.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPDeriveKey, CPGenKey, CPGetUserKey, CryptDestroyKey


CPDuplicateKey

The CPDuplicateKey function makes an exact copy of a key. Some keys have an associated state such as an initialization vector or a salt value. If a key with an associated state is duplicated, the associated state is also copied.

BOOL CPDuplicateKey(
  HCRYPTPROV hUID,     // in
  HCRYPTKEY hKey,      // in
  DWORD *pdwReserved,  // in
  DWORD dwFlags,       // in
  HCRYPTKEY *phKey     // out
);

Parameters

hUID
Handle to a particular key container within the CSP. This handle is obtained with a call to CPAcquireContext.
hKey
Handle of the key to be duplicated.
pdwReserved
This parameter is reserved for future use and must be NULL.
dwFlags
This parameter is reserved for future use and must be zero.
phKey
Address for the handle to the duplicated key.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
ERROR_CALL_NOT_IMPLEMENTED | Because this is a new function, existing CSPs might not implement it. This error is returned if the CSP does not support this function.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an illegal pointer.
NTE_BAD_KEY | The handle to the original key is not valid.

Remarks

The CPDuplicateKey function is used to make a copy of a key and the exact state of that key. For example, a caller can encrypt two separate messages with the same key, but with different salt values. A key is generated, a duplicate is made with the CPDuplicateKey function, and then different appropriate salt values are set on each key with the CPSetKeyParam function.

CPDestroyKey must be called to destroy any keys that are created with CPDuplicateKey. Destroying the original key does not destroy the duplicate key. Once a duplicate key is made, it is separate from the original key. There is no shared state between the two keys.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPDestroyKey, CryptDuplicateKey


CPExportKey

The CPExportKey function securely exports cryptographic keys from a CSP's key container.

BOOL CPExportKey(
  HCRYPTPROV hProv,      // in
  HCRYPTKEY hKey,        // in
  HCRYPTKEY hPubKey,     // in
  DWORD dwBlobType,      // in
  DWORD dwFlags,         // in
  BYTE *pbData,          // out
  DWORD *pdwDataLen      // in, out
);

Parameters

hProv
Handle to a particular key container within the CSP. This handle is obtained with a call to CPAcquireContext.
hKey
Handle of the key to be exported.
hPubKey
Handle of a cryptographic key belonging to the destination user. The exported key data within the created key BLOB is encrypted using this key. This ensures that only the destination user will be able to make use of the key BLOB.

Most often, this handle will be the handle of the key exchange public key of the destination user. Certain protocols, however, require that this handle be the handle of a session key belonging to the destination user.

If the key BLOB is a PUBLICKEYBLOB and is not to be encrypted, this parameter is not used and must be zero.

dwBlobType
Type of key BLOB to be exported. The following key BLOB types are defined.
BLOB type | Use
SIMPLEBLOB | To transport session keys.
PUBLICKEYBLOB | To transport public key.
PRIVATEKEYBLOB | To transport public/private key pairs.
OPAQUEKEYBLOB | To store session keys in an Schannel CSP. The OPAQUEKEYBLOB type is non-transferable and must be used within the CSP that generated the BLOB.

Additional key BLOB types can be defined as needed.

dwFlags
The following values are defined. These values are only used in Schannel CSPs.
Flag value | Effect
CRYPT_DESTROYKEY | Destroys the original key in the OPAQUEKEYBLOB.
CRYPT_SSL2_FALLBACK | Sets the first eight bytes of the RSA encryption block padding to 0x03 rather than to random data. This prevents version rollback attacks and is discussed in the SSL3 specification.

pbData
Pointer to a data buffer to return the key BLOB.

It is not an error if this parameter is NULL. If pbData is NULL, no parameter data is copied. Instead, the required buffer size (in bytes) is returned in pdwDataLen and a second call to the function with the correct number of bytes allocated for the pbData buffer is expected. For a detailed discussion and examples, see Retrieving Data of Unknown Length.

pdwDataLen
Address of a DWORD value to hold the length of the BLOB to be returned in the pbData buffer. Upon function entry, this DWORD value contains the number of bytes allocated for the pbData buffer. Upon exit, it must be set to the actual number of bytes of data needed for the pbData buffer.

If the buffer specified by pbData is not large enough to hold the key BLOB data, the ERROR_MORE_DATA error code is returned with the SetLastError function. In this case, the required buffer size must be returned in pdwDataLen.

If this function fails with any error code other than ERROR_MORE_DATA, zero is returned in this parameter.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
ERROR_MORE_DATA | The pbData buffer is not large enough to hold the requested data.
NTE_BAD_FLAGS | The dwFlags parameter contains an invalid value.
NTE_BAD_KEY | One or both of the keys specified by hKey and hPubKey are invalid.
NTE_BAD_KEY_STATE | The key cannot be exported because the CRYPT_EXPORTABLE flag was not specified when the key was created.
NTE_BAD_PUBLIC_KEY | The key BLOB type specified by dwBlobType is PUBLICKEYBLOB, but hPubKey does not contain a public key handle.
NTE_BAD_TYPE | The dwBlobType parameter specifies an unknown BLOB type.
NTE_BAD_UID | The CSP context that was specified when the hKey key was created cannot now be found.
NTE_NO_KEY | A session key is being exported and the hExpKey parameter does not specify a public key.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPImportKey, CryptExportKey


CPGenKey

The CPGenKey function generates a random cryptographic key or key pair.

BOOL CPGenKey(
  HCRYPTPROV hProv,     // in
  ALG_ID Algid,         // in
  DWORD dwFlags,        // in
  HCRYPTKEY *phKey     // out
);

Parameters

hProv
Handle to a particular key container within the CSP. This handle is obtained with a call to CPAcquireContext.
Algid
Identifier for the algorithm for which the key is being generated. This algorithm must be one of those supported by this CSP.

If a session key is to be generated, this value specifies an encryption algorithm such as:

  • CALG_RC2
  • CALG_RC4
  • CALG_DES

If a public/private key pair is to be generated, this value specifies a key pair type such as:

  • AT_KEYEXCHANGE
  • AT_SIGNATURE
dwFlags
Flags specifying attributes pertaining to the key generated. The sizes of RSA signature and key exchange keys can be set when the key is generated. The key size is set with the upper 16 bits of the dwFlags parameter and these 16 bits represent the length of the modulus in bits. This applies to the Microsoft Base Cryptographic Provider. These are flags currently defined.
Flag value | Effect
CRYPT_EXPORTABLE When a session key or private key is created and this flag is not set, the CSP must refuse to export the key. If the application attempts to export the key using CPExportKey, that function fails and returns the NTE_BAD_KEY_STATE error code.

This flag only applies to the export of session keys and private keys. It does not apply to public keys, which are always exportable.
CRYPT_CREATE_SALT When set, the new session key is assigned a random salt value. If this flag is not set, the session key is assigned a salt value of zero.

This flag does not apply to public/private key pairs.
CRYPT_NO_SALT | Specifies that a no salt value is assigned for 40-bit symmetric keys. For more information, see New Salt Value Functionality.
CRYPT_USER_PROTECTED When set, the CSP notifies the user through a dialog box or some other method when certain actions are attempted using this key. The precise behavior is specified by the CSP or the CSP type used.

If the provider context was acquired with CRYPT_SILENT set, using this flag causes a failure and the last error is set to NTE_SILENT_CONTEXT

The Microsoft Enhanced Cryptographic Provider supports this flag in Internet Explorer 4.0 and later, Windows 98, and Windows 2000. Prior to Internet Explorer 4.0, this flag was ignored.
CRYPT_PREGEN | Specifies an initial Diffie-Hellman or DSS key generation. Currently only useful with Diffie-Hellman/DSS CSPs.

phKey
Address to which the function copies a handle to the newly-generated key.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
NTE_BAD_ALGID | The Algid parameter specifies an algorithm that this CSP does not support.
NTE_BAD_FLAGS | The dwFlags parameter contains an invalid value.
NTE_FAIL | The function failed in some unexpected way.
NTE_BAD_UID | The hProv parameter does not contain a valid context handle.
NTE_PERM | An attempt was made to create a key pair when CRYPT_VERIFYCONTEXT was specified.
NTE_SILENT_CONTEXT | Provider could not perform the action because the context was acquired as silent.

Remarks

An application cannot create new key pairs if no key container is currently open. This can happen if CRYPT_VERIFYCONTEXT was set in the CPAcquireContext call. If a key cannot be created, the NTE_PERM error code is returned.

CPGenRandom is generally used to generate the random key material.

Keys generated for symmetric block ciphers must be set up by default in cipher block chaining (CBC) mode with an initialization vector of zero. This cipher mode provides a good default method for bulk-encrypting data. These parameters are changed using the CPSetKeyParam function.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPDestroyKey, CPExportKey, CPImportKey, CryptGenKey


CPGenRandom

The CPGenRandom function fills a buffer with random bytes.

BOOL CPGenRandom(
  HCRYPTPROV hProv,  // in
  DWORD dwLen,       // in
  BYTE *pbBuffer     // in, out
);

Parameters

hProv
Handle to a particular key container within the CSP. This handle is obtained with a call to CPAcquireContext.
dwLen
Number of bytes of random data to be generated.
pbBuffer
Buffer to which the function copies the random data. This buffer is dwLen bytes in length.

Upon input to the function, this buffer can contain up to dwLen bytes of random data that the CSP can use to generate a seed value. This is discussed further in Remarks.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
NTE_BAD_UID | The hProv parameter does not contain a valid context handle.
NTE_FAIL | The function failed in some unexpected manner.

Remarks

CPGenRandom is one of the more difficult functions to implement correctly, and it must be done correctly to maintain the security of a CSP. CPGenRandom is used internally by the CPGenKey function, as well by applications when generating data items used in cryptographic protocols such as challenge strings. A CSP is not producing message security if values of the cryptographic keys or challenge strings produced by a CSP are predictable.

There are two components to a good random number generator: a method of getting a random seed, and an algorithm that will generate a good pseudo-random stream of data based on that seed.

Generating a random seed can depend on the hardware used by the CSP. If the CSP has access to a hardware random number source such as some slightly radioactive material and a Geiger counter, the problem is solved. A completely software-based CSP might use one of the following sources:

  • The system time.
  • Any high-precision clocks that exist on the system board and peripherals.
  • The cursor or mouse pointer location.
  • Any accumulated physical state information devices such as in keyboard input buffers, I/O service queues, and video drivers.
  • The number of tasks in the OS scheduling queue, their task identifiers, or their code base addresses and sizes.
  • Data from the application, passed into the CryptGenRandom function and passed on to CPGenRandom as the input bytes in pbBuffer.

Some or all of this data can be hashed along with the random seed from the previous session to create a random seed. New seeds should be generated periodically throughout the session, to avoid placing too much reliance on the pseudo-random stream generator.

Once the random seed has been obtained, any number of algorithms can be used to generate a pseudo-random stream of data. Sometimes a stream cipher such as RC4 is used for this purpose, with the seed forming the keying material. The following sources describe other algorithms and techniques:

  • Bellare, M., and P. Rogaway. Optimal Asymmetric Encryption. Advances in Cryptology—EUROCRYPT '94, ed. by A. deSantis, Springer-Verlag, 1995, pp. 92-111, Lecture Notes in Computer Science, vol. 950.
  • Blum, L. , M. Blum, and M. Shub. A Simple Unpredictable Pseudo-Random Number Generator. SIAM Journal on Computing 15(2)(May 1986); 364-383.
  • M. Blum and S. Micali, "How to generate cryptographically strong sequences of pseudo-random bits," SIAM Journal on Computing 13(4)(November 1984); 850-864.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CryptGenRandom


CPGetKeyParam

The CPGetKeyParam function retrieves data that governs the operations of a key.

BOOL CPGetKeyParam(
  HCRYPTPROV hProv,       // in
  HCRYPTKEY hKey,         // in
  DWORD dwParam,          // in
  BYTE *pbData,           // out
  DWORD *pdwDataLen,      // in, out
  DWORD dwFlags           // in
);

Parameters

hProv
Handle to a particular key container within the CSP. This handle is obtained with a call to CPAcquireContext.
hKey
Handle to the key that is the target of the query.
dwParam
All key types can use any of the following key parameter types.
dwParam value | Key types | Copied to pdData | Returned pdwDataLen
KP_ALGID | all | The algorithm identifier (ALG_ID) used by this key object. | 4
KP_BLOCKLEN all If hKey is a session key, a DWORD value indicating the block length in bits.

If hKey is a public/private key pair, a DWORD value indicating the key pair's granularity. For RSA key pairs, this is the size of the modulus.

If the public-key algorithm does not support encryption, the NTE_BAD_TYPE error code is returned.

 4
KP_KEYLEN | all | The actual length of the key in bits. For more information, see Remarks. | 4
KP_SALT | all session keys | A BYTE array containing the key's current salt value. This parameter does not apply to public/private key pairs. If hKey references a public/private key pair, the NTE_BAD_TYPE error code is returned. | Length of the BYTE array
KP_PERMISSIONS | all | A DWORD value indicating the permission to be associated with the key. See Remarks for a table of permission flags. | 4
KP_IV | block cipher keys | A BYTE array containing the key's current initialization vector (IV). | Length of the BYTE array
KP_PADDING | block cipher keys | A DWORD value indicating the padding method used. Currently, PKCS5_Padding is defined. | 4
KP_MODE | block cipher keys | A DWORD value indicating the cipher mode used. See the table in Remarks for possible values. | 4
KP_MODE_BITS | block cipher keys | A DWORD value indicating the feedback width in bits. This is used only with OFB and CFB cipher modes. | 4
KP_EFFECTIVE_KEYLEN | RC2 | A DWORD value indicating the effective key length of an RC2 key. | 4

More parameters can be added as needed. General-purpose parameters can be define in coordination with Microsoft to promote cross-vendor standardization and allow the new parameter numbers to be added to the standard Microsoft Win32® header files.

pbData
Pointer to a data buffer. The dwParam parameter specifies the type of data to be copied into this buffer.

It is not an error if this parameter is NULL. If pbData is NULL, no data is copied. Instead, the required buffer size (in bytes) is returned in pdwDataLen and a second call to the function with the correct number of bytes allocated for the pbData buffer is expected. See Retrieving Data of Unknown Length for a detailed discussion and examples.

pdwDataLen
Address of a DWORD to hold the byte length for the pbData buffer. Upon function entry, the DWORD contains the number of bytes allocated for the pbData buffer. Upon exit, it must be set to the actual number of bytes needed for the pbData buffer.

If the buffer specified by pbData is not large enough to hold the requested data, the ERROR_MORE_DATA error code is returned with the SetLastError function. In this case, the required buffer size must be returned in pdwDataLen.

If this function fails with any error code other than ERROR_MORE_DATA, zero is returned in this parameter.

dwFlags
No flags are currently defined.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
ERROR_MORE_DATA | The pbData buffer is not large enough to hold the requested data.
NTE_BAD_FLAGS | The dwFlags parameter is non-zero.
NTE_BAD_KEY or NTE_NO_KEY | The key specified by the hKey parameter is invalid.
NTE_BAD_TYPE | The dwParam parameter specifies an unknown parameter number.
NTE_BAD_UID | The CSP context that was specified when the key was created cannot now be found.

Remarks

Microsoft CSPs return a key length of 64 bits for CALG_DES, 128 for CALG_3DES_112, and 192 for CALG_3DES. These lengths are different from the lengths returned when enumerating algorithms with CryptGetProvParam with dwParam set to PP_ENUMALGS. The length returned CPGetProvParam is the actual size of the key including parity bits.

Microsoft CSPs that support the ALG_ID of type CALG_CYLINK_MEK return 64 bits for that algorithm. CALG_CYLINK_MEK is a 40 bit key, but has parity bits and zeroed key bits to make the key length 64 bits.

The following table lists the permission flags that are currently defined.

Permission flag | Description | Value
CRYPT_ENCRYPT | Allows encryption | 0x0001
CRYPT_DECRYPT | Allows decryption | 0x0002
CRYPT_EXPORT | Allows key to be exported | 0x0004
CRYPT_READ | Allows parameters to be read | 0x0008
CRYPT_WRITE | Allows parameters to be set | 0x0010
CRYPT_MAC | Allows MACs to be used with key | 0x0020

The following table lists the cipher modes that are currently defined.

Cipher mode | Description | Value
CRYPT_MODE_ECB | Electronic codebook | 2
CRYPT_MODE_CBC | Cipher block chaining | 1
CRYPT_MODE_OFB | Output feedback mode | 3
CRYPT_MODE_CFB | Cipher feedback mode | 4

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPSetKeyParam, CryptGetKeyParam


CPGetUserKey

The CPGetUserKey function retrieves the handle of one of the permanent key pairs in the hProv key container.

BOOL CPGetUserKey(
  HCRYPTPROV hProv,       // in
  DWORD dwKeySpec,        // in
  HCRYPTKEY *phUserKey    // out
);

Parameters

hProv
Handle to a particular key container within the CSP. This handle is obtained with a call to CPAcquireContext.
dwKeySpec
Specification of the key to retrieve. The following key pair types are currently defined:
Key pair type | Descriptipn
AT_KEYEXCHANGE | Key used to encrypt and exchange session keys.
AT_SIGNATURE | Keys used to create and verify digital signatues.

phUserKey
Address to which the function copies the handle of the retrieved key. This pointer must not be NULL.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
NTE_BAD_KEY | The key specified by the hKey parameter is invalid.
NTE_BAD_UID | The CSP context that was specified when the key was created cannot now be found.
NTE_NO_KEY | The key specified by the dwKeySpec parameter does not exist.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPExportKey, CPGenKey, CryptGetUserKey


CPImportKey

The CPImportKey function transfers a cryptographic key from a key BLOB to a CSP key container.

BOOL CPImportKey(
  HCRYPTPROV hProv,       // in
  CONST BYTE *pbData,     // in
  DWORD  dwDataLen,       // in
  HCRYPTKEY hPubKey,      // in
  DWORD dwFlags,          // in
  HCRYPTKEY *phKey        // out
);

Parameters

hProv
Handle to a particular key container within the CSP. This handle is obtained with a call to CPAcquireContext.
pbData
Buffer containing the key BLOB. This key BLOB was generated by the CPExportKey function, either by this CSP or by a CSP running on a remote computer.

This key BLOB consists of a standard header followed by the key material. The key material is often encrypted.

dwDataLen
Length, in bytes, of the key BLOB.
hPubKey
The meaning of this parameter differs, depending on the CSP type and the type of key BLOB being imported.

If a signed key BLOB is being imported, the key is used to validate the signature of the key BLOB. In this case, this parameter must contain a handle to the key exchange public key of the party that created the key BLOB.

If the key BLOB is a SIMPLEBLOB encrypted with the key exchange key pair, this parameter can be the handle to the key exchange key.

If the key BLOB is encrypted with a session key, as is often done by Fortezza CSPs, for example, this parameter contains a handle to that session key.

If the key BLOB is a PUBLICKEYBLOB and is not encrypted, this parameter is not used and is set to zero.

dwFlags
This parameter is currently used only when a public/private key pair is being imported into the CSP in the form of a PRIVATEKEYBLOB. The following flags are defined:
Flag value | Description
CRYPT_EXPORTABLE | If the key being imported is eventually to be re-exported, the CRYPT_EXPORTABLE flag must be placed in this parameter. If the CRYPT_EXPORTABLE flag is not used, future calls to CryptExportKey with the key handle will fail.
CRYPT_NO_SALT | A no-salt value is specified for a 40-bit symmetric key. For more information, see New Salt Value Functionality.

phKey
Address to which the function copies a handle to the key that was imported.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
NTE_BAD_ALGID | The simple key BLOB being imported is not encrypted with the expected key exchange algorithm. The most likely cause of this error is incompatible CSPs.
NTE_BAD_DATA | The algorithm of the public key being imported is not supported by this CSP.
NTE_BAD_FLAGS | The dwFlags parameter is non-zero.
NTE_BAD_TYPE | The key BLOB type is not supported by this CSP and is possibly invalid.
NTE_BAD_UID | The hProv parameter does not contain a valid context handle.
NTE_BAD_VER | The key BLOB's version number indicates a key BLOB version that the CSP does not support.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPExportKey, CPGenKey, CryptImportKey


CPSetKeyParam

The CPSetKeyParam function customizes the operations of a key.

BOOL CPSetKeyParam(
  HCRYPTPROV hProv,        // in
  HCRYPTKEY hKey,          // in
  DWORD dwParam,           // in
  BYTE *pbData,            // in
  DWORD dwFlags            // in
);

Parameters

hProv
Handle to a particular key container within the CSP. This handle is obtained with a call to CPAcquireContext.
hKey
Handle to the target key on which to set parameters.
dwParam
The following table list currently defined dwParam values.
Value | Contents of the pbData buffer
KP_SALT | A BYTE array containing the key's current salt value.
KP_SALT_EX A BYTE array containing the key's current salt value.

This parameter is not used with public/private key pairs. If hKey references a public/private key pair, the NTE_BAD_TYPE error code is returned.
KP_PERMISSIONS A DWORD defining the key's permission flags. Flags can be combined using bitwise OR operations.

See the table in the Remarks section for key permission flag values and their meanings.
KP_IV | A BYTE array containing the key's current initialization vector (IV).
KP_PADDING | A DWORD indicating the padding method used by the key's cipher. PKCS5_PADDING is the only padding method value defined. It represents PKCS 5 ( sec 6.2) padding.
KP_MODE A DWORD indicating the cipher mode.

See the Remarks section for a table of possible cipher modes.
KP_MODE_BITS | A DWORD indicating the feedback width, in bits. This parameter only applies when the OFB or CFB cipher modes are used.
KP_EFFECTIVE_KEYLEN | A Microsoft base provider implementation compatible CSP using RC2 must support KP_EFFECTIVE_KEYLEN used to set the effective key length of an RC2 key.

Parameters can be added as needed. General-purpose parameters can be define in coordination with Microsoft to promote cross-vendor standardization and allow the new parameter numbers to be added to the standard Microsoft Win32® header files..

pbData
Parameter data buffer. Upon entry to the function, this buffer will contain the data that corresponds to the dwParam parameter value. Notice that the length of this data is not explicitly specified but is implied by the dwParam parameter value.
dwFlags
No flags are currently defined.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
NTE_BAD_FLAGS | The dwFlags parameter is non-zero or the pbData buffer contains an invalid value.
NTE_BAD_TYPE | The dwParam parameter specifies an unknown parameter.
NTE_BAD_UID | The CSP context that was specified when the hKey key was created cannot now be found.
NTE_FAIL | The function failed in some unexpected manner.

Remarks

The following table lists the defined permission flags:

Permission Flag | Description
CRYPT_ENCRYPT | Allows encryption
CRYPT_DECRYPT | Allows decryption
CRYPT_EXPORT | Allows key to be exported
CRYPT_READ | Allows parameters to be read
CRYPT_WRITE | Allows parameters to be set
CRYPT_MAC | Allows MACs to be used with key

The following table lists the defined cipher modes:

Cipher Mode | Description
CRYPT_MODE_ECB | Electronic codebook
CRYPT_MODE_CBC | Cipher block chaining
CRYPT_MODE_OFB | Output feedback mode
CRYPT_MODE_CFB | Cipher feedback mode

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPGenKey, CPGetKeyParam, CryptSetKeyParam


Data Encryption Functions

Data encryption functions support encryption and decryption operations. The following table briefly describes each function.

Function | Description
CPDecrypt | Decrypts a section of ciphertext using the specified encryption key.
CPEncrypt | Encrypts a section of plaintext using the specified encryption key.


CPDecrypt

The CPDecrypt function decrypts data previously encrypted with the CPEncrypt function. Optionally, the application can specify that the decrypted data be hashed.

BOOL CPDecrypt(
  HCRYPTPROV hProv,      // in
  HCRYPTKEY hKey,        // in
  HCRYPTHASH hHash,      // in
  BOOL Final,            // in
  DWORD dwFlags,         // in
  BYTE *pbData,          // in, out
  DWORD *pdwDataLen      // in, out
);

Parameters

hProv
Handle to a particular key container within the CSP. This handle is obtained by a call to CPAcquireContext.
hKey
Handle to the session key for the decryption. This key specifies the decryption algorithm to be used.
hHash
Handle to a hash object. This parameter is used only if a hash of the data is to be computed after the data is decrypted.

This parameter is zero if no hash is to be done.

Final
Boolean value specifying whether this is the last section in a series of data blocks being decrypted. This will be TRUE if this is the last or only block, and FALSE otherwise.
dwFlags
No flags are currently defined.
pbData
Buffer on input holding the ciphertext to be decrypted. Once the decryption has been performed, the plaintext is written to this buffer overwriting the ciphertext. If a block cipher is used and dwFlags is TRUE, any padding data must be removed before returning the plaintext to the application.

This is simpler than the encryption case, since the plaintext generated is never larger than the ciphertext.

pdwDataLen
Address of a DWORD. Upon entry, the DWORD is the number of bytes of ciphertext in the pbData buffer. If a block cipher is used and Final is FALSE, this value must be a multiple of the cipher block length. Decryption is done in place, and the CPDecrypt function does not need to buffer any data internally.

Upon exit, the DWORD pointed to by this parameter indicates the number of bytes of plaintext in the pbData buffer.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
NTE_BAD_ALGID | The hKey session key specifies an algorithm that this CSP does not support.
NTE_BAD_DATA | The data to be decrypted is invalid. For example, when a block cipher is used and the Final flag is FALSE, the value specified by pdwDataLen must be a multiple of the block size. This error can also be returned when the padding is found to be invalid.
NTE_BAD_FLAGS | The dwFlags parameter is non-zero.
NTE_BAD_HASH | The hHash parameter contains an invalid handle.
NTE_BAD_KEY | The hKey parameter does not contain a valid handle to a session key.
NTE_BAD_LEN | The size of the output buffer is too small to hold the generated plaintext.
NTE_BAD_UID | The CSP context that was specified when the key was created cannot now be found.
NTE_DOUBLE_ENCRYPT | The application attempted to decrypt the same data twice.
NTE_FAIL | The function failed in some unexpected way.

Remarks

In Windows 2000, the Microsoft Enhanced RSA Provider supports direct encryption with RSA public keys and decryption with RSA private keys. The encryption is done with PKCS #1 Type 2 padding, and on decryption this padding is verified. The length of ciphertext text data to be decrypted must be the same length as the modulus of the RSA key used to encrypt the data. If the ciphertext has 0x00 bytes in the most significant bytes, these bytes must be included in the input data buffer and in the input buffer length. The ciphertext must be in little-endian format.

For additional requirement for developing this function for an Schannel provider, see Bulk Data Encryption.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPEncrypt, CPGenKey, CryptDecrypt


CPEncrypt

The CPEncrypt function encrypts data. Optionally, the application can specify that a hash of the plaintext data is to be generated.

BOOL CPEncrypt(
  HCRYPTPROV hProv,       // in
  HCRYPTKEY hKey,         // in
  HCRYPTHASH hHash,       // in
  BOOL Final,             // in
  DWORD dwFlags,          // in
  BYTE *pbData,           // in, out
  DWORD *pdwDataLen,      // in, out
  DWORD dwBufLen          // in
);

Parameters

hProv
Handle to a particular key container within the CSP. This handle is obtained by a call to CPAcquireContext.
hKey
Handle to the key to use for the encryption. This key handle includes a a specification of the encryption algorithm to be used.
hHash
Handle to a hash object. This parameter is used only if a hash of the data is to be computed before time the data is encrypted.

This parameter is zero if no hash is to be done.

Final
Boolean value that specifies whether this is the last section in a series being encrypted. This will be TRUE if this is the last or only block, and FALSE otherwise.
dwFlags
No flags are currently defined.
pbData
Buffer holding the plaintext to be encrypted. Once the encryption has been performed, the ciphertext overwrites the plaintext in the pbdata buffer.
pdwDataLen
Address of a DWORD indicating byte length. Upon function entry, this DWORD specifies the number of bytes of plaintext in the pbData buffer. If a block cipher is used and dwFlags is FALSE, this must be a multiple of the cipher block length so that the CPEncrypt function need not buffer any data internally.

Upon exit, this DWORD indicates length in bytes of ciphertext in the pbData buffer.

When a block cipher is used, the size of the ciphertext generated is sometimes larger than that of the plaintext. However, it must never be greater than dwBufLen.

dwBufLen
Size of the pbData buffer in bytes.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
NTE_BAD_ALGID | The hKey session key specifies an algorithm that this CSP does not support.
NTE_BAD_DATA | The data to be encrypted is invalid. For example, when a block cipher is used and the Final flag FALSE, the value specified by pdwDataLen must be a multiple of the block size.
NTE_BAD_FLAGS | The dwFlags parameter is non-zero.
NTE_BAD_HASH | The hHash parameter contains an invalid handle.
NTE_BAD_HASH_STATE | An attempt was made to add data to a hash object that is already marked "finished."
NTE_BAD_KEY | The hKey parameter does not contain a valid handle to a key.
NTE_BAD_LEN | The size of the output buffer is too small to hold the generated ciphertext.
NTE_BAD_UID | The CSP context that was specified when the key was created cannot now be found.
NTE_DOUBLE_ENCRYPT | The application attempted to encrypt the same data twice.
NTE_FAIL | The function failed in some unexpected way.
NTE_NO_MEMORY | The CSP ran out of memory during the operation.

Remarks

In Windows 2000, the Microsoft Enhanced RSA Provider supports direct encryption with RSA public keys and decryption with RSA private keys. The encryption is done with PKCS #1 Type 2 padding, and on decryption this padding is verified. The length of plaintext data that can be encrypted with a call to CPEncrypt with an RSA key is the length of the key modulus minus 11 bytes. The 11 bytes is the chosen minimum for PKCS #1 padding. The ciphertext is returned in little-endian format.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPDecrypt, CPGenKey, CryptEncrypt


Hashing and Digital Signature Functions

Hashing and digital signature functions compute hashes and create and verify digital signatures. The following table briefly describes each function.

Function | Description
CPCreateHash | Creates a hash object and returns a handle to it.
CPDestroyHash | Destroys a hash object.
CPDuplicateHash | Makes an exact copy of a hash object and the state the hash is in.
CPGetHashParam | Retrieves a hash object parameter.
CPHashData | Hashes a block of data, adding it to the specified hash object.
CPHashSessionKey | Hashes a session key, adding it to the specified hash object.
CPSetHashParam | Sets a hash object parameter.
CPSignHash | Signs the specified hash object.
CPVerifySignature | Verifies a digital signature.


CPCreateHash

The CPCreateHash function creates a hash object and initiates the hashing of a stream of data.

BOOL CPCreateHash(
  HCRYPTPROV hProv,    // in
  ALG_ID Algid,        // in
  HCRYPTKEY hKey,      // in
  DWORD dwFlags,       // in
  HCRYPTHASH *phHash   // out
);

Parameters

hProv
Handle to a particular key container within the CSP. This handle is obtained by a call to CPAcquireContext.
Algid
Algorithm identifier (ALG_ID) of the hash algorithm to be used.
hKey
If the hash is a keyed hash algorithm such as MAC, the key handle for the hash is passed in this parameter. For non-keyed algorithms, this parameter is set to zero.
dwFlags
No flags are currently defined.
phHash
Address to which the function copies a handle to the new hash object.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
NTE_BAD_ALGID | The Algid parameter specifies an algorithm that this CSP does not support.
NTE_BAD_FLAGS | The dwFlags parameter is non-zero.
NTE_BAD_KEY | The algid parameter specifies a keyed hash algorithm, such as CALG_MAC, and the hKey parameter is either zero or an invalid key handle. This error code will also be returned if the key is to a stream cipher or if the cipher mode is one that does not use feedback.
NTE_NO_MEMORY | The CSP ran out of memory during the operation.

Remarks

For information on writing CPCreateHash for Schannel applications, see Schannel CSP Reference.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPDestroyHash, CPHashData, CryptCreateHash


CPDestroyHash

The CPDestroyHash function destroys the hash object referenced by the hHash parameter.

BOOL CPDestroyHash(
  HCRYPTPROV hProv, // in
  HCRYPTHASH hHash  // in
);

Parameters

hProv
Handle to a particular key container within the CSP. This handle is obtained by a call to CPAcquireContext.
hHash
Handle to the hash object to be destroyed.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
NTE_BAD_ALGID | The hHash handle specifies an algorithm that this CSP does not support.
NTE_BAD_HASH | The hash object specified by the hHash parameter is invalid.
NTE_BAD_UID | The CSP context that was specified when the hash object was created cannot now be found.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPCreateHash, CryptDestroyHash


CPDuplicateHash

The CPDuplicateHash function makes an exact copy of a hash and its state.

BOOL CPDuplicateHash(
  HCRYPTPROV hUID,          // in
  HCRYPTHASH hHash,         // in
  DWORD *pdwReserved,       // in
  DWORD dwFlags,            // in
  HCRYPTHASH *phHash        // out
);

Parameters

hUID
Handle to a particular key container within the CSP. This handle is obtained by a call to CPAcquireContext.
hHash
The handle to the hash to be duplicated.
pdwReserved
This parameter is reserved for future use and must be NULL.
dwFlags
This parameter is reserved for future use and must be zero.
phHash
The address of the handle to the duplicated hash. Must be the address of a buffer with enough memory allocated to hold the duplicated hash.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
ERROR_CALL_NOT_IMPLEMENTED | This is a new function and existing CSPs might not implement it. This error is returned if the CSP does not support this function.
ERROR_INVALID_PARAMETER | One of the parameters contains an invalid value. This is most often an illegal pointer.
NTE_BAD_HASH | The handle to the original hash is not valid.

Remarks

CPDuplicateHash makes a copy of a hash including its exact state. To generate two different hashes starting with some common hashed data,

  1. create a single hash object
  2. hash the common data to that object
  3. duplicate the object the CPDuplicateHash function.
  4. hash different data to the original hash object and the newly create object

CPDestroyHash must be called to destroy any hashes created with CPDuplicateHash. Destroying the original hash does not cause the duplicate hash to be destroyed. Once a duplicate hash is made, it is separate from the original hash. There is no shared state between the two hashes.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPDestroyHash, CryptDuplicateHash


CPGetHashParam

The CPGetHashParam function retrieves data about the operations of a hash object. The actual hash value can be obtained using this function.

BOOL CPGetHashParam(
  HCRYPTPROV hProv,        // in
  HCRYPTHASH hHash,        // in
  DWORD dwParam,           // in
  BYTE *pbData,            // out
  DWORD *pdwDataLen,       // in, out
  DWORD dwFlags            // in
);

Parameters

hProv
Handle to a particular key container within the CSP. This handle is obtained by a call to CPAcquireContext.
hHash
Handle to the target hash object on which a query is being made.
dwParam
Parameter number. The following table lists currently defined dwParam values and their meanings.
Value | Return contents of the pbData buffer
HP_ALGID | An algorithm specifier (ALG_ID) indicating the algorithm used by this hash object is copied to the pbData buffer. A value 4 is returned in pdwDataLen.
HP_HASHSIZE | A DWORD specifying the number of bytes in the hash value produced by this hash object is returned in the pbData buffer. A value 4 is returned in pdwDataLen.
HP_HASHVALUE The hash computed value for the hash object specified by hHash is returned in the pbData buffer. The length of the hash value should be returned in pdwDataLen.

The call to CPGetHashParam function completes the hash. After this call, no more data can be added to the hash. Additional calls to CPHashData or CPHashSessionKey must fail. However, additional calls to CPDeriveKey, CPGetHashParam, CPSignHash, and CPVerifySignature succeed and use the completed hash object.

Parameters can be added as needed. General-purpose parameters can be define in coordination with Microsoft to promote cross-vendor standardization and allow the new parameter numbers to be added to the standard Microsoft Win32® header files.

pbData
Pointer to a data buffer. The dwParam parameter specifies the type of data to be copied to this buffer.

It is not an error if this parameter is NULL. If pbData is NULL, no parameter data is copied. Instead, the required buffer size (in bytes) is returned in pdwDataLen and a second call to the function with the correct number of bytes allocated for the pbData buffer is expected. See Retrieving Data of Unknown Length for a detailed discussion and examples.

pdwDataLen
Address of a DWORD. Upon function entry, this DWORD contains the number of bytes allocated in the pbData buffer. Upon exit, this must be set to the number of bytes need for the pbData buffer.

If the buffer specified by pbData is not large enough to hold the requested data, the ERROR_MORE_DATA error code is returned by the SetLastError function. In this case, the required buffer size must be returned in pdwDataLen.

If this function fails with any error code other than ERROR_MORE_DATA, zero is returned in this parameter.

dwFlags
No flags are currently defined.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
ERROR_MORE_DATA | The pbData buffer is not large enough to hold the requested data.
NTE_BAD_FLAGS | The dwFlags parameter is non-zero.
NTE_BAD_HASH | The hash object specified by the hHash parameter is invalid.
NTE_BAD_TYPE | The dwParam parameter specifies an unknown parameter number.
NTE_BAD_UID | The CSP context that was specified when the hash was created cannot now be found.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPCreateHash, CPGetKeyParam, CPSetHashParam, CryptGetHashParam


CPHashData

The CPHashData function feeds data into a specified hash object.

BOOL CPHashData(
  HCRYPTPROV hProv,       // in
  HCRYPTHASH hHash,       // in
  CONST BYTE *pbData,     // in
  DWORD dwDataLen,        // in
  DWORD dwFlags           // in
);

Parameters

hProv
Handle to a particular key container within the CSP. This handle is obtained by a call to CPAcquireContext.
hHash
Handle to a hash object. An application obtains this handle by using the CryptCreateHash function.
pbData
Address of a buffer containing the data to be hashed.
dwDataLen
Number of bytes of data to be hashed. This must be zero if dwFlags is set to CRYPT_USERDATA.
dwFlags
The following value is currently defined:
CRYPT_USERDATA
The CSP must prompt the user to enter directly the data to be added to the hash. Any data entered is used and destroyed within this function and the application has no access to it. This flag can be used to allow the user to enter a PIN, a password, or other unique identification into the system. Support for this flag is optional.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
NTE_BAD_ALGID | The hHash handle specifies an algorithm that this CSP does not support.
NTE_BAD_FLAGS | The dwFlags parameter contains an invalid value.
NTE_BAD_HASH | The hash object specified by the hHash parameter is invalid.
NTE_BAD_HASH_STATE | An attempt was made to add data to a hash object that is already marked as "finished."
NTE_BAD_KEY | A keyed hash algorithm is being used, but the session key is no longer valid. This error will be generated if the session key is destroyed before the hashing operating is complete.
NTE_BAD_LEN | The CRYPT_USERDATA flag is set, and the dwDataLen parameter has a non-zero value.
NTE_BAD_UID | The CSP context that was specified when the hash object was created cannot now be found.
NTE_FAIL | The function failed in some unexpected way.
NTE_NO_MEMORY | The CSP ran out of memory during the operation.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPCreateHash, CPHashSessionKey, CryptHashData


CPHashSessionKey

The CPHashSessionKey function feeds a cryptographic key to a specified hash object. This allows a key to be hashed without the application having access to the key material.

BOOL CPHashSessionKey(
  HCRYPTPROV hProv,      // in
  HCRYPTHASH hHash,      // in
  HCRYPTKEY hKey,        // in
  DWORD dwFlags          // in
);

Parameters

hProv
Handle to a particular key container within the CSP. This handle is obtained by a call to CPAcquireContext.
hHash
Handle to a hash object. An application obtains this handle by using the CryptCreateHash function (in the CryptoAPI).
hKey
Handle to the session key object to be hashed.
dwFlags
The following dwFlags value is defined:
CRYPT_LITTLE_ENDIAN
Bytes of the key will be hashed in a little-endian form. The Microsoft Cryptographic Providers support this flag in Microsoft Internet Explorer version 4.0 and later, Windows 98, and Windows 2000.

Note By default (dwFlags is 0) the bytes of the key are hashed in a big-endian form.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
NTE_BAD_ALGID | The hHash handle specifies a hash algorithm that this function does not support.
NTE_BAD_FLAGS | The dwFlags parameter is non-zero.
NTE_BAD_HASH | The hash object specified by the hHash parameter is invalid.
NTE_BAD_HASH_STATE | An attempt was made to add data to a hash object that is already marked as "finished."
NTE_BAD_KEY | A keyed hash algorithm is being used, but the session key is no longer valid. This error will be generated if the session key passed to CPCreateHash is destroyed before the hashing operating is complete.
NTE_BAD_UID | The CSP context that was specified when the hash object was created cannot now be found.
NTE_FAIL | The function failed in some unexpected way.

Remarks

The only data this function adds to the hash object is the session key material, itself. If necessary, an application, not the CSP, can hash the key's salt, initialization vector, and other hash state material. Depending on the CSP type, the key material might need to be formatted or padded in some specific way before being added to the hash. See CSP Interoperability for more details.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPCreateHash, CPGenKey, CPHashData, CryptHashSessionKey


CPSetHashParam

The CPSetHashParam function customizes the operations of a hash object.

BOOL CPSetHashParam(
  HCRYPTPROV hProv,     // in
  HCRYPTHASH hHash,     // in
  DWORD dwParam,        // in
  BYTE *pbData,         // in
  DWORD dwFlags         // in
);

Parameters

hProv
Handle to a particular key container within the CSP. This handle is obtained by a call to CPAcquireContext.
hHash
Handle to the hash object on which to set parameters.
dwParam
The following defined dwParam parameter value can be set:
HP_HASHVAL
The pbData buffer contains a BYTE array to be added to the hash object. This data must be of the same size and format as the hash value returned by the CPGetHashParam function. This data is placed directly into the hash object.

Typically, the hash object specified by hHash will be empty. If this is not the case, an error can be returned.

This parameter gives applications the ability to sign hash values, without having access to the base data. Because the application and the user have no idea what is being signed, this operation is intrinsically risky. It is envisioned that most CSPs will not support this parameter.

Parameters can be added as needed. General-purpose parameters can be define in coordination with Microsoft to promote cross-vendor standardization and allow the new parameter numbers to be added to the standard Win32 header files.

pbData
Parameter data buffer. Upon entry to the function, this buffer will contain the data that corresponds to the dwParam parameter number. Notice that the length of this data is not explicitly specified but is implied by the dwParam parameter value.
dwFlags
No flags are currently defined.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
NTE_BAD_FLAGS | The dwFlags parameter is non-zero or the pbData buffer contains an invalid value.
NTE_BAD_HASH | The hash object specified by the hHash parameter is invalid.
NTE_BAD_TYPE | The dwParam parameter specifies an unknown parameter.
NTE_BAD_UID | The CSP context that was specified when the hKey key was created cannot now be found.
NTE_FAIL | The function failed in some unexpected way.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPCreateHash, CPGetHashParam, CPSignHash, CryptSetHashParam


CPSignHash

The CPSignHash function signs a hash object.

BOOL CPSignHash(
  HCRYPTPROV hProv,           // in
  HCRYPTHASH hHash,           // in
  DWORD dwKeySpec,            // in
  LPCWSTR sDescription,       // in
  DWORD dwFlags,              // in
  BYTE *pbSignature,          // out
  DWORD *pdwSigLen            // in, out
);

Parameters

hProv
Handle to a particular key container within the CSP. This handle is obtained by a call to CPAcquireContext.
hHash
Handle to the hash object to be signed.
dwKeySpec
Type of the key pair to be used to sign the hash. The following values are currently defined.
Value | Meaning
AT_KEYEXCHANGE | The key exchange public/private key pair is to be used.
AT_SIGNATURE | The digital signature public/private key pair is to be used.

sDescription
A NULL-terminated string with a description of the hash object to be signed. See the Remarks section for details.

The use of this parameter is not recommended because of security vulnerabilities. It is recommended that it always be interpreted as set to NULL. Some CSPs might prefer to keep supporting it for backward compatibility with the Microsoft Cryptographic Service Providers.

dwFlags
The following value is defined for use with RSA providers.
CRYPT_NOHASHOID
The hash object identifier (OID) is not placed into the RSA public key encryption. If this flag is not set, the hash OID in the default signature is as specified in the definition of DigestInfo in PKCS #7.

The Microsoft cryptographic providers support this flag in Windows 2000. This support is not included with Windows 98 or Internet Explorer 5.0 or later.

pbSignature
Pointer to a data buffer into which the signature data is to be placed.

It is not an error if this parameter is NULL. If pbData is NULL, no parameter data is copied. Instead, the required buffer size (in bytes) is returned in pdwSigLen and a second call to the function with the correct number of bytes allocated for the pbData buffer is expected. For a detailed discussion and examples, see Retrieving Data of Unknown Length.

pdwSigLen
Address of a DWORD value of the signature data length. Upon function entry, this DWORD value contains the number of bytes allocated for the pbSignature buffer. Upon exit, it is set to the number of bytes required for the pbSignature buffer.

If memory allocated for the pbSignature buffer is not large enough to hold the signature, the ERROR_MORE_DATA error code is returned by the SetLastError function. The required buffer size is returned in pdwDataLen.

If this function fails with any error code other than ERROR_MORE_DATA, zero is returned in this parameter.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
ERROR_MORE_DATA | The pbData buffer is not large enough to hold the requested data.
NTE_BAD_ALGID | The hHash handle specifies a hash algorithm that this function does not support.
NTE_BAD_FLAGS | The dwFlags parameter is non-zero.
NTE_BAD_HASH | The hash object specified by the hHash parameter is invalid.
NTE_BAD_UID | The CSP context that was specified when the hash object was created cannot now be found.
NTE_NO_KEY | The private key specified by dwKeySpec does not exist.
NTE_NO_MEMORY | The CSP ran out of memory during the operation.

Remarks

Depending on the key pair to be used, many CSPs ask the user directly before performing the signature operation. When this is the case, the sDescription string, if supported, is displayed to the user so that he or she knows what is being signed.

CPSignHash typically performs the following steps internally:

  1. The hash object is "finished," and the hash value extracted.
  2. The hash value is padded out as required by the signature algorithm.
  3. The actual signing operation is performed.

The CPSignHash function completes the hash. After calling CPSignHash, no more data can be added to the hash. Additional calls to CPHashData or CPHashSessionKey fail. However, additional calls to CPDeriveKey, CPGetHashParam, CPSignHash, and CPVerifySignature succeed and use the finished hash object.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPCreateHash, CPHashData, CPVerifySignature, CryptSignHash


CPVerifySignature

The CPVerifySignature function verifies the digital signature.

BOOL CPVerifySignature(
  HCRYPTPROV hProv,         // in
  HCRYPTHASH hHash,         // in
  CONST BYTE *pbSignature,  // in
  DWORD dwSigLen,           // in
  HCRYPTKEY hPubKey,        // in
  LPCWSTR sDescription,     // in
  DWORD dwFlags             // in
);

Parameters

hProv
Handle to a particular key container within the CSP. This handle is obtained by a call to CPAcquireContext.
hHash
Handle to the hash object to be verified.
pbSignature
Buffer containing the signature data.
dwSigLen
Length (in bytes) of the signature data.
hPubKey
Handle to the public key used to verify the signature.
sDescription
A NULL-terminated string with a description of the hash object.

The use of this parameter is not recommended because of security vulnerabilities. It is recommended that it always be interpreted as set to NULL. Some CSPs might prefer to keep supporting it for backward compatibility with the Microsoft Cryptographic Service Providers.

dwFlags
The following value is defined for RSA providers:
CRYPT_NOHASHOID
The hash object identifier (OID) is not expected to be present and is not checked. If this flag is not set, the hash OID in the default signature is verified as specified in the definition of DigestInfo in PKCS #7. Details of the PKCS standards can be found on the RSA Security Standards Web page, www.rsasecurity.com.

The Microsoft cryptographic providers support this flag in Windows 2000. This support is not included with Windows 98 or Internet Explorer 5.0 or later.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE, and the appropriate error code from the following table must be set using SetLastError.

Error | Description
NTE_BAD_FLAGS | The dwFlags parameter is non-zero.
NTE_BAD_HASH | The hash object specified by the hHash parameter is invalid.
NTE_BAD_KEY | The hPubKey parameter does not contain a handle to a valid public key.
NTE_BAD_SIGNATURE | The signature failed to verify. This could be because the data itself has changed, the description string did not match, or the wrong public key was specified by hPubKey. This error might also be returned if the hashing or signature algorithms do not match the ones used to create the signature.
NTE_BAD_UID | The CSP context that was specified when the hash object was created cannot now be found.
NTE_NO_MEMORY | The CSP ran out of memory during the operation.

Remarks

The CPVerifySignature function typically performs the following steps internally:

  1. The sDescription description string, if supported, is added to the hash object.
  2. The hash object is "finished," and the hash value extracted.
  3. The hash value is padded out as required by the signature algorithm.
  4. The actual verification operation is performed by using the hPubKey public key. The NTE_BAD_SIGNATURE error code is returned if the signed hash within the pbSignature buffer and the hash value in the hHash hash object do not match.

CPVerifySignature completes a hash. After CPVerifySignature has been called, no more data can be added to the hash. Additional calls to CPHashData or CPHashSessionKey fail. However, additional calls to CPDeriveKey, CPGetHashParam, CPSignHash, and CPVerifySignature succeed and use the finished hash object.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.

See Also

CPCreateHash, CPHashData, CPSignHash, CryptVerifySignature


CSP Auxiliary Functions

Functions in this section are used within a CSP's functions.

  • OffloadModExpo


OffloadModExpo

The OffloadModExpo function offloads modular exponentiation from a CSP to a hardware accelerator.

BOOL WINAPI OffloadModExpo(
  BYTE *pbBase,    // in
  BYTE *pbExpo,    // in
  DWORD cbExpo,    // in
  BYTE *pbMod,     // in
  DWORD cbMod,     // in
  BYTE *pbResult,  // out
  void *pReserved, // reserved
  DWORD dwFlags    // in
);

Parameters

pbBase
Pointer to the base value to be exponentiated. The value is in little-endian form and the length (number of bytes in the value) must be the length passed in cbMod. The value must be padded with 0x00 bytes if the most significant byte does not have a bit set. This value must be less than the value passed in the pbMod parameter.
pbExpo
Pointer to the exponent the base value is to be raised to. The value is in little-endian form and the length (number of bytes in the value) must be the length passed in cbMod. The value must be padded with 0x00 bytes if the most significant byte does not have a bit set. This value must be less than the value passed in the pbMod parameter.
cbExpo
DWORD value representing the length of the exponent in bytes.
pbMod
Pointer to the modulus. The value is in little-endian form and the length (number of bytes in the value) must be the length passed in cbMod. The most significant byte of the modulus value must not be a 0x00 byte.
cbMod
DWORD value representing the length of the modulus in bytes.
pbResult
Pointer to the calculated result.
pReserved
This parameter is reserved for future use and is set to NULL.
dwFlags
This parameter is reserved for future use and is set to NULL.

Return Values

If the function succeeds, the return value is TRUE.

If the function fails, the return value is FALSE. To retrieve extended error information, call GetLastError.

Remarks

A CSP will check in the registry for the value HKLM\Software\Microsoft\Cryptography\Offload\ExpoOffload that can be the name of a DLL. The CSP uses LoadLibrary to load that DLL and calls GetProcAddress to get the OffloadModExpo entry point. The CSP uses the entry point to perform all modular exponentiations for both public and private key operations.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Wincrypt.h.


CSP Structures and Types

This section describes the following structures and defined types

  • PROV_ENUMALGS
  • PROV_ENUMALGS_EX
  • VTableProvStruc
  • BLOBHEADER


PROV_ENUMALGS

The PROV_ENUMALGS structure is returned by calls to CryptGetProvParam or CPGetProvParam. It holds information on the algorithms supported by a CSP.

typedef struct _PROV_ENUMALGS {
    ALG_ID    aiAlgid;
    DWORD     dwBitLen;
    DWORD     dwNameLen;
    CHAR      szName[20];
} PROV_ENUMALGS;

Members

aiAlgid
An ALG_ID indicating an algorithm supported.
dwBitLen
A DWORD value indicating the length of the key.
dwNameLen
A DWORD value indicating the length of the name of the algorithm.
szName
A NULL-terminated sting containing the name of the algorithm.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.


PROV_ENUMALGS_EX

The PROV_ENUMALGS_EX structure is returned by calls to CryptGetProvParam or CPGetProvParam. It holds information on the algorithms supported by a CSP.

typedef struct _PROV_ENUMALGS_EX
{
    ALG_ID    aiAlgid;
    DWORD     dwDefaultLen;
    DWORD     dwMinLen;
    DWORD     dwMaxLen;
    DWORD     dwProtocols;
    DWORD     dwNameLen;
    CHAR      szName[20];
    DWORD     dwLongNameLen;
    CHAR      szLongName[40];
} PROV_ENUMALGS_EX;

Members

aiAlgid
An ALG_ID identifying an algorithm supported.
dwDefaultLen
A DWORD value indicating the default key length using the indicated algorithm.
dwMinLen
A DWORD value indicating the minimum key length using the indicated algorithm.
dwMaxLen
A DWORDvalue indicating the maximum key length using the indicated algorithm.
dwProtocols
A DWORD value indicating the number of protocols supported.
dwNameLen
A DWORD value indicating the length of the short protocol name.
szName
A NULL-terminated string with the name of the supported protocol.
dwLongNameLen
A DWORD value indicating the length of the supported protocol name.
szLongName
A NULL-terminated string with the long name of the supported protocol.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.


VTableProvStruc

The VTableProvStruc structure contains pointers to callback functions that can be used by CSP functions.

typedef struct _VTableProvStruc {
    DWORD    Version;
    FARPROC  FuncVerifyImage;
    FARPROC  FuncReturnhWnd;
    DWORD    dwProvType;
    BYTE     *pbContextInfo;
    DWORD    cbContextInfo;
    LPSTR    pszProvName;
} VTableProvStruc, *PVTableProvStruc;
BOOL FuncVerifyImage(LPCSTR lpszImage, BYTE *pSigData);
BOOL FuncReturnhWnd(DWORD *phWnd);

Members

Version
A DWORD value indicating the version of the structure. Three versions of this structure are used. Microsoft® Windows NT® version 4.0 and Microsoft® Windows® 95 use version 1, which consists of only the first three members: Version, FuncVerifyImage, and FuncReturnhWnd.

Version 2 is available with Windows 98. The first six members are used. Version 3 is available with Windows 2000. It includes all seven members.

FuncVerifyImage
Pointer to a callback function to verify a signature. See Remarks for details.
FuncReturnhWnd
Pointer to a callback function that returns information on a window handle to use when interacting directly with the user using Microsoft® Win32®. CSPs that do not communicate directly with the user and CSPs that use dedicated hardware for this purpose can ignore this entry. This window handle is zero by default, but some applications will set it to a different value by using the CryptSetProvParam function.
dwProvType
A DWORD value that specifies the type of provider to acquire. The following provider types are predefined, and are discussed in detail in CSP Interoperability .
  • PROV_RSA_FULL
  • PROV_RSA_SIG
  • PROV_DSS
  • PROV_FORTEZZA
  • PROV_MS_EXCHANGE
pbContextInfo
Pointer to an array of context information. The pbContextInfo and cbContextInfo members together determine the information set used when a CPSetProvParam is called with PP_CONTEXT_INFO set.
cbContextInfo
DWORD value indicating the number of elements in the pbContextInfo array.
pszProvName
String containing the name of the provider.

Remarks

The pointers in the VTableProvStruc structure are only available within the CPAcquireContext function. If members of the structure are needed after a call to CPAcquireContext is completed, copies of the needed structure elements must be made by the CSP. The function pointers in the structure can be copied and the function pointer can be used until the context is released.

All auxiliary DLLs into which a CSP makes function calls must be signed in the same manner (and with the same key) as the primary CSP DLL. To make this work properly, the auxiliary DLLs must be loaded dynamically, using the LoadLib function. But before LoadLib is called, the signature of the DLL must be verified. The CSP does this verification by calling the FuncVerifyImage function, as illustrated in the following code fragment:

BOOL (FARPROC *ProvVerifyImage)(LPCSTR lpszImage, BYTE *pSigData);
BYTE bSignature[72];

// "ProvVerifyImage" has been set to "pVTable->FuncVerifyImage"
// within the CPAcquireContext function.

// Load the C:\Winnt40\System32\signature.sig file into the
// bSignature buffer. During development, this file is created
// with the Sign.exe utility.
...

// Verify the signature on the C:\Winnt40\System32\Signature.dll file.
if(RCRYPT_FAILED(ProvVerifyImage("c:\\winnt40\\system32\\signature.dll",
                                 bSignature)) {
    SetLastError(NTE_BAD_SIGNATURE);
    return CRYPT_FAILED;
}

// Load the DLL with the LoadLib function, then acquire pointers to
// the member functions with the GetProcAddress function.
...

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.


BLOBHEADER

The BLOBHEADER structure indicates a key's BLOB type and the algorithm that the key uses. One of these structures is located at the beginning of the pbData member of every key BLOB.

This structure is not limited to the key BLOBs generated by the PROV_RSA_BASE and PROV_RSA_SIG provider types. The pbData member of any new key BLOB type must begin with this structure.

typedef struct _PUBLICKEYSTRUC {
    BYTE   bType;
    BYTE   bVersion;
    WORD   reserved;
    ALG_ID aiKeyAlg;
} BLOBHEADER, PUBLICKEYSTRUC;

Members

bType
Key BLOB type. The only BLOB types currently defined are PUBLICKEYBLOB, PRIVATEKEYBLOB, SIMPLEBLOB, and SYMMETRICWRAPKEYBLOB. Other key BLOB types will be defined as needed.

PUBLICKEYBLOBs are used to transport public keys, PRIVATEKEYBLOBs are used to transport public/private key pairs, SIMPLEBLOBs are used to transport session keys, and SYMMETRICWRAPKEYBLOBs are used to export and import a symmetric key wrapped with another symmetric key.

bVersion
Version number of the key BLOB format. This currently must always have a value of 0x02.
reserved
Reserved for future use. Must be set to zero.
aiKeyAlg
Algorithm identifier for the key contained by the key BLOB. Some examples are CALG_RSA_SIGN, CALG_RSA_KEYX, CALG_RC2, and CALG_RC4. Not all algorithm identifiers are valid with all BLOB types. For example, because an RC4 key is a session key, it cannot be exported into a PUBLICKEYBLOB.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later).
Header: Declared in Wincrypt.h.


CSP Constants

Cryptographic service providers use the following constants defined in Wincrypt.h:

Protocol Flags


Protocol Flags

Flag constant | Value
CRYPT_FLAG_PCT1 | 0x0001
CRYPT_FLAG_SSL2 | 0x0002
CRYPT_FLAG_SSL3 | 0x0004
CRYPT_FLAG_TLS1 | 0x0008


Schannel CSP Reference

CSPs written for both RSA/Schannel and Diffie-Hellman/Schannel protocols must implement all of the CP functions that all other CSPs must implement. In addition, CSPs that support these protocols must also deal with extensions for working with master keys and deriving bulk encryption/decryption and MAC keys from these master keys. The following topics deal with these function extensions:

  • CPCreateHash Schannel Extensions
  • CPDeriveKey Schannel Extensions
  • CPGetProvParam Schannel Extensions
  • CPHashSessionKey Schannel Extensions
  • CPSetKeyParam Schannel Extensions


CPCreateHash Schannel Extensions

The CPCreateHash function for RSA/Schannel must implement the CALG_SSL3_SHAMD5 Algid parameter. Both RSA/Schannel and Diffie-Hellman/Schannel protocols must implement the CALG_SCHANNEL_MASTER_HASH Algid.


CALG_SSL3_SHAMD5

This functionality must be implemented as it is implemented with the Microsoft Base Cryptographic Provider. For details on the contents and structure of this hash, see also SHA/MD5 RSA Signature Type.


CALG_SCHANNEL_MASTER_HASH

A master hash is created from the master key before deriving bulk encryption keys with a call to CPCreateHash:

CPCreateHash(
        hProv,
        CALG_SCHANNEL_MASTER_HASH,
        hMasterKey,
        0,
        &hMasterHash);

The master hash must not maintain a reference to the master key. All relevant data associated with the master key must be copied to the master hash object.

Depending on the protocol, the CSP implements the following operations within CPCreateHash.

PCT1

No key generation activities are implemented within this function. All key generation is done within CPDeriveKey.

SSL2

This function creates a key block from which the session keys are created. This key block is later used to create the respective session keys using CPDeriveKey. See the SSL 2 specification for a description of this key generation.

SSL 3.0

The key passed into this function as hMasterKey is not the master key but rather a pre-master key from which the master key is created. See the SSL 3.0 specification. This pre-master key is used to generate the master key using the following formula:

        master_key =
           MD5(
                pre_master_key +
                SHA(
                   'A' +
                   pre_master_key+
                   ClientHello.random +
                   ServerHello.random
                    )
                ) +
           MD5(
                pre_master_key +
                SHA(
                   'BB' +
                    pre_master_key +
                    ClientHello.random +
                    ServerHello.random
                    )
                ) +
           MD5(
                pre_master_key +
                SHA(
                   'CCC' +
                   pre_master_key +
                   ClientHello.random +
                   ServerHello.random
                    )
                );

Note The master key, not the pre-master key, is hashed using CPHashSessionKey.

This function also creates the key block from which the session keys are created. This key block is later used to create the respective session keys with the CPDeriveKey function. The key block is created using the following formula:

        key_block =
            MD5(
                master_key +
                SHA(
                    'A' +
                     master_key +
                     ServerHello.random +
                     ClientHello.random
                    )
                ) +
            MD5(
                master_key +
                SHA(
                    'BB' +
                    master_key +
                    ServerHello.random +
                    ClientHello.random
                    )
                 ) +
            MD5(
                 master_key +
                 SHA(
                    'CCC' +
                    master_key +
                    ServerHello.random +
                    ClientHello.random)) + [...];

TLS 1.0

The key passed into this function as hMasterKey is not the master key but rather a pre-master key from which the master key is created. See the TLS 1.0 specification. This pre-master key is used to generate the 48-byte master key using the following formula:

          master_key =
               PRF(
                  pre_master_key,
                  "master secret",
                  ClientHello.random +
                  ServerHello.random) [0..47];

This function creates the key block from which the session keys are created. This key block is later used to create the respective session keys with the CPDeriveKey function. For details, see the SSL 3.0 specification. The key block is created using the following formula:

          key_block =
               PRF(
                    SecurityParameters.master_key,
                    "key expansion",
                    SecurityParameters.server_random +
                         SecurityParameters.client_random
                   );

Note The master key, not the pre-master key, is hashed using CPHashSessionKey.


CPDeriveKey Schannel Extensions

For Schannel protocols, CPDeriveKey must implement all of its normal functionality but must also derive bulk encryption and MAC keys from the master hash object created by CPCreateHash. This is done using CPDeriveKey with one of the following algorithm identifiers (ALG_IDs):

  • CALG_SCHANNEL_ENC_KEY
  • CALG_SCHANNEL_MAC_KEY

If the CRYPT_SERVER flag is set in the dwFlags parameter, the key to be generated is a server write key; otherwise, it is a client write key.

See also Deriving Bulk Encryption and MAC Keys.

CALG_SCHANNEL_ENC_KEY

Generate a bulk encryption key. The algorithm and key size have previously been specified using CPSetKeyParam including some extensions discussed in CPSetKeyParam Schannel Extensions.

The CSP must create the initialization vector (IV) automatically.

CALG_SCHANNEL_MAC_KEY

Generate a MAC key. The algorithm has been previously been specified using CPSetKeyParam. Details may also be found in CPSetKeyParam Schannel Extensions.


CPGetProvParam Schannel Extensions

CPGetProvParam in a CSP used with Schannel protocols must support all of the normal functionality of CPGetProvParam and also the PP_ENUMALGS_EX parameter as described in Enumerating Supported Protocols.


CPHashSessionKey Schannel Extensions

CPHashSessionKey in a CSP used with Schannel protocols must support all of the normal functionality of CPHashSessionKey. In addition, it must support the CRYPT_LITTLE_ENDIAN flag. When this flag is set, the key is hashed in reverse order.


CPSetKeyParam Schannel Extensions

The CPSetKeyParam function in CSPs that support Schannel protocols must implement all of the normal functionality of CSSetKeyParam. In addition, it must support several new parameters.

The following new parameters are valid when used with a master key and can be set multiple times on the same master key. If a parameter is set multiple times, at each re-setting, the old value is discarded and replaced with the new value.

The following dwParam parameters have been added.

dwParam | Description
KP_SCHANNEL_ALG | Set the bulk encryption, MAC algorithms, and key sizes derive the master key. The use of this parameter is shown in Specifying the Algorithms.
KP_CLIENT_RANDOM | For PCT, set the challenge data. For SSL 3.0, TLS 1.0, and Diffie-Hellman, set the "client random" data. This parameter is not used with SSL 2.0. In all cases, the data is 32 bytes long.
KP_SERVER_RANDOM | For PCT, set the "connection id" data. For SSL 3.0, TLS 1.0, and Diffie-Hellman, set the "server random" data. For PCT, SSL 3.0, and TLS 1.0, the data originates in the "ClientHello" message. This parameter is not used with SSL 2.0. In all cases, the data is 32 bytes long.
KP_CERTIFICATE | This parameter is used only with PCT. It sets the "server certificate" data.
KP_ALGID | For use with Diffie-Hellman. Change the key from an agreed key to a required pre-master secret key. Two new algorithm types have been added for use with this value: CALG_SSL3_MASTER and CALG_TLS1_MASTER.


Other CSP Topics

Other CSP topics include:

  • Microsoft's CSP Signing Policy
  • Export Compliance Certificate (ECC)


Microsoft's CSP Signing Policy

Microsoft's interest in the CSP signing process is to maintain the integrity of system security and the exportability of CryptoAPI-enabled systems and applications, and to exercise due diligence under prevailing U.S. export controls. The CSP signing policy makes several major distinctions based on Microsoft's obligations under U.S. export law. First, it distinguishes between CSPs developed in the United States and Canada from those developed elsewhere. Second, it distinguishes between CSPs intended for sale or distribution within the U.S. or Canada only from those intended for export or sale outside the U.S. and Canada. Generally the signing policy requirements for CSPs intended for use only within the U.S. and Canada are fewer than for CSPs intended for export; and because U.S. export law restricts the export of any encryption technology or services, the requirements and restrictions on CSPs from vendors outside the U.S. and Canada intended for use outside the U.S. and Canada are greater still. Each of these scenarios is described in greater detail in the following sections.

Microsoft will sign CSPs subject only to the limitations of U.S. export controls. We will sign CSPs from competitors. At present, we will sign CSPs at our facilities in Redmond, Washington, USA.


CSP Signing Program - Limitations and Provisos (All Vendors)

Microsoft's interests in applying signatures to CSPs are

  • To maintain the integrity of system security
  • To ensure the exportability of CryptoAPI-enabled systems and applications
  • To exercise due diligence under prevailing U.S. and other national export controls.

Any disclosure requested by Microsoft is used solely to determine whether export approval is required, or if sufficient export approval exists, for Microsoft to sign a vendor's CSP.

Microsoft obtains no right to any CSP by virtue of signing it. Neither does Microsoft assume any responsibility for the CSPs signed. The CSP vendor is wholly responsible for the distribution, disposition and possible end-use of its CSPs, including any possible export or diversion of CSPs outside the U.S. and Canada or licensed destinations.

Microsoft relies on the CSP vendor's completion of the ECC, CSPDK Export Questionnaire and other documents as to the intended distribution, disposition and use of the CSP in or out of the U.S. and Canada, and as an assurance that the vendor will exercise due diligence over the operation, sale, or transfer of its CSP using CryptoAPI. If a vendor's intention changes after a CSP is signed (for example, it opts to export a CSP signed by Microsoft with the understanding that the CSP was for use in the U.S. and Canada only), the vendor is responsible for compliance with U.S. export regulations.

The digital signature applied to CSPs in no way grants U.S. export approval or any other form of legal approval for use of a CSP in any national or international context. In particular, Microsoft has no role in the U.S. export approval process of a CSP for a vendor from the U.S. or Canada: U.S. export approval (by license, classification, or exemption) is a separate requirement that CSP vendors must satisfy independently of the digital signature process, and it must precede the signature process when the CSP is intended for use outside the U.S. and Canada. Microsoft's involvement in U.S. export issues will be limited to applying for licenses to export to foreign vendors the CSPDK and to sign their CSPs, as well as to perform due diligence verification that licensed CSP vendors comply with the terms of any U.S. export license.

Microsoft cannot provide the CSPDK to, or sign CSPs from, any vendor who is engaged in a prohibited activity, who is from a prohibited destination, or who is a prohibited party as defined by U.S. law (including the Export Administration Regulations and International Traffic in Arms Regulations). U.S. export laws prohibit Microsoft from providing the CSPDK or signing any CSP if we have reason to know that a given vendor may intentionally violate U.S. export laws, despite a written assurance to the contrary.

The description of U.S. export controls in this section is provided for general information purposes only. This document reflects the U.S. export laws and CSP signing program in effect as of April 1997. Export laws are subject to rapid change; therefore this document may not accurately represent current export law. Please consult legal counsel and the appropriate export control agencies to ensure compliance with U.S. and local export laws.


CSP Signing Policy - North American CSP Vendors

CSP vendors pursuing CSP development within the United States and Canada must complete and return an Export Compliance Certificate (ECC) to Microsoft. Microsoft will make every effort to review the ECC and sign CSPs as expeditiously as possible. Exact time frames for review and signing depend on the circumstances of your request. A copy of the ECC is included at the end of this section.

North America Only CSP To distribute a CSP only inside the U.S. and Canada, complete the ECC and certify that the CSP will be distributed only in the U.S. or Canada. Return the ECC to Microsoft. When Microsoft has had a chance to review and verify the ECC, Microsoft will return information on arrangements to sign the CSP.

CSP Intended for Export To export a CSP, export approval from a U.S. or Canadian export licensing authority or claim an exemption under U.S. export law must be obtained. The completed ECC must contain evidence of export approval or exemption, and certify that the CSP is intended for export outside the U.S. or Canada. Return the ECC to Microsoft. Microsoft may independently confirm export approval, and when confirmation is complete, will return information on arrangements to sign the CSP.

Vendors should consult legal counsel or U.S. export authorities to determine whether an export approval or exemption applies to their CSP. For more information, see Background - U.S. Export Controls and CryptoAPI later in this section.

Note for Canadian CSP vendors Because Canadian export controls are not entirely consistent with U.S. export controls; U.S. and Canadian export authorities might need to agree whether a given CSP should be signed. Therefore an approval to export from Canada might not be sufficient for Microsoft to sign the CSP.

Before Microsoft applies a digital signature to any CSP - whether it is intended for use in the United States and Canada or elsewhere - Microsoft must receive an original, signed ECC. However, Microsoft can initiate review and confirm export approval against a fax copy of the complete ECC.

Ordinarily, Microsoft does not need to receive the actual CSP to complete signing, but can sign a message hash of the CSP itself. A U.S. export license or other export approval for a CSP intended for export might require independent or government verification of the CSP's implemented security features prior to signing. Getting this verification is the responsibility of the CSP vendor.


CSP Signing Policy - CSP Vendors outside North America

This section assumes that a CSP vendor from outside the U.S. and Canada has already received the CSPDK under an appropriate U.S. export license. Vendors who have not yet received the CSPDK can contact Microsoft (cspsign@microsoft.com) for information on the CSPDK license process.

Because all of the required certifications are completed during the U.S. export license process, when a CSP vendor from outside the U.S. and Canada is ready to have a CSP signed, it is not necessary to complete an Export Compliance Certificate or other documentation. These vendors can notify Microsoft when they are ready, or preferably notify Microsoft approximately two to three weeks prior to when the CSP may be ready to sign. Microsoft will use the time to verify the request against any possible terms and conditions of the export license covering the CSP development. When confirmation is complete, Microsoft will return information on arrangements to sign the CSP.

A U.S. export license or other export approval for a CSP intended for export might require independent or government verification of the CSP's implemented security features prior to signing, which would be the responsibility of the CSP vendor. It may also be a condition of the U.S. export license that Microsoft receives the actual CSP for signing, and not just a hash.

At present Microsoft will sign CSPs at its facilities in Redmond, Washington, USA. In the future Microsoft might sign CSPs at approved locations in foreign countries, at which time Microsoft will offer CSP vendors from outside the U.S. and Canada the option of offshore signing.

In summary, Microsoft will sign CSPs for vendors outside the U.S. and Canada subject to the limitations of U.S. export controls and other national controls on this technology. Microsoft will sign CSPs from competitors. Microsoft will make every effort to review signing requests and sign CSPs as expeditiously as possible. Exact time frames for review of signing requests and CSP signing depend significantly on whether the U.S. export license permitting the CSP development set down any conditions for review or confirmation of the CSP's implemented security features.


Background - U.S. Export Controls and CryptoAPI

As of January 1, 1997, export of the CSPDK or provision of CSP signing services outside the United States is regulated under "EI controls" of the Export Administration Regulations (EAR, 15 CFR 730-744) of the U.S. Commerce Department, Bureau of Export Administration (BXA). EI controls are the current equivalent of ITAR munitions export controls that applied to the CSPDK and CSP signing services prior to January 1st. EI controls require a Commerce export license prior to any export, transmission, provision or shipment of the CSPDK product or CSP signing service to any country, other than Canada, or to any person, entity or end user subject to U.S. export restrictions. The Commerce export license process and EI controls are described on the BXA Web site at http://www.bxa.doc.gov/encstart.htm.


Export Status of CSPs

The export status of a specific CSP varies, but generally it is subject to review and approval on a case-by-case basis by the U.S. Commerce Department, Bureau of Export Administration.


CryptoAPI and the Microsoft Base Cryptographic Provider

Microsoft® Windows NT® with CryptoAPI and the Microsoft Base Cryptographic Provider was transferred from State to Commerce jurisdiction by ODTC Case CJ 128-95, and qualifies for export under License Exception TSU (formerly GTDU) and the General Software Note (GSN) listed in Supplement 2 to Part 774 of the U.S. Commerce Export Administration Regulations. A subsequent transfer covers Microsoft® Windows® 95 with CryptoAPI and the Base Cryptographic Provider. These products may be exported to all destinations and users except countries, persons, entities, or end users subject to U.S. export restrictions. Restricted countries currently include, but are not necessarily limited to, Cuba, Iran, Iraq, Libya, North Korea, Sudan and Syria. Restricted persons and entities include but are not necessarily limited to anyone whose export privileges have been suspended, revoked, or denied by the U.S. Bureau of Export Administration or any other federal agency.

U.S. export laws restrain Microsoft and other U.S. companies from offering or enabling strong data encryption in their products intended for export from the U.S. or Canada. Software with data encryption, or software with APIs to provide cryptographic services, are treated as highly restricted commodities. By prohibiting foreign sale of these products to all but a few entities outside the U.S. or Canada, the U.S. government limits distribution of such products to the U.S. and Canada and eliminates virtually all foreign markets for most vendors, thereby removing much of the incentive to implement these features in the first place. Generally speaking, U.S. export restrictions have been a very effective deterrent to the proliferation of strong encryption in mass-market software in the U.S. and abroad.

An open cryptographic API allowing any vendor to implement any CSP might be very useful to security providers, but it would make the host operating system with the cryptographic API ineligible for export from the U.S. or Canada. To ensure that CryptoAPI-enabled Microsoft operating systems are and will remain exportable, Microsoft does not permit open access to these APIs. Microsoft has implemented the CSP signing policy to meet the dual objectives of providing as many vendors as possible a secure and flexible approach to enabling cryptographic services, while maintaining the foreign availability of Microsoft operating systems.

The digital signature requirement separates possible export controls on the CSP from the host operating system and applications, thereby allowing broader distribution of encryption-enabled products than would be possible under other circumstances. The signature effectively prevents arbitrary use of CryptoAPI, which ensures the continued exportability of the host operating system. By removing encryption services from host systems and applications, the burden of U.S. encryption export restrictions is placed squarely on the cryptographic provider which is already subject to these controls with respect to any CSP it markets, whether or not the CSP functions through CryptoAPI.

Microsoft's program for distribution of the CSPDK and CSP signing policy are specifically designed to minimize the impact of U.S. export laws to the greatest extent we think is possible today: they specifically do not interfere with the development of CSPs for use in he U.S. or Canada; the CSP signing policy expects vendors to perform due diligence in the licensing of their CSPs when those CSPs are intended for export from the U.S. or Canada; and the CSPDK distribution program and CSP signing policy comply with existing U.S. export laws for the provision of encryption products (CSPDKs) and services (CSP signatures) to vendors outside the U.S. or Canada.


Export Compliance Certificate (ECC)

EXPORT COMPLIANCE CERTIFICATE

For CSP Signing Services to North American Vendors

WHO SHOULD COMPLETE THIS DOCUMENT The Export Compliance Certificate ("ECC") is intended for CSP vendors with operations in the U.S. or Canada (hereafter 'North America') pursuing CSP development within North America, who seek to have Microsoft or a third-party designated by Microsoft digitally sign a vendor's CSP to enable it to access the Microsoft CryptoAPI. If you are a vendor located outside North America an export license agreement or other arrangement may replace the ECC.

DISCLAIMER AND NOTICE This document is used solely to determine whether export approval is required, or if sufficient export approval exists, for Microsoft to sign CSPs. Microsoft's interests in applying signatures to CSPs are to maintain the integrity of system security, ensure the exportability of CryptoAPI-enabled systems and applications, and to exercise due diligence under prevailing U.S. and other national export controls. Microsoft obtains no right to any CSP by virtue of signing it. Neither do we assume any responsibility for the CSPs we sign. The CSP vendor is wholly responsible for the distribution, disposition and possible end-use of its CSPs, including any possible export or diversion of CSPs outside North America or licensed destinations. The digital signature applied to CSPs in no way grants U.S. export approval or any other form of legal approval for use of a CSP in any national or international context. Microsoft has no role in the U.S. export approval process of a vendor's CSP: U.S. export approval (by license, classification, or exemption) is a separate requirement that CSP vendors must satisfy independently of the digital signature process, and it must precede the signature process when the CSP is intended for use outside North America.

CSP SIGNING CRITERIA AND VENDOR INSTRUCTIONS Microsoft will sign CSPs subject only to the limitations of U.S. export controls. We will sign CSPs from competitors. Microsoft will make every effort to complete ECC review and sign CSPs as expeditiously as possible. Exact time frames for review and signing depend on the circumstances of your request. Ordinarily Microsoft does not need to receive the actual CSP to complete signing, but can sign a hash of the CSP itself.

  • North America Only CSP If you don't intend to distribute your CSP outside North America: complete the ECC and certify that you will distribute your CSP only in the U.S. or Canada. Return the ECC to Microsoft. When you are ready, make an appointment for Microsoft to sign your CSP.
  • CSP Intended for Export If you do plan to export your CSP: obtain export approval from a U.S. or Canadian export licensing authority, complete the ECC with evidence of your export approval and certify that you intend to export your CSP from the U.S. or Canada. Return the ECC to Microsoft. Microsoft may independently confirm export approval, and when confirmation is complete, we'll arrange an appointment for Microsoft to sign your CSP.

    Canadian CSP vendors should note that because Canadian export controls are not entirely consistent with U.S. export controls; U.S. and Canadian export authorities may need to agree whether a given CSP should be signed. Therefore an approval to export from Canada may or may not be sufficient for Microsoft to sign the CSP.

Sign and Return to Microsoft Before Microsoft signs any CSP it must receive an original signed ECC with sufficient information to evaluate the request. Return ECCs to Microsoft Corporation, Attn: Richard Harrington, One Microsoft Way, Redmond, WA 98052-6399. Questions? Email cspsign@microsoft.com.

SECTION I - GENERAL INFORMATION

All North American (U.S. and Canada) CSP vendors must complete this section.

A. VENDOR INFORMATION Please give the physical address where CSP development has taken or will take place.

B. CSP INFORMATION Please supply sufficient information to identify your CSP by name and to categorize its cryptographic functions. Provide a separate Export Compliance Certificate for each CSP you need signed.

C. INTENDED DISTRIBUTION FOR THIS CSP At the time of this certification the vendor intends the above-described CSP for distribution, disposition or use (check one):

SECTION II - EVIDENCE OF EXPORT APPROVAL

Complete this section only if the described CSP is intended for distribution outside of North America (U.S. and Canada). Otherwise skip to Section III. For export approval, consult legal counsel or relevant export authorities. Commerce export controls are described on their web site at http://www.bxa.doc.gov/encstart.htm.

A. EXPORT CONTROL JURISDICTION FOR THIS CSP Check one of the following:

B. EXPORT APPROVAL INFORMATION Check any type of export approval that you have obtained for this CSP and wish to cite as evidence of export approval. If the CSP is intended for use outside North America, Microsoft cannot sign the CSP without evidence of export approval. You may optionally attach a copy of your export license, CJ/CCATS confirmation, or other export approval. The export approval must correspond to the Product Name and Version cited above.

SECTION III - EXPORT NOTICES

Vendor must execute the signature portion of the ECC acknowledging US export controls as they may apply to their CSP, and attesting to the accuracy of the information they provide herein.

*EXPORT NOTICE FOR CSP VENDORS CERTIFYING THAT THEIR CSP IS FOR DISTRIBUTION, DISPOSITION, OR USE SOLELY IN NORTH AMERICA: CSP Vendor acknowledges that their CSP is subject to US export control laws and regulations. CSP Vendor certifies that it does not intend to export or re-export the CSP named above outside of North America. If the CSP Vendor subsequently decides to export the CSP outside of North America by any means (including physical or electronic distribution), CSP Vendor agrees to obtain U.S. export approval. CSP Vendor is wholly responsible for such export, distribution, disposition and possible end-use of their CSP outside of North America, including complying with all US export or other national controls over their CSP modules, and that Microsoft assumes no responsibility or liability for CSP Vendor's failure to obtain required export approvals.

**EXPORT NOTICE FOR CSP VENDORS CERTIFYING THAT THEIR CSP IS FOR DISTRIBUTION, DISPOSITION, OR USE OUTSIDE OF NORTH AMERICA: CSP Vendor acknowledges that their CSP is subject to US export control laws and regulations. CSP Vendor certifies that it intends to export or re-export the CSP named above outside of North America. CSP Vendor further acknowledges that it is wholly responsible for such distribution, disposition and possible end-use of its CSP outside of North America, including complying with all US export or other national controls over the CSP modules, and that Microsoft assumes no responsibility or liability for CSP Vendor's failure to obtain required export approvals.

If "Company Name" or a company address is filled in below, then the individual signing the ECC represents that he/she has authority to execute this agreement on behalf of such company. This ECC does not otherwise amend or alter the End-User License Agreement for the CryptoAPI CSP Development Kit (CSPDK) previously signed and completed by the Vendor.

IN WITNESS WHEREOF, Recipient has caused this Export Compliance Certificate to be executed by its duly authorized representative, and that the information provided herein is true to the best of his/her knowledge.


CryptoAPI Tools

Purpose

CryptoAPI Tools are used to digitally sign files to be used with Microsoft® Authenticode®, and to view and manage certificates, certificate revocation lists (CRLs), and certificate trust lists (CTLs).

Run-time Requirements

The basic tools require at least Microsoft® Internet Explorer version 4.01 and will work on anything newer such as Internet Explorer 4.01 with SP1 or SP2, Microsoft® Windows NT® version 4.0 with SP4, and Microsoft® Windows® 2000.

About CryptoAPI Tools

General information about CryptoAPI Tools.

CryptoAPI Tools Reference

Documentation of CryptoAPI Tools utilities.

Feedback

Make error reports and feature requests directly to Microsoft.


About CryptoAPI Tools

This section presents the following topics:

  • Introduction to Code Signing
  • Components of CryptoAPI Tools
  • Finding Further Information on Code Signing


Introduction to Code Signing

The software industry must provide users with the means to trust code published on the Internet. Many Web pages contain only static information that can be downloaded with little risk. Some pages, however, contain controls and applications to be downloaded and run on a user's computer. These executable files can be risky to download and run.

Packaged software uses branding and trusted sales outlets to assure users of its integrity, but these guarantees are not available when code is transmitted on the Internet. Additionally, the Internet itself cannot provide any guarantee about the identity of the software creator. Nor can it guarantee that any software downloaded was not altered after its creation. Browsers can exhibit a warning message explaining the possible dangers of downloading data of any kind, but browsers cannot verify that code is what it claims to be. A more active approach must be taken to make the Internet a reliable medium for distributing software.

One approach to providing guarantees of the authenticity and integrity of files is attaching digital signatures to those files. A digital signature attached to a file positively identifies the distributor of that file and ensures that the contents of the file were not changed after the signature was created.

Digital signatures can be created and verified using Microsoft's cryptography APIs. For background information on cryptography and the CryptoAPI functions, see About CryptoAPI.

For detailed information on digital signatures, certificates, and certificate stores, see:

  • Hashes and Digital Signatures
  • Digital Certificates
  • Managing Certificates with Certificate Stores
  • Certificate Trust Verification

Currently, CryptoAPI Tools supports Microsoft® Authenticode® by allowing software vendors to sign the following types of files for Authenticode verification.

File extension | Contents
.exe | Files that contain executable programs.
.cab | Self-contained files used for application installation and setup. In a cabinet file, multiple files are compressed into one file. They are commonly found on Microsoft software distribution disks.
.cat | Files that contain digital thumbprints of several files. A .cat file can be used to ensure the integrity of the files whose thumbprints it includes.
.ocx | Files that contain Microsoft® ActiveX® controls.
.dll | Files that contain executable functions.
.stl | Files that contain a certificate trust list (CTL).


Components of CryptoAPI Tools

CryptoAPI Tools and Microsoft® Authenticode® require a set of client files, publishing tools, and a signing DLL.

Most of the basic tools require at least Microsoft® Internet Explorer version 4.01 and will work on anything newer such as Internet Explorer 4.01 with SP1 or SP2, Microsoft® Windows NT® version 4.0 with SP4, and Microsoft® Windows® 2000.

Some of the tools are also available with Internet Explorer 3.02. References for using these tools with Internet Explorer 3.02 can be found in Internet Explorer 3.02 Compatibility.

The publishing tools and the signing DLL are installed in the Mssdk\Bin directory. They include the following files.

File | Remarks
MakeCert.exe | Creates an X.509 certificate for testing purposes only.
Cert2SPC.exe | Creates an SPC for testing purposes only.
SignCode.exe | Signs and timestamps a file.
ChkTrust.exe | Checks the validity of the file.
MakeCTL.exe | Creates a certificate trust list (CTL).
CertMgr.exe | Manages certificates, CTLs, and certificate revocation lists (CRLs).
SetReg.exe | Sets registry keys controlling certificate verification.
Signer.dll | Required by the Internet Explorer 4.01 version of the tools, regardless of the Internet Explorer 5.0 or Windows NT SP versions.
MakeCat.exe | Creates an unsigned catalog file containing the hashes of a set of files along with associated attributes of each file.


Finding Further Information on Code Signing

Digital signing is discussed more fully in the following documents.

  • CCITT, Recommendation X.509, The Directory-Authentication Framework, Consultation Committee, International Telephone and Telegraph, International Telecommunications Union, Geneva, 1989.
  • RSA Laboratories, PKCS #7: Cryptographic Message Syntax Standard. Version 1.5, November, 1993.
  • Schneier, Bruce, Applied Cryptography, 2d ed. New York: John Wiley & Sons, 1996.
  • http://www.rsa.com


Using CryptoAPI Tools

This section explores the following topics:

  • Signing Files and Checking Signatures
  • Creating, Viewing, and Managing Certificates
  • Using Other CryptoAPI Tools


Signing Files and Checking Signatures

CryptoAPI Tools include utilities to digitally sign files and to check the validity of file signatures. The following sections discuss using these utilities:

  • Using SignCode
    • Adding Timestamps to Previously Signed Files
    • Using -j and -jp SignCode Options
    • Using the Digital Signature Wizard
  • Using ChkTrust


Using SignCode

The following commands sign and timestamp a file named MyControl.exe in an environment using Microsoft® Internet Explorer version 4.0 or later. The first statement uses a private-key from the MyKey key container. The second statement uses the private key in the file My.pvk:

SignCode -spc Cert.spc -k MyKey -n "MyControl"
-i http://example.microsoft.com -$ commercial -t
http://timestamp.verisign.com/scripts/timstamp.dll
MyControl.exe

SignCode -spc Cert.spc -v My.pvk -n "MyControl"
-i http://example.microsoft.com -$ commercial -t
http://timestamp.verisign.com/scripts/timstamp.dll
MyControl.exe

In both cases, a PKCS #7 object, Cert.spc, is embedded into the file MyControl.exe. In the first example, the signature is a hash of the original file encrypted with the private key of the key pair from the MyKey key container. In the second example, the signature is a hash encrypted with the private key from the file My.pvk. In both cases, the signature includes a timestamp.

The following command signs and timestamps a file using a certificate with the subject name MyCert from the default certificate store, MY. The program file being signed is MyControl.exe and it is given the friendly name "My Control."

SignCode -cn "myCert" -n "My Control"
-i http://example.microsoft.com -$ commercial -t
http://timestamp.verisign.com/scripts/timstamp.dll
MyControl.exe

The following command signs and timestamps a file using the one and only certificate in the DemoCert store. Because there is assumed to be only one certificate in the certificate store, it is not necessary to identify the certificate. The certificate store is at the default HKEY_CURRENT_USER registry location. The file to be signed is MyControl.exe. The file is given the friendly name "My control."

SignCode -s "DemoCert" -n "My control"
-i http://example.microsoft.com -$ commercial -t
http://timestamp.verisign.com/scripts/timstamp.dll
MyControl.exe

In Windows Explorer, a Digital Signature tab appears in the Properties dialog box of any file that has been signed.

When SignCode is used without options, a SignCode wizard will be displayed to guide the user through the operation. See Using the Digital Signature Wizard.


Adding Timestamps to Previously Signed Files

Timestamps are normally included when a file is signed using SignCode with the -t option. In addition, timestamps can be added to files that were signed without a timestamp. The following command adds a timestamp to a previously signed file:

SignCode -t http://timestamp.verisign.com/scripts/timstamp.dll
-x MyControl.exe

Note The -x option is used in conjunction with the -t option to indicate that the file to be timestamped has already been signed. Trying to timestamp a file previously signed by Internet Explorer 3.0 tools may fail with an error indicating that a re-sign is needed. Timestamping a previously signed file using the SignCode tool for Internet Explorer 3.02 or later might succeed; however, signing and timestamping at the same time works even if the file was previously signed by Internet Explorer 3.0 tools because the old signature is replaced.


Using -j and -jp SignCode Options

The -j and –jp options are provided for users of SignCode and Internet Explorer 4.0 or later. The user can write a dynamic-link library (DLL) with predefined entry points that returns an array of authenticated or unauthenticated attributes for signing files. SignCode takes the following actions using these options:

  1. Loads the DLL specified by the –j option.
  2. Passes the parameters specified by the –jp option to the DLL.
  3. Retrieves an array of authenticated or unauthenticated attributes for signing Java files from the DLL.
  4. Adds the attributes to the signature.

There are four predefined entry points for the DLL:

HRESULT WINAPI InitAttr (
  LPWSTR pInitString // IN: the initialization string
);

HRESULT WINAPI GetAttr (
  PCRYPT_ATTRIBUTES *ppsAuthenticated,   // OUT:
                                         // Authenticated attributes
                                         // added to signature
  PCRYPT_ATTRIBUTES *ppsUnauthenticated  // OUT:
                                         // Unauthenticated attributes
                                         // added to signature
);

HRESULT WINAPI ReleaseAttr (
  PCRYPT_ATTRIBUTES psAuthenticated,    // OUT:
                                        //Authenticated attributes
                                        //to be released
  PCRYPT_ATTRIBUTES psUnauthenticated   // OUT:
                                        // Unauthenticated attributes
                                        //to be released
);

HRESULT WINAPI ExitAttr ( );

SignCode calls these entry points in the following order:

       InitAttr (initString);    // initString is the parameter
                                 // specified by the –jp option.
       GetAttr ();
       ExitAttr ();
       InitAttr (initString);    // initString is the parameter
                                 //  specified by the –jp option
       ReleaseAttr ();
       ExitAttr ();


Using the Digital Signature Wizard

The Digital Signature Wizard is a graphical user interface (GUI) to run SignCode.exe. The wizard can be used instead of the command prompt. The Digital Signature Wizard provides the following options:

  • Selecting and using a specific certificate to sign a file
  • Selecting and using a specific private key
  • Selecting a key type
  • Selecting a hash algorithm for the signature
  • Adding a timestamp to the signed file

The Digital Signature Wizard is a CryptoAPI Tool available with Internet Explorer 5.0 and Microsoft® Windows NT® version 4.0 SP4 or later. The wizard can be started by calling the SignCode.exe utility with no options from the command prompt. Use of this wizard is self-explanatory.


Using ChkTrust

The following command demonstrates the use of ChkTrust with Internet Explorer 4.0 or later

ChkTrust MyProgram.exe

A successful response from either of the above would be:

Result: 0

This result indicates that the file checked has a valid digital signature. If the result returned is non-zero, the file does not have a valid signature.

Note Versions of ChkTrust older than the version released with Internet Explorer 3.02 cannot validate files signed with the current release of CryptoAPI Tools.


Creating, Viewing, and Managing Certificates

Certificates are read-only structures. The contents of a certificate can be viewed but cannot be modified. Information in the certificate itself includes the certificate's validity dates, issuer, subject, and the public key. However, certificates have associated properties, such as a friendly name, description, and allowed uses, that can be viewed and edited.

This section demonstrates creating test certificates, viewing certificates, and managing certificates and other security objects. The certificates and software publisher certificates (SPCs) that can be created with MakeCert are strictly for test purposes. A test root certificate and a test root private key are provided for testing purposes only. Independent software vendors must obtain a certificate from GTE, VeriSign, Inc., or other certification authority (CA) to sign code that will be distributed to the public.

This section includes the following topics:

  • Using MakeCert
  • Using Cert2SPC
  • Using MakeCTL
    • Using the Make CTL Wizard
  • Using CertMgr


Using MakeCert

The following examples create test certificates with MakeCert, using options available with Microsoft® Internet Explorer version 4.0 or later:

  • Make a certificate issued by the default test root. Save the certificate to a file.
    MakeCert myNew.cer
  • Make a certificate issued by the default test root. Save it to a certificate store.
    MakeCert –ss myNewStore
  • Make a certificate issued by the default test root. Create a .pvk file, save the certificate to both a store and a file, and then sign a document with the newly-created certificate.
    MakeCert –sv myNew.pvk –ss myNewStore myNew.cer
SignCode -v myNew.pvk -spc myNew.cer -t
     http://timestamp.verisign.com/scripts/timestamp.dll myControl.exe
  • Make a certificate issued by the default test root. Create a key container and save the certificate to both a store and a file.
    MakeCert –sk myNewKey –ss myNewStore myNew.cer
  • Make a certificate using the default test root. Save the certificate to a store. Then make another certificate issued by the newly-created certificate. Save the second certificate to another store.
    MakeCert –sk myNewKey –ss myNewStore
MakeCert –is myNewStore –ss anotherStore
  • Make a certificate using the default test root. Save the certificate to the MY store. Then make another certificate using the newly-created certificate. If there is more than one certificate in the MY store, the certificate must be identified using its common name.
    MakeCert –sk myNewKey –n "CN=XXZZYY" –ss my
MakeCert –is my –in "XXZZYY" –ss anotherStore
  • Make a certificate using the default test root. Save the certificate to the MY store and to a file. Then make another certificate using the newly created myNew certificate. If there is more than one certificate in the MY store, uniquely identify the first certificate using the certificate file name.
    MakeCert –sk myNewKey –n "CN=XXZZYY" –ss my myNew.cer
MakeCert –is my –ic myNew.cer –ss anotherStore
  • Create a self-signed certificate named myNewRoot using the default test root. Then use SignCode with the certificate to sign a file.
    MakeCert –sk myNewRootKey –r –ss myNewRoot
SignCode –s myNewRoot myControl.exe
  • Create a self-signed certificate named myNewRoot using the default test root. Save myNewRoot into a system certificate store ca. Then make a certificate from myNewRoot and sign some code with the certificate.

    Note When SignCode uses a certificate in a store for signing, it will also build a certificate chain from the signing certificate to a root. All of the certificates in the certificate chain must be in one of the following certificate stores: MY, ca, or Root. In this case, myNewRoot is in the ca certificate store.

    MakeCert –sk myNewRootKey –r –ss ca myNewRoot.cer
MakeCert –is ca –ic myNewRoot.cer –ss myNewSign
SignCode –s myNewSign myControl.exe


Using Cert2SPC

The following command wraps an X.509 certificate, MyCert.cer, into a test PKCS #7 Software Publishing Certificate (SPC), called MyCert.spc. The SPC created is to be used for test purposes only. An SPCused to actually sign code to be distributed to the public must be obtained from GTE, VeriSign, Inc., or another trusted CA.

Cert2SPC MyCert.cer MyCert.spc


Using MakeCTL

The MakeCTL utility creates a certificate trust list (CTL) and saves the encoded CTL to a certificate store or to a file.

The following example generates a CTL that includes all the certificates in a system certificate store named Root:

MakeCTL –s root output.stl

The following command generates a CTL that includes three certificates named One.cer, Two.cer, and Three.cer. The CTL is created in the file Output.stl.

MakeCTL one.cer two.cer three.cer output.stl

When MakeCTL is used without options, a MakeCTL wizard will be displayed to guide the user through the operation. For more information, see Using the MakeCTL Wizard.


Using the MakeCTL Wizard

The MakeCTL wizard provides a graphical user interface (GUI) to use instead of the command prompt to create a certificate trust list (CTL).

The MakeCTL wizard is a CryptoAPI Tool available with Internet Explorer 5.0, Microsoft® Windows NT® version 4.0 SP4 or later.

The MakeCTL Wizard is started by calling MakeCTL.exe from the command prompt with no options.

Windows Explorer can check the CTL information and the certificates in the CTL. Double-clicking on a .stl file opens the Certificate Trust List dialog box.


Using CertMgr

CertMgr can be used to view certificates, CRLs, and CTLs from a file or a certificate store, to copy certificates into a certificate store, to delete certificates from a certificate store, and to save certificates to files. A CertMgr wizard exists for Microsoft® Windows NT® version 4.0 with SP4 and Microsoft® Windows® 2000. To run the CertMgr wizard, call CertMgr from the command prompt with no options.

The file must be one of the following types:

  • An encoded CTL, CRL, or certificate file (could be base 64 encoded)
  • A PKCS #7 file
  • An SPC file
  • A signed document
  • A serialized storeFile

The following examples use CertMgr commands to perform common certificate tasks.

  • View the certificates, CRLs, and CTLs from Myfile.ext:
    CertMgr myFile.ext
  • View the certificates, CRLs, and CTLs from the MY system store:
    CertMgr -s my
  • Copy all the certificates, CRLs, and CTLs in a file named MyFile.ext to a new file, called NewFile.ext:
    CertMgr -add –all –c myFile.ext newFile.ext
  • Copy all the certificates, CRLs, and CTLs from the MY system store to a file called NewMy.ext:
    CertMgr -add -all –c –s my newMy.ext
  • Copy a certificate with common name myCert in the MY system store to a file called NewCert.cer:
    CertMgr -add –c –n myCert –s my newCert.cer
  • Delete all the certificates from the MY system store:
    CertMgr -del –all –c –s MY
  • Delete all the CTLs from the MY system store and save the resulting store to a file called NewStore.str:
    CertMgr -del –all –ctl –s my newStore.str
  • Build a CTL and move it to the Root store:
    //Make a self-signed test certificate called sign.cer.
MakeCert -sv sign.pvk -r -n "CN=THIS IS A TEST OF MAKECTL" sign.cer

// Make a test SPC file using Cert2SPC.
Cert2SPC sign.cer sign.spc

// Make another self-signed test certificate called test.cer.
MakeCert -sv test.pvk -r -n "CN=THIS IS MY TEST CERT" test.cer

// Make an SPC file using Cert2SPC.
Cert2SPC test.cer test.spc

// Make a test.stl from test.cer.
MakeCTL test.cer test.stl

// Sign test.stl with the sign.pvk and sign.spc made in step 1.
SignCode -v sign.pvk -spc sign.spc test.stl

// Move test.stl to the trust system store.
CertMgr –add –ctl test.stl -s trust

// Move sign.cer to the root system store.
CertMgr -add –c sign.cer -s root

// Sign something (test.exe) with test.pvk, and test.spc.
SignCode -v test.pvk -spc test.spc test.exe

// Since test.cer is in the test.stl, ChkTrust will succeed.
ChkTrust test.exe
  • Save an X.509 encoded certificate (with the common name "myCert") located in the Root certificate store to a file called NewCert.cer:
    certmgr -put -c -n myCert -s root newCert.cer

When CertMgr is used without options, a CertMgr wizard will be displayed to guide the user through the operation.


Using Other CryptoAPI Tools

This section includes the following topics:

  • Using SetReg
  • Using MakeCat


Using SetReg

The SetReg utility sets the value of the registry keys controlling the behavior of the Microsoft® Authenticode® certificate verification process. These keys, called the Software Publishing State Keys, control whether to trust a test root, allow offline approval of certificates, test certificate expiration dates, and perform revocation checks.

The following command lists the syntax and options for using SetReg:

setreg -?

The following command makes a test root trusted. By default, a test root is not trusted. After any changes in the key values are made, a list of the current value of all of the key values is displayed. If the -q option is used, the key values are not displayed:

setreg 1 TRUE

The following command makes a test root untrusted and causes all verification to check for revocation. The -q option is used so that the list of key values is not displayed:

setreg -q 1 FALSE 3 TRUE

Note Commands, options, and arguments are not case-sensitive.


Using MakeCat

The MakeCat utility makes an unsigned catalog file, which contains the hashes of a set of files along with associated attributes of each file in the set. A catalog file allows the user to sign one file (the catalog) instead of signing numerous individual files.

After the unsigned catalog file is signed and transmitted, the receiver can compare the hashes of the original files to the hashes contained within the catalog file and verify that the files are free of tampering.

Prior to using the MakeCat utility, the user must prepare a Catalog Definition File (cdf), using any text editor. The .cdf file contains the list of files and the attributes of the files to be cataloged (the specifications are listed below). The MakeCat utility scans the .cdf file, verifies the list of attributes of each listed file, adds the listed attributes to the catalog itself, hashes each of the listed files, and stores the hashes of each file into the catalog file. Each file has its hash and attributes stored separately within the catalog. This catalog file can then be signed and transmitted. The receiver can subsequently compare the hash of each file within the catalog with the hash of the original files to prove that the original content is free of tampering. MakeCat does not modify the .cdf file.

The following command generates a catalog file from the file Good.cdf.

MakeCat –v good.cdf

A file, Good.cdf, produces a catalog file, Good.cat, by parsing the files UnsignedPE.exe, UnsgnedDOS.exe, Unsigned.cab, Unsigned.Class, and SignedPE.exe. The parsed files, along with Good.cdf and the newly generated Good.cat, are all in the same directory.

[CatalogHeader]
Name=Good.cat
ResultDir=.\
PublicVersion=0x00000001
EncodingType=
CATATTR1=0x10010001:Movie1:TotalRekall
CATATTR2=0x10010001:Movie2:TheTimeMachine
CATATTR3=0x10010001:Movie3:WarOfTheWorlds

[CatalogFiles]
UnsignedPE=.\UnsignedPE.EXE
UnsignedDOS=.\UnsgnedDOS.EXE
<HASH>UnsignedCAB=.\Unsigned.CAB
UnsignedClass=.\Unsigned.Class
SignedPE=.\SignedPE.EXE


CryptoAPI Tools Reference

CryptoAPI Tools Reference includes these sections:

  • Utilities to Sign Files and Check Signatures
  • Utilities to Create, View, and Manage Certificates
  • Other CryptoAPI Tools Utilities
  • Internet Explorer 3.02 Compatibility


Utilities to Sign Files and Check Signatures

CryptoAPI Tools contains utilities to sign files digitally and to confirm signatures on files.

Utility | Remarks
SignCode | Signs files. The SignCode wizard allows the user to sign a file using a graphical user interface instead of the command prompt.
ChkTrust | Checks the validity of a signed file.

All user input to these utilities is now case-insensitive. Additionally, separate options now exist for the key-pair name and the private-key file.


SignCode

The SignCode utility signs a file. It can be used from the command prompt with Microsoft® Internet Explorer version 3.02 or later, or with Microsoft® Windows NT® version 4.0 or later. A CryptoAPI Tool wizard can be used with Internet Explorer 5.0 or later, or Windows NT 4.0 SP4 or later.

CryptoAPI Tools contains a utility called ChkTrust.exe. This may be used to check your signature before distributing your file.

SignCode [options] [fileName]
fileName
Name of the output file (Internet Explorer 4.0 or later). With Internet Explorer 3.02, the output file name is set using the -prog option.

Options

SignCode has three groups of options:

  • Options specific to SPC-file and private-key technology
  • Options specific to certificate store technology
  • Basic options applicable in all cases

Options specific to software publisher certificates (SPC) and private-key technology cannot be mixed with options specific to certificate store technology.

Options given in the following tables can be used only with Microsoft Internet Explorer 4.0 or later. For options to use with Internet Explorer version 3.02 see Internet Explorer 3.02 Compatibility.

The basic options can be applied in all cases.

Basic option | Description
-a hashName | Hashing algorithm to use. hashName must be set to either SHA1 or MD5 (default).
-i Info | Location, such as a URL, for obtaining information about your program.
-j dllName | Name of a DLL that returns an array of authenticated attributes for signing files. The user can specify more than one DLL by repeating the -j option. For example: -j dll1 -j dll2 -j dll3.
-jp dllParam | Parameter to be passed for the preceding DLL. For example: -j dll1 -jp dll1Param. Only one parameter is allowed per DLL. For a list of predefined DLLs and their parameters, see Using -j and -jp SignCode Options.
-n Name | Friendly name given to the program.
-t httpAddress | Indicates that the file is to be timestamped. A URL specifying an address of a timestamping server must be provided (see -x for timestamping previously signed files).
-tr times | Maximum number of timestamping trials. The default is 1. SignCode will repeat the timestamping operation until it is successful or the limit of the number of trials is reached.
-tw seconds | Number of seconds between each timestamping trial. The default is 0.
-x | Timestamp a previously signed file. No signing is performed. Must be used in conjunction with -t.
-$ signingAuthority | Type of publisher that created the code being signed, which must be either commercial or individual. The action SignCode will take depends upon both this setting and the signing certificate actually used. See the table following in Remarks.
-? | Displays all options.

The following options are specific to signing software publisher certifiticate (SPC) files and private-key technology only.

SPC/private-key option | Description
-k | Key container that holds the private key. Cannot be used with -v.
-ky keySpec | Indicates the key specification, which must be one of three possible values: 1. Signature, which stands for AT_SIGNATURE key specification. 2. Exchange, which stands for AT_KEYEXCHANGE key specification. 3. An integer, such as 3. See notes on key specifications below.
-spc filename | Indicates that the named file contains the signing certificate. Must be used with the -v option if the private key is in a .pvk file or a -k flag is the private key is in a registry key container.
-p providerName | CryptoAPI provider to use. The default is the user's default provider. (For more details, see the CryptoAPI 2.0 documentation.)
-v privateKeyFile | File containing the private key of the publisher (subject). This is usually a .pvk file. This option cannot be used with -k.
-y providerType | CryptoAPI provider type to use. The default is PROV_RSA_FULL. (For more details, see the CryptoAPI 2.0 documentation.)

Note When upgrading from Internet Explorer 3.02 to version 4.0 or later, the -pvk option should be mapped to either the -k option or -v option, depending on the storage location of the private key. If the private key is stored in a key container, use the -k option. If the private key is stored in a private key file, use the -v option.

If the -ky key specification option is used in Internet Explorer 4.0 or later, the specification must match the key specification indicated by the private key file or private key container. If the key specification option is not used, then the key specification indicated by the private key file or private key container will be used. If there is more than one key specification in the key container, SignCode will first attempt to use the AT_SIGNATURE key specification. If that fails, SignCode will then try to use AT_KEYEXCHANGE. Since most users have either an AT_SIGNATURE key or AT_KEYEXCHANGE key, this option does not need to be used in most cases.

The following options are specific to certificate store technology only.

Certificate Store Option | Description
-c certificateFile | File containing the encoded signing certificate. SignCode will search the certificate store for a matching certificate. Either -c or -cn can be used to identify the signing certificate in the certificate store to use.
-cn commonNameString | Common name of the encoded signing certificate. SignCode will search in the certificate store for a certificate whose common name includes commonNameString. If the common name of more than one certificate in the certificate store includes commonNameString, SignCode will fail and issue an error.
-r storeLocation | Registry location of the certificate store, which must be set to either currentUser (registry key HKEY_CURRENT_USER) or localMachine (registry key HKEY_LOCAL_MACHINE). currentUser is the default.
-s storeName | Certificate store that includes the signing certificate and associated private key. The default is my. If there is more than one certificate in the store, the desired certificate must be uniquely identified using the -c or -cn options, or SignCode will fail.
-sha1 thumbprint | The thumbprint is the sha1 hash of the signing certificate included in the certificate store.
-sp storePolicy Certificate store policy, which must be set to either chain or spcStore (default).

If chain is set, all of the certificates in the verification chain including self-signed certificates are added to the signature.

If this option not used or if spcStore is set, trusted, self-signed certificates are not included with the certificates in the chain that are added to the signature.

Remarks

The signature type (commercial or individual) used by SignCode depends on the signing option and certificate used. In some cases, SignCode will fail the requested operation if there is a conflict. The possible signing actions are as follows.

Certificate Type | -$ commercial | -$ individual | no option
Commercial Only | commercial | fail | commercial
Individual Only | fail | individual | individual
Both | commercial | individual | commercial
None | fail | individual | individual

After a file has been signed and timestamped, using a valid certificate, the file can be distributed to customers.

Note Certificates generated with the test utilities MakeCert and Cert2SPC are NOT valid for signing code to be distributed to the public. Independent software vendors must obtain a certificate from GTE, VeriSign, Inc., or another CA to signing code that will be distributed to the public.


ChkTrust

The ChkTrust utility checks the validity of a signed file. If the hashes agree, ChkTrust verifies the signing certificate.

ChkTrust [options] signedFile
signedFile
Name of the signed file containing the signature to be verified.

Options

Options given in the following table can be used only with Microsoft Internet Explorer 4.0 or later. For options to use with Internet Explorer version 3.02 see Internet Explorer 3.02 Compatibility.

Option | Description
-q | Do not display user interface.
-v | Verbose mode. Displays detailed information about the validity of a signed file. The default is to display brief information.
-? | Displays all of the options.

Remarks

ChkTrust with Internet Explorer 4.0 or later can distinguish file types automatically. The -c and -i switches used in Internet Explorer 3.02 are obsolete.

For a command prompt example, see Using ChkTrust.


Utilities to Create, View, and Manage Certificates

CryptoAPI Tools contain utilities to perform common certificate management tasks.

Utility | Remarks
MakeCert | Creates a test X.509 certificate.
Cert2SPC | Creates a test software publisher's certificate (SPC).
MakeCTL | Creates a certificate trust list. MakeCTL is also available in a wizard that allows the user to make a CTL using a graphical user interface instead of the command prompt.
CertMgr | Manages certificates, certificate trust lists, and certificate revocation lists.

All user input to these utilities is case-insensitive. Separate options now exist for the key-pair name and the private-key file.


MakeCert

The MakeCert utility creates an X.509 certificate, signed by the test root key or other specified key, that binds your name to the public part of the key pair. The certificate is saved to a file, a system certificate store, or both.

MakeCert [basic options | extended options] outputFile
outputFile
Name of the file where the certificate will be written. May be omitted if the certificate is not to be written to a file.

Options

MakeCert includes basic and extended options. Basic options are those most commonly used to create a certificate. Extended options provide more flexibility. The options for MakeCert are also divided into three functional groups:

  • Extended options applicable to SPC-file, private-key, and certificate store technology.
  • Extended options specific to SPC-file and private-key technology only.
  • Basic options specific to certificate store technology only.

Options given in the following tables can be used only with Microsoft Internet Explorer 4.0 or later. For options to use with Internet Explorer version 3.02 see Internet Explorer 3.02 Compatibility.

Basic Option | Description
-a algorithm | Hash algorithm. Must be set to either SHA1 or MD5 (default).
-b dateStart | Date the certificate first becomes valid. The default is when the certificate is created. The format of dateStart is mm/dd/yyyy.
-cy certificateTypes | Certificate type. Can be end for end-entity, authority for certification authority, or both.
-e dateEnd | Date when the validity period ends. The default is the year 2039.
-eku OID1,OID2… | Inserts a list of one or more comma-separated, enhanced key usage object identifiers (OIDs) into the certificate. For example, -eku 1.3.6.1.5.5.7.3.2 inserts the client authentication OID. For definitions of allowable OIDs, see the Wincrypt.h file in CryptoAPI 2.0.
-h numChildren | Maximum height of the tree below this certificate.
-l policyLink | Link to SPC agency policy information (for example, a URL).
-m nMonths | Duration of the validity period.
-n name | Name for the publisher's certificate. This name must conform to the X.500 standard. The simplest method is to use "CN=MyName" format. For example: -n "CN=Test".
-nscp | The Netscape client authentication extension should be included.
-r | Creates a self-signed certificate.
-sc subjectCertFile | Certificate file name with the existing subject public key to be used.
-sk subjectKey | Location of the subject's key container which holds the private key. If a key container does not exist, one is created. If neither the -sk or -sv option is used, a default key container is created and used by default.
-sky subjectKeySpec | Subject's key specification, which must be one of three possible values: 1. Signature (AT_SIGNATURE key specification) 2. Exchange (AT_KEYEXCHANGE key specification) 3. An integer, such as 3. See notes on key specifications below.
-sp subjectProviderName | CryptoAPI provider for subject. The default is the user's provider. See the CryptoAPI 2.0 documentation for details on CryptoAPI providers.
-sr subjectCertStoreLocation | Registry location of the subject's certificate store, which must be either localMachine (registry key HKEY_LOCAL_MACHINE) or currentUser (registry key HKEY_CURRENT_USER). currentUser is the default.
-ss subjectCertStoreName | Name of the subject's certificate store where the generated certificate will be stored.
-sv subjectKeyFile | Name of the subject's .pvk file. If neither the -sk or -sv option is used, a default key container is created and used by default.
-sy nSubjectProviderType | CryptoAPI provider type for subject. The default is PROV_RSA_FULL. See the CryptoAPI 2.0 documentation for details on CryptoAPI provider types.
-# serialNumber | Serial number of the certificate. The maximum value is 2^31. The default is a value generated by the utility that is guaranteed to be unique.
-$ certificateAuthority | Type of certification authority, which must be set to either commercial (for certificates to be used by commercial software publishers) or individual (for certificates to be used by individual software publishers).
-? | Displays the basic options.
-! | Displays the extended options.

Note If the -sky key specification option is used in Microsoft® Internet Explorer version 4.0 or later, the specification must match the key specification indicated by the private key file or private key container. If the key specification option is not used, the key specification indicated by the private key file or private key container will be used. If there is more than one key specification in the key container, MakeCert will first attempt to use the AT_SIGNATURE key specification. If that fails, MakeCert will try to use AT_KEYEXCHANGE. Since most users have either an AT_SIGNATURE key or AT_KEYEXCHANGE key, this option does not need to be used in most cases.

The following options are only for software publisher certificate (SPC)-files and private-key technology.

SPC/Private Key Option | Description
-ic issuerCertFile | Location of the issuer's certificate.
-ik issuerKey | Location of the issuer's key container. The default is the test root key.
-iky issuerKeySpec | Issuer's key specification, which must be one of three possible values: 1. Signature (AT_SIGNATURE key specification) 2. Exchange, (AT_KEYEXCHANGE key specification) 3. An integer, such as 3. See notes on key specifications below.
-ip issuerProviderName | CryptoAPI provider for issuer. The default is the user's provider. See the CryptoAPI 2.0 documentation for details on CryptoAPI providers.
-iv issuerKeyFile | Issuer's private-key file. The default is the test root.
-iy nIssuerProviderType | CryptoAPI provider type for issuer. The default is PROV_RSA_FULL. See the CryptoAPI 2.0 documentation for details on CryptoAPI provider types.

Note If the -iky key specification option is used in Internet Explorer 4.0 or later, the specification must match the key specification indicated by the private key file or private key container. If the key specification option is not used, the key specification indicated by the private key file or private key container will be used. If there is more than one key specification in the key container, MakeCert will first attempt to use the AT_SIGNATURE key specification. If that fails, MakeCert will try to use AT_KEYEXCHANGE. Since most users have either an AT_SIGNATURE key or AT_KEYEXCHANGE key, this option does not need to be used in most cases.

The following options are for certificate store technology only.

Certificate Store Option | Description
-ic issuerCertFile | File containing the issuer's certificate. MakeCert will search in the certificate store for a certificate with an exact match.
-in issuerNameString | Common name of the issuer's certificate. MakeCert will search in the certificate store for a certificate whose common name includes issuerNameString.
-ir issuerCertStoreLocation | Registry location of the issuer's certificate store, which must be either localMachine (registry key HKEY_LOCAL_MACHINE) or currentUser (HKEY_CURRENT_USER). currentUser is the default.
-is issuerCertStoreName | Issuer's certificate store that includes the issuer's certificate and its associated private key information. If there is more than one certificate in the store, the user must uniquely identify it with the -ic or -in option. If the certificate in the certificate store is not uniquely identified, MakeCert will fail.


Cert2SPC

The Cert2SPC utility creates a test software publisher certificate (SPC) using existing X.509 certificates. Cert2SPC can wrap multiple X.509 certificates into a PKCS #7 signed-data object.

Note This utility is for test purposes only. A valid SPC is obtained from a CA.

Cert2SPC cert1.cer cert2.cer. . .certN.cer output.spc
cert1 . . . certN
Names of the X.509 certificates to include in the SPC. Each certificate name ends with the .cer extension.
output
Name of the PKCS #7 object containing the X.509 certificates to be created. The output file name ends with the .spc extension.


MakeCTL

The MakeCTL utility creates a certificate trust list (CTL) and saves the encoded CTL to a certificate store or to a file. MakeCTL is only supported with Internet Explorer 4.0 or later. A CryptoAPI Tool wizard is available with Internet Explorer 5.0 or later and Windows NT 4.0 SP4 or later.

The input to MakeCTL is an array of certificate stores. MakeCTL builds a CTL that includes the SHA1 hash of all of the certificates in the certificate stores. A certificate store can be one of the following:

  • A serialized store file
  • A PKCS #7 file
  • An encoded certificate file
  • A system store
MakeCTL [-u subjectUsageID] [-s [-r registryLocation]]
     store1 [-s [-r registryLocation]] store2 … [-s [-r registryLocation]]
     storeN output.stl
store1 . . . storeN
Names of the certificate stores for which to make the certificate trust list.
output
Name of the output file to contain the CTL.

Options

The following options are supported.

Option | Description
-u subjectUsageID | CTL subject usage identifier. The default identifier, 1.3.6.1.4.1.311.2.2.1, defined as szOID_TRUSTED_CODESIGNING_CA_LIST in Wintrust.h, specifies that the CTL consists of root CAs for code signing. It can be any enhanced key usage object identifier (OID).
-s | Indicates that the certificate store is a system store.
-r registryLocation | Registry location of the system certificate store. Meaningful only when –s is set. Must be set to either currentUser (registry key HKEY_CURRENT_USER) or localMachine (registry key HKEY_LOCAL_MACHINE). The default setting is currentUser.
-? | Lists command syntax and options.

Remarks

An encoded CTL file must be signed before using. CTL files can be signed using the SignCode utility. Once the CTL file is signed, it can be moved to the trust system store by CertMgr. CertMgr can also move the CTL's signed certificate to the Root store. If the subject usage identifier of the CTL is szOID_TRUSTED_CODESIGNING_CA_LIST (the default), all the files signed by certificates in the CTL will be trusted by ChkTrust and Microsoft® Authenticode®.

For examples, see Using MakeCTL.


CertMgr

The CertMgr utility replaces DumpCert. It includes new capabilities for the management of certificates, certificate trust lists (CTLs), and certificate revocation lists (CRLs). CertMgr performs four functions:

  • Displays certificates, CTLs, and CRLs.
  • Copies certificates, CTLs, and CRLs from one certificate store to another.
  • Deletes certificates, CTLs, and CRLs from a certificate store.
  • Saves an X.509 encoded certificate, CTL, and CRL from a certificate store to a file.

This utility performs one of these actions depending on the action indicated in the command.

CertMgr [-add | -del | -put][options] [-s [–r registryLocation]]
SourceName [-s [–r registryLocation]] [DestinationName]

The following table indicates the basic actions of the CertMgr utility.

Action Flag | Description
none | Displays certificates, CRLs, or CTLs.
-add | Copies certificates, CTLs, and CRLs to a certificate store.
-del | Deletes certificates, CTLs, and CRLs from a certificate store.
-put | Saves an X.509 encoded certificate, CTL, or CRL to a file.

With no action flag (to display only), SourceName is the name of the certificate store or file containing the items to display. The store can be a serialized store (StoreFile) or a system store. By default, CertMgr displays all the certificates, CTLs, or CRLs in the certificate store or file. DestinationName is not used for display.

When using -add, SourceStore is the source certificate store that contains the existing certificates, CTLs, and CRLs. DestinationStore is the destination certificate store to which the certificates, CTLs, and CRLs will be added. The destination store will be saved as a serialized store, unless the -7 option is used, which saves the store as a PKCS #7 file. Note that the -7 option cannot be used when the destination store is a system store.

When using -del, SourceStore is the source certificate store that contains the existing certificates, CTLs, and CRLs. DestinationStore is the destination certificate store which will contain copies of the remaining certificates, CTLs, and CRLs after the specified items have been deleted. If DestinationStore is not specified, SourceStore will also serve as the destination store (it will be modified). The destination store will be saved as a serialized store, unless the -7 option is used, which saves the store as a PKCS #7 file. Note that the -7 option cannot be used when the destination store is a system store.

When using -put, SourceStore is the source certificate store that contains the existing certificates, CTLs, and CRLs. DestinationName is the name of a file to which an X.509 encoded certificate, CTL, and CRL will be saved. If the -7 option is used, the file will be saved as a PKCS #7 file.

Options

The following options apply to all CertMgr functions except where noted.

Option | Action flag | Description
-v | none (display only) | Verbose mode. Displays detailed information about certificates, CTLs, and CRLs. The default is to display brief information.
-c | all | Use certificates only.
-CTL | all | Use CTLs only.
-CRL | all | Use CRLs only.
-all | -add -del -put | Adds all entries of the chosen type.
-e encodingType | all | Certificate encoding type.
-y storeProviderType | all | Store provider type.
-7 | -add -del -put | Saves the destination store as a PKCS #7 file.
-f dwFlags | all | Store open flag. This is the dwFlags parameter passed to CertOpenStore. The default value is CERT_SYSTEM_STORE_CURRENT_USER. Meaningful only if -y is set. For more information, see CertOpenStore.
-n commonNameString | -add -del -put | Common name of the certificate. Can be used only with certificates.
-sha1 sha1Hash | -add -del -put | SHA1 hash of the certificate, CTL, or CRL to be copied, deleted, or saved.
-s | all | Indicates that the store is a system store.
-r registryLocation | all | Registry location of the system certificate store. Meaningful only when -s is set. Must be set to either currentUser (registry key HKEY_CURRENT_USER) or localMachine (registry key HKEY_LOCAL_MACHINE). currentUser is the default.
-? | all | Displays all the options.

Remarks

CertMgr is only supported in Internet Explorer 4.0 or later.

CertMgr can copy, delete, or save one or more certificates, CTLs, or CRLs. If there is more than one item in one of these categories, the user has three options:

  • Use the -all option to copy, delete, or save all the items in the category indicated.
  • Use the -n and -sha1 options to uniquely identify the item to be copied, deleted, or saved.
  • If -all, or -n and -sha1 are not indicated, CertMgr prompts the user with a list of items to copy, delete, or save. The user responds by entering the index of the item to be copied, deleted, or saved.

The actions of CertMgr use slight variations of the syntax and options. The syntax and options specific to an action must be used.

CertMgr works with two kinds of certificate stores: StoreFile and system store. A StoreFile can be one of the following kinds of files:

  • An encoded CTL/CRL/certificate file (could be base 64 encoded)
  • A PKCS #7 file
  • A signed document
  • A serialized StoreFile

It is not necessary to specify the type of the StoreFile. CertMgr can determine the StoreFile type and take the appropriate actions.

A system store is a certificate store normally located in the registry under currentUser. The user can refer to a system store by providing just its name. It is not necessary to specify the certificate store provider type. Depending on the type of StoreFile or system store, CertMgr chooses the corresponding store provider type.


Other CryptoAPI Tools Utilities

CryptoAPI Tools contain utilities to perform common verification tasks.

Utility | Remarks
SetReg | Sets registry keys controlling the certificate verification process.
MakeCat | Makes an unsigned catalog file. This catalog file is subsequently used to compare the hashes within the catalog file to the hashes of individual files, to prove that the original files are free of tampering.

All user input to these utilities is case-insensitive. Separate options now exist for the key-pair name and the private-key file.


SetReg

The SetReg utility sets the value of the registry keys controlling the behavior of the Microsoft® Authenticode® certificate verification process. These keys are called the Software Publishing State Keys. After completing the requested action, the utility displays the current state of the Software Publishing State Keys.

SetReg [options] [Choice # <TRUE | FALSE>]

Options

The options can be one of the following values. Options given in the following table can be used only with Microsoft Internet Explorer 4.0 or later. For options to use with Internet Explorer version 3.02 see Internet Explorer 3.02 Compatibility.

Option | Description
-q | Suppress the display of the Software Publishing State Key values after SetReg has completed the requested action. The values are displayed by default.
-? | List command syntax and options.

Choice # must be one of the following values. All of the listed values are valid for Internet Explorer 3.02 and later, except 9 and 10, which are for Internet Explorer 4.0 or later only.

Choice | Description | Result
1 | Trust the Test Root | If TRUE, trusts a test root. This is equivalent to running "regedit wvtston.reg" in Internet Explorer 3.x. The default is FALSE. Any file signed with a test root will not verify unless this flag is set to TRUE.
2 | Use expiration date on certificates | If TRUE, checks the certificate expiration date. To ignore expiration dates, set this flag to FALSE. The default is TRUE.
3 | Check the revocation list | If TRUE, performs the revocation check. To bypass revocation check, set this flag to FALSE. The default is FALSE in Internet Explorer 3.x and TRUE in Internet Explorer 4.0 or later.
4 | Offline revocation server OK (Individual) | If TRUE, allows offline approval for individual certificates. The default is FALSE.
5 | Offline revocation server K (Commercial) | If TRUE, allows offline approval for commercial certificates. The default prior to Windows 2000 is FALSE. The default for Windows 2000 is TRUE
6 | Java offline revocation server OK (Individual) | If TRUE, allows offline approval for individual certificates and does not display the user interface for bad certificates. The default is FALSE.
7 | Java offline revocation server OK (Commercial) | If TRUE, allows offline approval for commercial certificates and does not display the user interface for bad certificates. The default prior to Windows 2000 is FALSE. The default for Windows 2000 is TRUE.
8 | Invalidate version 1 signed objects | If TRUE, invalidates version 1 signed objects. The default is FALSE.
9 | Check the revocation list of timestamp server | If TRUE, performs the revocation check on the timestamp server's certificate. The default is FALSE. For Internet Explorer 4.0 or later only.
10 | Only trust items found in the Trust database | If TRUE, allows downloads from publishers that are contained in the Personal Trust Database. The default is FALSE. For Internet Explorer 4.0 or later only.


MakeCat

The MakeCat utility is a CryptoAPI Tool available with Internet Explorer 5.0 or Windows NT 4.0 SP4 or later

MakeCat [options] filename
filename
Name of the .cdf file to be parsed. See Remarks for required structure and contents.

Options

-v:
Verbose. Displays all progress and error messages.
-n:
Do not stop on a recoverable error.
-r
Forces the MakeCat program to terminate if it encounters recoverable errors. Specifically, it will terminate when processing the entries in the catalog files section of a .cdf file.

Remarks

The .cdf file must be built with the following specifications:

[CatalogHeader]
Name=Name
ResultDir=ResultDir
PublicVersion=Version
EncodingType=Encodingtype
CATATTR1={type}:{oid}:{value} (optional)
CATATTR2={type}:{oid}:{value} (optional)

[CatalogFiles]
{reference tag}=file path and name
{reference tag}ALTSIPID={guid} (optional)
{reference tag}ATTR1={type}:{oid}:{value} (optional)
{reference tag}ATTR2={type}:{oid}:{value} (optional)

where:

[CatalogHeader]
This section defines information about the entire catalog file.
Name
Name of the catalog file including its extension.
ResultDir
Directory where the created .cat file will be placed. If not indicated, the default current directory is used. If the directory does not exist, it is created.
Version
Version of the catalog. If left blank, the default value, one, is used.
Encodingtype
Type of message encoding used. If left blank, the default EncodingType is PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 0x00010001.

Currently defined encoding types are shown in the following table.
Encoding Type | Value
X509_ASN_ENCODING | 0x00000001
PKCS_7_ASN_ENCODING | 0x00010000

[CatalogFiles]
This section defines each member of the catalog file with files of various types and attributes of various types in separate groups.
reference tag
The text reference to the file. This can include any ASCII text characters except "=". The system must be able to reproduce this tag after installation.

One convention is to use the lowercase base file name of the file that is being hashed.

Another convention (preferred) is to use <HASH> to use the string form of the tag.

file path and name
The file name, including extension to be parsed, and the relative path to the file. Any type of file that can be signed with SignCode (.exe, .cab, .cat, .ocx, .dll, and .stl files) can be added to a catalog.
ALTSIPID
The SIP GUID that is to be used for hashing instead of the standard SIP based on file type. This entry is optional. If this entry is omitted, the member will be hashed using the default SIP. If no default installed SIP is found, the Flat SIP will be used.
guid
The text representation of a globally unique identifier (GUID).
ATTRx
An attribute or statement about the file or content. This entry is optional. There can be any number of attributes, including none.
type
Defines what type of attribute is being added in the format 0x00000000 (text). The following table lists the available values, which can be combined using the bitwise OR operator to specify more than one attribute.
Value | Meaning
0x10000000 | Authenticated attribute (signed, included in the hash).
0x20000000 | Unauthenticated attribute (unsigned, not included in the hash, not verifiable).
0x00010000 | Attribute is represented in plain text. No conversion will be done.
0x00020000 | Attribute is represented in base 64 encoding. This is used to represent binary data.
0x00000001 | Attribute is a name-value pair. Use the oid parameter for the name. This attribute is slow and therefore it is recommended that this option have limited use.
0x00000002 | Attribute is referenced by an OID.

oid
The text representation of the attribute's reference key. It is an object identifier (OID) in the form of a text string in dotted quad notation (for example, a.b.c.d) or a text Name.
value
The text representation (depending on the type value) of the attribute content (value). The EOL character(s) determine the length.

The generated catalog file is unsigned. If it is to be signed prior to transmittal, it is signed using the SignCode utility.


Internet Explorer 3.02 Compatibility

This topic lists difference in the option used with CryptoAPI Tools with Internet Explorer 3.02. CryptoAPI Tools under Internet Explorer 3.0 are the same as currently used with Internet Explorer 4.0 and later except as noted in the following sections:

  • SignCode Used with Internet Explorer 3.02
  • ChkTrust Used with Internet Explorer 3.02
  • MakeCert Used with Internet Explorer 3.02
  • SetReg Used with Internet Explorer 3.02


SignCode Used with Internet Explorer 3.02

The following table show options that can be used with the SignCode utility under Internet Explorer 3.02 that differ from current, Internet Explorer 4.0 and later option usage. For more information about the current options available with this utility, see SignCode.

3.02 option | 4.0 option | Description
-sha | -a SHA1 | Use the SHA hashing algorithm.
-md5 | -a MD5 | Use the MD5 hashing algorithm.
-commercial | -$ commercial | Code being signed was created by a commercial software publisher.
-individual | -$ individual | Code being signed was created by an individual software publisher.
-info Info | -i Info | Location, such as a URL, for obtaining information about your program.
-name Name | -n Name | Friendly name given to the program.
-nocerts | Not used. | In Internet Explorer 4.0 or later, all certificates will always be included in the message.
-prog fileName | Not used. | In Internet Explorer 4.0 or later, the file name is always placed as the last item in the command.
timestamper | -t httpAddress | Indicates that the file is to be timestamped.
-nosigning | -x | Timestamp a previously signed file.
-pvk privateKey | -k | Key container that holds the private key.
-pvk privateKeyFile | -v privateKeyFile | Name of a file containing the private key of the publisher (subject).
-provider providerName | -p providerName | CryptoAPI provider to use.
-spc credentials | Not used. | File that contains the credentials.
-providerType providerType | -y providerType | CryptoAPI provider type to use.


ChkTrust Used with Internet Explorer 3.02

The following table show options that can be used with the ChkTrust utility under Internet Explorer 3.02 that differ from current, Internet Explorer 4.0 and later option usage. For more information about the current options available with this utility, see ChkTrust.

3.02 Option | 4.0 Option | Description
-c | Not used. | Signed file is a cabinet file.
-i | Not used. | Signed file is a PE image file.
-n | -q | Do not display user interface.


MakeCert Used with Internet Explorer 3.02

The following table show options that can be used with the MakeCert utility under Internet Explorer 3.02 that differ from current, Internet Explorer 4.0 and later option usage. For more information about the current options available with this utility, see MakeCert.

3.02 Option | 4.0 Option | Description
-a | -a SHA1 | SHA1 hash algorithm should be used.
-m | -a MD5 | MD5 hash algorithm should be used.
-c | -$ commercial | Certificate will be used by commercial software publishers.
-c f | Not used. | Certificate will be used by commercial software publishers who have met the minimum financial criteria.
-t:types | -cy certificateTypes | Certificate type.
-g | Not used. | Creates a glue certificate.
-i | -$ individual | Certificate will be used by individual software publishers.
-l: policyLink | -l policyLink | Link to SPC agency policy information.
-d: nMonths | -m nMonths | Duration of the validity period.
-n: name | -n name | Name for the publisher's certificate.
-n | -nscp | The Netscape client authentication extension should be included.
-u: subjectCertFile | -sc subjectCertFile | Certificate file name with the existing subject public key to be used.
-u: subjectKey | -sk subjectKey | Location of the subject's key container which holds the private key.
-k: subjectKeyfile | -sv subjectKeyFile | Name of the subject's .pvk file.
-i: issuerCertificate | -ic issuerCertificate | Location of the issuer's certificate.
-s: issuerKeyFile | -ik issuerKey | Location of the issuer's key container.
-k: keySpec | -iky issuerKeySpec | Issuer's key specification.
-x: providerName | -ip issuerProviderName | CryptoAPI provider for issuer.
-y: nProviderType | -iy nIssuerProviderType | CryptoAPI provider type for issuer.


SetReg Used with Internet Explorer 3.02

The following table show options that can be used with the SetReg utility under Internet Explorer 3.02 that differ from current, Internet Explorer 4.0 and later option usage. For more information about the current options available with this utility, see SetReg.

3.02 option | 4.0 option | Description
-h | -? | List command syntax and options.


WinTrust

Purpose

WinTrust includes a function and structures used by that function to verify trust in files, catalogs, memory blobs, signatures, or certificates. In the case of verifying certificates, WinTrust calls the CryptoAPI trust chain building functions, CertGetCertificateChain and CertVerifyCertificateChainPolicy. An application can use those functions directly, and their direct use is recommended.

Where Applicable

WinTrust can be used in all Microsoft® Windows®-based applications.

Developer Audience

WinTrust is designed for use by C programmers.

Run-time Requirements

Applications that use WinTrust require Microsoft® Windows NT® version 4.0 or later. For information on which operating systems are required to use a particular function, see the Requirements section of the function documentation.

See Also

CryptoAPI

WinTrust Reference

Documentation of specific WinTrust functions and structures.

Feedback

Make error reports and feature requests directly to Microsoft.


WinTrust Reference

The following elements are used with WinTrust:

  • WinTrust Functions
  • WinTrust Structures


WinTrust Functions

The following function is used with WinTrust:

WinVerifyTrust


WinVerifyTrust

The WinVerifyTrust function performs a trust verification action on a specified object. The function passes the inquiry to a trust provider, if one exists, that supports the action identifier.

HRESULT WINAPI WinVerifyTrust(
  HWND hWnd,
  GUID *pgActionID,
  WINTRUST_DATA *pWinTrustData
);

Parameters

hWnd
[in] Optional handle to a caller window. A trust provider can use this value to determine whether it can interact with the user. However, trust providers typically perform verification actions with input from the user.

This parameter can be one of the following values:
Value | Meaning
INVALID_HANDLE_VALUE | There is no interactive user. The trust provider performs the verification action without the user's assistance.
Zero | The trust provider can use the interactive desktop to display its user interface.
A valid window handle | A trust provider can treat any value other than INVALID_HANDLE_VALUE or zero as a valid window handle that it can use to interact with the user.

pgActionID
[in] Pointer to a GUID structure that identifies an action and the trust provider that supports that action. This value indicates the type of verification action to be performed on the structure pointed to by pWinTrustData.

The WinTrust service is designed to work with trust providers implemented by third parties. Each trust provider provides its own unique set of action identifiers. For information about the action identifiers supported by a trust provider, see the documentation for that trust provider.

For example, Microsoft provides a Software Publisher Trust Provider that can establish the trustworthiness of software being downloaded from the Internet or some other public network. The Software Publisher Trust Provider supports the following action identifiers. These constants are defined in softpub.h.
Value | Description
WINTRUST_ACTION_GENERIC_VERIFY | Verifiy a certificate chain only.
WINTRUST_ACTION_GENERIC_VERIFY_V2 | Verify a file or object using the Microsoft Authenticode Policy Provider.
HTTPSPROV_ACTION | Verify an SSL/PCT connection through Internet Explorer.

pWinTrustData
[in] Pointer to a WINTRUST_DATA structure that contains information that the trust provider needs to process the specified action identifier. Typically, the structure includes information that identifies the object that the trust provider must evaluate.

The format of the structure depends on the action identifier. For information about the data required for a specific action identifier, see the documentation for the trust provider that supports that action.

Return Values

If the trust provider verifies that the subject is trusted for the specified action, the return value is ERROR_SUCCESS. Otherwise, the function returns a status code from the trust provider.

For example, a trust provider might indicate that the subject is not trusted, or is trusted but with limitations or warnings. The return value can be a trust-provider-specific value described in the documentation for an individual trust provider, or it can be one of the following error codes.

Value | Meaning
TRUST_E_SUBJECT_NOT_TRUSTED | The subject failed the specified verification action. Most trust providers return a more detailed error code that describes the reason for the failure.
TRUST_E_PROVIDER_UNKNOWN | The trust provider is not recognized on this system.
TRUST_E_ACTION_UNKNOWN | The trust provider does not support the specified action.
TRUST_E_SUBJECT_FORM_UNKNOWN | The trust provider does not support the form specified for the subject.

Remarks

The WinVerifyTrust function enables applications to invoke a trust provider to verify that a specified object satisfies the criteria of a specified verification operation. The pgActionID parameter identifies the verification operation, and the pWinTrustData parameter identifies the object whose trust is to be verified. A trust provider is a DLL registered with WinTrust. A call to WinVerifyTrust forwards that call to the registered trust provider, if there is one, that supports that specified action identifier.

For example, the Software Publisher Trust Provider can verify that an executable image file comes from a trusted software publisher and that the file has not been modified since it was published. In this case, the pWinTrustData parameter specifies the name of the file and the type of file, such as a Microsoft Portable Executable image file or a Java class file.

Each trust provider supports a specific set of actions that it can evaluate. Each action has a globally unique identifier (GUID) that identifies it. A trust provider can support any number of action identifiers, but two trust providers cannot support the same action identifier.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Wintrust.h; include Softpub.h.
Library: Use Wintrust.lib.


WinTrust Structures

The following structures are used with WinTrust.

WINTRUST_DATA
WINTRUST_FILE_INFO
WINTRUST_CATALOG_INFO
WINTRUST_BLOB_INFO
WINTRUST_SGNR_INFO
WINTRUST_CERT_INFO


WINTRUST_DATA

The WINTRUST_DATA structure is used when calling WinVerifyTrust to pass necessary information into the trust providers.

typedef struct _WINTRUST_DATA
{
  DWORD           cbStruct;
  LPVOID          pPolicyCallbackData;
  LPVOID          pSIPClientData;
  DWORD           dwUIChoice;
  DWORD           fdwRevocationChecks;
  DWORD           dwUnionChoice;
  union
  {
    struct WINTRUST_FILE_INFO_      *pFile;
    struct WINTRUST_CATALOG_INFO_   *pCatalog;
    struct WINTRUST_BLOB_INFO_      *pBlob;
    struct WINTRUST_SGNR_INFO_      *pSgnr;
    struct WINTRUST_CERT_INFO_      *pCert;
  };
  DWORD           dwStateAction;
  HANDLE          hWVTStateData;
} WINTRUST_DATA, *PWINTRUST_DATA;

Members

cbStruct
Count of bytes in this structure.
pPolicyCallbackData
Pointer to a data buffer used to pass policy-specific data to a policy provider. This member may be NULL.
pSIPClientData
Pointer to a data buffer used to pass SIP-specific data to an SIP provider. This member may be NULL.
dwUIChoice;
Indication of the kind of user interface (UI) to be used. This member must be one of the following values.
Value | Meaning
WTD_UI_ALL | Display all UI.
WTD_UI_NONE | Display no UI.
WTD_UI_NOBAD | Do not display any negative UI.
WTD_UI_NOGOOD | Do not display any positive UI.

This is a required member.

fdwRevocationChecks;
Certificate revocation check options. Can be set to add revocation checking to be done in addition to that done by the selected policy provider. This member must be one of the following values.
Value | Meaning
WTD_REVOKE_NONE | No additional revocation checking is to be done.
WTD_REVOKE_WHOLECHAIN | Revocation checking is to be done on the whole chain.

This is a required member.

dwUnionChoice
Indication of the union member to be used and, thus, the type of object for which trust will be verified. This member must be one of the following values.
Value | Meaning
WTD_CHOICE_FILE | Use the file pointed to by pFile.
WTD_CHOICE_CATALOG | Use the catalog pointed to by pCatalog.
WTD_CHOICE_BLOB | Use the BLOB pointed to by pBlob.
WTD_CHOICE_SIGNER | Use the WINTRUST_SGNR_INFO structure pointed to by pSgnr.
WTD_CHOICE_CERT | Use the certificate pointed to by pCert.

This is a required member.

pFile
Pointer to a WINTRUST_FILE_INFO structure.
pCatalog
Pointer to a WINTRUST_CATALOG_INFO structure.
pBlob
Pointer to a WINTRUST_BLOB_INFO structure.
pSgnr
Pointer to a WINTRUST_SGNR_INFO structure.
pCert
Pointer to a WINTRUST_CERT_INFO structure.
dwStateAction
Currently unused. Set to zero.
hWVTStateData
Currently unused. Set to Null.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Winbase.h.


WINTRUST_FILE_INFO

The WINTRUST_FILE_INFO structure is used when calling WinVerifyTrust to verify an individual file.

typedef struct WINTRUST_FILE_INFO_
{
  DWORD      cbStruct;
  LPCWSTR    pcwszFilePath;
  HANDLE     hFile;
} WINTRUST_FILE_INFO, *PWINTRUCT_FILE_INFO;

Members

cbStruct
Count of bytes in this structure.
pcwszFilePath
Full path and file name of the file to be verified. This member is required.
hFile
File handle to the open file to be verified. This handle must be to a file that has at least read permission. This member is optional and may be set to NULL.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Winbase.h.


WINTRUST_CATALOG_INFO

The WINTRUST_CATALOG_INFO structure is used when calling WinVerifyTrust to verify a member of a Microsoft catalog.

typedef struct WINTRUST_CATALOG_INFO_
{
  DWORD        cbStruct;
  DWORD        dwCatalogVersion;
  LPCWSTR      pcwszCatalogFilePath;
  LPCWSTR      pcwszMemberTag;
  LPCWSTR      pcwszMemberFilePath;
  HANDLE       hMemberFile;

} WINTRUST_CATALOG_INFO, *PWINTRUST_CATALOG_INFO;

Members

cbStruct
Count of bytes in this structure.
dwCatalogVersion
Catalog version number. This member is optional.
pcwszCatalogFilePath
The full path and file name of the catalog file containing the member to be verified. This member is required.
pcwszMemberTag
Tag of a member file to be verified. This member is required.
pcwszMemberFilePath
The full path and file name of the catalog member file to be verified. This member is required.
hMemberFile
Handle of the open catalog member file to be verified. The handle must be to a file with at least read permissions. This member is optional.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Winbase.h.


WINTRUST_BLOB_INFO

The WINTRUST_BLOB_INFO structure is used when calling WinVerifyTrust to verify a memory BLOB.

typedef struct WINTRUST_BLOB_INFO_
{
  DWORD       cbStruct;
  LPCWSTR     pcwszDisplayName
  DWORD       cbMem;
  BYTE        *pbMem;
} WINTRUST_BLOB_INFO, *PWINTRUST_BLOB_INFO;

Members

cbStruct
Count of bytes in this structure.
pcwszDisplayName
String with the name of the memory object pointed to by pbMem.
cbMem
Length in bytes of the memory BLOB to be verified
pbMem
Pointer to a memory BLOB to be verified.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Winbase.h.


WINTRUST_SGNR_INFO

The WINTRUST_SGNR_INFO structure is used when calling WinVerifyTrust to verify a CMSG_SIGNER_INFO structure.

typedef struct WINTRUST_SGNR_INFO_
{
  DWORD             cbStruct;
  LPCWSTR           pcwszDisplayName
  CMSG_SIGNER_INFO  *psSignerInfo;
  DWORD             chStores;
  HCERTSTORE        *pahStores;

} WINTRUST_SGNR_INFO, *PWINTRUST_SGNR_INFO;

Members

cbStruct
Count of bytes in this structure.
pcwszDisplayName
String with the name representing the signer to be checked.
psSignerInfo
Pointer to a CMSG_SIGNER_INFO structure that includes the signature to be verified.
chStores
The number of store handles in pahStores.
pahStores
An array of open certificate stores to be added to the list of stores that the policy provider uses to find certificates while building a trust chain.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Winbase.h.


WINTRUST_CERT_INFO

The WINTRUST_CERT_INFO structure is used when calling WinVerifyTrust to verify a CERT_CONTEXT.

typedef struct WINTRUST_CERT_INFO_
{
  DWORD         cbStruct;
   LPCWSTR      pcwszDisplayName;
  CERT_CONTEXT  *psCertContext;
  DWORD         chStores;
  HCERTSTORE    *pahStores;
} WINTRUST_CERT_INFO, *PWINTRUST_CERT_INFO;

Members

cbStruct
Count of bytes in this structure.
pcwszDisplayName
String with the name of the memory object pointed to by the pbMem member of the WINTRUST_BLOB_INFO structure.
psCertContext
Pointer to the CERT_CONTEXT to be verified.
chStores
The number of store handles in pahStores.
pahStores
An array of open certificate stores to add to the list of stores that the policy provider looks in to find certificates while building a trust chain.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 or later.
Header: Declared in Winbase.h.


Smart Card

Purpose

Smart Card provides services for developing and using smart card systems. It provides a link between smart card readers and smart card – aware applications running in the personal-computer environment. Smart Card is designed specifically for Microsoft® Windows® 95 OSR2.1, Windows 98, and Windows NT®/Windows® 2000, with support for CryptoAPI and the Windows driver model.

About Smart Card

General information about Smart Card.

Smart Card Reference

Documentation of Smart Card functions, structures, interfaces, and error codes.

Feedback

Make error reports and feature requests directly to Microsoft.


About Smart Card

The basic components of the smart card subsystem are based on PC/SC standards (see specifications at http://www.pcscworkgroup.com/). These basic components include:

  • A resource manager that uses a Win32® application programming interface (API).
  • A user interface (UI) that works with the resource manager.
  • Several base service providers that provide access to specific services. In contrast to the resource manager's Win32® API, service providers use a COM interface model to provide smart card services.

The following illustration shows the relationships of these components in the overall smart card architecture.

For information on how the smart card subsystem works with other services available in the Microsoft Internet Security Framework, see Relation to Other Services.

The basic components for Smart Card are already installed on Microsoft® Windows® 2000 platforms. For Microsoft Windows NT®, Microsoft Windows 95 (OSR2.1) and Microsoft Windows 98, the components can be installed by means of the smart card redistributables contained in the Platform SDK. The installation CDs for Windows 95 (OSR2.1) and Windows 98 also contain the basic components.

For information about Smart Card components, see the following topics.

Topics | Contents
Smart Card Concepts | Basic concepts describing the interaction between users and smart cards.
Smart Card Resource Manager | The resource manager API, which manages the access to readers and to smart cards.
Smart Card User Interface | The smart card common dialog.
Smart Card Service Providers | Interfaces, commands, and wrappers that provide smart card capabilities.

Additionally, current Microsoft smart card developments can be found at http://www.microsoft.com/smartcard/.


Smart Card Concepts

This section covers some basic concepts that may be used when describing the interaction between users (and applications) and smart cards. These concepts include terms, as well as a discussion of two basic interactions between users and smart cards. However, this section does not attempt to describe all possible ways a user might interact with a smart card.

Note In addition to the basic concepts described here, the Smart Card Glossary also provides definitions of the terms used throughout these documents.

For Information On… | See…
Readers and reader groups | SMART CARD Readers
Smart cards and their COM interfaces | Smart Card Interfaces
Exposing card services to different programming environments | Primary Service Provider
Smart card setup utilities and the information they must supply | Introducing Smart Cards to the System
How an application or service provider connects to a smart card | Accessing a Smart Card
How other parts of the Microsoft Internet Security Framework use Smart Card | Relation to Other Services

For information on how the smart card subsystem works with other services available in the Microsoft Internet Security Framework, see Relation to Other Services.


Smart Card Readers

Readers are standard devices in a smart card system. They are controlled through drivers, and are introduced to and removed from the system through Plug and Play or through the control panel Devices applet.

Each reader must be defined for use by the smart card subsystem. The subsystem is not responsible for any reader not specifically given to it.

Smart card readers can be divided into logical groups called reader groups. These groups can be defined by the subsystem, as well as defined by administrators and users. A reader can belong to more than one reader group

The smart card subsystem defines the following groups.

SCard$AllReaders
This group contains all the readers in the system. A new reader given to the smart card subsystem is automatically included in the system-wide reader group, SCard$AllReaders.
SCard$DefaultReaders
This default group, one for each terminal, contains all the readers assigned to the terminal that are not reserved for specific use.


Smart Card Interfaces

A smart card interface consists of a predefined set of services available within a smart card, the protocols necessary to invoke the services, and any assumptions regarding the context of the services.

With respect to smart cards, the term "interface" is similar to how it is used in COM, which in turn is similar in concept to the ISO 7816/5 application identifier but with a different scope.

Each smart card interface is identified by a globally unique identifier (GUID). For example, an interface might be defined that provides biorhythm information to its holder. If a given smart card supports this service, then it may claim to support that interface GUID. Using the interface GUIDs, an application may search for a particular set of interfaces, locating any card that supports that set, to complete a task.

Although an interface has one GUID, it might be implemented differently on different cards. For example, the biorhythm interface mentioned above can have several different implementations, yet all are referenced using the same GUID. The different implementations would not change the interaction between the application and the smart card; however, the interaction between the service provider and the smart cards may differ depending on the interface's implementation.

The set of interfaces supported by a smart card is defined during smart card introduction (see Introducing Smart Cards to the System).


Primary Service Provider

Each smart card known to the system may have a registered COM interface listed as its primary service provider. When you access a smart card through COM, this primary service provider supplies the control interfaces to the card. This allows card services to be exposed to a wide range of programming environments, including Java and Visual Basic.


Introducing Smart Cards to the System

Before the smart card subsystem can find a smart card, the smart card must be introduced to the system. This is typically done with a smart card setup utility provided by the card manufacturer. The utility could come as a program on a floppy disk (with the smart card), an ActiveX control available on a web site, and so on.

The setup utility must provide the following pieces of information about the card:

  • Its ATR string, and an optional mask to use as an aid in identifying the card.
  • A list of smart card interfaces supported by the card.
  • A friendly name for the card, to be used in identifying the card to the user. In most cases, the user will supply this to the setup utility.
  • The primary service provider associated with the card (optional), to be used when accessing the card through COM interfaces.

To simplify setup utilities, and to ensure the integrity of the smart card database, the smart card subsystem provides the following two functions. SCardIntroduceCardType introduces a smart card into the database and SCardForgetCardType removes it from the database.


Accessing a Smart Card

The smart card subsystem provides several means for an application or service provider to connect to a smart card:

  • An application can call SCardConnect to connect to a card that resides in a given reader. This is the simplest way to establish communication with a smart card.
  • An application can search for a specific smart card within a given reader group. The application identifies the card by its friendly name, and specifies a list of readers in which the card may appear. The resource manager searches the list of readers for any cards with an ATR string that matches the named card, and returns status information to the application. The smart card subsystem never puts up a GUI or interacts with the card beyond obtaining the ATR string. It does, however, supply sufficient information for the application or a common control to be able to walk the user through locating the desired card or card type. This results in mapping the request to a specific reader, to which further I/O is directed.
  • An application can request a list of cards supporting a given set of smart card interfaces. The application can then use the list in the previous case. This allows applications to connect to cards based on their capabilities, without regard to their names.

When an application looks for a card, it supplies an array of reader names in which to look. For each reader element in the array, the resource manager supplies the following information:

  • Whether the reader is available for use by this application.
  • Whether there is a card inserted into this reader, and if so, what its ATR string is.
  • Whether the card's ATR string matches any of the requested cards' ATR strings.

The application uses the returned information to apply further filters to the cards or to prompt the user to select the desired card. Note that one or more of the returned list of readers may be opened for exclusive use by other applications, so access to this list of readers is not guaranteed.


Relation to Other Services

Other parts of the Microsoft Internet Security Framework use the smart card subsystem, as shown in the following illustration. (Because of U.S. export restrictions, a CSP that uses an SCSP to communicate cryptographic-related requests should sign and verify the SCSP.)

See http://www.microsoft.com/smartcard/ for more information on the role of the smart card subsystem in the Microsoft Internet Security Framework.


Smart Card Resource Manager

The smart card resource manager manages the access to readers and to smart cards. To manage these resources, it performs the following three functions.

  • Identifies and tracks resources.
  • Allocates readers and resources across multiple applications.
  • Supports transaction primitives for accessing services available on a given card.

    Note This is an important point because current cards are single-threaded devices that often require the execution of multiple commands to complete a single function. Transactions allow multiple commands to be executed without interruption, ensuring that intermediate state information is not corrupted.

The resource manager can be accessed directly by way of the resource manager API or indirectly through any smart card service provider.

The resource manager API is a set of Win32® functions that provide direct access to the resource manager's services. (For an overview of the Win32 functions provided by the API, see Smart Card Resource Manager API.) In comparison, smart card service providers use COM interfaces.

Many of the Win32 functions in the resource manager API have equivalents in the properties and methods of the smart card service providers' COM interfaces. And although most application developers will find the COM model easier to work with, some applications will still need to use the Win32 functions to perform certain tasks. For example, applications that need to manipulate the list of readers or reader groups in the smart card database, and those that need direct control of a reader must use the resource manager API. The services that provide these capabilities are available only in the Win32 functions, not in the COM model provided by the service providers.

For information on how the resource manager is implemented in Microsoft® Windows®, see Resource Manager Implementation.


Resource Manager Implementation

The resource manager runs as a trusted service in a single process. All requests for smart card access are made to the resource manager, which routes them to the reader that contains the targeted card.

Smart cards are often used in conjunction with security and personal privacy. Wherever possible, the resource manager uses the security mechanisms existing within the underlying operating system when accessing a reader or smart card.


Smart Card Resource Manager API

The resource manager API provides the following functionality.

To… | See…
Query the smart card database. | Smart Card Database Query Functions
Manage the smart card database. | Smart Card Database Management Functions
Manage the context of the resource manager's database operations. | Resource Manager Context Functions
Release allocated memory. | Resource Manager Support Function
Track smart cards within readers. | Smart Card Tracking Functions
Connect to and communicate with a smart card, including transferring data using T=0, T=1, and raw protocols. | Smart Card and Reader Access Functions
Communicate with cards that may not conform to the ISO 7816 specifications. | Direct Card Access Functions


Smart Card Database Query Functions

These functions query the smart card database. They can provide a list of smart cards supplied by a specific user, the interfaces and primary service provider of a specific card, the reader groups defined for the system, and the readers within a set of reader groups.

When using these functions, you can query the complete smart card database, or you can narrow the search by setting the resource manager context. The resource manager context is set by calling SCardEstablishContext) before calling a query function.

Note Without a specified context, some information may still be inaccessible due to security restrictions.

To… | Call…
Retrieve the identifier (GUID) of the primary service provider for the given card. | SCardGetProviderId
Retrieve a list of cards previously introduced to the system by a specific user. | SCardListCards
Retrieve the identifiers (GUIDs) of the interfaces supplied by a given card. | SCardListInterfaces
Retrieve a list of reader groups that have previously been introduced to the system. | SCardListReaderGroups
Retrieve the list of readers within a set of named reader groups. | SCardListReaders


Smart Card Database Management Functions

These functions manage the smart card database, updating the database using a specified resource manager context.

Note Database security is maintained by placing access restrictions on the database, rather than by adding security mechanisms to the smart card subsystem.

To… | Call…
Add a reader to a reader group. | SCardAddReaderToGroup
Remove a smart card from the system. | SCardForgetCardType
Remove a reader from the system. | SCardForgetReader
Remove a reader group from the system. | SCardForgetReaderGroup
Introduce a new card to the system. | SCardIntroduceCardType
Introduce a new reader to the system. | SCardIntroduceReader
Introduce a new reader group to the system. | SCardIntroduceReaderGroup
Remove a reader from a reader group. | SCardRemoveReaderFromGroup


Resource Manager Context Functions

These functions establish and release the resource manager context that is used by the database query and database management functions.

To… | Call…
Establishes a context for accessing the smart card database. | SCardEstablishContext
Closes an established context. | SCardReleaseContext


Resource Manager Support Function

This function frees memory allocated through the use of the SCARD_AUTOALLOCATE length designator, simplifying the use of the other resource manager functions.

To… | Call…
Releases memory returned through the use of SCARD_AUTOALLOCATE. | SCardFreeMemory


Smart Card Tracking Functions

These functions let you track cards within readers. These routines typically use the SCARD_READERSTATE structure within an array.

To… | Call…
Search for a card whose ATR string matches a supplied card name. | SCardLocateCards
Block execution until the current availability of cards changes. | SCardGetStatusChange
Terminate outstanding actions. | SCardCancel


Smart Card and Reader Access Functions

These functions connect to and communicate with a specific smart card. I/O operations to the card use a buffer for sending or receiving data and a structure that contains protocol control information. The protocol control information structure always begins with an SCARD_IO_REQUEST structure.

To… | Call…
Connect to a card. | SCardConnect
Reestablish a connection. | SCardReconnect
Terminate a connection. | SCardDisconnect
Start a transaction, blocking other applications from accessing a card. | SCardBeginTransaction
End a transaction, allowing other applications to access a card. | SCardEndTransaction
Provide the current status of the reader. | SCardStatus
Requests service and receives data back from a card using T=0, T=1, and raw protocols. | SCardTransmit


Direct Card Access Functions

The smart card subsystem lets you communicate with cards that may not conform to the ISO 7816 specifications. To do this, these functions allow you to control the attributes of the communications between the application and the card by giving you direct, low-level manipulation of the reader.

To use these functions, you have to supply an identifier for the attribute in question. For valid attribute identifiers and values, refer to Table 3-1 in Requirements for PC-Connected Interface Devices.

To… | Call…
Provide direct control of the reader. | SCardControl
Get reader attributes. | SCardGetAttrib
Set reader attribute. | SCardSetAttrib


Smart Card User Interface

The smart card user interface (UI) is a single common dialog that lets the user specify or search for a smart card to open (that is, connect to and use in an application).

Following are two ways you can use the common dialog. Both assume that the dialog UI will be displayed. (See OPENCARDNAME for more information.)

To let the user select a smart card to open (that is, connect to and use in the calling application)

  1. Declare a variable of type OPENCARDNAME.
  2. Fill in the appropriate information for the common dialog to narrow the search for a card that the calling application is looking for. This would include specifying lpstrGroupNames, lpstrCardNames, and, in future releases, rgguidInterfaces. This would also include specifying a preferred sharemode and protocol to use when the common dialog connects to the card using the dwShareMode and dwProtocols OPENCARDNAME structure members.
  3. Call the GetOpenCardName function to display the common dialog to the user. A simple help information line will be displayed, and if one of the cards being requested is found, the card will be highlighted in the display. For multiple card name searches, the first reader containing one of the preferred cards will be highlighted.

  4. The user then selects a card, clicks OK, and connects to the smart card.

To search for a specific card by using the lpfnConnect, lpfnCheck, and lpfnDisconnect callback functions.

  1. Declare a variable of type OPENCARDNAME.
  2. Fill in the appropriate information for the common dialog to use to narrow the search for a card that the calling application seeks. This would include giving lpstrGroupNames, lpstrCardNames, and, in future releases, rgguidInterfaces).
  3. In addition, create the Connect, Check, and Disconnect callback functions and set the lpfnConnect, lpfnCheck, and lpfnDisconnect OPENCARDNAME data members appropriately.

    Note All three functions and members must be available when using the common dialog in this way.

  4. Call the GetOpenCardName common dialog function.
  5. The common dialog will then look for the requested cards. If a matching card name or ATR string is found, the Connect, Check, and Disconnect callback functions will be called in sequence. If a card passes the Check routine (that is, the Check callback returns TRUE), this card is highlighted in the display to the user.

    Note If multiple card names are given, the first reader that contains one of the requested cards and passes the Check routine will be the selected card.

  6. If no matches are found, the common dialog seen above will appear.


Smart Card Service Providers

Smart Card Service Providers (SCSP) provide access to Smart Card capabilities. They can provide access to a single capability, such as the base service providers provided by the Smart Card SDK, or they can provide access to several capabilities in order to accomplish a more complex task.

Service providers provide access through COM interfaces. The Smart Card SDK provides the COM interfaces used by its own base service providers, as well as several application interfaces that can be used when developing custom service providers.

For Information On… | See…
Base service providers | Base Service Providers
Adding functionality to a service provider. | Building an ISO7816-4 APDU Command
A vendor wrapper example. | Vendor Wrapper Service Provider

For an overview of all the COM interfaces provided by the smart card SDK (base service provider and application interfaces), see Smart Card Interfaces.


Base Service Providers

These service providers provide the basic smart card capabilities. They can be used to access a single smart card capability, or their COM interfaces can be combined to provide several capabilities within a single service provider. These service providers are the building blocks for developing additional functionality to other service providers.

The following tasks can be performed by base service provider interfaces supplied by the Smart Card SDK.

To… | Use… | In DLL…
Connect to a smart card, implement transactions, close connections, etc. | ISCard | SCardSSP
Maintain a command APDU and reply APDU. | ISCardCmd | SCardSSP
Query the smart card database. | ISCardDatabase | SCardSSP
Locate a smart card or reader. | ISCardLocate | SCardSSP
Build an ISO7816-4 command APDU. | ISCardISO7816 | SCardSSP
Wrap an Istream buffer using Microsoft® Visual Basic® – compatible types. | IByteBuffer | SCardSSP

The following example shows a typical use of these base service provider interfaces. In this example, the ISCard, ISCardISO7816, and ISCardCmd interfaces are used to perform a transaction.

To perform a transaction

  1. Create an instance for all base service provider interfaces needed (for example, ISCard, ISCardISO7816, and ISCardCmd).
  2. Connect to a particular smart card using the methods in the ISCard interface.
  3. Using ISCardISO7816 and an ISCardCmd object, build an ISO 7816-4 command by calling an ISCardISO7816 method. The command is contained in ISCardCmd as the command APDU.
  4. Do a transaction with the card by calling the ISCard transaction method and passing the created ISCardCmd object. When the transaction is complete, the results are stored in ISCardCmd reply APDU.
  5. Interpret the ISCardCmd reply APDU and repeat.
  6. Release all interfaces when operations are complete.

For information on the APDU command is built within the DLLs, see Building an ISO7816-4 APDU Command.


Building an ISO7816-4 APDU Command

To add functionality to a service provider, you need to know how an ISO7816-4 APDU is built within the base service provider DLLs. The following procedure gives a brief overview of the build process.

Note The code segments included here are not necessarily complete; refer to the example applications and DLLs for more information.

To Build an ISO7816-4 APDU Command

  1. Create an instance of ISCardCmd and ISCardISO7816 interface/objects.

    // Create an ISCardCmd object
// Note: To use CoCreateInstance on Windows 95, make sure no Distributed COM
// flags are included in the API call or during build. Do not define flags
// _WIN32_DCOM or _WIN32_WINNT >= 0x0400.
hresult = CoCreateInstance(CLSID_CSCardCmd,
                           NULL,
                           CLSCTX_ALL,
                           IID_ISCardCmd,
                           (LPVOID*) &g_pISCardCmd);
//Create an ISCardISO7816 object
hresult = CoCreateInstance(CLSID_CSCardISO7816,
                           NULL,
                           CLSCTX_ALL,
                           IID_ISCardISO7816,
                           (LPVOID*) &g_pISCardISO7816);

    The ISCardCmd object contains two IByteBuffer buffers. One buffer contains the actual APDU command string (plus any data to send with the command). The other contains any reply information returned by the card after command execution.

  2. Using these objects, we can now create a valid ISO7816-4 command as follows:
    // Do challenge
hresult = g_pISCardISO7816->GetChallenge(dwLengthOfChallenge,
                                         &g_pISCardCmd);

    Here is the code used in the GetChallenge method:

    STDMETHODIMP CSCardISO7816::GetChallenge(IN DWORD dwBytesExpected /*= 0*/,
                                         IN OUT LPSCARDCMD *ppCmd)
{
    // Locals.
    HRESULT hr = S_OK;

    try
    {
        // Is the ISCardCmd object ok?
        hr = IsSCardCmdValid(ppCmd);
        if (FAILED(hr))
            throw (hr);

        // Do it!
        hr = (*ppCmd)->BuildCmd(m_byClassId,
                                (BYTE) INS_GET_CHALLENGE),
                                (BYTE) INS_NULL),// P1 = 0x00
                                (BYTE) INS_NULL),// P2 = 0x00
                                NULL,
                                &dwBytesExpected);
        if (FAILED(hr))
            throw (hr);
    }
}

    The ISCardISO7816::GetChallenge method simply uses the ISCardCmd::BuildCmd to build the requested APDU. This is done by writing the appropriate information into the ISCardCmd APDU buffer in the hr = (*ppCmd)->BuildCmd line above.

  3. Using the built ISCardCmd object, do a transaction with the card, interpret the results, and continue.

Expanding beyond ISO7816-4

The recommended way to expand the service provider build-execute process described above is to create a new COM object. This COM object should support a new interface that allows creation of non-ISO7816-4 commands and should aggregate the ISCardISO7816 interface.


Vendor Wrapper Service Provider

The purpose of the vendor wrapper is to encapsulate and utilize the low-level COM interfaces (supplied by the smart card manufacturers) for a particular smart card. These interfaces are not supplied by Microsoft.

As described in part 6 of the Interoperability Specification for ICCs and Personal Computer Systems (see specifications at http://www.pcscworkgroup.com/), the functionality exposed by this wrapper is easier to use than the functionality of four separate service providers. The wrapper's functionality can be divided into four main areas:

  • Smart card authentication services, such as get challenge and card authentication.
  • Smart card file access or file system services, such as open, close, read, and write.
  • Smart card management, such as attach and detach.
  • Smart card verification services, such as verify and change code.

The functionality is specific to the type of card being used (which functions the card supports, protocols, etc.) and will be different for each card.

The Microsoft SCardCOM example wrapper uses the ATL COM library to implement a simple wrapper and lay down a template for other wrappers. It implements the following interfaces.

Interface/Object | Description
ISCardAuth | Authentication services.
ISCardFileAccess | File system services.
ISCardManage | Management services.
ISCardVerify | Verification services.

Note The SCardCOM example is provided only as an example of implementing the wrapper interfaces. To prevent DLL name collision with other vendors, you must not use SCardCOM.dll as the name of any DLLs you create.

Following is a typical use of the vendor wrapper. This example uses the ISCardManage interface to create instances of the interfaces that will be wrapped into the service provider and the ISCardVerify interface to verify their operation.

To build a wrapper service provider

  1. Create an instance of the ISCardManage interface. Use this interface to create an instance of required interfaces (for example, ISCardFileAccess or ISCardVerify). When creating these interfaces, any corresponding low-level COM interfaces would also be created.
  2. Attach/connect to a card through the appropriate ISCardManage method.
  3. Perform required operations through the appropriate ISCardVerify method (which may call multiple low-level COM interfaces and methods to complete).
  4. Repeat for other operations.
  5. Release when complete.

The COM interface name and interface identifier (GUID) should not change from those used in the code or example wrapper. However, the class GUID (that is, where an actual implementation of an interface resides) must be changed from those used. This is especially important when implementing a vendor wrapper. One example would be using multiple vendor wrappers on a particular computer. These wrappers should implement the same COM interfaces, but will always use different implementation strategies. Therefore, different classes (and class IDs) are required.


Smart Card Reference

This section describes the functions, structures, interfaces, and error codes provided by Smart Card.

Section | Contents
Smart Card Functions | Functions which allow interaction with smart cards and smart card readers.
Smart Card Structures | Structures used by smart card functions.
Smart Card Interfaces | Interfaces which may be used in smart card operations.
Smart Card Error Codes | Primary error codes returned by smart card functions.


Smart Card Functions

The Smart Card SDK provides the following functions.

Function | Description
GetOpenCardName | Displays the smart card "select card" dialog. (Replaced by SCardUIDlgSelectCard in Microsoft® Windows® 2000).
SCardAddReaderToGroup | Adds a reader to a reader group.
SCardBeginTransaction | Starts a transaction.
SCardCancel | Terminates all outstanding actions within a context.
SCardCancelTransaction | Reserved for future use.
SCardConnect | Establishes a connection between the calling application and a smart card.
SCardControl | Gets direct control of the reader after SCardConnect is called.
SCardDisconnect | Terminates a connection between the calling application and a smart card.
SCardEndTransaction | Completes a transaction.
SCardEstablishContext | Establishes a resource manager context for accessing the smart card database.
SCardForgetCardType | Removes a previously defined smart card from the smart card subsystem.
SCardForgetReader | Removes a previously defined reader from the smart card subsystem.
SCardForgetReaderGroup | Removes a previously defined reader group from the smart card subsystem.
SCardFreeMemory | Releases memory allocated by resource manager.
SCardGetAttrib | Gets the current reader's attributes from a given reader, driver, or smart card.
SCardGetCardTypeProviderName | Gets the provider name given a card name and provider type.
SCardGetProviderId | Gets the identifier (GUID) of the Primary Service Provider for a smart card.
ScardGetStartedEvent | Gets an event handle when the starting of a smart card resource manager is signaled.
SCardGetStatusChange | Blocks execution until status of the reader(s) changes.
SCardIntroduceCardType | Introduces a new smart card to the smart card subsystem.
SCardIntroduceReader | Introduces a new reader to the smart card subsystem.
SCardIntroduceReaderGroup | Introduces a new reader group to the smart card subsystem.
SCardIsValidContext | Verifies a smart card context handle.
SCardListCards | Provides a list of smart cards already introduced to the subsystem.
SCardListInterfaces | Provides a list of interfaces supplied by a given smart card.
SCardListReaderGroups | Provides a list of reader groups already introduced to the subsystem.
SCardListReaders | Provides a list of readers already introduced to the subsystem.
SCardLocateCards | Locates the card(s) that matches a given ATR string.
SCardReconnect | Reestablishes an existing connection from the calling application to the smart card.
SCardReleaseContext | Closes an established resource manager context.
SCardRemoveReaderFromGroup | Removes a reader from an existing reader group.
SCardSetAttrib | Sets a given reader attribute.
SCardSetCardTypeProviderName | Sets the provider name for a card name and provider type.
SCardStatus | Gets the current state of a reader.
SCardTransmit | Sends a service request to a smart card.
SCardUIDlgSelectCard | Displays the smart card "select card" dialog.


GetOpenCardName

The GetOpenCardName function displays the smart card "select card" dialog. Beginning with Microsoft® Windows® 2000, call the function SCardUIDlgSelectCard instead of GetOpenCardName. GetOpenCardName is maintained for backward compatibility with version 1.0 of the Microsoft Smart Card Base Components, but calls to GetOpenCardName are mapped to SCardUIDlgSelectCard.

LONG GetOpenCardName(
  IN LPOPENCARDNAME pDlgStruc
);

Parameters

pDlgStruc
Points to the OPENCARDNAME structure for the "select card" dialog.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Example Code

SCARDCONTEXT    hSC;
OPENCARDNAME    dlgStruct;
WCHAR           szReader[256], szCard[256];
WCHAR           szSearchCard[20];
LONG            lReturn;

// Specify the search card.
lstrcpy( szSearchCard, L"GemSAFE");
// A trailing second NULL is necessary.
szSearchCard[lstrlen(szSearchCard) + 1] = (WCHAR)0x00;

// Establish a context.
// It will be assigned to the structure's hSCardContext field.
lReturn = SCardEstablishContext( SCARD_SCOPE_USER,
                                NULL,
                                NULL,
                                &hSC );
if ( SCARD_S_SUCCESS != lReturn )
{
    printf("Failed SCardEstablishContext\n");
    exit(1);
}

// Initialize the structure.
memset( &dlgStruct, 0, sizeof (dlgStruct) );
dlgStruct.dwStructSize = sizeof (dlgStruct);
dlgStruct.hSCardContext = hSC;
dlgStruct.dwFlags = SC_DLG_FORCE_UI;
dlgStruct.lpstrRdr = szReader;
dlgStruct.nMaxRdr = 256;
dlgStruct.lpstrCard = szCard;
dlgStruct.nMaxCard = 256;
dlgStruct.lpstrTitle = L"My Select Card Title";
dlgStruct.lpstrCardNames = szSearchCard;
dlgStruct.nMaxCardNames = 20;

// Display the select card dialog.
lReturn = GetOpenCardName( &dlgStruct);
if ( SCARD_S_SUCCESS != lReturn )
    printf("Failed GetOpenCardName - %x\n", lReturn );
else
    printf("Reader: %S\nCard: %S\n", szReader, szCard );

// Release the context (by SCardReleaseContext - not shown here).

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Scarddlg.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

OPENCARDNAME


SCardAddReaderToGroup

The SCardAddReaderToGroup function adds a reader to a reader group.

LONG SCardAddReaderToGroup(
  IN SCARDCONTEXT hContext,
  IN LPCTSTR szReaderName,
  IN LPCTSTR szGroupName
);

Parameters

hContext
Supplies the handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
szReaderName
Supplies the friendly name of the reader that you are adding.
szGroupName
Supplies the friendly name of the group to which you are adding the reader.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

SCardAddReaderToGroup automatically creates the reader group specified if it does not already exist. SCardAddReaderToGroup is a database management function. For a description of other database management functions, see Smart Card Database Management Functions.

Example Code

// Add a reader to the group.
// lReturn is of type LONG.
// hContext was set by a previous call to SCardEstablishContext.
// "MyReader" and "MyReaderGroup" are known by the system (via
// SCardIntroduceReader and SCardIntroduceReaderGroup, respectively).
lReturn = SCardAddReaderToGroup( hContext,
                                L"MyReader",
                                L"MyReaderGroup");
if ( SCARD_S_SUCCESS != lReturn )
    printf("Failed SCardAddReaderToGroup\n");

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

SCardEstablishContext, SCardIntroduceReader, SCardIntroduceReaderGroup, SCardRemoveReaderFromGroup


SCardBeginTransaction

The SCardBeginTransaction function starts a transaction, waiting for the completion of all other transactions before it begins.

When the transaction starts, all other applications are blocked from accessing the smart card while the transaction is in progress.

LONG SCardBeginTransaction(
  IN SCARDHANDLE hCard
);

Parameters

hCard
Supplies the reference value obtained from a previous call to SCardConnect.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

SCardBeginTransaction is a smart card and reader access function. For a description of other access functions, see Smart Card and Reader Access Functions.

Example Code

// Begin a transaction.
// lReturn is of type LONG.
// hCard was previously set by SCardConnect.
lReturn = SCardBeginTransaction( hCard );
if ( SCARD_S_SUCCESS != lReturn )
    printf("Failed SCardBeginTransaction\n");

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.

See Also

SCardConnect, SCardEndTransaction


SCardCancel

The SCardCancel function terminates all outstanding actions within a specific resource manager context.

The only requests that you can cancel are those that require waiting for external action by the smart card or user. Any such outstanding action requests will terminate with a status indication that the action was canceled. This is especially useful to force outstanding SCardGetStatusChange calls to terminate.

LONG SCardCancel(
  IN SCARDCONTEXT hContext
);

Parameters

hContext
Supplies the handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

SCardCancel is a smart card tracking function. For a description of other tracking functions, see Smart Card Tracking Functions.

Example Code

// Cancel the wait for external action.
// lReturn is of type LONG.
// hContext was previously set by SCardEstablishContext.
lReturn = SCardCancel( hContext );
if ( SCARD_S_SUCCESS != lReturn )
    printf("Failed SCardCancel\n");

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.

See Also

SCardEstablishContext, SCardGetStatusChange, SCardLocateCards


SCardConnect

The SCardConnect function establishes a connection (using a specific resource manager context) between the calling application and a smart card contained by a specific reader. If no card exists in the specified reader, an error is returned.

LONG SCardConnect(
  IN SCARDCONTEXT hContext,
  IN LPCTSTR szReader,
  IN DWORD dwShareMode,
  IN DWORD dwPreferredProtocols,
  OUT LPSCARDHANDLE phCard,
  OUT LPDWORD pdwActiveProtocol
);

Parameters

hContext
Supplies the handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
szReader
Supplies the name of the reader containing the target card.
dwShareMode
Supplies a flag that indicates whether other applications may form connections to the card. The following are the possible values.
Value | Meaning
SCARD_SHARE_SHARED | This application is willing to share the card with other applications.
SCARD_SHARE_EXCLUSIVE | This application is not willing to share the card with other applications.
SCARD_SHARE_DIRECT | This application is allocating the reader for its private use, and will be controlling it directly. No other applications are allowed access to it.

dwPreferredProtocols
Supplies a bit mask of acceptable protocols for the connection. Possible values, which may be combined with the OR operation.
Value | Meaning
SCARD_PROTOCOL_T0 | T=0 is an acceptable protocol.
SCARD_PROTOCOL_T1 | T=1 is an acceptable protocol.
0 | This parameter may be zero only if dwShareMode is set to SCARD_SHARE_DIRECT. In this case, no protocol negotiation will be performed by the drivers until an IOCTL_SMARTCARD_SET_PROTOCOL control directive is sent with SCardControl.

phCard
Receives a handle that identifies the connection to the smart card in the designated reader.
pdwActiveProtocol
Receives a flag that indicates the established active protocol. The following are the possible values.
Value | Meaning
SCARD_PROTOCOL_T0 | T=0 is the active protocol.
SCARD_PROTOCOL_T1 | T=1 is the active protocol.
SCARD_PROTOCOL_UNDEFINED | SCARD_SHARE_DIRECT has been specified, so that no protocol negotiation has occurred. It is possible that there is no card in the reader.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

SCardConnect is a smart card and reader access function. For a description of other access functions, see Smart Card and Reader Access Functions.

Example Code

SCARDHANDLE     hCardHandle;
LONG            lReturn;
DWORD           dwAP;

// Connect to the reader.
// hContext is a SCARDCONTEXT previously set by
// a call to SCardEstablishContext.
lReturn = SCardConnect( hContext,
                        L"Rainbow Technologies SCR3531 0",
                        SCARD_SHARE_SHARED,
                        SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
                        &hCardHandle,
                        &dwAP );
if ( SCARD_S_SUCCESS != lReturn )
{
    printf("Failed SCardConnect\n");
    exit(1);  // Or other appropriate action.
}

// Use the connection; here we will merely display the
// active protocol.
switch ( dwAP )
{
    case SCARD_PROTOCOL_T0:
        printf("Active protocol T0\n");
        break;

    case SCARD_PROTOCOL_T1:
        printf("Active protocol T1\n");
        break;

    case SCARD_PROTOCOL_UNDEFINED:
    default:
        printf("Active protocol unnegotiated or unknown\n");
        break;
}

// Remember to disconnect (by calling SCardDisconnect).
// …

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

SCardControl, SCardDisconnect, SCardEstablishContext, SCardReconnect


SCardControl

The SCardControl function gives you direct control of the reader. You can call it any time after a successful call to SCardConnect and before a successful call to SCardDisconnect. The effect on the state of the reader depends on the control code.

LONG SCardControl(
  IN SCARDHANDLE hCard,
  IN DWORD dwControlCode,
  IN LPCVOID lpInBuffer,
  IN DWORD nInBufferSize,
  OUT LPVOID lpOutBuffer,
  IN DWORD nOutBufferSize,
  OUT LPDWORD lpBytesReturned
);

Parameters

hCard
This is the reference value returned from SCardConnect.
dwControlCode
Supplies the control code for the operation. This value identifies the specific operation to be performed.
lpInBuffer
Supplies a pointer to a buffer that contains the data required to perform the operation. This parameter can be NULL if the dwControlCode parameter specifies an operation that does not require input data.
nInBufferSize
Supplies the size, in bytes, of the buffer pointed to by lpInBuffer.
lpOutBuffer
Points to a buffer that receives the operation's output data. This parameter can be NULL if the dwControlCode parameter specifies an operation that does not produce output data.
nOutBufferSize
Supplies the size, in bytes, of the buffer pointed to by lpOutBuffer.
lpBytesReturned
Points to a DWORD that receives the size, in bytes, of the data stored into the buffer pointed to by lpOutBuffer.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

SCardControl is a direct card access function. For a description of other direct access functions, see Direct Card Access Functions.

Example Code

// Issue a control code.
// hCardHandle was set by a previous call to SCardConnect.
// dwControlCode is of type DWORD and
// was previously set to a valid control code.
// This particular control code requires no input data
// and expects no output data.
lReturn = SCardControl( hCardHandle,
                        dwControlCode,
                        NULL,
                        0,
                        NULL,
                        0,
                        0 );
if ( SCARD_S_SUCCESS != lReturn )
    printf("Failed SCardControl\n");

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.

See Also

SCardConnect, SCardDisconnect


SCardDisconnect

The SCardDisconnect function terminates a connection previously opened between the calling application and a smart card in the target reader.

LONG SCardDisconnect(
  IN SCARDHANDLE hCard,
  IN DWORD dwDisposition
);

Parameters

hCard
Supplies the reference value obtained from a previous call to SCardConnect.
dwDisposition
Indicates what to do with the card in the connected reader on close. The following are the possible values.
Value | Meaning
SCARD_LEAVE_CARD | Don't do anything special.
SCARD_RESET_CARD | Reset the card.
SCARD_UNPOWER_CARD | Power down the card.
SCARD_EJECT_CARD | Eject the card.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

If an application (which previously called SCardConnect) exits without calling SCardDisconnect, the card is automatically reset.

SCardDisconnect is a smart card and reader access function. For a description of other access functions, see Smart Card and Reader Access Functions.

Example Code

// Terminate the connection.
// lReturn is a LONG variable.
// hCardHandle was set by a previous call to SCardConnect.
lReturn = SCardDisconnect(hCardHandle,
                          SCARD_LEAVE_CARD);
if ( SCARD_S_SUCCESS != lReturn )
{
    printf("Failed SCardDisconnect\n");
    exit(1);  // Or other appropriate action.
}

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.

See Also

SCardConnect, SCardReconnect


SCardEndTransaction

The SCardEndTransaction function completes a previously declared transaction, allowing other applications to resume interactions with the card.

LONG SCardEndTransaction(
  IN SCARDHANDLE hCard,
  IN DWORD dwDisposition
);

Parameters

hCard
Supplies the reference value obtained from a previous call to SCardConnect. This value would also have been used in an earlier call to SCardBeginTransaction.
dwDisposition
Indicates what to do with the card in the connected reader on close. The following are the possible values.
Value | Meaning
SCARD_LEAVE_CARD | Don't do anything special.
SCARD_RESET_CARD | Reset the card.
SCARD_UNPOWER_CARD | Power down the card.
SCARD_EJECT_CARD | Eject the card.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

SCardEndTransaction is a smart card and reader access function. For a description of other access functions, see Smart Card and Reader Access Functions.

Example Code

// End a transaction.
// lReturn is of type LONG.
// hCard was previously set by SCardConnect, and was
// used in an earlier call to SCardBeginTransaction.
lReturn = SCardEndTransaction(hCard,
                              SCARD_LEAVE_CARD);
if ( SCARD_S_SUCCESS != lReturn )
    printf("Failed SCardEndTransaction\n");

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.

See Also

SCardConnect, SCardBeginTransaction


SCardEstablishContext

The SCardEstablishContext function establishes the resource manager context (the scope) within which database operations are performed.

LONG SCardEstablishContext(
  IN DWORD dwScope,
  IN LPCVOID pvReserved1,
  IN LPCVOID pvReserved2,
  OUT LPSCARDCONTEXT phContext
);

Parameters

dwScope
Supplies the scope of the resource manager context. The following are the possible values.
Value | Meaning
SCARD_SCOPE_USER | Database operations are performed within the domain of the user.
SCARD_SCOPE_SYSTEM | Database operations are performed within the domain of the system. (The calling application must have appropriate access permissions for any database actions.)

pvReserved1
Reserved for future use, and must be NULL. Reserved to allow a suitably privileged management application to act on behalf of another user.
pvReserved2
Reserved for future use, and must be NULL. Reserved to allow a suitably privileged management application to act on behalf of another terminal.
phContext
Receives a handle to the established resource manager context. This handle can now be supplied to other functions attempting to do work within this context.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

The context handle returned by SCardEstablishContext can be used by database query and management functions. For a description of these functions see, Smart Card Database Query Functions and Smart Card Database Management Functions.

To release an established resource manager context, use SCardReleaseContext.

Example Code

SCARDCONTEXT    hSC;
LONG            lReturn;
// Establish the context.
lReturn = SCardEstablishContext(SCARD_SCOPE_USER,
                                NULL,
                                NULL,
                                &hSC);
if ( SCARD_S_SUCCESS != lReturn )
    printf("Failed SCardEstablishContext\n");
else
{
    // Use the context as needed. When done,
    // free the context by calling SCardReleaseContext.
    // …
}

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.

See Also

SCardReleaseContext


SCardForgetCardType

The SCardForgetCardType function removes an introduced smart card from the smart card subsystem.

LONG SCardForgetCardType(
  IN SCARDCONTEXT hContext,
  IN LPCTSTR szCardName
);

Parameters

hContext
Supplies the handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
szCardName
Supplies the friendly name of the card to be removed from the smart card database.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

SCardForgetCardType is a database management function. For a description of other database management functions, see Smart Card Database Management Functions.

Example Code

// Remove the card type from the system.
// lReturn is of type LONG.
// hContext was set by a previous call to SCardEstablishContext.
// "MyCardName" was previously introduced (by SCardIntroduceCardType).
lReturn = SCardForgetCardType(hContext,
                              L"MyCardName");
if ( SCARD_S_SUCCESS != lReturn )
    printf("Failed SCardForgetCardType\n");

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

SCardEstablishContext, SCardForgetReader, SCardForgetReaderGroup, SCardIntroduceCardType


SCardForgetReader

The SCardForgetReader function removes a previously introduced reader from control by the smart card subsystem. It is removed from the smart card database, including from any reader group that it may have been added to.

LONG SCardForgetReader(
  IN SCARDCONTEXT hContext,
  IN LPCTSTR szReaderName
);

Parameters

hContext
Supplies the handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
szReaderName
Supplies the friendly name of the reader to be removed from the smart card database.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

If the specified reader is the last member of a reader group, the reader group is automatically removed as well.

SCardForgetReader is a database management function. For a description of other database management functions, see Smart Card Database Management Functions.

Example Code

// Remove the friendly name of the reader from the system.
// lReturn is of type LONG.
// hContext was set by a previous call to SCardEstablishContext.
lReturn = SCardForgetReader(hContext,
                            TEXT("MyReader"));
if ( SCARD_S_SUCCESS != lReturn )
    printf("Failed SCardForgetReader\n");

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

SCardEstablishContext, SCardForgetCardType, SCardForgetReaderGroup, SCardIntroduceReader


SCardForgetReaderGroup

The SCardForgetReaderGroup function removes a previously introduced smart card reader group from the smart card subsystem. Although this function automatically clears all readers from the group, it does not affect the existence of the individual readers in the database.

LONG SCardForgetReaderGroup(
  IN SCARDCONTEXT hContext,
  IN LPCTSTR szGroupName
);

Parameters

hContext
Supplies the handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
szGroupName
Supplies the friendly name of the reader group to be removed. System-defined reader groups cannot be removed from the database.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

SCardForgetReaderGroup is a database management function. For a description of other database management functions, see Smart Card Database Management Functions.

Example Code

// Remove the reader group from the system.
// lReturn is of type LONG.
// hContext was set by a previous call to SCardEstablishContext.
lReturn = SCardForgetReaderGroup(hContext,
                                 L"MyReaderGroup");
if ( SCARD_S_SUCCESS != lReturn )
    printf("Failed SCardForgetReaderGroup\n");

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

SCardEstablishContext, SCardForgetCardType, SCardForgetReader, SCardIntroduceReaderGroup


SCardFreeMemory

The SCardFreeMemory function releases memory that has been returned from the resource manager using the SCARD_AUTOALLOCATE length designator.

LONG SCardFreeMemory(
  IN SCARDCONTEXT hContext,
  IN LPCVOID pvMem
);

Parameters

hContext
Supplies the handle that identifies the resource manager context returned from SCardEstablishContext, or NULL if the creating function also specified NULL for its hContext (see Smart Card Database Query Functions).
pvMem
Supplies the memory block to be released.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Example Code

// Free the memory.
// lReturn is of type LONG.
// hSC was set by an earlier call to SCardEstablishContext.
// pmszReaders was set by an earlier call to SCardListReaders.
lReturn = SCardFreeMemory(hSC,
                          pmszReaders );
if ( SCARD_S_SUCCESS != lReturn )
    printf("Failed SCardFreeMemory\n");

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.

See Also

SCardEstablishContext, SCardGetProviderId, SCardListCards' SCardListInterfaces, SCardListReaderGroups, SCardListReaders


SCardGetAttrib

The SCardGetAttrib function gets the current reader attributes for the given handle. It does not affect the state of the reader, driver, or card.

LONG SCardGetAttrib(
  IN SCARDHANDLE hCard,
  IN DWORD dwAttrId,
  OUT LPBYTE pbAttr,
  IN OUT LPDWORD pcbAttrLen
);

Parameters

hCard
Supplies the reference value returned from SCardConnect.
dwAttrId
Supplies the identifier for the attribute to get. The following table lists possible values for dwAttrId. These values are read-only. Note that vendors may not support all attributes.
Value | Description
SCARD_ATTR_ATR_STRING | Answer to reset (ATR) string.
SCARD_ATTR_CHANNEL_ID DWORD encoded as 0xDDDDCCCC, where DDDD = data channel type and CCCC = channel number:
  • The following encodings are defined for DDDD:
  • 0x01 serial I/O; CCCC is a port number.
  • 0x02 parallel I/O; CCCC is a port number.
  • 0x04 PS/2 keyboard port; CCCC is zero.
  • 0x08 SCSI; CCCC is SCSI ID number.
  • 0x10 IDE; CCCC is device number.
  • 0x20 USB; CCCC is device number.
  • 0xFy vendor-defined interface with y in the range 0 through 15; CCCC is vendor defined.
SCARD_ATTR_CHARACTERISTICS DWORD indicating which mechanical characteristics are supported. If zero, no special characteristics are supported. Note that multiple bits can be set:
  • 0x00000001 Card swallowing mechanism
  • 0x00000002 Card ejection mechanism
  • 0x00000004 Card capture mechanism

All other values are reserved for future use (RFU).
SCARD_ATTR_CURRENT_BWT | Current block waiting time.
SCARD_ATTR_CURRENT_CLK | Current clock rate, in kHz.
SCARD_ATTR_CURRENT_CWT | Current character waiting time.
SCARD_ATTR_CURRENT_D | Bit rate conversion factor.
SCARD_ATTR_CURRENT_EBC_ENCODING Current error block control encoding.

0 = longitudinal redundancy check (LRC)

1 = cyclical redundancy check (CRC).
SCARD_ATTR_CURRENT_F | Clock conversion factor.
SCARD_ATTR_CURRENT_IFSC | Current byte size for information field size card.
SCARD_ATTR_CURRENT_IFSD | Current byte size for information field size device.
SCARD_ATTR_CURRENT_N | Current guard time.
SCARD_ATTR_CURRENT_PROTOCOL_TYPE | DWORD encoded as 0x0rrrpppp where rrr is RFU and should be 0x000. pppp encodes the current protocol type. Whichever bit has been set indicates which ISO protocol is currently in use. (For example, if bit 0 is set, T=0 protocol is in effect.)
SCARD_ATTR_CURRENT_W | Current work waiting time.
SCARD_ATTR_DEFAULT_CLK | Default clock rate, in kHz.
SCARD_ATTR_DEFAULT_DATA_RATE | Default data rate, in bps.
SCARD_ATTR_DEVICE_FRIENDLY_NAME | Reader's friendly name.
SCARD_ATTR_DEVICE_IN_USE | Reserved for future use.
SCARD_ATTR_DEVICE_SYSTEM_NAME | Reader's system name.
SCARD_ATTR_DEVICE_UNIT | Instance of this vendor's reader attached to the computer. The first instance will be device unit 0, the next will be unit 1 (if it is the same brand of reader) and so on. Two different brands of readers will both have 0 for this value.
SCARD_ATTR_ICC_INTERFACE_STATUS | Single byte. 0 if smart card electrical contact is not active; non-zero if contact is active.
SCARD_ATTR_ICC_PRESENCE Single byte indicating smart card presence:

0 = not present

1 = card present but not swallowed (applies only if reader supports smart card swallowing)

2 = card present (and swallowed if reader supports smart card swallowing)

4 = card confiscated.
SCARD_ATTR_ICC_TYPE_PER_ATR Single byte indicating smart card type:

0 = unknown type

1 = 7816 Asynchronous

2 = 7816 Synchronous

Other values RFU.
SCARD_ATTR_MAX_CLK | Maximum clock rate, in kHz.
SCARD_ATTR_MAX_DATA_RATE | Maximum data rate, in bps.
SCARD_ATTR_MAX_IFSD | Maximum bytes for information file size device.
SCARD_ATTR_POWER_MGMT_SUPPORT | 0 if device does not support power down while smart card is inserted. Non-zero otherwise.
SCARD_ATTR_PROTOCOL_TYPES | DWORD encoded as 0x0rrrpppp where rrr is RFU and should be 0x000. pppp encodes the supported protocol types. A '1' in a given bit position indicates support for the associated ISO protocol, so if bits 0 and 1 are set, both T=0 and T=1 protocols are supported.
SCARD_ATTR_VENDOR_IFD_SERIAL_NO | Vendor-supplied interface device serial number.
SCARD_ATTR_VENDOR_IFD_TYPE | Vendor-supplied interface device type (model designation of reader).
SCARD_ATTR_VENDOR_IFD_VERSION | Vendor-supplied interface device version (DWORD in the form 0xMMmmbbbb where MM = major version, mm = minor version, and bbbb = build number).
SCARD_ATTR_VENDOR_NAME | Vendor name.

pbAttr
Points to a buffer that receives the attribute whose ID is supplied in dwAttrId. If this value is NULL, SCardGetAttrib ignores the buffer length supplied in pcbAttrLen, writes the length of the buffer that would have been returned if this parameter had not been NULL to pcbAttrLen, and returns a success code.
pcbAttrLen
Supplies the length of the pbAttr buffer in bytes, and receives the actual length of the received attribute If the buffer length is specified as SCARD_AUTOALLOCATE, then pbAttr is converted to a pointer to a byte pointer, and receives the address of a block of memory containing the attribute. This block of memory must be deallocated with SCardFreeMemory.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Attribute value not supported. | ERROR_NOT_SUPPORTED.
Other Failure | An error code (see Error Codes for a list of all error codes).

Remarks

SCardGetAttrib is a direct card access function. For a description of other direct access functions, see Direct Card Access Functions.

Example Code

LPBYTE   pbAttr = NULL;
DWORD    cByte = SCARD_AUTOALLOCATE;
DWORD    i;
LONG     lReturn;

// Retrieve an attribute.
// hCardHandle was set by a previous call to SCardConnect.
lReturn = SCardGetAttrib(hCardHandle,
                         SCARD_ATTR_VENDOR_NAME,
                         (LPBYTE)&pbAttr,
                         &cByte);
if ( SCARD_S_SUCCESS != lReturn )
{
    if ( ERROR_NOT_SUPPORTED == lReturn )
        printf("Value not supported\n");
    else
    {
        // Some other error occurred.
        printf("Failed SCardGetAttrib - %x\n", lReturn);
        exit(1);  // Or other appropriate action
    }
}
else
{
    // Output the bytes.
    for (i = 0; i < cByte; i++)
        printf("%c", *(pbAttr+i));
    printf("\n");

    // Free the memory when done.
    // hContext was set earlier by SCardEstablishContext
    lReturn = SCardFreeMemory( hContext, pbAttr );
}

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.

See Also

SCardConnect, SCardFreeMemory, SCardSetAttrib


SCardGetCardTypeProviderName

The SCardGetCardTypeProviderName function returns the name of the module (dynamic link library) containing the provider for a given card name and provider type.

LONG SCardGetCardTypeProviderName(
  IN SCARDCONTEXT hContext,
  IN LPCTSTR szCardName,
  IN DWORD dwProviderId,
  OUT LPTSTR szProvider,
  IN OUT LPDWORD pcchProvider
);

Parameters

hContext
Supplies the handle that identifies the resource manager context. The resource manager context can be set by a previous call to SCardEstablishContext. This value can be NULL if the call to SCardGetCardTypeProviderName is not directed to a specific context.
szCardName
Supplies the name of the card type with which this provider name is associated.
dwProviderId
Supplies the identifier for the provider associated with this card type. The value provided for dwProviderId can be one of the following.
Value | Action
SCARD_PROVIDER_PRIMARY | The function retrieves the name of the smart card's primary service provider as a GUID string.
SCARD_PROVIDER_CSP | The function retrieves the name of the cryptographic service provider.

szProvider
String variable which will contain the retrieved provider name upon successful completion of this function.
pcchProvider
Pointer to DWORD value. On input, *pcchProvider supplies the length of the szProvider buffer in characters. If this value is SCARD_AUTOALLOCATE, then szProvider is converted to a pointer to a string pointer and receives the address of a block of memory containing the string. This block of memory must be deallocated by calling SCardFreeMemory.

On output, this value represents the actual number of characters, including the null terminator, in the szProvider variable.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

Upon successful completion of this function, the value in szProvider can be used as the third parameter in a call to CryptAcquireContext.

Example Code

LPTSTR szProvider = NULL;
LPTSTR szCardName = _T("WindowsCard");
DWORD  chProvider = SCARD_AUTOALLOCATE;
LONG   lReturn = SCARD_S_SUCCESS;

// Retrieve the provider name.
// hContext was set by SCardEstablishContext.
lReturn = SCardGetCardTypeProviderName(hContext,
                                       szCardName,
                                       SCARD_PROVIDER_CSP,
                                       (LPTSTR)&szProvider,
                                       &chProvider);
if (SCARD_S_SUCCESS == lReturn)
{
    BOOL fSts = TRUE;
    HCRYPTPROV hProv = NULL;

  // Acquire a Cryptographic operation context.
    fSts = CryptAcquireContext(&hProv,
                               NULL,
                               szProvider,
                               PROV_RSA_FULL,
                               0);
    // Perform Cryptographic operations with smart card
    // ...

    // Free memory allocated by SCardGetCardTypeProviderName.
    lReturn = SCardFreeMemory(hContext, szProvider);
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows 2000.

See Also

SCardSetCardTypeProviderName


SCardGetProviderId

The SCardGetProviderId function returns the identifier (GUID) of the primary service provider for a given card.

The caller supplies the name of a smart card (previously introduced to the system) and receives the registered identifier of the primary service provider GUID, if one exists.

LONG SCardGetProviderId(
  IN SCARDCONTEXT hContext,
  IN LPCTSTR szCard,
  OUT LPGUID pguidProviderId
);

Parameters

hContext
Supplies the handle that identifies the resource manager context for the query. The resource manager context can be set by a previous call to SCardEstablishContext, or set to NULL if the query is not directed towards a specific context.
szCard
Supplies the name of the card defined to the system.
pguidProviderId
Receives the identifier (GUID) of the primary service provider. This provider may be activated via COM, and will supply access to other services in the card.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

SCardGetProviderId is a database query function. For a description of other database query functions, see Smart Card Database Query Functions.

Example Code

GUID    guidProv;
LONG    lReturn;

// Get the provider ID.
// hContext was set by a previous call to SCardEstablishContext.
// "MyCardName" was introduced earlier by SCardIntroduceCardType.
lReturn = SCardGetProviderId(hContext,
                             L"MyCardName",
                             &guidProv);
if ( SCARD_S_SUCCESS != lReturn )
    printf("Failed SCardGetProviderId - %x\n", lReturn);
else
{
    // Use the provider GUID as needed.
    // ...
}

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

SCardEstablishContext, SCardListCards, SCardListInterfaces, SCardListReaderGroups, SCardListReaders


SCardGetStartedEvent

The SCardGetStartedEvent function returns an event handle when an event signals that the smart card resource manager is started. The event-object handle can be specified in a call to one of the wait functions. The returned handle must be closed by calling the CloseHandle function.

HANDLE ScardGetStartedEvent(
);

Return Values

The function returns an event HANDLE if it succeeds or NULL if it fails. If the function fails, the GetLastError function provides information on the cause of the failure. The returned handle must be closed by calling the CloseHandle function.


SCardGetStatusChange

The SCardGetStatusChange function blocks execution until the current availability of the cards in a specific set of readers changes.

The caller supplies a list of readers to be monitored by an SCARD_READERSTATE array and the maximum amount of time (in milliseconds) that it is willing to wait for an action to occur on one of the listed readers. Note that SCardGetStatusChange uses the user-supplied value in the dwCurrentState members of the rgReaderStates parameter as the definition of the current state of the readers. The function returns when there is a change in availability, having filled in the dwEventState members of the rgReaderStates parameter appropriately.

LONG SCardGetStatusChange(
  IN SCARDCONTEXT hContext,
  IN DWORD dwTimeout,
  IN OUT LPSCARD_READERSTATE rgReaderStates,
  IN DWORD cReaders
);

Parameters

hContext
Supplies the handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
dwTimeout
Supplies the maximum amount of time (in milliseconds) to wait for an action. A value of zero causes the function to return immediately. A value of INFINITE causes this function never to time out.
rgReaderStates
Supplies an array of SCARD_READERSTATE structures that specify the readers to watch, and receives the result.
cReaders
Supplies the number of elements in the rgReaderStates array.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

SCardGetStatusChange is a smart card tracking function. For a description of other tracking functions, see Smart Card Tracking Functions.

Consult the code snippet for SCardLocateCards for an example of how to call this function.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

SCardCancel, SCardEstablishContext, SCardLocateCards, SCARD_READERSTATE


SCardIntroduceCardType

The SCardIntroduceCardType function introduces a smart card to the smart card subsystem (for the active user) by adding it to the smart card database.

LONG SCardIntroduceCardType(
  IN SCARDCONTEXT hContext,
  IN LPCTSTR szCardName,
  IN LPCGUID pguidPrimaryProvider,
  IN LPCGUID rgguidInterfaces,
  IN DWORD dwInterfaceCount,
  IN LPCBYTE pbAtr,
  IN LPCBYTE pbAtrMask,
  IN DWORD cbAtrLen
);

Parameters

hContext
Supplies the handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
szCardName
Supplies the name by which the user can recognize the card.
pguidPrimaryProvider
Points to the identifier (GUID) for the smart card's primary service provider.
rgguidInterfaces
Supplies an array of identifiers (GUIDs) that identify the interfaces supported by the smart card.
dwInterfaceCount
Supplies the number of identifiers in the rgguidInterfaces array.
pbAtr
Supplies an ATR string that can be used for matching purposes when querying the smart card database (see SCardListCards). The length of this string is determined by normal ATR parsing.
pbAtrMask
Supplies an optional bitmask to use when comparing the ATRs of smart cards to the ATR supplied in pbAtr. If this value is non-NULL, it must point to a string of bytes the same length as the ATR string supplied in pbAtr. When a given ATR string 'A' is compared to the ATR supplied in pbAtr, it matches if and only if A & M = pbAtr, where M is the supplied mask, and & represents bitwise logical AND.
cbAtrLen
Supplies the length of the ATR and optional ATR Mask. If this value is zero, then the length of the ATR is determined by normal ATR parsing. This value cannot be zero if a pbAtrMask value is supplied.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

SCardIntroduceCardType is a database management function. For a description of other database management functions, see Smart Card Database Management Functions.

To remove a smart card, use SCardForgetCardType.

Example Code

GUID  MyGuid = { 0xABCDEF00,
                 0xABCD,
                 0xABCD,
                 0xAA, 0xBB, 0xCC, 0xDD,
                 0xAA, 0xBB, 0xCC, 0xDD };

static const BYTE MyATR[] =     { 0xaa, 0xbb, 0xcc, 0x00, 0xdd };
static const BYTE MyATRMask[] = { 0xff, 0xff, 0xff, 0x00, 0xff};

LONG            lReturn;

// Introduce the card type.
// hContext was set by a previous call to SCardEstablishContext.
lReturn = SCardIntroduceCardType(hContext,
                                 L"MyCardName",
                                 &MyGuid,
                                 NULL,    // No interface array
                                 0,       // Interface count = 0
                                 MyATR,
                                 MyATRMask,
                                 sizeof(MyATR));
if ( SCARD_S_SUCCESS != lReturn )
    printf("Failed SCardIntroduceCardType\n");

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

SCardEstablishContext, SCardForgetCardType, SCardIntroduceReader, SCardIntroduceReaderGroup, SCardListCards


SCardIntroduceReader

The SCardIntroduceReader function introduces a new name for an existing smart card reader.

Note Smart card readers are automatically introduced to the system; a smart card reader vendor's setup program can also introduce a smart card reader to the system.

LONG SCardIntroduceReader(
  IN SCARDCONTEXT hContext,
  IN LPCTSTR szReaderName,
  IN LPCTSTR szDeviceName
);

Parameters

hContext
Supplies the handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
szReaderName
Supplies the friendly name to be assigned to the reader.
szDeviceName
Supplies the system name of the smart card reader, for example, "Bull TLP3 0".

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

All readers installed on the system are automatically introduced by their system name. Typically, SCardIntroduceReader is called only to change the name of an existing reader.

SCardIntroduceReader is a database management function. For a description of other database management functions, see Smart Card Database Management Functions.

To remove a reader, use SCardForgetReader.

Example Code

// This code snippet renames the reader name.
// This is a two step process (first add the new
// name, then forget the old name).
LPBYTE    pbAttr = NULL;
DWORD     cByte = SCARD_AUTOALLOCATE;
LONG      lReturn;

// Step 1: Add the new reader name.
// The device name attribute is a necessary value.
// hCardHandle was set by a previous call to SCardConnect.
lReturn = SCardGetAttrib(hCardHandle,
                         SCARD_ATTR_DEVICE_SYSTEM_NAME,
                         (LPBYTE)&pbAttr,
                         &cByte);
if ( SCARD_S_SUCCESS != lReturn )
{
    printf("Failed SCardGetAttrib\n");
    exit(1);  // Or other error action
}
// Add the reader name.
// hContext was set earlier by SCardEstablishContext.
lReturn = SCardIntroduceReader(hContext,
                               TEXT("My New Reader Name"),
                               (LPCTSTR)pbAttr );
if ( SCARD_S_SUCCESS != lReturn )
{
    printf("Failed SCardIntroduceReader\n");
    exit(1);  // Or other error action
}

// Step 2: Forget the old reader name.
lReturn = SCardForgetReader(hContext,
                            (LPCTSTR)pbAttr );
if ( SCARD_S_SUCCESS != lReturn )
{
    printf("Failed SCardForgetReader\n");
    exit(1);  // Or other error action
}

// Free the memory when done.
lReturn = SCardFreeMemory( hContext, pbAttr );

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

SCardEstablishContext, SCardIntroduceCardType, SCardIntroduceReaderGroup, SCardForgetReader


SCardIntroduceReaderGroup

The SCardIntroduceReaderGroup function introduces a reader group to the smart card subsystem. However, the reader group is not created until the group is specified when adding a reader to the smart card database.

LONG SCardIntroduceReaderGroup(
  IN SCARDCONTEXT hContext,
  IN LPCTSTR szGroupName
);

Parameters

hContext
Supplies the handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
szGroupName
Supplies the friendly name to be assigned to the new reader group.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

ScardIntroduceReaderGroup is provided for PC/SC specification compatibility. Reader groups are not stored until a reader is added to the group.

SCardIntroduceReaderGroup is a database management function. For a description of other database management functions, see Smart Card Database Management Functions.

To remove a reader group, use SCardForgetReaderGroup.

Example Code

// Introduce the reader group.
// lReturn is of type LONG.
// hContext was set by a previous call to SCardEstablishContext.
lReturn = SCardIntroduceReaderGroup(hContext,
                                    L"MyReaderGroup");
if ( SCARD_S_SUCCESS != lReturn )
    printf("Failed SCardIntroduceReaderGroup\n");

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

SCardAddReaderToGroup, SCardEstablishContext, SCardIntroduceCardType, SCardIntroduceReader, SCardForgetReaderGroup


SCardIsValidContext

The SCardIsValidContext function determines whether a smart card context handle is valid.

LONG SCardIsValidContext(
  IN SCARDCONTEXT hContext
);

Parameters

hContext
Supplies the handle that identifies the resource manager context. The resource manager context can be set by a previous call to SCardEstablishContext.

Return Values

This function returns one of the following values.

Value | Description
SCARD_S_SUCCESS | hContext is valid.
ERROR_INVALID_HANDLE | hContext is not valid.
Other values | An error code (see Error Codes for a list of all error codes).

Remarks

Call this function to determine if a smart card context handle is still valid. Once a smart card context handle has been set by SCardEstablishContext, it may become invalid if the resource manager service has been shut down.

Example Code

// Check the smart card context handle.
// hContext was set previously by SCardEstablishContext.

LONG    lReturn;
lReturn = SCardIsValidContext(hContext);
if ( SCARD_S_SUCCESS != lReturn )
{
    // Function failed; check return value.
    if ( ERROR_INVALID_HANDLE == lReturn )
        printf("Handle is invalid\n");
    else
    {
        // Some unexpected error occurred; report and bail out.
        printf("Failed SCardIsValidContext - %x\n", lReturn);
        exit(1);  // Or other appropriate error action.
    }
}
else
{
    // Handle is valid; proceed as needed.
    // ...
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.

See Also

SCardEstablishContext


SCardListCards

The SCardListCards function searches the smart card database and provides a list of named cards previously introduced to the system by the user.

The caller specifies an ATR string, a set of interface identifiers (GUIDs), or both. If both an ATR string and an identifier array are supplied, the cards returned will match the ATR string supplied and support the interfaces specified.

LONG SCardListCards(
  IN SCARDCONTEXT hContext,
  IN LPCBYTE pbAtr,
  IN LPCGUID rgguidInterfaces,
  IN DWORD cguidInterfaceCount,
  OUT LPTSTR mszCards,
  IN OUT LPDWORD pcchCards
);

Parameters

hContext
Supplies the handle that identifies the resource manager context for the query. The resource manager context can be set by a previous call to SCardEstablishContext, or set to NULL if the query is not directed towards a specific context.
pbAtr
Supplies the address of an ATR string to compare to known cards, or NULL if no ATR matching is to be performed.
rgguidInterfaces
Supplies an array of identifiers (GUIDs), or NULL if no interface matching is to be performed. When an array is supplied, a card name will be returned only if all the specified identifiers are supported by the card.
cguidInterfaceCount
Supplies the number of entries in the rgguidInterfaces array. If rgguidInterfaces is NULL, then this value is ignored.
mszCards
Receives a multi-string that lists the smart cards found. If this value is NULL, SCardListCards ignores the buffer length supplied in pcchCards, returning the length of the buffer that would have been returned if this parameter had not been NULL to pcchCards and a success code.
pcchCards
Supplies the length of the mszCards buffer in characters, and receives the actual length of the multi-string structure, including all trailing Null characters. If the buffer length is specified as SCARD_AUTOALLOCATE, then mszCards is converted to a pointer to a string pointer, and receives the address of a block of memory containing the multi-string structure. This block of memory must be deallocated with SCardFreeMemory.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

To return all smart cards introduced to the subsystem, set pbAtr and rgguidInterfaces to NULL.

SCardListCards is a database query function. For a description of other database query functions, see Smart Card Database Query Functions.

Example Code

LPTSTR pmszCards = NULL;
LPTSTR pCard;
LONG lReturn;
DWORD cch = SCARD_AUTOALLOCATE;

// Retrieve the list of cards.
lReturn = SCardListCards(NULL,
                         NULL,
                         NULL,
                         NULL,
                         (LPTSTR)&pmszCards,
                         &cch );
if ( SCARD_S_SUCCESS != lReturn )
{
    printf("Failed SCardListCards\n");
    exit(1); // Or other appropriate error action
}
// Do something with the multi string of cards.
// Here, we'll merely output the values.
// A double-null terminates the list of values.
pCard = pmszCards;
while ( '\0' != *pCard )
{
    // Display the value.
    printf("%S\n", pCard );
    // Advance to the next value.
    pCard = pCard + wcslen(pCard) + 1;
}

// Remember to free pmszCards (by calling SCardFreeMemory).
// …

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

SCardEstablishContext, SCardFreeMemory, SCardGetProviderId, SCardListInterfaces, SCardListReaderGroups, SCardListReaders


SCardListInterfaces

The SCardListInterfaces function provides a list of interfaces supplied by a given card.

The caller supplies the name of a smart card previously introduced to the subsystem, and receives the list of interfaces supported by the card.

LONG SCardListInterfaces(
  IN SCARDCONTEXT hContext,
  IN LPCTSTR szCard,
  OUT LPGUID pguidInterfaces,
  IN OUT LPDWORD pcguidInterfaces
);

Parameters

hContext
Supplies the handle that identifies the resource manager context for the query. The resource manager context can be set by a previous call to SCardEstablishContext, or set to NULL if the query is not directed towards a specific context.
szCard
Supplies the name of the smart card already introduced to the smart card subsystem.
pguidInterfaces
Receives an array of interface identifiers (GUIDs) that indicate the interfaces supported by the smart card. If this value is NULL, SCardListInterfaces ignores the array length supplied in pcguidInterfaces, returning the size of the array that would have been returned if this parameter had not been NULL to pcguidInterfaces and a success code.
pcguidInterfaces
Supplies the size of the pguidInterfaces array, and receives the actual size of the returned array. If the array size is specified as SCARD_AUTOALLOCATE, then pguidInterfaces is converted to a pointer to a GUID pointer, and receives the address of a block of memory containing the array. This block of memory must be deallocated with SCardFreeMemory.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

SCardListInterfaces is a database query function. For a description of other database query functions, see Smart Card Database Query Functions.

Example Code

LPGUID          pGuids = NULL;
LONG            lReturn;
DWORD           cGuid = SCARD_AUTOALLOCATE;

// Retrieve the list of interfaces.
lReturn = SCardListInterfaces(NULL,
                              L"MyCard",
                              (LPGUID)&pGuids,
                              &cGuid );
if ( SCARD_S_SUCCESS != lReturn )
{
    printf("Failed SCardListInterfaces\n");
    exit(1);   // Or other appropriate action
}

if ( 0 != cGuid )
{
    // Do something with the array of Guids.
    // Remember to free pGuids when done (by SCardFreeMemory).
    // ...
}

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

SCardEstablishContext, SCardFreeMemory, SCardGetProviderId, SCardListCards, SCardListReaderGroups, SCardListReaders


SCardListReaderGroups

The SCardListReaderGroups function provides the list of reader groups that have previously been introduced to the system.

LONG SCardListReaderGroups(
  IN SCARDCONTEXT hContext,
  OUT LPTSTR mszGroups,
  IN OUT LPDWORD pcchGroups
);

Parameters

hContext
Supplies the handle that identifies the resource manager context for the query. The resource manager context can be set by a previous call to SCardEstablishContext, or set to NULL if the query is not directed towards a specific context.
mszGroups
Receives a multi-string that lists the reader groups defined to the system and available to the current user on the current terminal. If this value is NULL, SCardListReaderGroups ignores the buffer length supplied in pcchGroups, writes the length of the buffer that would have been returned if this parameter had not been NULL to pcchGroups, and returns a success code.
pcchGroups
Supplies the length of the mszGroups buffer in characters, and receives the actual length of the multi-string structure, including all trailing Null characters. If the buffer length is specified as SCARD_AUTOALLOCATE, then mszGroups is converted to a pointer to a string pointer, and receives the address of a block of memory containing the multi-string structure. This block of memory must be deallocated with SCardFreeMemory.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

A group is returned only if it contains at least one reader. This includes the group SCard$DefaultReaders. The group SCard$AllReaders cannot be returned, since it only exists implicitly.

SCardListReaderGroups is a database query function. For a description of other database query functions, see Smart Card Database Query Functions.

Example Code

LPTSTR          pmszReaderGroups = NULL;
LPTSTR          pReaderGroup;
LONG            lReturn;
DWORD           cch = SCARD_AUTOALLOCATE;

// Retrieve the list the reader groups.
// hSC was set by a previous call to SCardEstablishContext.
lReturn = SCardListReaderGroups(hSC,
                                (LPTSTR)&pmszReaderGroups,
                                &cch );
if ( SCARD_S_SUCCESS != lReturn )
    printf("Failed SCardListReaderGroups\n");
else
{
    // Do something with the multi string of reader groups.
    // Here, we'll merely output the values.
    // A double-null terminates the list of values.
    pReaderGroup = pmszReaderGroups;
    while ( '\0' != *pReaderGroup )
    {
        // Display the value.
        printf("%S\n", pReaderGroup );
        // Advance to the next value.
        pReaderGroup = pReaderGroup + wcslen(pReaderGroup) + 1;
    }

    // Remember to free pmszReaderGroups by a call to SCardFreeMemory.
    // …
}

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

SCardEstablishContext, SCardFreeMemory, SCardGetProviderId, SCardListCards, SCardListInterfaces, SCardListReaders


SCardListReaders

The SCardListReaders function provides the list of readers within a set of named reader groups, eliminating duplicates.

The caller supplies a list of reader groups, and receives the list of readers within the named groups. Unrecognized group names are ignored.

LONG SCardListReaders(
  IN SCARDCONTEXT hContext,
  IN LPCTSTR mszGroups,
  OUT LPTSTR mszReaders,
  IN OUT LPDWORD pcchReaders
);

Parameters

hContext
Supplies the handle that identifies the resource manager context for the query. The resource manager context can be set by a previous call to SCardEstablishContext, or set to NULL if the query is not directed towards a specific context.
mszGroups
Supplies the names of the reader groups defined to the system, as a multi-string. Use a NULL value to list all readers in the system (that is, the SCard$AllReaders group).
mszReaders
Receives a multi-string that lists the card readers within the supplied reader groups. If this value is NULL, SCardListReaders ignores the buffer length supplied in pcchReaders, writes the length of the buffer that would have been returned if this parameter had not been NULL to pcchReaders, and returns a success code.
pcchReaders
Supplies the length of the mszReaders buffer in characters, and receives the actual length of the multi-string structure, including all trailing Null characters. If the buffer length is specified as SCARD_AUTOALLOCATE, then mszReaders is converted to a pointer to a string pointer, and receives the address of a block of memory containing the multi-string structure. This block of memory must be deallocated with SCardFreeMemory.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Group contains no readers | SCARD_E_NO_READERS_AVAILABLE
Other | An error code (see Error Codes for a list of all error codes).

Remarks

SCardListReaders is a database query function. For a description of other database query functions, see Smart Card Database Query Functions.

Example Code

LPTSTR          pmszReaders = NULL;
LPTSTR          pReader;
LONG            lReturn, lReturn2;
DWORD           cch = SCARD_AUTOALLOCATE;

// Retrieve the list the readers.
// hSC was set by a previous call to SCardEstablishContext.
lReturn = SCardListReaders(hSC,
                           NULL,
                           (LPTSTR)&pmszReaders,
                           &cch );
switch( lReturn )
{
    case SCARD_E_NO_READERS_AVAILABLE:
        printf("Reader is not in groups.\n");
        // Take appropriate action.
        // ...
        break;

    case SCARD_S_SUCCESS:
        // Do something with the multi string of readers.
        // Here, we'll merely output the values.
        // A double-null terminates the list of values.
        pReader = pmszReaders;
        while ( '\0' != *pReader )
        {
            // Display the value.
            printf("Reader: %S\n", pReader );
            // Advance to the next value.
            pReader = pReader + wcslen(pReader) + 1;
        }
        // Free the memory.
        lReturn2 = SCardFreeMemory( hSC,
                                   pmszReaders );
        if ( SCARD_S_SUCCESS != lReturn2 )
            printf("Failed SCardFreeMemory\n");
        break;

default:
        printf("Failed SCardListReaders\n");
        // Take appropriate action.
        // ...
        break;
}

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

SCardEstablishContext, SCardFreeMemory, SCardGetProviderId, SCardListCards, SCardListInterfaces, SCardListReaderGroups


SCardLocateCards

The SCardLocateCards function searches the readers listed in the rgReaderStates parameter for a card with an ATR string that matches one of the card names specified in mszCards, returning immediately with the result.

LONG SCardLocateCards(
  IN SCARDCONTEXT hContext,
  IN LPCTSTR mszCards,
  IN OUT LPSCARD_READERSTATE rgReaderStates,
  IN DWORD cReaders
);

Parameters

hContext
Supplies the handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
mszCards
Supplies a multi-string that contains the names of the cards to search for.
rgReaderStates
Supplies an array of SCARD_READERSTATE structures that specify the readers to search, and receives the result.
cReaders
Supplies the number of elements in the rgReaderStates array.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

This service is especially useful when used in conjunction with SCardGetStatusChange. If no matching cards are found by means of SCardLocateCards, the calling application may use SCardGetStatusChange to wait for card availability changes.

SCardLocateCards is a smart card tracking function. For a description of other tracking functions, see Smart Card Tracking Functions.

Example Code

#include <stdio.h>
#include <winscard.h>
#include <tchar.h>

HRESULT __cdecl main()
{
HRESULT           hr = S_OK;
LPTSTR            szReaders, szRdr;
DWORD             cchReaders = SCARD_AUTOALLOCATE;
DWORD             dwI, dwRdrCount;
SCARD_READERSTATE rgscState[MAXIMUM_SMARTCARD_READERS];
TCHAR             szCard[MAX_PATH];
SCARDCONTEXT      hSC;
LONG              lReturn;

// Establish the card to watch for.
// Multiple cards can be looked for, but
// this sample looks for only one card.
lstrcpy( szCard, TEXT("GemSAFE"));
szCard[lstrlen(szCard) + 1] = 0;  // Double trailing zero.

// Establish a context.
lReturn = SCardEstablishContext(SCARD_SCOPE_USER,
                                NULL,
                                NULL,
                                &hSC );
if ( SCARD_S_SUCCESS != lReturn )
{
    printf("Failed SCardEstablishContext\n");
    exit(1);
}

// Determine which readers are available.
lReturn = SCardListReaders(hSC,
                           NULL,
                           (LPTSTR)&szReaders,
                           &cchReaders );
if ( SCARD_S_SUCCESS != lReturn )
{
    printf("Failed SCardListReaders\n");
    exit(1);
}
// Place the readers into the state array.
szRdr = szReaders;
for ( dwI = 0; dwI < MAXIMUM_SMARTCARD_READERS; dwI++ )
{
    if ( 0 == *szRdr )
        break;
    rgscState[dwI].szReader = szRdr;
    rgscState[dwI].dwCurrentState = SCARD_STATE_UNAWARE;
    szRdr += lstrlen(szRdr) + 1;
}
dwRdrCount = dwI;

// If any readers are available, proceed.
if ( 0 != dwRdrCount )
{
  for (;;)
  {
    // Look for the card.
    lReturn = SCardLocateCards(hSC,
                               szCard,
                               rgscState,
                               dwRdrCount );
    if ( SCARD_S_SUCCESS != lReturn )
    {
        printf("Failed SCardLocateCards\n");
        exit(1);
    }

    // Look through the array of readers.
    for ( dwI=0; dwI < dwRdrCount; dwI++)
    {
        if ( 0 != ( SCARD_STATE_ATRMATCH &
                    rgscState[dwI].dwEventState))
        {
           _tprintf( TEXT("Card '%s' found in reader '%s'.\n"),
                     szCard,
                     rgscState[dwI].szReader );
            SCardFreeMemory( hSC,
                             szReaders );
            return 0;  // Context will be release automatically.
        }
        // Update the state.
        rgscState[dwI].dwCurrentState = rgscState[dwI].dwEventState;
    }

  // Card not found yet; wait until there is a change.
  lReturn = SCardGetStatusChange(hSC,
                                 INFINITE, // infinite wait
                                 rgscState,
                                 dwRdrCount );
  if ( SCARD_S_SUCCESS != lReturn )
  {
    printf("Failed SCardGetStatusChange\n");
    exit(1);
  }
 }  // for (;;)
}
else
    printf("No readers available\n");

// Release the context.
lReturn = SCardReleaseContext(hSC);
if ( SCARD_S_SUCCESS != lReturn )
{
    printf("Failed SCardReleaseContext\n");
    exit(1);
}

SCardFreeMemory( hSC,
                 szReaders );

return hr;
}

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

SCardCancel, SCardEstablishContext, SCardGetStatusChange, SCARD_READERSTATE


SCardReconnect

The SCardReconnect function reestablishes an existing connection between the calling application and a smart card. This function moves a card handle from direct access to general access, or acknowledges and clears an error condition that is preventing further access to the card.

LONG SCardReconnect(
  IN SCARDHANDLE hCard,
  IN DWORD dwShareMode,
  IN DWORD dwPreferredProtocols,
  IN DWORD dwInitialization,
  OUT LPDWORD pdwActiveProtocol
);

Parameters

hCard
Supplies the reference value obtained from a previous call to SCardConnect.
dwShareMode
Supplies a flag that indicates whether other applications may form connections to this card. The following are the possible values.
Value | Meaning
SCARD_SHARE_SHARED | This application will share this card with other applications.
SCARD_SHARE_EXCLUSIVE | This application will not share this card with other applications.

dwPreferredProtocols
Supplies a bit mask of acceptable protocols for this connection. Possible values, which may be combined with the OR operation.
Value | Meaning
SCARD_PROTOCOL_T0 | T=0 is an acceptable protocol.
SCARD_PROTOCOL_T1 | T=1 is an acceptable protocol.

dwInitialization
Indicates what kind of initialization should be performed on the card. The following are the possible values.
Value | Meaning
SCARD_LEAVE_CARD | Don't do anything special on reconnect.
SCARD_RESET_CARD | Reset the card (Warm Reset).
SCARD_UNPOWER_CARD | Power down the card and reset it (Cold Reset).

pdwActiveProtocol
Receives a flag that indicates the established active protocol. The following are the possible values.
Value | Meaning
SCARD_PROTOCOL_T0 | T=0 is the active protocol.
SCARD_PROTOCOL_T1 | T=1 is the active protocol.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return Value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

SCardReconnect is a smart card and reader access function. For a description of other access functions, see Smart Card and Reader Access Functions.

Example Code

DWORD     dwAP;
LONG      lReturn;

// Reconnect.
// hCardHandle was set by a previous call to SCardConnect.
lReturn = SCardReconnect(hCardHandle,
                         SCARD_SHARE_SHARED,
                         SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
                         SCARD_LEAVE_CARD,
                         &dwAP );
if ( SCARD_S_SUCCESS != lReturn )
    printf("Failed SCardReconnect\n");

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.

See Also

SCardConnect, SCardDisconnect


SCardReleaseContext

The SCardReleaseContext function closes an established resource manager context, freeing any resources allocated under that context, including SCARDHANDLE objects and memory allocated using the SCARD_AUTOALLOCATE length designator.

LONG SCardReleaseContext(
  IN SCARDCONTEXT hContext
);

Parameters

hContext
Supplies the handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Example Code

// Free the context.
// lReturn is of type LONG.
// hSC was set by an earlier call to SCardEstablishContext.
lReturn = SCardReleaseContext(hSC);
if ( SCARD_S_SUCCESS != lReturn )
    printf("Failed SCardReleaseContext\n");

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.

See Also

SCardEstablishContext


SCardRemoveReaderFromGroup

The SCardRemoveReaderFromGroup function removes a reader from an existing reader group. This function has no affect on the reader.

LONG SCardRemoveReaderFromGroup(
  IN SCARDCONTEXT hContext,
  IN LPCTSTR szReaderName,
  IN LPCTSTR szGroupName
);

Parameters

hContext
Supplies the handle that identifies the resource manager context. The resource manager context is set by a previous call to SCardEstablishContext.
szReaderName
Supplies the friendly name of the reader to be removed.
szGroupName
Supplies the friendly name of the group from which the reader should be removed.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

When the last reader is removed from a group, the group is automatically forgotten.

SCardRemoveReaderFromGroup is a database management function. For a description of other database management functions, see Smart Card Database Management Functions.

To add a reader to a reader group, use SCardAddReaderToGroup.

Example Code

// Remove a reader from the group.
// lReturn is of type LONG.
// hContext was set by a previous call to SCardEstablishContext.
// The group is automatically forgotten if no readers remain in it.
lReturn = SCardRemoveReaderFromGroup(hContext,
                                     L"MyReader",
                                     L"MyReaderGroup");
if ( SCARD_S_SUCCESS != lReturn )
    printf("Failed SCardRemoveReaderFromGroup\n");

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

SCardEstablishContext, SCardAddReaderToGroup, SCardForgetCardType, SCardForgetReader, SCardForgetReaderGroup


SCardSetAttrib

The SCardSetAttrib function sets the given reader attribute for the given handle. It does not affect the state of the reader, reader driver, or smart card. Not all attributes are supported by all readers (nor can they be set at all times) as many of the attributes are under direct control of the transport protocol.

LONG SCardSetAttrib(
  IN SCARDHANDLE hCard,
  IN DWORD dwAttrId,
  IN LPCBYTE pbAttr,
  IN DWORD cbAttrLen
);

Parameters

hCard
Supplies the reference value returned from SCardConnect.
dwAttrId
Supplies the identifier for the attribute to set. The following table lists possible values for dwAttrId. These values are write-only. Note that vendors may not support all attributes.
Value | Description
SCARD_ATTR_SUPRESS_T1_IFS_REQUEST | Suppress sending of T=1 IFSD packet from the reader to the card. (Can be used if the currently inserted card doesn't support an IFSD request.)

pbAttr
Points to a buffer that supplies the attribute whose ID is supplied in dwAttrId.
cbAttrLen
Supplies the length (in bytes) of the attribute value in the pbAttr buffer.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

SCardSetAttrib is a direct card access function. For a description of other direct access functions, see Direct Card Access Functions.

Example Code

// Set the attribute.
// hCardHandle was set by a previous call to SCardConnect.
// dwAttrID is a DWORD value, specifying the attribute ID.
// pbAttr points to the buffer of the new value.
// cByte is the count of bytes in the buffer.
lReturn = SCardSetAttrib(hCardHandle,
                         dwAttrID,
                         (LPBYTE)pbAttr,
                         cByte);
if ( SCARD_S_SUCCESS != lReturn )
    printf("Failed SCardSetAttrib\n");

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.

See Also

SCardConnect, SCardGetAttrib


SCardSetCardTypeProviderName

The SCardSetCardTypeProviderName function specifies the name of the module (dynamic link library) containing the provider for a given card name and provider type.

LONG SCardSetCardTypeProviderName(
  IN SCARDCONTEXT hContext,
  IN LPCTSTR szCardName,
  IN DWORD dwProviderId,
  IN LPCTSTR szProvider
);

Parameters

hContext
Supplies the handle that identifies the resource manager context. The resource manager context can be set by a previous call to SCardEstablishContext. This value can be NULL if the call to SCardSetCardTypeProviderName is not directed to a specific context.
szCardName
Supplies the name of the card type with which this provider name is associated.
dwProviderId
Supplies the identifier for the provider associated with this card type. The value provided for dwProviderId can be one of the following.
Value | Action
SCARD_PROVIDER_PRIMARY | The function specifies the name of the smart card's primary service provider as a GUID string.
SCARD_PROVIDER_CSP | The function specifies the name of the cryptographic service provider.

szProvider
String variable being assigned as the provider name, representing the cryptographic service provider (CSP).

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

This function sets the provider name, while SCardGetCardTypeProviderName can be used to retrieve the provider name.

Example Code

LPTSTR            szNewProvName = _T("My Provider Name");
LPTSTR            szCardName = _T("WindowsCard");
LONG              lReturn = SCARD_S_SUCCESS;

// Set the card type provider name.
// hContext was set by SCardEstablishContext.
lReturn = SCardSetCardTypeProviderName(hContext,
                                      szCardName,
                                      SCARD_PROVIDER_CSP,
                                      szNewProvName);
if ( SCARD_S_SUCCESS != lReturn )
{
    printf("Failed SCardSetCardTypeProviderName - %x\n", lReturn);
    exit(1);
}

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows 2000.

See Also

SCardGetCardTypeProviderName


SCardStatus

The SCardStatus function provides the current status of a smart card in a reader. You can call it any time after a successful call to SCardConnect and before a successful call to SCardDisconnect. It does not affect the state of the reader or reader driver.

LONG SCardStatus(
  IN SCARDHANDLE hCard,
  OUT LPTSTR szReaderName,
  IN OUT LPDWORD pcchReaderLen,
  OUT LPDWORD pdwState,
  OUT LPDWORD pdwProtocol,
  OUT LPBYTE pbAtr,
  IN OUT LPDWORD pcbAtrLen
);

Parameters

hCard
This is the reference value returned from SCardConnect.
szReaderName
Receives a list of friendly names (multi-string) by which the currently connected reader is known.
pcchReaderLen
On input, supplies the length of the szReaderName buffer.

On output, receives the actual length (in characters) of the reader name list, including the trailing NULL character. If this buffer length is specified as SCARD_AUTOALLOCATE, then szReaderName is converted to a pointer to a string pointer, and receives the address of a block of memory containing the multi-string structure.

pdwState
Receives the current state of the smart card in the reader. Upon success, it receives one of the following state indicators:
Value | Meaning
SCARD_ABSENT | There is no card in the reader.
SCARD_PRESENT | There is a card in the reader, but it has not been moved into position for use.
SCARD_SWALLOWED | There is a card in the reader in position for use. The card is not powered.
SCARD_POWERED | Power is being provided to the card, but the reader driver is unaware of the mode of the card.
SCARD_NEGOTIABLE | The card has been reset and is awaiting PTS negotiation.
SCARD_SPECIFIC | The card has been reset and specific communication protocols have been established.

pdwProtocol
Receives the current protocol, if any. The returned value is meaningful only if the returned value of pdwState is SCARD_SPECIFICMODE. Possible returned values are the following:
Value | Meaning
SCARD_PROTOCOL_RAW | The Raw Transfer protocol is in use.
SCARD_PROTOCOL_T0 | The ISO 7816/3 T=0 protocol is in use.
SCARD_PROTOCOL_T1 | The ISO 7816/3 T=1 protocol is in use.

pbAtr
Points to a 32-byte buffer that receives the ATR string from the currently inserted card, if available.
pcbAtrLen
On input, supplies the length of the pbAtr buffer. On output, receives the number of bytes in the ATR string (32 bytes maximum).

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return Value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

SCardStatus is a smart card and reader access function. For a description of other access functions, see Smart Card and Reader Access Functions.

Example Code

WCHAR           szReader[200];
DWORD           cch = 200;
BYTE            bAttr[32];
DWORD           cByte = 32;
DWORD           dwState, dwProtocol;
LONG            lReturn;

// Determine the status.
// hCardHandle was set by an earlier call to SCardConnect.
lReturn = SCardStatus(hCardHandle,
                      szReader,
                      &cch,
                      &dwState,
                      &dwProtocol,
                      (LPBYTE)&bAttr,
                      &cByte);

if ( SCARD_S_SUCCESS != lReturn )
{
    printf("Failed SCardStatus\n");
    exit(1);     // Or other appropriate action.
}

// Examine retrieved status elements.
// Here, we'll look at the reader name and card state.
printf("%S\n", szReader );
switch ( dwState )
{
    case SCARD_ABSENT:
        printf("Card absent.\n");
        break;
    case SCARD_PRESENT:
        printf("Card present.\n");
        break;
    case SCARD_SWALLOWED:
        printf("Card swallowed.\n");
        break;
    case SCARD_POWERED:
        printf("Card has power.\n");
        break;
    case SCARD_NEGOTIABLE:
        printf("Card reset and waiting PTS negotiation.\n");
        break;
    case SCARD_SPECIFIC:
        printf("Card has specific communication protocols set.\n");
        break;
    default:
        printf("Unknown or unexpected card state.\n");
        break;
}

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

SCardConnect, SCardDisconnect


SCardTransmit

The SCardTransmit function sends a service request to the smart card, and expects to receive data back from the card.

LONG SCardTransmit(
  IN SCARDHANDLE hCard,
  IN LPCSCARD_I0_REQUEST pioSendPci,
  IN LPCBYTE pbSendBuffer,
  IN DWORD cbSendLength,
  IN OUT LPSCARD_IO_REQUEST pioRecvPci,
  OUT LPBYTE pbRecvBuffer,
  IN OUT LPDWORD pcbRecvLength
);

Parameters

hCard
Supplies the reference value returned from SCardConnect.
pioSendPci
Pointer to the protocol header structure for the instruction. This buffer is in the format of an SCARD_IO_REQUEST structure, followed by the specific protocol control information (PCI).

For the T=0, T=1, and Raw protocols, the PCI structure is constant. The smart card subsystem supplies a global T=0, T=1, or Raw PCI structure, which you can reference by using the symbols SCARD_PCI_T0, SCARD_PCI_T1, and SCARD_PCI_RAW respectively.

pbSendBuffer
Pointer to the actual data to be written to the card.

T=0 Note For T=0, the data parameters are placed into the pbSendBuffer according to the following structure:

struct {
    BYTE
        bCla,   // The instruction class
        bIns,   // The instruction code
        bP1,    // Parameter to the instruction
        bP2,    // Parameter to the instruction
        bP3;    // Size of I/O Transfer
} CmdBytes;

Members

bCla
The T=0 instruction class
bIns
An instruction code in the T=0 instruction class
bP1, bP2
Reference codes completing the instruction code
bP3
The number of data bytes which are to be transmitted during the command, per ISO 7816-4, Section 8.2.1.

The data sent to the card should immediately follow the send buffer. In the special case where no data is sent to the card and no data is expected in return, bP3 is not sent.

cbSendLength
Supplies the length (in bytes)of the pbSendBuffer parameter.

T=0 Note For T=0, in the special case where no data is sent to the card and no data expected in return, this length must reflect that the bP3 member is not being sent: the length should be sizeof(CmdBytes) – sizeof(BYTE).

pioRecvPci
Pointer to the protocol header structure for the instruction, followed by a buffer in which to receive any returned protocol control information (PCI) specific to the protocol in use. This parameter may be NULL if no returned PCI is desired.
pbRecvBuffer
Pointer to any data returned from the card.

T=0 Note For T=0, the data is immediately followed by the SW1 and SW2 status bytes. If no data is returned from the card, then this buffer will only contain the SW1 and SW2 status bytes.

pcbRecvLength
Supplies the length of the pbRecvBuffer parameter (in bytes) and receives the actual number of bytes received from the smart card.

T=0 Note For T=0, the receive buffer must be at least two bytes long, in order to receive the SW1 and SW2 status bytes.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

SCardTransmit is a smart card and reader access function. For a description of other access functions, see Smart Card and Reader Access Functions.

T=0 Protocol Remarks

For the T=0 protocol, the data received back are the SW1 and SW2 status codes, possibly preceded by response data. The following paragraphs provide information on the send and receive buffers used to transfer data and issue a command.

Sending Data to the Card
To send n bytes of data to the card, where n>0, the send and receive buffers must be formatted as follows.

The first four bytes of the pbSendBuffer buffer contain the CLA, INS, P1, and P2 values for the T=0 operation. The fifth byte shall be set to n: the size (in bytes) of the data to be transferred to the card. The next n bytes shall contain the data to be sent to the card.

The cbSendLength parameter shall be set to the size of the T=0 header information (CLA, INS, P1 and P2) plus a byte containing the length of the data to be transferred (n), plus the size of data to be sent. In this example, this is n+5.

The pbRecvBuffer will receive the SW1 and SW2 status codes from the operation.

The pcbRecvLength should be at least 2, and will be set to 2 upon return.

Obtaining Data from the Card
To receive n>0 bytes of data from the card, the send and receive buffers must be formatted as follows.

The first four bytes of the pbSendBuffer buffer contain the CLA, INS, P1, and P2 values for the T=0 operation. The fifth byte shall be set to n: the size (in bytes) of the data to be transferred from the card. If 256 bytes are to be transferred from the card, then this byte shall be set to zero.

The cbSendLength parameter shall be set to 5, the size of the T=0 header information.

The pbRecvBuffer will receive the data returned from the card, immediately followed by the SW1 and SW2 status codes from the operation.

The pcbRecvLength should be at least n+2, and will be set to n+2 upon return.

Issuing a Command Without Exchanging Data
To issue a command to the card that does not involve the exchange of data (either sent or received), the send and receive buffers must be formatted as follows.

The pbSendBuffer buffer shall contain the CLA, INS, P1, and P2 values for the T=0 operation. The P3 value is not sent. (This is to differentiate the header from the case where 256 bytes are expected to be returned.)

The cbSendLength parameter shall be set to 4, the size of the T=0 header information (CLA, INS, P1, and P2).

The pbRecvBuffer will receive the SW1 and SW2 status codes from the operation.

The pcbRecvLength should be at least 2, and will be set to 2 upon return.

Example Code

// Transmit the request.
// lReturn is of type LONG.
// hCardHandle was set by a previous call to SCardConnect.
// pbSend points to the buffer of bytes to send.
// dwSend is the DWORD value for the number of bytes to send.
// pbRecv points to the buffer for returned bytes.
// dwRecv is the DWORD value for the number of returned bytes.
lReturn = SCardTransmit(hCardHandle,
                        SCARD_PCI_T0,
                        pbSend,
                        dwSend,
                        NULL,
                        pbRecv,
                        &dwRecv );
if ( SCARD_S_SUCCESS != lReturn )
{
    printf("Failed SCardTransmit\n");
    exit(1);   // Or other appropriate error action.
}

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Library: Use Winscard.lib.

See Also

SCardConnect, SCARD_IO_REQUEST


SCardUIDlgSelectCard

The SCardUIDlgSelectCard function displays the smart card "select card" dialog.

LONG SCardUIDlgSelectCard(
  IN LPOPENCARDNAME_EX pDlgStruc
);

Parameters

pDlgStruc
Points to the OPENCARDNAME_EX structure for the "select card" dialog.

Return Values

This function returns different values depending on whether it succeeds or fails.

Outcome | Return Value
Success | SCARD_S_SUCCESS.
Failure | An error code (see Error Codes for a list of all error codes).

Remarks

The SCardUIDlgSelectCard function provides a method for connecting to a specific smart card. When called, this function performs a search for appropriate smart cards matching the OPENCARD_SEARCH_CRITERIA member of *pDlgStruc. Depending on the dwFlags member of *pDlgStruc, this function takes the following actions.

Value for dwFlag | Action
SC_DLG_FORCE_UI | Connects to the card selected by the user from the smart card 'Select Card' dialog.
SC_DLG_MINIMAL_UI | Selects the smart card if only one meets the criteria, or returns information about the user's selection if more than one smart card meets the criteria.
SC_DLG_NO_UI | Selects the first available card.

This function replaces GetOpenCardName. GetOpenCardName is maintained for backward compatibility with version 1.0 of the Microsoft Smart Card Base Components.

Example Code

SCARDCONTEXT     hSC;
OPENCARDNAME_EX  dlgStruct;
WCHAR            szReader[256];
WCHAR            szCard[256];
LONG             lReturn;

// Establish a context.
// It will be assigned to the structure's hSCardContext field.
lReturn = SCardEstablishContext(SCARD_SCOPE_USER,
                                NULL,
                                NULL,
                                &hSC );
if ( SCARD_S_SUCCESS != lReturn )
{
    printf("Failed SCardEstablishContext\n");
    exit(1);
}

// Initialize the structure.
memset(&dlgStruct, 0, sizeof(dlgStruct));
dlgStruct.dwStructSize = sizeof(dlgStruct);
dlgStruct.hSCardContext = hSC;
dlgStruct.dwFlags = SC_DLG_FORCE_UI;
dlgStruct.lpstrRdr = szReader;
dlgStruct.nMaxRdr = 256;
dlgStruct.lpstrCard = szCard;
dlgStruct.nMaxCard = 256;
dlgStruct.lpstrTitle = L"My Select Card Title";

// Display the select card dialog.
lReturn = SCardUIDlgSelectCard(&dlgStruct);
if ( SCARD_S_SUCCESS != lReturn )
    printf("Failed SCardUIDlgSelectCard - %x\n", lReturn );
else
    printf("Reader: %S\nCard: %S\n", szReader, szCard );

// Release the context (by SCardReleaseContext - not shown here).

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Winscard.h.
Library: Use Scarddlg.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows 2000.

See Also

OPENCARDNAME_EX


Smart Card Structures

The Smart Card SDK provides the following structures.

Use… | To…
OPENCARD_SEARCH_CRITERIA | Provide specific search information used by the SCardUIDlgSelectCard function.
OPENCARDNAME_EX | Provide information used by the SCardUIDlgSelectCard function.
OPENCARDNAME | Provide information used by the GetOpenCardName function.
SCARD_IO_REQUEST | Begin a protocol control information structure.
SCARD_READERSTATE | Track smart cards within a reader.


OPENCARD_SEARCH_CRITERIA

The OPENCARD_SEARCH_CRITERIA structure is used by the SCardUIDlgSelectCard function in order to recognize cards that meet the requirements set forth by the caller. You can, however, call SCardUIDlgSelectCard without using this structure.

typedef struct {
  DWORD          dwStructSize;
  LPTSTR         lpstrGroupNames;
  DWORD          nMaxGroupNames;
  LPCGUID        rgguidInterfaces;
  DWORD          cguidInterfaces;
  LPTSTR         lpstrCardNames;
  DWORD          nMaxCardNames;
  LPOCNCHKPROC   lpfnCheck;
  LPOCNCONNPROC  lpfnConnect;
  LPOCNDSCPROC   lpfnDisconnect;
  LPVOID         pvUserData;
  DWORD          dwShareMode;
  DWORD          dwPreferredProtocols;
} OPENCARD_SEARCH_CRITERIA, *POPENCARD_SEARCH_CRITERIA, *LPOPENCARD_SEARCH_CRITERIA;

Members

dwStructSize
Specifies the length of the structure, in bytes. Must not be NULL.
lpstrGroupNames
Points to a buffer containing null-terminated group name strings. The last string in the buffer must be terminated by two NULL characters. Each string is the name of a group of cards that is to be included in the search. If lpstrGroupNames is NULL, the default group (Scard$DefaultReaders) is searched.
nMaxGroupNames
Maximum number of bytes (ANSI version) or characters (Unicode version) in the lpstrGroupNames string.
rgguidInterfaces
Reserved for future use. An array of GUIDs identifying the interfaces required. Set this member to NULL for this release.
cguidInterfaces
Reserved for future use. The number of interfaces in the rgguidInterfaces array. Set this member to NULL for this release.
lpstrCardNames
Points to a buffer containing null-terminated card name strings. The last string in the buffer must be terminated by two NULL characters. Each string is the name of a card that is to be located.
nMaxCardNames
Maximum number of bytes (ANSI version) or characters (Unicode version) in the lpstrCardNames string.
lpfnCheck
Pointer to the caller's card verify routine. If no special card verification is required, this pointer is NULL. If the card is rejected by the verify routine, FALSE is returned and the card will be disconnected. If the card is accepted by the verify routine, TRUE is returned.

The prototype for the check routine is

Boolean Check(
  hSCardContext,  //  the card context passed in the parameter block
  hCard,          //  card handle
  pvUserData      //  pointer to user data passed in the parameter block
);
lpfnConnect
Pointer to the caller's card connect routine. If the caller needs to perform additional processing to connect to the card, this function pointer is set to the user's connect function. If the connect function is successful, the card is left connected and initialized, and the card handle is returned.

The prototype for the connect routine is

Connect(
  hSCardContext,  // the card context passed in the parameter block
  szReader,       // the name of the reader
  mszCards,       // multistring containing the possible card names in the reader
  pvUserData      // pointer to user data passed in parameter block
);
lpfnDisconnect
Pointer to the caller's card disconnect routine.

The prototype for the disconnect routine is

Disconnect(
  hSCardContext,  //  the card context passed in the parameter block
  hCard,          //  card handle
  pvUserData      //  pointer to user data passed in the parameter block
);

Note When you use lpfnConnect, lpfnCheck, and lpfnDisconnect, all three callback procedures should be present. Using these callbacks allows further verification that the calling application has found the appropriate card. This is the best way to ensure the appropriate card is selected. However, when using a non-NULL value for lpfnCheck, either both lpfnConnect and lpfnDisconnect must be non-NULL (and pvUserData should also be provided), or dwShareMode and dwPreferredProtocols must both be set.

pvUserData
A void pointer to user data. This pointer is passed back to the caller on the Connect, Check, and Disconnect routines.
dwShareMode
If lpfnConnect is not NULL, the dwShareMode and dwPreferredProtocols members are ignored. If lpfnConnect is NULL and dwShareMode is non-zero, an internal call is made to SCardConnect using dwShareMode and dwPreferredProtocols as the parameter.
dwPreferredProtocols
Used for internal connection as described in dwShareMode.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

OPENCARDNAME_EX, SCardUIDlgSelectCard


OPENCARDNAME

The OPENCARDNAME structure contains the information that the GetOpenCardName function uses to initialize a smart card Select Card dialog box. Note that in Windows® 2000, calling SCardUIDlgSelectCard with OPENCARDNAME_EX is recommended over calling GetOpenCardName with OPENCARDNAME. OPENCARDNAME is provided for backward compatibility.

typedef struct {
  DWORD           dwStructSize;
  HWND            hwndOwner;
  SCARDCONTEXT    hSCardContext;
  LPTSTR          lpstrGroupNames;
  DWORD           nMaxGroupNames;
  LPTSTR          lpstrCardNames;
  DWORD           nMaxCardNames;
  LPCGUID         rgguidInterfaces;
  DWORD           cguidInterfaces;
  LPTSTR          lpstrRdr;
  DWORD           nMaxRdr;
  LPTSTR          lpstrCard;
  DWORD           nMaxCard;
  LPCTSTR         lpstrTitle;
  DWORD           dwFlags;
  LPVOID          pvUserData;
  DWORD           dwShareMode;
  DWORD           dwPreferredProtocols;
  DWORD           dwActiveProtocol;
  LPOCNCONNPROC   lpfnConnect;
  LPOCNCHKPROC    lpfnCheck;
  LPOCNDSCPROC    lpfnDisconnect;
  SCARDHANDLE     hCardHandle;
} OPENCARDNAME, *LPOPENCARDNAME;

Members

dwStructSize
Specifies the length of the structure, in bytes. Must not be NULL.
hwndOwner
Identifies the window that owns the dialog box. This member can be any valid window handle, or it can be NULL for desktop default.
hSCardContext
Context used for communication with the smart card resource manager. Call SCardEstablishContext to set the resource manager context and SCardReleaseContext to release it. Must not be NULL.
lpstrGroupNames
Points to a buffer containing null-terminated group name strings. The last string in the buffer must be terminated by two NULL characters. Each string is the name of a group of cards that is to be included in the search. If lpstrGroupNames is NULL, the default group (Scard$DefaultReaders) is searched.
nMaxGroupNames
Maximum number of bytes (ANSI version) or characters (Unicode version) in the lpstrGroupNames string.
lpstrCardNames
Points to a buffer containing null-terminated card name strings. The last string in the buffer must be terminated by two NULL characters. Each string is the name of a card that is to be located.
nMaxCardNames
Maximum number of bytes (ANSI version) or characters (Unicode version) in the lpstrCardNames string.
rgguidInterfaces
Reserved for future use. An array of GUIDs identifying the interfaces required. Set this member to NULL for this release.
cguidInterfaces
Reserved for futures use. The number of interfaces in the rgguidInterfaces array. Set this member to NULL for this release.
lpstrRdr
If the card is located, the lpstrRdr buffer contains the name of the reader that contains the located card. The buffer should be at least 256 characters long.
nMaxRdr
Specifies the size, in bytes (ANSI version) or characters (Unicode version), of the buffer pointed to by lpstrRdr. If the buffer is too small to contain the reader information, GetOpenCardName returns SCARD_E_NO_MEMORY and the required size of the buffer pointed to by lpstrRdr.
lpstrCard
If the card is located, the lpstrCard buffer contains the name of the located card. The buffer should be at least 256 characters long.
nMaxCard
Specifies the size, in bytes (ANSI version) or characters (Unicode version), of the buffer pointed to by lpstrCard. If the buffer is too small to contain the card information, GetOpenCardName returns SCARD_E_NO_MEMORY and the required size of the buffer in nMaxCard.
lpstrTitle
Points to a string to be placed in the title bar of the dialog box. If this member is NULL, the system uses the default title "Select Card:".
dwFlags
A set of bit flags you can use to initialize the dialog box. When the dialog box returns, it sets these flags to indicate the user's input. This member can be a combination of the following flags.
Flag | Meaning
SC_DLG_MINIMAL_UI | Displays the dialog only if the card being searched for by the calling application is not located and available for use in a reader. This allows the card to be found, connected (either through the internal dialog mechanism or the user callback functions), and returned to the calling application.
SC_DLG_NO_UI | Force no display of the Select Card user interface (UI), regardless of search outcome.
SC_DLG_FORCE_UI | Force display of the Select Card UI, regardless of the search outcome.

pvUserData
A void pointer to user data. This pointer is passed back to the caller on the Connect, Check, and Disconnect routines.
dwShareMode
If lpfnConnect is not NULL, the dwShareMode and dwPreferredProtocols members are ignored. If lpfnConnect is NULL and dwShareMode is non-zero, then an internal call is made to SCardConnect using dwShareMode and dwPreferredProtocols as the dwShareMode and dwPreferredProtocols parameters. If the connect succeeds, hCardHandle is set to the handle returned by SCardConnect. If lpfnConnect is NULL and dwShareMode is zero, the dialog box returns hCardHandle as NULL.
dwPreferredProtocols
Used for internal connection as described in dwShareMode.
dwActiveProtocol
Returns the actual protocol in use when the dialog makes a connection to a card.
lpfnConnect
Pointer to the caller's card connect routine. If the caller needs to perform additional processing to connect to the card, this function pointer is set to the user's connect function. If the connect function is successful, the card is left connected and initialized, and the card handle is returned.

The prototype for the connect routine is

Connect(
  hSCardContext,  // the card context passed in the parameter block
  szReader,       // the name of the reader
  mszCards,       // multistring containing the possible card names in the reader
  pvUserData      // pointer to user data passed in parameter block
);
lpfnCheck
Pointer to the caller's card verify routine. If no special card verification is required, this pointer is NULL.

If the card is rejected by the verify routine, FALSE is returned and the card will be disconnected, as indicated by lpfnDisconnect.

If the card is accepted by the verify routine, TRUE is returned. When the user accepts the card, all other cards currently connected will be disconnected, as indicated by lpfnDisconnect, and this card will be returned as the located card. The located card will remain connected.

The prototype for the check routine is

Check(
  hSCardContext,  //  the card context passed in the parameter block
  hCard,          //  card handle
  pvUserData      //  pointer to user data passed in the parameter block
);
lpfnDisconnect
Pointer to the caller's card disconnect routine.

The prototype for the disconnect routine is

Disconnect(
  hSCardContext,  //  the card context passed in the parameter block
  hCard,          //  card handle
  pvUserData      //  pointer to user data passed in the parameter block
);

Note When using lpfnConnect, lpfnCheck, and lpfnDisconnect, all three callback procedures should be present. Using these callbacks allows further verification that the calling application has found the appropriate card. This is the best way to ensure the appropriate card is selected.

hCardHandle
Handle of the connected card (either through an internal dialog connect or an lpfnConnect callback).

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

GetOpenCardName, SCardUIDlgSelectCard , SCardConnect, SCardEstablishContext, SCardReleaseContext


OPENCARDNAME_EX

The OPENCARDNAME_EX structure contains the information that the SCardUIDlgSelectCard function uses to initialize a smart card Select Card dialog box.

typedef struct {
  DWORD                      dwStructSize;
  SCARDCONTEXT               hSCardContext;
  HWND                       hwndOwner;
  DWORD                      dwFlags;
  LPCTSTR                    lpstrTitle;
  LPCTSTR                    lpstrSearchDesc;
  HICON                      hIcon;
  POPENCARD_SEARCH_CRITERIA  pOpenCardSearchCriteria;
  LPOCNCONNPROC              lpfnConnect;
  LPVOID                     pvUserData;
  DWORD                      dwShareMode;
  DWORD                      dwPreferredProtocols;
  LPTSTR                     lpstrRdr;
  DWORD                      nMaxRdr;
  LPTSTR                     lpstrCard;
  DWORD                      nMaxCard;
  DWORD                      dwActiveProtocol;
  SCARDHANDLE                hCardHandle;
} OPENCARDNAME_EX, *POPENCARDNAME_EX, *LPOPENCARDNAME_EX;

Members

dwStructSize
Specifies the length of the structure, in bytes. The value of this member must not be NULL.
hSCardContext
Context used for communication with the smart card resource manager. Call SCardEstablishContext to set the resource manager context and SCardReleaseContext to release it. The value of this member must not be NULL.
hwndOwner
Identifies the window that owns the dialog box. This member can be any valid window handle, or it can be NULL for the desktop default.
dwFlags
A set of bit flags you can use to initialize the dialog box. When the dialog box returns, it sets these flags to indicate the user's input. This member can be one of the following flags.
Flag | Meaning
SC_DLG_MINIMAL_UI | Displays the dialog only if the card being searched for by the calling application is not located and available for use in a reader. This allows the card to be found, connected (either through the internal dialog mechanism or the user callback functions), and returned to the calling application.
SC_DLG_NO_UI | Force no display of the Select Card user interface (UI), regardless of search outcome.
SC_DLG_FORCE_UI | Force display of the Select Card UI, regardless of the search outcome.

lpstrTitle
Points to a string to be placed in the title bar of the dialog box. If this member is NULL, the system uses the default title "Select Card:".
lpstrSearchDesc
Points to a string to be displayed to the user as a prompt to insert the smart card. If this member is NULL, the system uses the default text "Please insert a smart card".
hIcon
Handle to an icon (32 x 32 pixels). You can specify a vendor-specific icon to display in the dialog. If this value is NULL, a generic smart card reader – loaded icon is displayed.
pOpenCardSearchCriteria
Pointer to the OPENCARD_SEARCH_CRITERIA structure to be used, or NULL if one is not used.
lpfnConnect
Pointer to the caller's card connect routine. If the caller needs to perform additional processing to connect to the card, this function pointer is set to the user's connect function. If the connect function is successful, the card is left connected and initialized, and the card handle is returned.

The prototype for the connect routine is as follows:

Connect(
  hSCardContext,  // the card context passed in the parameter block
  szReader,       // the name of the reader
  mszCards,       // multistring containing the possible card names in the reader
  pvUserData      // pointer to user data passed in parameter block
);
pvUserData
A void pointer to user data. This pointer is passed back to the caller on the Connect routine.
dwShareMode
If lpfnConnect is not NULL, the dwShareMode and dwPreferredProtocols members are ignored. If lpfnConnect is NULL and dwShareMode is non-zero, an internal call is made to SCardConnect using dwShareMode and dwPreferredProtocols as the dwShareMode and dwPreferredProtocols parameters. If the connect succeeds, hCardHandle is set to the handle returned by SCardConnect. If lpfnConnect is NULL and dwShareMode is zero, hCardHandle is set to NULL.
dwPreferredProtocols
Used for internal connection as described in dwShareMode.
lpstrRdr
If the card is located, the lpstrRdr buffer contains the name of the reader that contains the located card. The buffer should be at least 256 characters long.
nMaxRdr
Specifies the size, in bytes (ANSI version) or characters (Unicode version), of the buffer pointed to by lpstrRdr. If the buffer is too small to contain the reader information, SCardUIDlgSelectCard returns SCARD_E_NO_MEMORY and the required size of the buffer pointed to by lpstrRdr.
lpstrCard
If the card is located, the lpstrCard buffer contains the name of the located card. The buffer should be at least 256 characters long.
nMaxCard
Specifies the size, in bytes (ANSI version) or characters (Unicode version), of the buffer pointed to by lpstrCard. If the buffer is too small to contain the card information, SCardUIDlgSelectCard returns SCARD_E_NO_MEMORY and the required size of the buffer in nMaxCard.
dwActiveProtocol
Returns the actual protocol in use when the dialog makes a connection to a card.
hCardHandle
Handle of the connected card (either through an internal dialog connect or an lpfnConnect callback).

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Winscard.h.
Unicode: Implemented as Unicode and ANSI versions on Windows 2000.

See Also

Error Codes, SCardUIDlgSelectCard, SCardConnect, SCardEstablishContext, SCardReleaseContext


SCARD_IO_REQUEST

The SCARD_IO_REQUEST structure begins a protocol control information structure. Any protocol-specific information then immediately follows this structure. The entire length of the structure must be aligned with the underlying hardware architecture word size. For example, in Win32 the length of any PCI information must be a multiple of four bytes so that it aligns on a 32-bit boundary.

typedef struct {
  DWORD           dwProtocol;
  DWORD           cbPciLength;
} SCARD_IO_REQUEST;

Members

dwProtocol
Identifies the protocol in use.
cbPciLength
Supplies the length, in bytes, of the SCARD_IO_REQUEST structure plus any following PCI-specific information.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winsmcrd.h.

See Also

SCardTransmit


SCARD_READERSTATE

The SCARD_READERSTATE structure is used by functions for tracking smart cards within readers.

typedef struct {
  LPCTSTR   szReader;
  LPVOID    pvUserData;
  DWORD     dwCurrentState;
  DWORD     dwEventState;
  DWORD     cbAtr;
  BYTE      rgbAtr[36];
} SCARD_READERSTATE, *PSCARD_READERSTATE, *LPSCARD_READERSTATE;

Members

szReader
Points to the name of the reader being monitored.
pvUserData
Not used by the smart card subsystem. Used by the application.
dwCurrentState
Supplies the current state of the reader, as seen by the application. This field can take on any of the following values, in combination, as a bit mask.
Value | Meaning
SCARD_STATE_UNAWARE | The application is unaware of the current state, and would like to know. The use of this value results in an immediate return from state transition monitoring services. This is represented by all bits set to zero.
SCARD_STATE_IGNORE | The application is not interested in this reader, and it should not be considered during monitoring operations. If this bit value is set, all other bits are ignored.
SCARD_STATE_UNAVAILABLE | The application believes that this reader is not available for use. If this bit is set, then all the following bits are ignored.
SCARD_STATE_EMPTY | The application believes that there is not card in the reader. If this bit is set, all the following bits are ignored.
SCARD_STATE_PRESENT | The application believes that there is a card in the reader.
SCARD_STATE_ATRMATCH | The application believes that there is a card in the reader with an ATR matching one of the target cards. If this bit is set, SCARD_STATE_PRESENT is assumed. This bit has no meaning to SCardGetStatusChange beyond SCARD_STATE_PRESENT.
SCARD_STATE_EXCLUSIVE | The application believes that the card in the reader is allocated for exclusive use by another application. If this bit is set, SCARD_STATE_PRESENT is assumed.
SCARD_STATE_INUSE | The application believes that the card in the reader is in use by one or more other applications, but may be connected to in shared mode. If this bit is set, SCARD_STATE_PRESENT is assumed.
SCARD_STATE_MUTE | The application believes that there is an unresponsive card in the reader.

dwEventState
Receives the current state of the reader, as known by the smart card resource manager. This field can take on any of the following values, in combination, as a bit mask.
Value | Meaning
SCARD_STATE_IGNORE | This reader should be ignored.
SCARD_STATE_CHANGED | There is a difference between the state believed by the application, and the state known by the resource manager. When this bit is set, the application may assume a significant state change has occurred on this reader.
SCARD_STATE_UNKNOWN | The given reader name is not recognized by the resource manager. If this bit is set, then SCARD_STATE_CHANGED and SCARD_STATE_IGNORE will also be set.
SCARD_STATE_UNAVAILABLE | The actual state of this reader is not available. If this bit is set, then all the following bits are clear.
SCARD_STATE_EMPTY | There is no card in the reader. If this bit is set, all the following bits will be clear.
SCARD_STATE_PRESENT | There is a card in the reader.
SCARD_STATE_ATRMATCH | There is a card in the reader with an ATR matching one of the target cards. If this bit is set, SCARD_STATE_PRESENT will also be set. This bit is only returned on the SCardLocateCards function.
SCARD_STATE_EXCLUSIVE | The card in the reader is allocated for exclusive use by another application. If this bit is set, SCARD_STATE_PRESENT will also be set.
SCARD_STATE_INUSE | The card in the reader is in use by one or more other applications, but may be connected to in shared mode. If this bit is set, SCARD_STATE_PRESENT will also be set.
SCARD_STATE_MUTE | There is an unresponsive card in the reader.

cbAtr
The number of bytes in the returned ATR.
rgbAtr
The ATR of the inserted card, with extra alignment bytes.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 OSR2.1 or later.
Header: Declared in Winscard.h.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.

See Also

SCardGetStatusChange, SCardLocateCards


Smart Card Interfaces

The Smart Card SDK provides the following COM interfaces. (The methods for a specific interface are listed in the TOC and on the reference page for that interface).

Interface | Description
IByteBuffer | Manages a stream object.
ISCard | Opens and manages a connection to a smart card.
ISCardAuth | Authenticates an application, smart card, or user.
ISCardCmd | Constructs and manages a smart card Application Protocol Data Unit (APDU).
ISCardDatabase | Performs smart card resource manager database operations.
ISCardFileAccess | Performs common file services such as locating, selecting, reading, writing, creating, and deleting files
ISCardISO7816 | Constructs an APDU command.
ISCardLocate | Locates a smart card.
ISCardManage | Manages the smart card system.
ISCardTypeConv | Provides methods used to support other smart card COM interfaces. This interface is provided for backwards compatibility only and should no longer be used.
ISCardVerify | Verifies or changes card holder verification (CHV) policy.


IByteBuffer

The IByteBuffer interface is provided to read, write and manage stream objects. This object essentially is a wrapper for the IStream object.

Methods

Method | Description
Clone | Clones an IByteBuffer object.
Commit | Commits a transaction.
CopyTo | Copies bytes to another object.
Initialize | Initializes the IByteBuffer object.
LockRegion | Restricts access to a range of bytes.
Read | Reads bytes into memory.
Revert | Discards changes since the last Commit call.
Seek | Changes the seek pointer.
SetSize | Changes the size of the stream object.
Stat | Retrieves statistical information about a stream.
UnlockRegion | Removes access restriction previously set by LockRegion.
Write | Writes bytes to the stream.

Requirements

Windows NT/2000: Requires Windows 2000.
Windows 95/98: Unsupported.
Header: Declared in Scardssp.h. Library: Use Scardssp.tlb.


IByteBuffer::Clone

The Clone method creates a new object with its own seek pointer that references the same bytes as the original IByteBuffer object.

HRESULT Clone(
  LPBYTEBUFFER *ppByteBuffer
);

Parameters

ppByteBuffer
[out] When successful, points to the location of an IByteBuffer pointer to the new stream object. If an error occurs, this parameter is NULL.

Return Values

The return value is an HRESULT. A value of S_OK indicates the call was successful.

Remarks

This method creates a new stream object for accessing the same bytes but using a separate seek pointer. The new stream object sees the same data as the source stream object. Changes written to one object are immediately visible in the other. Range locking is shared between the stream objects.

The initial setting of the seek pointer in the cloned stream instance is the same as the current setting of the seek pointer in the original stream at the time of the clone operation.

Example Code

HRESULT  hr;

// Clone the buffer.
hr = pIByteBuff->Clone(&pIByteClone);
if (FAILED(hr))
  printf("Failed IByteBuffer::Clone\n");

Requirements

Windows NT/2000: Requires Windows 2000.
Windows 95/98: Unsupported.
Header: Declared in Scardssp.h. Library: Use Scardssp.tlb.


IByteBuffer::Commit

The Commit method ensures that any changes made to an object open in transacted mode are reflected in the parent storage.

HRESULT Commit(
  LONG grfCommitFlags
);

Parameters

grfCommitFlags
[in] Controls how the changes for the stream object are committed. See the STGC enumeration for a definition of these values.

Return Values

The return value is an HRESULT. A value of S_OK indicates the call was successful.

Remarks

This method ensures that changes to a stream object opened in transacted mode are reflected in the parent storage. Changes that have been made to the stream since it was opened or last committed are reflected to the parent storage object. If the parent is opened in transacted mode, the parent may still revert at a later time rolling back the changes to this stream object. The compound file implementation does not support opening streams in transacted mode, so this method has very little effect other than to flush memory buffers.

Example Code

HRESULT  hr;

// Commit the buffer.
hr = pIByteBuff->Commit(STGC_DEFAULT | STGC_CONSOLIDATE);
if (FAILED(hr))
  printf("Failed IByteBuffer::Commit\n");

Requirements

Windows NT/2000: Requires Windows 2000.
Windows 95/98: Unsupported.
Header: Declared in Scardssp.h. Library: Use Scardssp.tlb.


IByteBuffer::CopyTo

The CopyTo method copies a specified number of bytes from the current seek pointer in the object to the current seek pointer in another object.

HRESULT CopyTo(
  LPBYTEBUFFER *pByteBuffer,
  LONG cb,
  LONG *pcbRead,
  LONG *pcbWritten
);

Parameters

pByteBuffer
[in] Points to the destination stream. The stream pointed to by pByteBuffer can be a new stream or a clone of the source stream.
cb
[in] Specifies the number of bytes to copy from the source stream.
pcbRead
[out] Pointer to the location where this method writes the actual number of bytes read from the source. You can set this pointer to NULL to indicate that you are not interested in this value. In this case, this method does not provide the actual number of bytes read.
pcbWritten
[out] Pointer to the location where this method writes the actual number of bytes written to the destination. You can set this pointer to NULL to indicate that you are not interested in this value. In this case, this method does not provide the actual number of bytes written.

Return Values

The return value is an HRESULT. A value of S_OK indicates the call was successful.

Remarks

This method copies the specified bytes from one stream to another. It can also be used to copy a stream to itself. The seek pointer in each stream instance is adjusted for the number of bytes read or written.

Example Code

HRESULT  hr;
LONG     lRead, lWrite;

// Copy the buffer.
hr = pIByteBuff->CopyTo(&pIByteCopy,
                        20,
                        &lRead
                        &lWrite);
if (FAILED(hr))
  printf("Failed IByteBuffer::CopyTo\n");

Requirements

Windows NT/2000: Requires Windows 2000.
Windows 95/98: Unsupported.
Header: Declared in Scardssp.h. Library: Use Scardssp.tlb.


IByteBuffer::Initialize

The Initialize method prepares the IByteBuffer object for use. This method must be called prior to calling any other methods in the IByteBuffer interface.

HRESULT Initialize(
  LONG lSize,
  BYTE *pData
);

Parameters

lSize
The initial size in bytes of the data the stream is to contain.
pData
If not NULL, the initial data to write to the stream.

Return Values

The return value is an HRESULT. A value of S_OK indicates the call was successful.

Remarks

When using a new IByteBuffer stream, call this method prior to using any of the other IByteBuffer methods.

Example Code

UCHAR    ucFileName[] = {0x3f, 0x00};    // Master File (MF)
HRESULT  hr;

// pIByteRequest is a pointer to an instantiated IByteBuffer object.
hr = pIByteRequest->Initialize(2, ucFileName);
if (FAILED(hr))
    printf("Failed IByteBuffer::Initialize\n");

Requirements

Windows NT/2000: Requires Windows 2000.
Windows 95/98: Unsupported.
Header: Declared in Scardssp.h. Library: Use Scardssp.tlb.


IByteBuffer::LockRegion

The LockRegion method restricts access to a specified range of bytes in the buffer object.

HRESULT LockRegion(
  LONG libOffset,
  LONG cb,
  LONG dwLockType
);

Parameters

libOffset
[in] Integer that specifies the byte offset for the beginning of the range.
cb
[in] Integer that specifies the length of the range, in bytes, to be restricted.
dwLockType
[in] Specifies the restrictions being requested on accessing the range. This can be one of the values in the following table.
Value | Effect
LOCK_WRITE | The specified range of bytes can be opened and read any number of times, but writing to the locked range is prohibited except for the owner that was granted this lock.
LOCK_EXCLUSIVE | Writing to the specified range of bytes is prohibited except for the owner that was granted this lock.
LOCK_ONLYONCE | If this lock is granted, no other LOCK_ONLYONCE lock can be obtained on the range. Usually this lock type is an alias for some other lock type. Thus, specific implementations can have additional behavior associated with this lock type.

Return Values

The return value is an HRESULT. A value of S_OK indicates the call was successful.

Remarks

The byte range can extend past the current end of the stream. Locking beyond the end of a stream is useful as a method of communication between different instances of the stream without changing data that is actually part of the stream.

Three types of locking can be supported: locking to exclude other writers, locking to exclude other readers or writers, and locking that allows only one requestor to obtain a lock on the given range, which is usually an alias for one of the other two lock types. A given stream instance might support either of the first two types, or both. The lock type is specified by dwLockType, using a value from the LOCKTYPE enumeration.

Any region locked with IByteBuffer::LockRegion must later be explicitly unlocked by calling IByteBuffer::UnlockRegion with exactly the same values for the libOffset, cb, and dwLockType parameters. The region must be unlocked before the stream is released. Two adjacent regions cannot be locked separately and then unlocked with a single unlock call.

Example Code

HRESULT  hr;

// Lock a region.
hr = pIByteBuff->LockRegion(0, 10, LOCK_EXCLUSIVE);
if (FAILED(hr))
  printf("Failed IByteBuffer::LockRegion\n");

Requirements

Windows NT/2000: Requires Windows 2000.
Windows 95/98: Unsupported.
Header: Declared in Scardssp.h. Library: Use Scardssp.tlb.


IByteBuffer::Read

The Read method reads a specified number of bytes from the buffer object into memory starting at the current seek pointer.

HRESULT Read(
  BYTE *pByte,
  LONG cb,
  LONG *pcbRead
);

Parameters

pByte
[out] Points to the buffer into which the stream data is read. If an error occurs, this value is NULL.
cb
[in] Specifies the number of bytes of data to attempt to read from the stream object.
pcbRead
[out] Address of a LONG variable that receives the actual number of bytes read from the stream object. You can set this pointer to NULL to indicate that you are not interested in this value. In this case, this method does not provide the actual number of bytes read.

Return Values

The return value is an HRESULT. A value of S_OK indicates the call was successful.

Remarks

This method reads bytes from this stream object into memory. The stream object must be opened in STGM_READ mode. This method adjusts the seek pointer by the actual number of bytes read.

The number of bytes actually read is also returned in the pcbRead parameter.

Notes to Callers

The actual number of bytes read can be fewer than the number of bytes requested if an error occurs or if the end of the stream is reached during the read operation.

Some implementations might return an error if the end of the stream is reached during the read. You must be prepared to deal with the error return or S_OK return values on end of stream reads.

Example Code

BYTE     byAtr[32];
long     lBytesRead, i;
HRESULT  hr;

// pAtr is a pointer to a previously instantiated IByteBuffer.
// It was used in an earlier call by ISCard::get_Atr.
// Use IByteBuffer::Read to access the retrieved ATR bytes.
hr = pAtr->Read(byAtr, 32, &lBytesRead);
// Use the ATR value. (This example merely displays the bytes.)
for ( i = 0; i < lBytesRead; i++)
    printf("%c", *(byAtr + i));
printf("\n");

Requirements

Windows NT/2000: Requires Windows 2000.
Windows 95/98: Unsupported.
Header: Declared in Scardssp.h. Library: Use Scardssp.tlb.


IByteBuffer::Revert

The Revert method discards all changes that have been made to a transacted stream since the last IByteBuffer::Commit call.

HRESULT Revert(void);

Parameters

None.

Return Values

The return value is an HRESULT. A value of S_OK indicates the call was successful and the stream was reverted to its previous version.

Remarks

This method discards changes made to a transacted stream since the last commit operation.

Example Code

HRESULT  hr;

hr = pIByteBuff->Revert();
if (FAILED(hr))
  printf("Failed IByteBuffer::Revert\n");

Requirements

Windows NT/2000: Requires Windows 2000.
Windows 95/98: Unsupported.
Header: Declared in Scardssp.h. Library: Use Scardssp.tlb.


IByteBuffer::Seek

The Seek method changes the seek pointer to a new location relative to the beginning of the buffer, to the end of the buffer, or to the current seek pointer.

HRESULT Seek(
  LONG dlibMove,
  LONG dwOrigin,
  LONG *plibNewPosition
);

Parameters

dlibMove
[in] Displacement to be added to the location indicated by dwOrigin. If dwOrigin is STREAM_SEEK_SET, this is interpreted as an unsigned value rather than signed.
dwOrigin
[in] Specifies the origin for the displacement specified in dlibMove. The origin can be one of the values in the following table.
Value | Description
STREAM_SEEK_SET | The new seek pointer is an offset relative to the beginning of the stream. In this case, the dLibMove parameter is the new seek position relative to the beginning of the stream.
STREAM_SEEK_CUR | The new seek pointer is an offset relative to the current seek pointer location. In this case, the dLibMove parameter is the signed displacement from the current seek position.
STREAM_SEEK_END | The new seek pointer is an offset relative to the end of the stream. In this case, the dLibMove parameter is the new seek position relative to the end of the stream.

plibNewPosition
[out] Pointer to the location where this method writes the value of the new seek pointer from the beginning of the stream. You can set this pointer to NULL to indicate that you are not interested in this value. In this case, this method does not provide the new seek pointer.

Return Values

The return value is an HRESULT. A value of S_OK indicates the call was successful.

Remarks

IByteBuffer::Seek changes the seek pointer so subsequent reads and writes can take place at a different location in the stream object. It is an error to seek before the beginning of the stream. It is not, however, an error to seek past the end of the stream. Seeking past the end of the stream is useful for subsequent writes, as the stream will at that time be extended to the seek position immediately before the write is done.

You can also use this method to obtain the current value of the seek pointer by calling this method with the dwOrigin parameter set to STREAM_SEEK_CUR and the dlibMove parameter set to 0 so the seek pointer is not changed. The current seek pointer is returned in the plibNewPosition parameter.

Example Code

LONG     lNewPos;
HRESULT  hr;

// Change the seek pointer.
hr = pIByteBuff->Seek(5, STREAM_SEEK_SET, &lNewPos);
if (FAILED(hr))
  printf("Failed IByteBuffer::Seek\n");
else
  printf("New position is %x\n", lNewPos);

Requirements

Windows NT/2000: Requires Windows 2000.
Windows 95/98: Unsupported.
Header: Declared in Scardssp.h. Library: Use Scardssp.tlb.


IByteBuffer::SetSize

The SetSize method changes the size of the stream object.

HRESULT SetSize(
  LONG libNewSize
);

Parameters

libNewSize
[in] Specifies the new size of the stream as a number of bytes

Return Values

The return value is an HRESULT. A value of S_OK indicates the call was successful.

Remarks

IByteBuffer::SetSize changes the size of the stream object. Call this method to preallocate space for the stream. If the libNewSize parameter is larger than the current stream size, the stream is extended to the indicated size by filling the intervening space with bytes of undefined value. This operation is similar to the IByteBuffer::Write method if the seek pointer is past the current end-of-stream.

If the libNewSize parameter is smaller than the current stream, then the stream is truncated to the indicated size.

The seek pointer is not affected by the change in stream size.

Calling IByteBuffer::SetSize can be an effective way of trying to obtain a large chunk of contiguous space.

Example Code

LONG     lNewSize = 256;
HRESULT  hr;

// Change the buffer size.
hr = pIByteBuff->SetSize(lNewSize);
if (FAILED(hr))
  printf("Failed IByteBuffer::SetSize\n");

Requirements

Windows NT/2000: Requires Windows 2000.
Windows 95/98: Unsupported.
Header: Declared in Scardssp.h. Library: Use Scardssp.tlb.


IByteBuffer::Stat

The Stat method retrieves statistical information from the stream object.

HRESULT Stat(
  LPSTATSTRUCT pstatstg,
  LONG grfStatFlag
);

Parameters

pstatstg
[out] Points to a STATSTRUCT structure where this method places information about this stream object. This pointer is NULL if an error occurs.
grfStatFlag
[in] Specifies that this method does not return some of the fields in the STATSTRUCT structure, thus saving a memory allocation operation. Values are taken from the STATFLAG enumeration

Return Values

The return value is an HRESULT. A value of S_OK indicates the call was successful.

Remarks

IByteBuffer::Stat retrieves a pointer to the STATSTRUCT structure that contains information about this open stream.

Example Code

STATSTRUCT  statstr;
HRESULT     hr;

// Retrieve the statistical information.
hr = pIByteBuff->Stat(&statstr,
                      STATFLAG_DEFAULT);
if (FAILED(hr))
  printf("Failed IByteBuffer::Stat\n");
else
  // Use statstr as needed.

Requirements

Windows NT/2000: Requires Windows 2000.
Windows 95/98: Unsupported.
Header: Declared in Scardssp.h. Library: Use Scardssp.tlb.


IByteBuffer::UnlockRegion

The UnlockRegion method removes the access restriction on a range of bytes previously restricted with IByteBuffer::LockRegion.

HRESULT UnlockRegion(
  LONG libOffset,
  LONG cb,
  LONG dwLockType
);

Parameters

libOffset
[in] Specifies the byte offset for the beginning of the range.
cb
[in] Specifies, in bytes, the length of the range to be restricted.
dwLockType
[in] Specifies the access restrictions previously placed on the range.

Return Values

The return value is an HRESULT. A value of S_OK indicates the call was successful.

Remarks

IByteBuffer::UnlockRegion unlocks a region previously locked with the IByteBuffer::LockRegion method. Locked regions must later be explicitly unlocked by calling IByteBuffer::UnlockRegion with exactly the same values for the libOffset, cb, and dwLockType parameters. The region must be unlocked before the stream is released. Two adjacent regions cannot be locked separately and then unlocked with a single unlock call.

Example Code

HRESULT  hr;

// Unlock a region.
hr = pIByteBuff->UnlockRegion(0, 10, LOCK_EXCLUSIVE);
if (FAILED(hr))
  printf("Failed IByteBuffer::UnlockRegion\n");

Requirements

Windows NT/2000: Requires Windows 2000.
Windows 95/98: Unsupported.
Header: Declared in Scardssp.h. Library: Use Scardssp.tlb.


IByteBuffer::Write

The Write method writes a specified number from bytes into the stream object starting at the current seek pointer.

HRESULT Write(
  BYTE *pByte,
  LONG cb,
  LONG *pcbWritten
);

Parameters

pByte
[in] Address of the buffer containing the data that is to be written to the stream. A valid pointer must be provided for this parameter even when cb is zero.
cb
[in] The number of bytes of data to attempt to write into the stream. Can be zero.
pcbWritten
[out] Address of a LONG variable where this method writes the actual number of bytes written to the stream object. The caller can set this pointer to NULL, in which case, this method does not provide the actual number of bytes written.

Return Values

The return value is an HRESULT. A value of S_OK indicates the call was successful.

Remarks

IByteBuffer::Write writes the specified data to a stream object. The seek pointer is adjusted for the number of bytes actually written. The number of bytes actually written is returned in the pcbWritten parameter. If the byte count is zero bytes, the write operation has no effect.

If the seek pointer is currently past the end of the stream and the byte count is nonzero, this method increases the size of the stream to the seek pointer and writes the specified bytes starting at the seek pointer. The fill bytes written to the stream are not initialized to any particular value. This is the same as the end-of-file behavior in the MS-DOS FAT file system.

With a zero byte count and a seek pointer past the end of the stream, this method does not create the fill bytes to increase the stream to the seek pointer. In this case, you must call the IByteBuffer::SetSize method to increase the size of the stream and write the fill bytes.

The pcbWritten parameter can have a value even if an error occurs.

In the COM-provided implementation, stream objects are not sparse. Any fill bytes are eventually allocated on the disk and assigned to the stream.

Example Code

LONG     lWrite;
HRESULT  hr;

// Write to the buffer.
// byData is an array of 64 bytes.
hr = pIByteBuff->Write(byData,
                       64,
                       &lWrite);
if (FAILED(hr))
  printf("Failed IByteBuffer::Write\n");

Requirements

Windows NT/2000: Requires Windows 2000.
Windows 95/98: Unsupported.
Header: Declared in Scardssp.h. Library: Use Scardssp.tlb.


ISCard

The ISCard interface lets you open and manage a connection to a smart card. Each connection to a card requires a single, corresponding instance of the ISCard interface.

The smart card resource manager must be available whenever an instance of ISCard is created. If this service is unavailable, creation of the interface will fail.

The following example shows a typical use of the ISCard interface. The ISCard interface is used to connect to the smart card, submit a transaction, and release the smart card.

To submit a transaction to a specific card

  1. Create an ISCard interface.
  2. Attach to a smart card by specifying a smart card reader or by using a previously established, valid handle.
  3. Create transaction commands with ISCardCmd, and ISCardISO7816 smart card interfaces.
  4. Use ISCard to submit the transaction commands for processing by the smart card.
  5. Use ISCard to release the smart card.
  6. Release the ISCard interface.

Methods

Method | Description
get_Atr | Retrieves the ATR string of the smart card.
get_CardHandle | Retrieves the handle for the connected smart card.
get_Context | Retrieves the current resource manager context handle.
get_Protocol | Retrieves the identifier of the protocol currently in use on the smart card.
get_Status | Retrieves the current state the smart card is in.
AttachByHandle | Attaches an object to an open and configured smart card handle.
AttachByReader | Opens the smart card in the named reader.
Detach | Closes the open connection to the smart card.
LockSCard | Claims exclusive access to the smart card.
ReAttach | Resets and reinitializes the smart card.
Transaction | Executes a write and read operation on the smart card command (APDU) object.
UnlockScard | Releases exclusive access to the smart card.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardmgr.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardmgr.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).


ISCard::get_Atr

The get_Atr method retrieves an ATR string of the smart card.

HRESULT get_Atr(
  LPBYTEBUFFER *ppAtr
);

Parameters

ppAtr
[out, retval] Pointer to a byte buffer in the form of an IStream that will contain the ATR string on return.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | ppAtr is invalid.
E_POINTER | A bad pointer was passed in ppAtr.
E_OUTOFMEMORY | Memory to satisfy the request is unavailable.

Remarks

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

// Retrieve the ATR.
// pISCard is a pointer to a previously instantiated ISCard.
// pAtr is a pointer to a previously instantiated IByteBuffer.
hr = pISCard->get_Atr(&pAtr);
if (FAILED(hr))
{
    printf("Failed get_Atr\n");
    // Take other error handling action.
}
// Success, you can now use IByteBuffer::Read to access ATR bytes.
BYTE  byAtr[32];
   long  lBytesRead, i;
   // Read the ATR string into a byte array.
   hr = pAtr->Read(byAtr, 32, &lBytesRead);
   // Use the ATR value. (This example merely displays the bytes.)
   for ( i = 0; i < lBytesRead; i++)
       printf("%c", *(byAtr + i));
   printf("\n");

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardmgr.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardmgr.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

get_CardHandle, get_Context, get_Protocol, get_Status, ISCard, IByteBuffer::Read


ISCard::get_CardHandle

The get_CardHandle method retrieves the handle for a connected smart card. Returns (*pHandle) == NULL if not connected.

HRESULT get_CardHandle(
  HSCARD *pHandle
);

Parameters

pHandle
[out, retval] Pointer to the card handle on return.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | pHandle is invalid.
E_POINTER | A bad pointer was passed in pHandle.

Remarks

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

HSCARD   hSC;
HRESULT  hr;

// Retrieve the card handle.
hr = pISCard->get_CardHandle(&hSC);
if (FAILED(hr))
{
   printf("Failed get_CardHandle\n");
   // Take other error handling action as needed.
}
// Use card handle as needed.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardmgr.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardmgr.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

get_Atr, get_Context, get_Protocol, get_Status, ISCard


ISCard::get_Context

The get_Context method retrieves the current resource manager context handle. Returns (*pContext) == NULL if no context has been established.

HRESULT get_Context(
  HSCARDCONTEXT *pContext
);

Parameters

pContext
[out, retval] Pointer to the context handle on return.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | pContext is invalid.
E_POINTER | A bad pointer was passed in pContext.

Remarks

The resource manager context is set by calling the smart card function SCardEstablishContext.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

HSCARDCONTEXT  hCtx;
HRESULT        hr;

// Retrieve the smart card context.
hr = pISCard->get_Context(&hCtx);
if (FAILED(hr))
{
   printf("Failed get_Context\n");
   // Take other error handling action as needed.
}
// Use smart card context as needed.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardmgr.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardmgr.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

get_Atr, get_CardHandle, get_Protocol, get_Status, ISCard, SCardEstablishContext


ISCard::get_Protocol

The get_Protocol retrieves the identifier of the protocol currently in use on the smart card.

HRESULT get_Protocol(
  SCARD_PROTOCOLS *pProtocol
);

Parameters

pProtocol
[out, retval] Pointer to the protocol identifier.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | pProtocol is invalid.
E_POINTER | A bad pointer was passed in pProtocol.

Remarks

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

SCARD_PROTOCOLS   scProtocol;
HRESULT           hr;

// Retrieve the protocol.
hr = pISCard->get_Protocol(&scProtocol);
if (FAILED(hr))
{
   printf("Failed get_Protocol\n");
   // Take other error handling action as needed.
}
// Use the retrieved protocol. (This example merely displays it.)
switch (scProtocol)
{
    case T0:
        printf("T0 protocol\n");
        break;
    case T1:
        printf("T1 protocol\n");
        break;
    default:
        printf("Other protocol\n");
        break;
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardmgr.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardmgr.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

get_Atr, get_CardHandle, get_Context, get_Status, ISCard


ISCard::get_Status

The get_Status method retrieves the current state of the smart card.

HRESULT get_Status(
  SCARD_STATES *pStatus
);

Parameters

pStatus
[out] Pointer to the state variable.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | pStatus is invalid.
E_POINTER | A bad pointer was passed in pStatus.

Remarks

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

SCARD_STATES    scState;
HRESULT         hr;

// Determine the current state of the smart card.
hr = pISCard->get_Status(&scState);
if (FAILED(hr))
{
   printf("Failed get_Status\n");
   exit(1);  // Or other error handling action.
}
// Use the retrieved value. (This example merely displays it.)
switch (scState)
{
    case ABSENT:
        printf("Absent state\n");
        break;
    case PRESENT:
        printf("Present state\n");
        break;
    case SWALLOWED:
        printf("Swallowed state\n");
        break;
    case POWERED:
        printf("Powered state\n");
        break;
    case NEGOTIABLEMODE:
        printf("Negotiable mode state\n");
        break;
    case SPECIFICMODE:
        printf("Specific mode state\n");
        break;
    default:
        printf("Unexpected state\n");
        break;
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardmgr.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardmgr.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

get_Atr, get_CardHandle, get_Context, get_Protocol, ISCard


ISCard::AttachByHandle

The AttachByHandle method attaches the SCard object to an open and configured smart card handle.

HRESULT AttachByHandle(
  HSCARD hCard
);

Parameters

hCard
[in] Handle to an open connection to a smart card.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | hCard is invalid.

Remarks

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

HRESULT  hr;

// hSC is of type HSCARD and has been previously assigned.
// Attach SCard to the smart card using the value in hSC.
hr = pISCard->AttachByHandle(hSC);
if (FAILED(hr))
{
   printf("Failed AttachByHandle\n");
   // Take other error handling action as needed.
}
// Proceed using attached reader.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardmgr.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardmgr.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

AttachByReader, Detach,get_CardHandle, ISCard, ReAttach


ISCard::AttachByReader

The AttachByReader method opens the smart card in the named reader.

HRESULT AttachByReader(
  BSTR bstrReaderName,
  SCARD_SHARE_MODES ShareMode,
  SCARD_PROTOCOLS PrefProtocol
);

Parameters

bstrReaderName [in]
Pointer to the name of the smart card reader.
ShareMode [in, defaultvalue(EXCLUSIVE)]
Mode in which to claim access to the smart card.
Values | Description
EXCLUSIVE | No one else use this connection to the smart card.
SHARED | Other applications can use this connection.

PrefProtocol [in, defaultvalue(T0)]
Preferred protocol values:

T0
T1
RAW
T0|T1

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Open on the smart card in the named reader has been completed successfully.
E_INVALIDARG | There is something wrong with one or more of the parameters passed into the function.

Remarks

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

// The reader name is vendor specific; change as needed.
#define READER_NAME L"Vendor Reader 0"

BSTR     bstrReader = NULL;
HRESULT  hr;

bstrReader = SysAllocString(READER_NAME);

// Connect to the reader.
hr = pISCard->AttachByReader(bstrReader, SHARED, T0);
if (FAILED(hr))
{
    printf("Failed AttachByReader\n");
    // Take other error handling action.
}
// When done, free BSTR.
if (NULL != bstrReader)
    SysFreeString(bstrReader);

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardmgr.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardmgr.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

AttachByHandle, Detach, ISCard, ReAttach


ISCard::Detach

The Detach method closes the open connection to the smart card.

HRESULT Detach(
  SCARD_DISPOSITIONS Disposition
);

Parameters

Disposition [in, defaultvalue(LEAVE)]
Indicates what should be done with the card in the connected reader.
Values | Description
LEAVE | Leaves the smart card in the current state.
RESET | Resets the smart card to some known state.
UNPOWER | Removes power from the smart card.
EJECT | Ejects the smart card if the reader has eject capabilities.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Disposition is invalid.

Remarks

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

HRESULT    hr;

// Detach the smart card.
hr = pISCard->Detach(LEAVE);
if (FAILED(hr))
{
   printf("Failed Detach\n");
   // Take error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardmgr.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardmgr.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

AttachByHandle, AttachByReader, Detach, ISCard, ReAttach


ISCard::LockSCard

The LockSCard method claims exclusive access to the smart card.

HRESULT LockSCard(void);

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.

Remarks

In addition to the COM error code listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

HRESULT    hr;

// Lock the smart card.
hr = pISCard->LockSCard();
if (FAILED(hr))
{
    printf("Failed LockSCard\n");
    // Take error handling action as needed.
}
// Use smart card; unlock the smart card when done.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardmgr.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardmgr.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

ISCard, UnlockSCard


ISCard::ReAttach

The ReAttach method resets, or reinitializes, the smart card.

HRESULT ReAttach(
  SCARD_SHARE_MODES ShareMode,
  SCARD_DISPOSITIONS InitState
);

Parameters

ShareMode [in, defaultvalue(EXCLUSIVE)]
Mode in which to share or exclusively own the connection to the smart card.
Values | Description
EXCLUSIVE | No one else use this connection to the smart card.
SHARED | Other applications can use this connection.

InitState [in, defaultvalue(LEAVE)]
Indicates what to do with the card.
Values | Description
LEAVE | Leaves the smart card in the current state.
RESET | Resets the smart card to some known state.
UNPOWER | Removes power from the smart card.
EJECT | Ejects the smart card if the reader has eject capabilities.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | There is something wrong with one or more of the parameters passed into the function.

Remarks

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

HRESULT    hr;

// Reattach the smart card.
hr = pISCard->ReAttach(SHARED, LEAVE);
if (FAILED(hr))
{
   printf("Failed ReAttach\n");
   // Take error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardmgr.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardmgr.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

AttachByHandle, AttachByReader, Detach, ISCard


ISCard::Transaction

The Transaction method executes a write and read operation on the smart card command (APDU) object. The reply string from the smart card for the command string defined in the card that was sent to the smart card will be accessible after this function returns.

HRESULT Transaction(
  LPSCARDCMD *ppCmd
);

Parameters

ppCmd [in, out]
Pointer to the smart card command object.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | ppCmd is invalid.
E_POINTER | A bad pointer was passed in ppCmd.
E_OUTOFMEMORY | Memory to satisfy the request is unavailable.

Remarks

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

HRESULT    hr;

// pISCard is a pointer to an instance of ISCard.
// pISCardCmd is a pointer to an instance of ISCardCmd,
// and ISCardCmd::BuildCmd has already been called.
hr = pISCard->Transaction(&pISCardCmd);
if (FAILED(hr))
{
    printf("Failed ISCard::Transaction\n");
    // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardmgr.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardmgr.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

AttachByHandle, AttachByReader, Detach, get_Atr, get_CardHandle, get_Context, get_Protocol, get_Status, ISCard, LockSCard, ReAttach, Transaction, UnlockSCard


ISCard::UnlockSCard

The UnlockSCard method releases exclusive access to the smart card.

HRESULT UnlockSCard(
  SCARD_DISPOSITIONS Disposition
);

Parameters

Disposition [in, defaultvalue(LEAVE)]
Indicates what should be done with the card in the connected reader.
Values | Description
LEAVE | Leaves the smart card in the current state.
RESET | Resets the smart card to some known state.
UNPOWER | Removes power from the smart card.
EJECT | Ejects the smart card if the reader has eject capabilities.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Disposition is invalid

Remarks

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

HRESULT    hr;

// Unlock the smart card.
hr = pISCard->UnlockSCard(LEAVE);
if (FAILED(hr))
{
   printf("Failed UnlockSCard\n");
   // Take error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardmgr.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardmgr.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

ISCard, LockSCard


ISCardAuth

The following interface definition is provided as a standard that can be followed when developing a smart card service provider.

The ISCardAuth interface can be used to expose authentication services supported by a smart card. These services include application authentication, smart card authentication, and user authentication.

The following example shows a typical use of the ISCardAuth interface.

To use ISCardAuth

  1. Create an ISCardAuth interface (through the corresponding ISCardManage interface method).
  2. Call the appropriate ISCardAuth method (APP_Auth, GetChallenge, ICC_Auth, or User_Auth).
  3. Release the ISCardAuth interface.

Methods

ISCardAuth Methods | Definition
APP_Auth | Allows the application to authenticate itself using a challenge/signature protocol.
GetChallenge | Returns a challenge from the smart card.
ICC_Auth | Allows an application to authenticate the smart card.
User_Auth | Allows access to user authentication services.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.


ISCardAuth::APP_Auth

The APP_Auth method authenticates the application. It allows an application to authenticate itself (using a challenge/signature protocol) when authentication is requested by a smart card.

HRESULT APP_Auth(
  LONG lAlgoID,
  LPBYTEBUFFER pParam,
  LPBYTEBUFFER pBuffer
);

Parameters

lAlgoID [in]
Specifies the algorithm to be used in the authentication process.
pParam [in]
IByteBuffer containing vendor-specific parameters of the authentication process.
pBuffer [in]
Contains data required for the calculation.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

For a list of all the methods provided by the ISCardAuth interface, see ISCardAuth.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardAuth


ISCardAuth::GetChallenge

The GetChallenge method returns a challenge from the smart card.

HRESULT GetChallenge(
  LONG lAlgoID,
  LONG lLengthOfChallenge,
  LPBYTEBUFFER pParam,
  LPBYTEBUFFER *pBuffer
);

Parameters

lAlgoID [in, optional]
Specifies the algorithm to be used in the authentication process.
lLengthOfChallenge [in]
Maximum length of expected response.
pParam [in]
IByteBuffer containing vendor-specific parameters of the authentication process.
pBuffer [in ,out]
On input, points to the buffer.

On output, contains the challenge data from the card.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

For a list of all the methods provided by the ISCardAuth interface, see ISCardAuth.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardAuth


ISCardAuth::ICC_Auth

The ICC_Auth method allows an application to authenticate the smart card.

HRESULT ICC_Auth(
  LONG lAlgoID,
  LPBYTEBUFFER pParam,
  LPBYTEBUFFER *pBuffer
);

Parameters

lAlgoID [in]
Specifies the algorithm to be used in the authentication process.
pParam [in]
IByteBuffer containing vendor-specific parameters of the authentication process.
pBuffer [in, out]
On input, contains data to be used in the authentication process.

On output, contains the result of the authentication process.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

For a list of all the methods provided by the ISCardAuth interface, see ISCardAuth.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardAuth


ISCardAuth::User_Auth

The User_Auth method allows access to user authentication services.

HRESULT User_Auth(
  LONG lAlgorID,
  LPBYTEBUFFER pParam,
  LPBYTEBUFFER pBuffer
);

Parameters

lAlgorID [in]
Specifies the algorithm to be used in the authentication process.
pParam [in]
IByteBuffer containing vendor-specific parameters of the authentication process.
pBuffer [in]
Contains data to be used in the authentication process.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

For a list of all the methods provided by the ISCardAuth interface, see ISCardAuth.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardAuth


ISCardCmd

The ISCardCmd interface provides the methods needed to construct and manage a smart card application protocol data unit (APDU ). This interface encapsulates two buffers:

  • The APDU buffer contains the command sequence that will be sent to the card.
  • The APDUReply buffer contains data returned from the card after execution of the APDU command (this data is also referred to as the return APDU).

The following example shows a typical use of the ISCardCmd interface. The ISCardCmd interface is used to build the an APDU.

To submit a transaction to a specific card

  1. Create an ISCard interface and connect to a smart card.
  2. Create an ISCardCmd interface.
  3. Build a smart card APDU command using the ISCardISO7816 interface or one of ISCardCmd's build methods).
  4. Execute the command on the smart card by calling the appropriate ISCard interface method.
  5. Evaluate the returned response.
  6. Repeat the procedure as needed.
  7. Release the ISCardCmd interface and others as needed.

Methods

ISCardCmd Methods | Description
get_AlternateClassId | Retrieves the current alternate class ID value.
put_AlternateClassId | Sets the alternate class ID value.
get_Apdu | Retrieves the raw APDU.
put_Apdu | Copies the APDU from an IByteBuffer (IStream) object into the APDU wrapped in this interface object.
get_ApduLength | Retrieves the length of the APDU.
get_ApduReply | Retrieves the reply APDU.
put_ApduReply | Sets a new reply APDU.
get_ApduReplyLength | Retrieves the length of the reply APDU.
put_ApduReplyLength | Reserved for future use.
get_ClassId | Retrieves the class ID from the APDU.
put_ClassId | Sets a new class ID in the APDU.
get_Data | Retrieves the data field from the APDU.
put_Data | Sets or copies a given data field into the APDU.
get_InstructionId | Retrieves the instruction ID byte from the APDU.
put_InstructionId | Sets the given instruction ID byte in the APDU.
get_LeField | Retrieves the Le field of the APDU.
get_Nad | Reserved for future use.
put_Nad | Changes the Nad from the default of zero to the specified value.
get_P1 | Retrieves the first parameter byte from the APDU.
put_P1 | Sets the first parameter byte in the APDU.
get_P2 | Retrieves the second parameter byte from the APDU.
put_P2 | Sets the second parameter byte in the APDU.
get_P3 | Retrieves the third parameter byte from the APDU.
get_ReplyNad | Returns the node address (Nad) used by the card in the reply message.
put_ReplyNad | Reserved for future use.
get_ReplyStatus | Retrieves the reply APDU's message status word.
put_ReplyStatus | Sets a new reply APDU's message status word.
get_ReplyStatusSW1 | Retrieves the reply APDU's message SW1 status byte.
get_ReplyStatusSW2 | Retrieves the reply APDU's message SW2 status byte.
get_Type | Reserved for future use.
BuildCmd | Constructs a valid command APDU for transmission to a smart card.
Clear | Clears the APDU and the reply APDU message buffers.
Encapsulate | Encapsulates the given command APDU into another command APDU for transmission to a smart card.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).


ISCardCmd::get_AlternateClassId

The get_AlternateClassId method retrieves the value of the alternate class ID. This method will fail unless the alternate ID has been set by a previous call to put_AlternateClassId.

HRESULT get_AlternateClassId(
    BYTE * pbyClass
);

Parameters

pbyClass
[out, retval] Pointer to the byte that contains the alternate class ID value on return.

Return Values

The possible return values are the following.

Value | Meaning
S_OK | Operation was completed successfully.
E_INVALIDARG | pbyClass is invalid.
E_ACCESSDENIED | The alternate class ID has not been previously set by a call to put_AlternateClassId.

Remarks

This method applies to communications using the T=0 protocol. See put_AlternateClassId for related information.

Example Code

BYTE     byAltClassID;
HRESULT  hr;

// Retrieve the alternate class ID.
hr = pISCardCmd->get_AlternateClassId(&byAltClassID);
if (FAILED(hr))
{
  printf("Failed get_AltClassId\n");
  // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

put_AlternateClassId


ISCardCmd::put_AlternateClassId

The put_AlternateClassId method specifies a new alternate class identifier in the APDU.

HRESULT put_AlternateClassId(
    BYTE byClass
);

Parameters

byClass
[in] The byte that represents the alternate class identifier. The default value is 0 (zero).

Remarks

With communications using the T=0 protocol, additional card commands can be automatically generated by the APDU and sent to the transmission protocol data unit (TPDU). The additional commands typically use the same class ID as the original command; specifying a new class ID by means of this method allows automatically generated commands to use the new class ID.

Example Code

HRESULT  hr;

// Set the class ID.
hr = pISCardCmd->put_AlternateClassId(0xC0);
if (FAILED(hr))
{
  printf("Failed put_AlternateClassId\n");
  // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

get_AlternateClassId


ISCardCmd::get_Apdu

The get_Apdu method retrieves the raw APDU.

HRESULT get_Apdu(
  LPBYTEBUFFER *ppApdu
);

Parameters

ppApdu
[out, retval] Pointer to the byte buffer mapped through an IStream that contains the APDU message on return.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | ppApdu is invalid.
E_POINTER | A bad pointer was passed in ppApdu.
E_OUTOFMEMORY | Out of memory.

Remarks

To copy the APDU from an IByteBuffer (IStream) object into the APDU wrapped in this interface object, call put_Apdu.

To determine the length of the APDU, call get_ApduLength.

For a list of all the methods provided by the ISCardCmd interface, see ISCardCmd.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

HRESULT    hr;

// pIByteApdu is a pointer to an instance of IByteBuffer.
// Retrieve the APDU.
hr = pISCardCmd->get_Apdu(&pIByteApdu);
if (FAILED(hr))
{
    printf("Failed get_Apdu.\n");
    // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

get_ApduLength, ISCardCmd, put_Apdu


ISCardCmd::put_Apdu

The put_Apdu method copies the APDU from the IByteBuffer (IStream) object into the APDU wrapped in this interface object.

HRESULT put_Apdu(
  LPBYTEBUFFER pApdu
);

Parameters

pApdu
[in] Pointer to the ISO 7816-4 APDU to be copied in.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | pApdu is invalid.
E_POINTER | A bad pointer was passed in pApdu.
E_OUTOFMEMORY | Out of memory.

Remarks

To retrieve the raw APDU from the byte buffer mapped through an IStream that contains the APDU message, call get_Apdu.

For a list of all the methods provided by the ISCardCmd interface, see ISCardCmd.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

HRESULT    hr;

// pIByteApdu is a pointer to an instance of IByteBuffer.
// Set the APDU.
hr = pISCardCmd->put_Apdu(pIByteApdu);
if (FAILED(hr))
{
    printf("Failed put_Apdu.\n");
    // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

get_Apdu, ISCardCmd


ISCardCmd::get_ApduLength

The get_ApduLength method determines the length (in bytes) of the APDU.

HRESULT get_ApduLength(
  LONG *plSize
);

Parameters

plSize
[out, retval] Pointer to the length of the APDU.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | plSize is invalid.
E_POINTER | A bad pointer was passed in plSize.
E_OUTOFMEMORY | Out of memory.

Remarks

To retrieve the raw APDU from the byte buffer mapped through an IStream that contains the APDU message, call get_Apdu.

For a list of all the methods provided by the ISCardCmd interface, see ISCardCmd.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

LONG    lLen;
HRESULT hr;

// Retrieve the APDU length.
hr = pISCardCmd->get_ApduLength(&lLen);
if (FAILED(hr))
{
    printf("Failed get_ApduLength\n");
    // Take other error handling action.
}
else
    printf("Length returned is %d\n", lLen);

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

get_Apdu, ISCardCmd


ISCardCmd::get_ApduReply

The get_ApduReply retrieves the reply APDU, placing it in a specific byte buffer. The reply may be NULL if no transaction has been performed on the command APDU.

HRESULT get_ApduReply(
  LPBYTEBUFFER *ppReplyApdu
);

Parameters

ppReplyApdu
[out, retval] Pointer to the byte buffer (mapped through an IStream) that contains the APDU reply message on return.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | ppReplyApdu is invalid.
E_POINTER | A bad pointer was passed in ppReplyApdu.
E_OUTOFMEMORY | Out of memory.

Remarks

To determine the length of the APDU reply, call get_ApduReplyLength.

To set a new reply APDU, call put_ApduReply.

For a list of all the methods provided by the ISCardCmd interface, see ISCardCmd.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

HRESULT      hr;

// lLe was set by a call to ISCardCmd::get_ApduReplyLength.
// pIByteReply is a pointer to an instance of IByteBuffer.
if (lLe > 0)
{
    // Get reply data if available.
    hr = pISCardCmd->get_ApduReply(&pIByteReply);
    if (FAILED(hr))
    {
        printf("Failed ISCardCmd::get_ApduReply.\n");
        // Take other error handling action as needed.
    }
    else
    {
        BYTE byReplyBytes[256];
        LONG lBytesRead;

        hr = pIByteReply->Read(byReplyBytes, lLe, &lBytesRead);
        if (FAILED(hr))
        {
            printf("Failed IByteBuffer::Read.\n");
            // Take other error handling action as needed.
        }
        // Use the bytes in byReplyBytes as needed.
    }
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

get_ApduReplyLength, ISCardCmd, put_ApduReply


ISCardCmd::put_ApduReply

The put_ApduReply method sets a new reply APDU.

HRESULT put_ApduReply(
  LPBYTEBUFFER pReplyApdu
);

Parameters

pReplyApdu
[in] Pointer to the byte buffer (mapped through an IStream) that contains the replay APDU message on return.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | pReplyApdu is invalid.
E_POINTER | A bad pointer was passed in pReplyApdu.
E_OUTOFMEMORY | Out of memory.

Remarks

To get an existing reply APDU, call get_ApduReply.

For a list of all the methods provided by the ISCardCmd interface, see ISCardCmd.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

HRESULT    hr;

// pIByteReply is a pointer to an instance of IByteBuffer.
// Set the reply data.
hr = pISCardCmd->put_ApduReply(pIByteReply);
if (FAILED(hr))
{
    printf("Failed put_ApduReply.\n");
    // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

get_ApduReply, get_ApduReplyLength, ISCardCmd


ISCardCmd::get_ApduReplyLength

The get_ApduReplyLength method determines the length (in bytes) of the reply APDU.

HRESULT get_ApduReplyLength(
  LONG *plSize
);

Parameters

plSize
[out, retval] Pointer to the size of the reply APDU message.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | plSize is invalid.
E_POINTER | A bad pointer was passed in plSize.
E_OUTOFMEMORY | Out of memory.

Remarks

To get an existing reply APDU, call get_ApduReply.

For a list of all the methods provided by the ISCardCmd interface, see ISCardCmd.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

LONG    lLen;
HRESULT hr;

// Retrieve the APDU reply length.
hr = pISCardCmd->get_ApduReplyLength(&lLen);
if (FAILED(hr))
{
    printf("Failed get_ApduReplyLength\n");
    // Take other error handling action.
}
else
    printf("Length returned is %d\n", lLen);

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

get_ApduReply, ISCardCmd, put_ApduReply


ISCardCmd::get_ClassId

The get_ClassId method retrieves the class identifier from the APDU.

HRESULT get_ClassId(
  BYTE *pbyClass
);

Parameters

pbyClass
[out, retval] Pointer to the byte that represents the class identifier.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | pbyClass is invalid.
E_POINTER | A bad pointer was passed in pbyClass.
E_OUTOFMEMORY | Out of memory.

Remarks

To set the class identifier to a new value, call put_ClassId.

For a list of all the methods provided by the ISCardCmd interface, see ISCardCmd.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

BYTE     byClassID;
HRESULT  hr;

// Retrieve the class ID.
hr = pISCardCmd->get_ClassId(&byClassID);
if (FAILED(hr))
{
  printf("Failed get_ClassId\n");
  // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

ISCardCmd, put_ClassId


ISCardCmd::put_ClassId

The put_ClassId method sets a new class identifier in the APDU.

HRESULT put_ClassId(
  BYTE byClass
);

Parameters

byClass
[in, defaultvalue(0)] The byte that represents the class identifier.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | byClass is invalid.
E_OUTOFMEMORY | Out of memory.

Remarks

To retrieve the current class identifier, call get_ClassId.

For a list of all the methods provided by the ISCardCmd interface, see ISCardCmd.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

HRESULT  hr;

// Set the class ID.
hr = pISCardCmd->put_ClassId(0xC0);
if (FAILED(hr))
{
  printf("Failed put_ClassId\n");
  // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

get_ClassId, ISCardCmd


ISCardCmd::get_Data

The get_Data method retrieves the data field from the APDU, placing it in a byte buffer object.

HRESULT get_Data(
  LPBYTEBUFFER *ppData
);

Parameters

ppData
[out, retval] Pointer to the byte buffer object (IStream) that holds the APDU's data field on return.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | ppData is invalid.
E_POINTER | A bad pointer was passed in ppData.
E_OUTOFMEMORY | Out of memory.

Remarks

To set the data field of the APDU, call put_Data.

For a list of all the methods provided by the ISCardCmd interface, see ISCardCmd.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

HRESULT    hr;

// pIByteData is a pointer to an instance of IByteBuffer.
// Retrieve the data.
hr = pISCardCmd->get_Data(&pIByteData);
if (FAILED(hr))
{
    printf("Failed get_Data.\n");
    // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

ISCardCmd, put_Data


ISCardCmd::put_Data

The put_Data method sets the data field in the APDU.

HRESULT put_Data(
  LPBYTEBUFFER pData
);

Parameters

pData
[in] Pointer to the byte buffer object (IStream) to be copied into the APDU's data field.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | pData is invalid.
E_POINTER | A bad pointer was passed in pData.
E_OUTOFMEMORY | Out of memory.

Remarks

When you set a new data portion of the message, the length of the data field is calculated and stored in the P3 parameter of the APDU. To retrieve the length of the data field, call get_P3.

To retrieve the data field from the APDU, call get_Data.

Example Code

HRESULT    hr;

// pIByteData is a pointer to an instance of IByteBuffer.
// Set the data.
hr = pISCardCmd->put_Data(pIByteData);
if (FAILED(hr))
{
    printf("Failed put_Data.\n");
    // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

get_Data, get_P3, ISCardCmd


ISCardCmd::get_InstructionId

The get_InstructionId method retrieves the instruction identifier byte from the APDU.

HRESULT get_InstructionId(
  BYTE *pbyIns
);

Parameters

pbyIns
[out, retval] Pointer to the byte that is the instruction ID from the APDU on return.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | pbyIns is invalid parameter.
E_POINTER | A bad pointer was passed in pbyIns.
E_OUTOFMEMORY | Out of memory.

Remarks

To set the instructional identifier to a new value, call put_InstructionId.

For a list of all the methods provided by the ISCardCmd interface, see ISCardCmd.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

BYTE  byInstructID;
HRESULT hr;

// Retrieve the instruction ID.
hr = pISCardCmd->get_InstructionId(&byInstructID);
if (FAILED(hr))
{
  printf("Failed get_InstructionId\n");
  // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

ISCardCmd, put_InstructionId


ISCardCmd::put_InstructionId

The put_InstructionId sets the given instruction identifier in the APDU.

HRESULT put_InstructionId(
  BYTE byIns
);

Parameters

byIns
[in] The byte that is the instruction identifier.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | byIns is invalid.
E_OUTOFMEMORY | Out of memory.

Remarks

To get the existing instructional identifier, call get_InstructionId.

For a list of all the methods provided by the ISCardCmd interface, see ISCardCmd.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

HRESULT hr;

// Set the instruction ID.
hr = pISCardCmd->put_InstructionId(0xb2);
if (FAILED(hr))
{
  printf("Failed put_InstructionId\n");
  // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

get_InstructionId, ISCardCmd


ISCardCmd::get_LeField

The get_LeField method returns the Le field of the APDU.

HRESULT get_LeField(
    LONG * plSize
);

Parameters

[out,retval] plSize
Pointer to the Le field value on return.

Return Values

The possible return values are the following.

Value | Meaning
S_OK | Operation was completed successfully.
E_INVALIDARG | plSize is invalid.

Example Code

LONG     lLe;
HRESULT  hr;

// Retrieve the Le field value.
hr = pISCardCmd->get_LeField(&lLe);
if (FAILED(hr))
{
    printf("Failed get_LeField\n");
    // Take other error handling action.
}
else
    printf("Le field value returned is %d\n", lLe);

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

ISCardCmd


ISCardCmd::put_Nad

The put_Nad method specifies the node address (Nad) to use with the ISCardCmd interface. This applies to communications using the T=1 protocol communications only. By default, the ISCardCmd object uses a Nad of zero.

HRESULT put_Nad(
  BYTE bNad
);

Parameters

bNad
[in] Byte representing the Nad to use.

Return Values

The possible return values are the following.

Value | Meaning
S_OK | Operation was completed successfully.
E_INVALIDARG | bNad is invalid.

Remarks

This method should be called only when it is necessary to use a value other than zero for the Nad.

Example Code

HRESULT  hr;

// Set the Nad.
// byNadValue is a previously assigned BYTE value.
hr = pISCardCmd->put_Nad(byNadValue);
if (FAILED(hr))
{
  printf("Failed put_Nad\n");
  // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

ISCardCmd


ISCardCmd::get_P1

The get_P1 method retrieves the first parameter (P1) byte from the APDU.

HRESULT get_P1(
  BYTE *pbyP1
);

Parameters

pbyP1
[out, retval] Pointer to the P1 byte in the APDU on return.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | pbyP1 is invalid.
E_POINTER | A bad pointer was passed in pbyP1.
E_OUTOFMEMORY | Out of memory.

Remarks

To set the P1 parameter to a new value, call put_P1.

To get the P2 or P3 parameters, call get_P2 and get_P3 respectively.

For a list of all the methods provided by the ISCardCmd interface, see ISCardCmd.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

BYTE  byP1;
HRESULT  hr;

// Retrieve the P1 byte.
hr = pISCardCmd->get_P1(&byP1);
if (FAILED(hr))
{
  printf("Failed get_P1\n");
  // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

get_P2, get_P3, ISCardCmd, put_P1


ISCardCmd::put_P1

The put_P1 method sets the first parameter (P1) byte of the APDU.

HRESULT put_P1(
  BYTE byP1
);

Parameters

byP1
[in] The byte that is the P1 field.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | byP1 is invalid.
E_OUTOFMEMORY | Out of memory.

Remarks

To set the P2 value of the APDU, call put_P2.

To retrieve the existing P1, P2, and P3 values, call get_P1, get_P2 or get_P3 respectively.

For a list of all the methods provided by the ISCardCmd interface, see ISCardCmd.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

HRESULT  hr;

// Set the P1 byte.
hr = pISCardCmd->put_P1(0x06);
if (FAILED(hr))
{
  printf("Failed put_P1\n");
  // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

get_P1, get_P2, get_P3, ISCardCmd, put_P2


ISCardCmd::get_P2

The get_P2 method retrieves the second parameter (P2) byte from the APDU

HRESULT get_P2(
  BYTE *pbyP2
);

Parameters

pbyP2
[out, retval] Pointer to the byte that is the P2 from the APDU on return.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | pbyP2 is invalid.
E_POINTER | A bad pointer was passed in pbyP2.
E_OUTOFMEMORY | Out of memory.

Remarks

To set the P2 parameter to a new value, call put_P2.

To get the P1 or P3 parameters, call get_P1 and get_P3 respectively.

For a list of all the methods provided by the ISCardCmd interface, see ISCardCmd.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

BYTE  byP2;
HRESULT  hr;

// Retrieve the P2 byte.
hr = pISCardCmd->get_P2(&byP2);
if (FAILED(hr))
{
  printf("Failed get_P2\n");
  // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

get_P1, get_P3, ISCardCmd, put_P2


ISCardCmd::put_P2

The put_P2 method sets the second parameter (P2) byte in the APDU.

HRESULT put_P2(
  BYTE byP2
);

Parameters

byP2
[in] The byte that is the P2 field.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | byP2 is invalid.
E_OUTOFMEMORY | Out of memory.

Remarks

To set the P1 value of the APDU, call put_P1.

To retrieve the existing P1, P2, and P3 values, call get_P1, get_P2 or get_P3 respectively.

For a list of all the methods provided by the ISCardCmd interface, see ISCardCmd.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

HRESULT  hr;

// Set the P2 byte.
hr = pISCardCmd->put_P2(0x06);
if (FAILED(hr))
{
  printf("Failed put_P2\n");
  // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

get_P1, get_P2, get_P3, get_P2, ISCardCmd, put_P1


ISCardCmd::get_P3

The get_P3 method retrieves the third parameter (P3) byte from the APDU. This read-only byte value represents the size of the data portion of the APDU.

HRESULT get_P3(
  BYTE *pbyP3
);

Parameters

pbyP3
[out, retval] Pointer to the byte that is the P3 from the APDU on return.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | pbyP3 is invalid.
E_POINTER | A bad pointer was passed in pbyP3.
E_OUTOFMEMORY | Out of memory.

Remarks

The P3 parameter is read only, and therefore cannot be set.

To get the P1 or P2 parameters, call get_P1 and get_P2 respectively.

For a list of all the methods provided by the ISCardCmd interface, see ISCardCmd.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

BYTE  byP3;
HRESULT  hr;

// Retrieve the P3 byte.
hr = pISCardCmd->get_P3(&byP3);
if (FAILED(hr))
{
  printf("Failed get_P3\n");
  // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

get_P1, get_P2, ISCardCmd


ISCardCmd::get_ReplyNad

The get_ReplyNad method retrieves the node address (Nad) used by the card in the reply message.

HRESULT get_ReplyNad(
  BYTE * pbNad
);

Parameters

pbNad
[out, retval] Pointer to the byte that contains the Nad used by the reply message, on return.

Return Values

The possible return values are the following.

Value | Meaning
S_OK | Operation was completed successfully.
E_INVALIDARG | pbNad is invalid.
E_ACCESSDENIED | Internal calls were unable to retrieve nad information.

Remarks

In addition to the COM error codes listed above, this method may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

BYTE    byNad
HRESULT hr;

// Get reply Nad.
hr = pISCardCmd->get_ReplyNad(&byNad);
if (FAILED(hr))
{
  printf("Failed get_ReplyNad\n");
  // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

ISCardCmd


ISCardCmd::get_ReplyStatus

The get_ReplyStatus method retrieves the reply APDU's message status word.

HRESULT get_ReplyStatus(
  LPWORD pwStatus
);

Parameters

pwStatus
[out, retval] Pointer to the word that is the status on return.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | pwStatus is invalid.
E_POINTER | A bad pointer was passed in pwStatus.
E_OUTOFMEMORY | Out of memory.

Remarks

To set the reply APDU's message status word, call put_ReplyStatus.

For a list of all the methods provided by the ISCardCmd interface, see ISCardCmd.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

WORD    wReplyStatus;
HRESULT hr;

// Get reply status.
hr = pISCardCmd->get_ReplyStatus(&wReplyStatus);
if (FAILED(hr))
{
  printf("Failed get_ReplyStatus\n");
  // Take other error handling action as needed.
}
else
{
  if (wReplyStatus != 0x9000)
  {
    printf("APDU failed - Error [0x%x]\n", wReplyStatus);
    // Take other error handling action as needed.
  }
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

ISCardCmd, put_ReplyStatus


ISCardCmd::put_ReplyStatus

The put_ReplyStatus sets a new reply APDU's message status word.

HRESULT put_ReplyStatus(
  WORD wStatus
);

Parameters

wStatus
[in] The word that is the status.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | wStatus is invalid.
E_OUTOFMEMORY | Out of memory.

Remarks

To get the reply APDU's message status word, call get_ReplyStatus.

For a list of all the methods provided by the ISCardCmd interface, see ISCardCmd.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

WORD     wNewStatus = 0x0000;
HRESULT  hr;

// Set reply status.
hr = pISCardCmd->put_ReplyStatus(wNewStatus);
if (FAILED(hr))
{
  printf("Failed put_ReplyStatus\n");
  // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

get_ReplyStatus, ISCardCmd


ISCardCmd::get_ReplyStatusSW1

The get_ReplyStatusSW1 method retrieves the reply APDU's SW1 status byte.

HRESULT get_ReplyStatusSW1(
  LPBYTE pbySW1
);

Parameters

pbySW1
[out, retval] Pointer to the byte that contains the value of the SW1 byte on return.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | pbySW1 is Invalid.
E_POINTER | A bad pointer was passed in pbySW1.
E_OUTOFMEMORY | Out of memory.

Remarks

The reply APDU's SW1 status byte is read only.

To retrieve the reply APDU's SW2 status byte, call get_ReplyStatusSW2.

For a list of all the methods provided by the ISCardCmd interface, see ISCardCmd.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

BYTE     bySW1;
HRESULT  hr;

// Retrieve the reply status SW1 byte.
hr = pISCardCmd->get_ReplyStatusSW1(&bySW1);
if (FAILED(hr))
{
  printf("Failed get_ReplyStatusSW1\n");
  // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

get_ReplyStatusSW2, get_ReplyStatus, ISCardCmd


ISCardCmd::get_ReplyStatusSW2

The get_ReplyStatusSW2 method retrieves the reply APDU's SW2 status byte.

HRESULT get_ReplyStatusSW2(
  LPBYTE pbySW2
);

Parameters

pbySW2
[out, retval] Pointer to the byte that contains the value of the SW2 byte on return.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | pbySW2 is invalid.
E_POINTER | A bad pointer was passed in pbySW2.
E_OUTOFMEMORY | Out of memory.

Remarks

The reply APDU's SW2 status byte is read only.

To retrieve the reply APDU's SW1 status byte, call get_ReplyStatusSW1.

For a list of all the methods provided by the ISCardCmd interface, see ISCardCmd.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

BYTE     bySW2;
HRESULT  hr;

// Retrieve the reply status SW2 byte.
hr = pISCardCmd->get_ReplyStatusSW2(&bySW2);
if (FAILED(hr))
{
  printf("Failed get_ReplyStatusSW2\n");
  // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

get_ReplyStatusSW1, get_ReplyStatus, ISCardCmd


ISCardCmd::BuildCmd

The BuildCmd method constructs a valid command APDU for transmission to a smart card.

HRESULT BuildCmd(
  BYTE byClassId,
  BYTE byInsId,
  BYTE byP1,
  BYTE byP2,
  LPBYTEBUFFER pbyData,
  LONG *p1Le
);

Parameters

byClassId
[in] Command class identifier.
byInsId
[in] Command instruction identifier.
byP1
[in, defaultvalue(0)] Command's first parameter.
byP2
[in, defaultvalue(0)] Command's second parameter.
pbyData
[in, defaultvalue(NULL)] Pointer to the data portion of the command.
p1Le
[in, defaultvalue(NULL)] Pointer to a LONG integer containing the expected length of the returned data.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | One of the parameters are Invalid.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

To encapsulate the command into another command, call Encapsulate.

For a list of all the methods provided by the ISCardCmd interface, see ISCardCmd.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

LONG       lLe = 0;
HRESULT    hr;

// pISCardCmd is a pointer to an instance of ISCardCmd.
// pIByteRequest is a pointer to an instance of IByteBuffer,
// and IByteBuffer::Initialize has already been called.
hr = pISCardCmd->BuildCmd(0x00,   // Some cards prefer 0xC0
                          0xa4,   // 'Select File'
                          0x00,
                          0x00,
                          pIByteRequest,
                          &lLe);
if (FAILED(hr))
{
    printf("Failed ISCardCmd::BuildCmd\n");
    // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

Encapsulate, ISCardCmd


ISCardCmd::Clear

The Clear method clears the APDU and reply APDU message buffers.

HRESULT Clear(void);

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
S_FALSE | Unknown error.

Remarks

To build a command APDU, call BuildCmd.

For a list of all the methods provided by the ISCardCmd interface, see ISCardCmd.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

HRESULT  hr;

// Clear the APDU and reply APDU message buffers.
hr = pISCardCmd->Clear();
if (FAILED(hr))
{
    printf("Failed ISCardCmd::Clear\n");
    // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

BuildCmd, ISCardCmd


ISCardCmd::Encapsulate

The Encapsulate method encapsulates the given command APDU into another command APDU for transmission to a smart card.

HRESULT Encapsulate(
  LPBYTEBUFFER pApdu,
  ISO_APDU_TYPE ApduType
);

Parameters

pApdu
[in] Pointer to the APDU to be encapsulated.
ApduType
[in] Specifies the ISO 7816-4 case for T=0 transmissions. Possible values are:

ISO_CASE_1
ISO_CASE_2
ISO_CASE_3
ISO_CASE_4

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in pApdu.
E_OUTOFMEMORY | Out of memory.

Remarks

To build a command APDU, call BuildCmd.

For a list of all the methods provided by the ISCardCmd interface, see ISCardCmd.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

HRESULT    hr;

// pIByteApdu is a pointer to an instance of IByteBuffer.
// Encapsulate the APDU.
hr = pISCardCmd->Encapsulate(pIByteApdu, ISO_CASE_1);
if (FAILED(hr))
{
    printf("Failed Encapsulate.\n");
    // Take other error handling action as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

BuildCmd, ISCardCmd


ISCardDatabase

The ISCardDatabase interface provides the methods for performing the smart card resource manager's database operations. These operations include listing known smart cards, readers, and reader groups, plus retrieving the interfaces supported by a smart card and its primary service provider.

Note The identifier of the primary service provider is a COM GUID that can be used to instantiate and use the COM objects for a specific card.

The following example shows a typical use of the ISCardDatabase interface. In this case, the ISCardDatabase interface is used to list all the known smart cards.

To submit a transaction to a specific card

  1. Create an ISCardDatabase interface.
  2. Call ListCards to retrieve all the known smart cards based on an ATR string or their supported interfaces.
  3. Release the ISCardDatabase interface.

Methods

ISCardDatabase Methods | Description
GetProviderCardId | Retrieves the identifier of the primary service provider for a specific smart card.
ListCardInterfaces | Retrieves the interface identifiers (GUIDs) of all the interfaces supported by a specific smart card.
ListCards | Retrieves all the smart card names that match a specific set of interface identifiers (GUIDs) or an ATR string.
ListReaderGroups | Retrieves the names of the reader groups that the resource manager has knowledge of.
ListReaders | Retrieve the names of the readers that the resource manager has knowledge of.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardmgr.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardmgr.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).


ISCardDatabase::GetProviderCardId

The GetProviderCardId method retrieves the identifier (GUID) of the primary service provider for the specified smart card.

HRESULT GetProviderCardId(
  BSTR bstrCardName,
  LPGUID *ppguidProviderId
);

Parameters

bstrCardName
[in] Name of the smart card.
ppguidProviderId
[out, retval] Pointer to the primary service provider's identifier (GUID) if successful; NULL if operation failed.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDPARAMETER | Invalid parameter.
E_POINTER | A bad pointer was passed in ppguidProviderId.
E_OUTOFMEMORY | Out of memory.

Remarks

To list the interfaces of the smart card, call ListCardInterfaces.

To retrieve all known smart cards, readers and reader groups call ListCard, ListReaders, and ListReaderGroups respectively.

For a list of all the methods provided by the ISCardDatabase interface, see ISCardDatabase.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

BSTR     bstrCard = NULL;
LPGUID   pguidProvId = NULL;
HRESULT  hr;

bstrCard = SysAllocString(L"My Card");
hr = pISCDataBase->GetProviderCardId(bstrCard,&pguidProvId);
if (FAILED(hr))
{
   printf("Failed GetProviderCardId\n");
}
else
{
    // Use pguidProvId as needed.
}

// Free BSTR when done.
if ( NULL != bstrCard )
{
    SysFreeString(bstrCard);
    bstrCard=NULL;
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardmgr.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardmgr.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

ISCardDatabase, ListCardInterfaces, ListCards, ListReaderGroups, ListReaders


ISCardDatabase::ListCardInterfaces

The ListCardInterfaces method retrieves the identifiers (GUIDs) of all the interfaces supported for the specified smart card.

HRESULT ListCardInterfaces(
  BSTR bstrCardName,
  LPSAFEARRAY *ppInterfaceGuids
);

Parameters

bstrCardName
[in] Name of the smart card.
ppInterfaceGuids
[out, retval] Pointer to the interface GUIDs if successful; NULL if operation failed.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDPARAMETER | Invalid parameter.
E_POINTER | A bad pointer was passed in ppInterfaceGuids.
E_OUTOFMEMORY | Out of memory.

Remarks

To retrieve the primary service provider of the smart card, call GetProviderCardId.

To retrieve all known smart cards, readers, and reader groups call ListCard, ListReaders, and ListReaderGroups respectively.

For a list of all the methods provided by the ISCardDatabase interface, see ISCardDatabase.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

BSTR         bstrCard = NULL;
LPSAFEARRAY  pGuids = NULL;
HRESULT      hr;

bstrCard = SysAllocString(L"GemSAFE");
// Call the function for the specified card.
hr = pISCDataBase->ListCardInterfaces(bstrCard,
                                      &pGuids);
if (FAILED(hr))
{
   printf("Failed ListCardInterfaces\n");
   // Take other error handling action as needed.
}
else
{
   // Use the safe array as needed.
   // ...
   // Free BSTR when done.
   if (bstrCard)
       SysFreeString(bstrCard);
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardmgr.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardmgr.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

GetProviderCardId, ISCardDatabase, ListCards, ListReaderGroups, ListReaders


ISCardDatabase::ListCards

The ListCards method retrieves all of the smart card names that match the specified interface identifiers (GUIDs), the specified ATR string, or both.

HRESULT ListCards(
  LPBYTEBUFFER pAtr,
  LPSAFEARRAY pInterfaceGuids,
  LONG localeId,
  LPSAFEARRAY *ppCardNames
);

Parameters

pAtr
[in, defaultvalue(NULL) ] Pointer to a smart card ATR string. The ATR string must be packaged into an IByteBuffer.
pInterfaceGuids
[in, defaultvalue(NULL)] Pointer to a SAFEARRAY of COM interface identifiers (GUIDs) in BSTR format.
localeId
[in, lcid, defaultvalue(0x0409)] Language localization identifier.
ppCardNames
[out, retval] Pointer to a SAFEARRAY of BSTRs that contains the names of the smart cards that satisfied the search parameters if successful; NULL if the operation failed.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDPARAMETER | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

To retrieve all known readers or reader groups, call ListReaders or ListReaderGroups respectively.

To retrieve the primary service provider or the interfaces of a specific card GetProviderCardId or ListCardInterfaces respectively.

For a list of all the methods provided by the ISCardDatabase interface, see ISCardDatabase.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

// Define or determine byAtr as needed for your ATR use.
BYTE byAtr[] = {0x3b,0x27,0x00,0x80,0x65,0xa2,0x0c,0x01,0x01,0x37};
LPSAFEARRAY pSafeArray = NULL;
HRESULT          hr;

// pIByteBuff is a pointer to an instance of IByteBuffer.
hr = pIByteBuff->Initialize(sizeof(byAtr), byAtr);

// Call the function for the specified ATR.
hr = pISCDataBase->ListCards(pIByteBuff,
                             NULL,
                             0,
                             &pSafeArray);
if (FAILED(hr))
{
   printf("Failed ListCards\n");
   // Take other error handling action as needed.
}
else
{
   // Use the safe array as needed.
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardmgr.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardmgr.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

GetProviderCardId, ISCardDatabase, ListCardInterfaces, ListReaderGroups, ListReaders


ISCardDatabase::ListReaderGroups

The ListReaderGroups method retrieves the names of the reader groups registered in the smart card database.

HRESULT ListReaderGroups(
  LONG localeId,
  LPSAFEARRAY *ppReaderGroups
);

Parameters

localeId
[in, lcid, defaultvalue(0x0409)] Language localization ID.
ppReaderGroups
[out, retval] Pointer to a SAFEARRAY of BSTRs that contains the names of the smart card reader groups that satisfied the search parameters if successful; NULL if the operation failed.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDPARAMETER | Invalid parameter.
E_POINTER | A bad pointer was passed in ppReaderGroups.
E_OUTOFMEMORY | Out of memory.

Remarks

To retrieve all known smart cards or readers, call ListCards or ListReaders respectively.

To retrieve the primary service provider or the interfaces of a specific card GetProviderCardId or ListCardInterfaces respectively.

For a list of all the methods provided by the ISCardDatabase interface, see ISCardDatabase.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

LPSAFEARRAY pGroups = NULL;
HRESULT     hr;

// Determine the reader groups.
hr = pISCDataBase->ListReaderGroups(0x0409,  // English (US)
                                    &pGroups);
if (FAILED(hr))
{
   printf("Failed ListReaderGroups\n");
   // Take other error handling action as needed.
}
else
{
   // Use the safe array as needed.
   // ...
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardmgr.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardmgr.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

GetProviderCardId, ISCardDatabase, ListCardInterfaces, ListCards, ListReaders


ISCardDatabase::ListReaders

The ListReaders method retrieves the names of the smart card readers registered in the smart card database.

HRESULT ListReaders(
  LONG localeId,
  LPSAFEARRAY *ppReaders
);

Parameters

localeId
[in, lcid, defaultvalue(0x0409)] Language localization ID.
ppReaders
[out, retval] Pointer to a SAFEARRAY of BSTRs that contains the names of the smart card readers if successful; NULL if the operation failed.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDPARAMETER | Invalid parameter.
E_POINTER | A bad pointer was passed in ppReaders.
E_OUTOFMEMORY | Out of memory.

Remarks

To retrieve all known smart cards or reader groups, call ListCards or ListReaderGroups respectively.

To retrieve the primary service provider or the interfaces of a specific card GetProviderCardId or ListCardInterfaces respectively.

For a list of all the methods provided by the ISCardDatabase interface, see ISCardDatabase.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Example Code

LPSAFEARRAY pReaders = NULL;
HRESULT     hr;

// Determine the reader groups.
hr = pISCDataBase->ListReaders(0x0409,  // English (US)
                               &pReaders);
if (FAILED(hr))
{
   printf("Failed ListReaders\n");
   // Take other error handling action as needed.
}
else
{
   // Use the safe array as needed.
   // ...
}

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardmgr.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardmgr.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

GetProviderCardId, ISCardDatabase, ListCardInterfaces, ListCards, ListReaderGroups


ISCardFileAccess

The following interface definition is provided as a standard that can be followed when developing a smart card service provider.

The ISCardFileAccess interface can be used to implement a high-level interface to a card-based file system with an underlying card file system based on the structure defined in ISO/IEC 7816-4. Other implementations are possible, but this is expected to be the most common.

The ISCardFileAccess interface can be used to expose file system entities in a manner very familiar to application developers in the PC environment. It provides mechanisms for locating specific files and performing common operations such as selecting, reading, writing, creating and deleting. It encapsulates and masks much of the low-level detail involved in performing these operations at the card level.

Following is a typical use of the ISCardFileAccess interface. In this case, the ISCardFileAccess interface is used to select, open and write to a file.

To write to a file

  1. Call ISCardManage::CreateFileAccess to create an ISCardFileAccess interface.
  2. Call Open to select and open the file.
  4. Call Write.
  5. Call Close.
  6. Release the ISCardFileAccess interface.

Methods

ISCardFileAccess Methods | Description
ChangeDir | Changes the current smart card directory to the new specified directory.
Close | Closes the specified file.
Create | Creates a file at a given location within the ICC file system.
Delete | Deletes a specified file.
Directory | Retrieves a list of files.
GetCurrentDir | Returns an absolute path to the currently selected directory.
GetFileCapabilities | Retrieves file capabilities.
GetProperties | Retrieves the primitive data referred by tags for the specified object.
Invalidate | Invalidates the specified file.
Open | Opens the specified file for further use.
Read | Reads and returns the specified data from a given file.
Rehabilitate | Makes a file (EF or DF), which has been previously invalidated with the Invalidate command, accessible by the application.
Seek | Selects the object from which read/write access will be done.
SetProperties | Sets the primitive data referred by tags for the specified object.
Write | Writes data to a current opened file.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.


ISCardFileAccess::ChangeDir

The ChangeDir method changes the current smart card directory to the new specified directory.

HRESULT ChangeDir(
  REFTYPE refType,
  BSTR bstrNewDir
);

Parameters

refType [in]
Specifies the type of reference used in bstrNewDir as follows:

SC_TYPE_BY_NAME
SC_TYPE_BY_ID
SC_TYPE_BY_SHORT
SC_TYPE_BY_ANY

bstrNewDir [in]
Specifies a file/directory name (by refType) to select.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_OUTOFMEMORY | Out of memory.

Remarks

To get an absolute path to the currently selected directory, call GetCurrentDir.

For a list of all the methods defined by the ISCardFileAccess interface, see ISCardFileAccess.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

GetCurrentDir, ISCardFileAccess


ISCardFileAccess::Close

The Close method closes the specified file. No further access to file is allowed.

HRESULT Close(
  HSCARD_FILE hFile
);

Parameters

hFile [in]
Handle to the file to be closed.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_OUTOFMEMORY | Out of memory.

Remarks

To open a file, call Open.

For a list of all the methods defined by the ISCardFileAccess interface, see ISCardFileAccess.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardFileAccess, Open


ISCardFileAccess::Create

The Create method creates a file at a given location within the smart card file system.

HRESULT Create(
  REFTYPE refType,
  BSTR bstrPathSpec,
  TLV_TABLE TLV,
  SCARD_FLAGS flags,
  LPBYTEBUFFER pDataBuffer
);

Parameters

refType [in]
Specifies the type of reference used in bstrPathSpec as follows:

SC_TYPE_BY_NAME
SC_TYPE_BY_ID
SC_TYPE_BY_SHORT
SC_TYPE_BY_ANY

bstrPathSpec [in]
Specifies file ID to be created within current context.
TLV [in]
List of TLV (tag,length,value) structures which values have to be set.
flags [in]
Specifies whether secure messaging has to be used and data preallocated.

SC_FL_SECURE_MESSAGING
SC_FL_PREALLOCATED

pDataBuffer [in, defaultvalue(NULL)]
Pointer to preallocated data.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

For a list of all the methods defined by the ISCardFileAccess interface, see ISCardFileAccess.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardFileAccess


ISCardFileAccess::Delete

The Delete method deletes a file at a given location within the smart card file system.

HRESULT Delete(
  REFTYPE refType,
  BSTR bstrPathSpec,
  SCARD_FLAGS flags
);

Parameters

refType [in]
Specifies the type of reference used in bstrPathSpec as follows:

SC_TYPE_BY_NAME
SC_TYPE_BY_ID
SC_TYPE_BY_SHORT
SC_TYPE_BY_ANY

bstrPathSpec [in]
Specifies ID of the file to be deleted.
flags [in]
Specifies whether secure messaging has to be used and data preallocated:

SC_FL_SECURE_MESSAGING
SC_FL_PREALLOCATED

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation was completed successfully.
E_INVALIDARG | Invalid parameter.
E_NOTIMPL | The interface has not implemented this method.

Remarks

For a list of all the methods defined by the ISCardFileAccess interface, see ISCardFileAccess.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

Create, ISCardFileAccess


ISCardFileAccess::Directory

The Directory method retrieves a list of files of the specified type from the current directory.

HRESULT Directory(
  FILETYPE fileType,
  LPSAFEARRAY *ppFileList
);

Parameters

fileType [in]
Specifies the type of smart card files to list. This can be one of the following values.
Value | Description
SC_TYPE_DIRECTORIES | List directory files only.
SC_TYPE_FILES | List elementary files only.
SC_TYPE_ALL_FILES | List both directory and elementary files.
SC_TYPE_DIRECTORY_FILE | Directory file.
SC_TYPE_TRANSPARENT_EF | Transparent elementary file.
SC_TYPE_FIXED_EF | Linear fixed elementary file.
SC_TYPE_CYCLIC_EF | Cyclic elementary file.
SC_TYPE_VARIABLE_EF | Linear variable elementary file.

ppFileList [out, retval]
Array of BSTRs representing the list of files matching the specifier in fileType.

Return Values

The possible return values are the following.

Value | Meaning
S_OK | Operation was completed successfully.
E_INVALIDARG | Invalid parameter.
E_NOTIMPL | The interface has not implemented this method.
E_OUTOFMEMORY | Out of memory.
E_POINTER | A bad pointer was passed in for ppFileList.

Remarks

For a list of all the methods defined by the ISCardFileAccess interface, see ISCardFileAccess.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardFileAccess


ISCardFileAccess::GetCurrentDir

The GetCurrentDir method returns an absolute path to the currently selected directory.

HRESULT GetCurrentDir(
  BSTR *pbstrPathSpec
);

Parameters

pbstrPathSpec [out, retval]
Pointer to a BSTR that will contain the path.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

To change the current directory, call ChangeDir.

For a list of all the methods defined by the ISCardFileAccess interface, see ISCardFileAccess.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ChangeDir, ISCardFileAccess


ISCardFileAccess::GetFileCapabilities

The GetFileCapabilities method retrieves a list of file capabilities from the current file.

HRESULT GetFileCapabilities(
  LPTLV_TABLE * ppProperties,
  LONG * plProperties,
  SCARD_FLAGS Flags
);

Parameters

ppProperties
[in, out] Pointer to TLV (tag,length,value) structures. On input, indicates the files for which to get properties; on output, contains the properties. The following is a definition of the TLV structure.
typedef struct
{
  DWORD  Tag;
  DWORD  Length;
  BYTE[]  Value;
  BOOL  Valid;
} TLV;

For more details on TLV structures, consult the documentation at http://www.pcscworkgroup.com/.

plProperties
[in, out] Pointer to the number of TLV entries in ppProperties.
Flags
[in] Specifies whether secure messaging has to be used and data preallocated.

SC_FL_SECURE_MESSAGING
SC_FL_PREALLOCATED

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation was completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

For a list of all the methods defined by the ISCardFileAccess interface, see ISCardFileAccess.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardFileAccess


ISCardFileAccess::GetProperties

The GetProperties method retrieves the primitive data referred by TLVs (tag, length, value) for the specified object.

HRESULT GetProperties(
  REFTYPE refType,
  BSTR bstrPathSpec,
  SCARD_FLAGS flags,
  LPTLV_TABLE *ppTLV
);

Parameters

refType [in]
Specifies the type of reference used in bstrNewDir as follows:

SC_TYPE_BY_NAME
SC_TYPE_BY_ID
SC_TYPE_BY_SHORT
SC_TYPE_BY_ANY

bstrPathSpec [in]
Specifies file.
flags [in]
Specifies whether secure messaging should be used.

SC_FL_SECURE_MESSAGING

ppTLV [in, out]
Pointer to TLV structures whose value has been retrieved.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

For a list of all the methods defined by the ISCardFileAccess interface, see ISCardFileAccess.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardFileAccess


ISCardFileAccess::Invalidate

The Invalidate method invalidates the specified file (EF or DF). An invalidated file cannot be accessed by other methods prior to using Rehabilitate.

HRESULT Invalidate(
  BSTR bstrPathSpec,
  SCARD_FLAGS flags
);

Parameters

bstrPathSpec [in]
Specifies file.
flags [in]
Specifies whether secure messaging should be used.

SC_FL_SECURE_MESSAGING

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

For a list of all the methods defined by the ISCardFileAccess interface, see ISCardFileAccess.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardFileAccess, Rehabilitate


ISCardFileAccess::Open

The Open method opens the specified file for further use.

HRESULT Open(
  REFTYPE refType,
  BSTR bstrPathSpec,
  HSCARD_FILE *phFile
);

Parameters

refType [in]
Specifies the type of reference used in bstrPathSpec as follows:

SC_TYPE_BY_NAME
SC_TYPE_BY_ID
SC_TYPE_BY_SHORT
SC_TYPE_BY_ANY

bstrPathSpec [in]
Specifies file to open.
phFile [out, retval]
Pointer to an HSCARD_FILE that will hold the file handle.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

To close a file, call Close.

For a list of all the methods defined by the ISCardFileAccess interface, see ISCardFileAccess.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

Close, ISCardFileAccess


ISCardFileAccess::Read

The Read method reads and returns the specified data from a given file.

HRESULT Read(
  HSCARD_FILE hFile,
  LONG *lBytesToRead,
  SCARD_FLAGS flags,
  LPBYTEBUFFER *ppBuffer
);

Parameters

hFile [in]
Handle of the open file to access.
lBytesToRead [in]
Length of data to be read (in) or number of bytes read (out). Returns list of files as an array of BSTRs.
flags [in]
Specifies whether secure messaging should be used.

SC_FL_SECURE_MESSAGING

ppBuffer [out, retval]
IByteBuffer containing the read data.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

For a list of all the methods defined by the ISCardFileAccess interface, see ISCardFileAccess.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardFileAccess


ISCardFileAccess::Rehabilitate

The Rehabilitate method makes a file (EF or DF), which was previously invalidated with the Invalidate method, accessible by the application.

HRESULT Rehabilitate(
  BSTR bstrPathSpec,
  SCARD_FLAGS flags
);

Parameters

bstrPathSpec [in]
Specifies the file to rehabilitate.
flags [in]
Specifies whether secure messaging should be used.

SC_FL_SECURE_MESSAGING

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_OUTOFMEMORY | Out of memory.

Remarks

For a list of all the methods defined by the ISCardFileAccess interface, see ISCardFileAccess.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

Invalidate, ISCardFileAccess


ISCardFileAccess::Seek

The Seek method selects the object from which (read/write) access will be done.

HRESULT Seek(
  HSCARD_FILE hFile,
  SEEKTYPE Seek,
  LONG lOffset
);

Parameters

hFile [in]
Handle to an open file.
Seek [in]
Specifies where the seek should begin:

SC_SEEK_FROM_BEGINNING
SC_SEEK_FROM_END
SC_SEEK_RELATIVE

lOffset [in]
The number of data objects from the reference object.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_OUTOFMEMORY | Out of memory.

Remarks

To read to or write from a file, call Read or Write respectively.

For a list of all the methods defined by the ISCardFileAccess interface, see ISCardFileAccess.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardFileAccess, Read, Write


ISCardFileAccess::SetProperties

The SetProperties method sets the primitive referred by TLVs (tag, length, value) for the specified object.

HRESULT SetProperties(
  REFTYPE refType,
  BSTR bstrPathSpec,
  SCARD_FLAGS flags,
  LPTLV_TABLE pTable
);

Parameters

refType [in]
Specifies the type of reference used in bstrPathSpec as follows:

SC_TYPE_BY_NAME
SC_TYPE_BY_ID
SC_TYPE_BY_SHORT
SC_TYPE_BY_ANY

bstrPathSpec [in]
Specifies file.
flags [in]
Specifies whether secure messaging should be used.

SC_FL_SECURE_MESSAGING

pTable [in]
Pointer to TLV structures whose value should be set.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

For a list of all the methods defined by the ISCardFileAccess interface, see ISCardFileAccess.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardFileAccess


ISCardFileAccess::Write

The Write method writes data to a current opened file.

HRESULT Write(
  HSCARD_FILE hFile,
  LPBYTEBUFFER pData,
  SCARD_FLAGS flags
);

Parameters

hFile [in]
Handle to an open file.
pData [in]
Contains the object/data to be written.
flags [in]
Specifies whether secure messaging should be used.

SC_FL_SECURE_MESSAGING

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

To open a file, call Open.

To close the file, call Close.

For a list of all the methods defined by the ISCardFileAccess interface, see ISCardFileAccess.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

Close, ISCardFileAccess, Open


ISCardISO7816

The ISCardISO7816 interface provides methods for implementing ISO 7816-4 functionality. With the exception of ISCardISO7816::SetDefaultClassId, these methods create an APDU command that is encapsulated in a ISCardCmd object.

The ISO 7816-4 specification defines standard commands available on smart cards. The specification also defines how a smart card Application Protocol Data Unit (APDU) command should be constructed and sent to the smart card for execution. This interface automates the building process.

The following example shows a typical use of the ISCardISO7816 interface. In this case, the ISCardISO7816 interface is used to build an APDU command.

To submit a transaction to a specific card

  1. Create an ISCardISO7816 and ISCardCmd interface. The ISCardCmd interface is used to encapsulate the APDU.
  2. Call the appropriate method of the ISCardISO7816 interface, passing the required parameters and the ISCardCmd interface pointer.

    The ISO 7816-4 APDU command will be built and encapsulated in the ISCardCmd interface.

  3. Release the ISCardISO7816 and ISCardCmd interfaces.

Note In the method reference pages, if a bit sequence in a table is not defined, assume that bit sequence is reserved for future use or proprietary to a specific vendor.

Methods

ISCardISO7816 Methods | Description
AppendRecord | Constructs a command that appends a record to the end of an elementary file (EF).
EraseBinary | Sets part of the content of an elementary to its logical erased state, sequentially, starting from a given offset.
ExternalAuthenticate | Conditionally updates the security status using the result of the computation by the card, based on a challenge previously issued by the card (for example, by the INS_GET_CHALLENGE command), a possibly secret key stored in the card, and authentication data transmitted by the interface device.
GetChallenge | Requires the issuing of a challenge for use in a security-related procedure.
GetData | Retrieves a single primitive data object or a set of data objects contained in a constructed data object, based on the type of file specified.
GetResponse | Transmits from the card to the interface device APDU(s) that otherwise could not be transmitted by the available protocols.
InternalAuthenticate | Initiates the computation of the authentication data by the card using the challenge data sent from the interface device and a relevant secret stored in the card.
ManageChannel | Opens and closes logical channels.
PutData | Stores one primitive data object, or one or more data objects contained in a constructed data object, within the current resource manager context.
ReadBinary | Constructs a command that acquires a response message that gives that part of the contents of an EF with transparent structure.
ReadRecord | Constructs a command that reads the contents of the specified records of an elementary file.
SelectFile | Sets a current file within a logical channel.
SetDefaultClassId | Assigns a standard class ID byte that will be used in all operations when constructing an ISO 7816-4 command APDU.
UpdateBinary | Initiates the update of the bits already present in an EF with the bits given in the command APDU.
UpdateRecord | Constructs a command that initiates the updating of a specific record.
Verify | Initiates the comparison in the card of the verification data sent from the interface device with the reference data stored in the card.
WriteBinary | Initiates the writing of binary values into an EF.
WriteRecord | Constructs a command that writes a record.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardsrv.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardsrv.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).


ISCardISO7816::AppendRecord

The AppendRecord method constructs an APDU command that either appends a record to the end of a linear-structured elementary file (EF) or writes record number 1 in an cyclic-structured elementary file.

HRESULT AppendRecord(
  BYTE byRefCtrl,
  LPBYTEBUFFER pData,
  LPSCARDCMD *ppCmd
);

Parameters

byRefCtrl [in, defaultvalue(NULL_BYTE)]
Identifies the elementary file to be appended:
Meaning | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1
Current EF | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
Short EF ID | x | x | x | x | x | 0 | 0 | 0
Reserved | x | x | x | x | x | x | x | x

pData [in]
Pointer to the data to be appended to the file:

Tn (1 byte)
Ln (1 or 3 bytes)
data (Ln bytes)

ppCmd [in, out]
On input, a pointer to an ISCardCmd interface object or NULL.

On return, it is filled with the APDU command constructed by this operation. If ppCmd was set to NULL, a smart card ISCardCmd object is internally created and returned via the ppCmd pointer.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

The encapsulated command can only be performed if the security status of the smart card satisfies the security attributes of the elementary file read.

If another elementary file is selected at the time of issuing this command, it may be processed without identification of the currently selected file.

Elementary files without a record structure cannot be read. The encapsulated command aborts if applied to an elementary file without a record structure.

For a list of all the methods provided by the ISCardISO7816 interface, see ISCardISO7816.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardsrv.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardsrv.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

ISCardISO7816, ReadRecord, UpdateRecord, WriteRecord


ISCardISO7816::EraseBinary

The EraseBinary method constructs an APDU command that sequentially sets part of the content of an elementary file to its logical erased state, starting from a given offset.

HRESULT EraseBinary(
  BYTE byP1,
  BYTE byP2,
  LPBYTEBUFFER pData,
  LPSCARDCMD *ppCmd
);

Parameters

byP1, byP2 [in]
RFU position.
If… | Then…
b8=1 in P1 | b7 and b6 of P1 are set to 0 (RFU bits), b5 to b1 of P1 are a short EF identifier and P2 is the offset of the first byte to be erased (in data units) from the beginning of the file.
b8=0 in P1 | then P1 || P2 is the offset of the first byte to be erased (in data units) from the beginning of the file.

If the data field is present, it codes the offset of the first data unit not to be erased. This offset shall be higher than the one coded in P1-P2. When the data field is empty, the command erases up to the end of the file.

pData [in, defaultvalue(NULL)]
Pointer to the data that specifies the erase range; may be NULL.
ppCmd [in, out]
On input, a pointer to an ISCardCmd interface object or NULL.

On return, it is filled with the APDU command constructed by this operation. If ppCmd was set to NULL, a smart card ISCardCmd object is internally created and returned via the ppCmd pointer.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

The encapsulated command can only be performed if the security status of the smart card satisfies the security attributes of the elementary file being processed.

When the command contains a valid short elementary identifier, it sets the file as current elementary file.

Elementary files without a transparent structure cannot be erased. The encapsulated command aborts if applied to an elementary file without a transparent structure.

For a list of all the methods provided by the ISCardISO7816 interface, see ISCardISO7816.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardsrv.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardsrv.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

ISCardISO7816, ReadBinary, UpdateBinary, WriteBinary


ISCardISO7816::ExternalAuthenticate

The ExternalAuthenticate method constructs an APDU command that conditionally updates security status, verifying the identity of the computer when the smart card does not trust it.

The command uses the result (yes or no) of the computation by the card (based on a challenge previously issued by the card — for example, by the INS_GET_CHALLENGE command), a key (possibly secret) stored in the card, and authentication data transmitted by the interface device.

HRESULT ExternalAuthenticate(
  BYTE byAlgorithmRef,
  BYTE bySecretRef,
  LPBYTEBUFFER pChallenge,
  LPSCARDCMD *ppCmd
);

Parameters

byAlgorithmRef [in, defaultvalue(NULL_BYTE)]
Reference of the algorithm in the card.

If this value is zero, this indicates that no information is given. The reference of the algorithm is known either before issuing the command or is provided in the data field.

bySecretRef [in, defaultvalue(NULL_BYTE)]
Reference of the secret:
Meaning | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1
No Info | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
Global ref 0 - - - - - - -
Specific ref 1 - - - - - - -
RFU - x x - - - - -
Secret - - - x x x x x

No Info = No information is given. The reference of the secret is known either before issuing the command or is provided in the data field.

Global ref = Global reference data (an MF specific key).

Specific ref = Specific reference data (a DF specific key).

RFU = 00 (other values are RFU).

Secret = Number of the secret.

pChallenge [in, defaultvalue(NULL)]
Pointer to the authentication-related data; may be NULL.
ppCmd [in, out]
On input, a pointer to an ISCardCmd interface object or NULL.

On return, it is filled with the APDU command constructed by this operation. If ppCmd was set to NULL, a smart card ISCardCmd object is internally created and returned via the ppCmd pointer.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

For the encapsulated command to be successful, the last challenge obtained from the card must be valid.

Unsuccessful comparisons may be recorded in the card (for example, to limit the number of further attempts of the use of the reference data).

For a list of all the methods provided by the ISCardISO7816 interface, see ISCardISO7816.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardsrv.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardsrv.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

InternalAuthenticate, ISCardISO7816


ISCardISO7816::GetChallenge

The GetChallenge method constructs an APDU command that issue a challenge (for example, a random number) for use in a security-related procedure.

HRESULT GetChallenge(
  LONG lBytesExpected,
  LPSCARDCMD *ppCmd
);

Parameters

lBytesExpected [in, defaultvalue(0)]
Maximum length of the expected response.
ppCmd [in, out]
On input, a pointer to an ISCardCmd interface object or NULL.

On return, it is filled with the APDU command constructed by this operation. If ppCmd was set to NULL, a smart card ISCardCmd object is internally created and returned via the ppCmd pointer.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

The challenge is valid at least for the next command.

For a list of all the methods provided by the ISCardISO7816 interface, see ISCardISO7816.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardsrv.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardsrv.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

ExternalAuthenticate, InternalAuthenticate, ISCardISO7816


ISCardISO7816::GetData

The GetData method constructs an APDU command that retrieves either a single primitive data object or a set of data objects (contained in a constructed data object), depending on the type of file selected.

HRESULT GetData(
  BYTE byP1,
  BYTE byP2,
  LONG lBytesToGet,
  LPSCARDCMD *ppCmd
);

Parameters

byP1, byP2 [in]
Parameters:
Value | Meaning
0000 - 003F | RFU
0040 - 00FF | BER-TLV tag (1 byte) in P2
0100 - 01FF | Application data (proprietary coding)
0200 - 02FF | SIMPLE-TLV tag in P2
0300 - 03FF | RFU
0400 - 04FF | BER-TLV tag (2 bytes) in P1-P2

lBytesToGet [in, defaultvalue(0)]
Number of bytes expected in the response.
ppCmd [in, out]
On input, a pointer to an ISCardCmd interface object or NULL.

On return, it is filled with the APDU command constructed by this operation. If ppCmd was set to NULL, a smart card ISCardCmd object is internally created and returned via the ppCmd pointer.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

The encapsulated command can only be performed if the security status of the smart card satisfies the security attributes of the elementary file being read. Security conditions are dependent on the policy of the card, and may be manipulated through ExternalAuthenticate, InternalAuthenticate, ISCardAuth, etc.

To select a file, call SelectFile.

For a list of all the methods provided by the ISCardISO7816 interface, see ISCardISO7816.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardsrv.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardsrv.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

ExternalAuthenticate, InternalAuthenticate, ISCardAuth, ISCardISO7816, PutData, SelectFile


ISCardISO7816::GetResponse

The GetResponse method constructs an APDU command that transmits APDU commands (or part of an APDU command) which otherwise could not be transmitted by the available protocols.

HRESULT GetResponse(
  BYTE byP1,
  BYTE byP2,
  LONG lDataLength,
  LPSCARDCMD *ppCmd
);

Parameters

byP1, byP2 [in, defaultvalue(0)]
Per the ISO 7816-4, P1 and P2 should be 0 (RFU).
lDataLength [in, defaultvalue(0)]
Length of data transmitted.
ppCmd [in, out]
On input, a pointer to an ISCardCmd interface object or NULL.

On return, it is filled with the APDU command constructed by this operation. If ppCmd was set to NULL, a smart card ISCardCmd object is internally created and returned via the ppCmd pointer.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

For a list of all the methods provided by the ISCardISO7816 interface, see ISCardISO7816.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardsrv.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardsrv.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

ISCardISO7816


ISCardISO7816::InternalAuthenticate

The InternalAuthenticate method constructs an APDU command that initiates the computation of the authentication data by the card using the challenge data sent from the interface device and a relevant secret (for example, a key) stored in the card.

When the relevant secret is attached to the MF, the command may be used to authenticate the card as a whole.

When the relevant secret is attached to another DF, the command may be used to authenticate that DF.

HRESULT InternalAuthenticate(
  BYTE byAlgorithmRef,
  BYTE bySecretRef,
  LPBYTEBUFFER pChallenge,
  LONG lReplyBytes,
  LPSCARDCMD *ppCmd
);

Parameters

byAlgorithmRef [in, defaultvalue(NULL_BYTE)]
Reference of the algorithm in the card.

If this value is zero, this indicates that no information is given. The reference of the algorithm is known either before issuing the command or is provided in the data field.

bySecretRef [in, defaultvalue(NULL_BYTE)]
Reference of the secret:
Meaning | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1
No Info | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
Global ref 0 - - - - - - -
Specific ref 1 - - - - - - -
RFU - x x - - - - -
Secret - - - x x x x x

No Info = No information is given.

Global ref = Global reference data (an MF specific key).

Specific ref = Specific reference data (a DF specific key).

RFU = 00 (other values are RFU).

Secret = Number of the secret.

pChallenge [in]
Pointer to the authentication-related data (for example, challenge).
lReplyBytes [in, defaultvalue(0)]
Maximum number of bytes expected in response.
ppCmd [in, out]
On input, a pointer to an ISCardCmd interface object or NULL.

On return, it is filled with the APDU command constructed by this operation. If ppCmd was set to NULL, a smart card ISCardCmd object is internally created and returned via the ppCmd pointer.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

The successful execution of the command may be subject to successful completion of prior commands (for example, VERIFY or SELECT FILE) or selections (for example, the relevant secret).

If a key and an algorithm are currently selected when issuing the command, then the command may implicitly use the key and the algorithm.

The number of times the command is issued may be recorded in the card to limit the number of further attempts of using the relevant secret or the algorithm.

For a list of all the methods provided by the ISCardISO7816 interface, see ISCardISO7816.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardsrv.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardsrv.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

ExternalAuthenticate, ISCardISO7816


ISCardISO7816::ManageChannel

The ManageChannel method constructs an APDU command that opens and closes logical channels.

The open function opens a new logical channel other than the basic one. Options are provided for the card to assign a logical channel number, or for the logical channel number to be supplied to the card.

The close function explicitly closes a logical channel other than the basic one. After the successful closing, the logical channel shall be available for re-use.

HRESULT ManageChannel(
  BYTE byChannelState,
  BYTE byChannel,
  LPSCARDCMD *ppCmd
);

Parameters

byChannelState [in, defaultvalue(ISO_CLOSE_LOGICAL_CHANNEL)]
Bit b8 of P1 is used to indicate the open function or the close function; if b8 is 0 then MANAGE CHANNEL shall open a logical channel and if b8 is 1 then MANAGE CHANNEL shall close a logical channel:

P1 = '00' to open

P1 = '80' to close

Other values are RFU

byChannel [in, defaultvalue(ISO_LOGICAL_CHANNEL_0)]
For the open function (P1 = '00'), the bits b1 and b2 of P2 are used to code the logical channel number in the same manner as in the class byte, the other bits of P2 are RFU.

When b1 and b2 of P2 are NULL, then the card will assign a logical channel number that will be returned in bits b1 and b2 of the data field.

When b1 and/or b2 of P2 are not NULL, they code a logical channel number other than the basic one; then the card will open the externally assigned logical channel number.

ppCmd [in, out]
On input, a pointer to an ISCardCmd interface object or NULL.

On return, it is filled with the APDU command constructed by this operation. If ppCmd was set to NULL, a smart card ISCardCmd object is internally created and returned via the ppCmd pointer.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

When the open function is successfully performed from the basic logical channel, the MF shall be implicitly selected as the current DF and the security status of the new logical channel should be the same as the basic logical channel after ATR. The security status of the new logical channel should be separate from that of any other logical channel.

When the open function is successfully performed from a logical channel, which is not the basic one, the current DF of the logical channel that issued the command will be selected as the current DF. In addition, the security status for the new logical channel should be the same as the security status of the logical channel from which the open function was performed.

After a successful close function, the security status related to this logical channel is lost.

For a list of all the methods provided by the ISCardISO7816 interface, see ISCardISO7816.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardsrv.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardsrv.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

ISCardISO7816


ISCardISO7816::PutData

The PutData method constructs an APDU command that stores a single primitive data object or the set of data objects contained in a constructed data object, depending on the file selected.

How the objects are stored (writing once and/or updating and/or appending) depends on the definition or the nature of the data objects.

HRESULT PutData(
  BYTE byP1,
  BYTE byP2,
  LPBYTEBUFFER pData,
  LPSCARDCMD *ppCmd
);

Parameters

byP1, byP2 [in]
Coding of P1-P2:
Value | Meaning
0000 - 003F | RFU
0040 - 00FF | BER-TLV tag (1 byte) in P2
0100 - 01FF | Application data (proprietary coding)
0200 - 02FF | SIMPLE-TLV tag in P2
0300 - 03FF | RFU
0400 - 04FF | BER-TLV tag (2 bytes) in P1-P2

pData [in]
Pointer to a byte buffer that contains the parameters and data to be written.
ppCmd [in, out]
On input, a pointer to an ISCardCmd interface object or NULL.

On return, it is filled with the APDU command constructed by this operation. If ppCmd was set to NULL, a smart card ISCardCmd object is internally created and returned via the ppCmd pointer.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

The command can be performed only if the security status satisfies the security conditions defined by the application within the context for the function.

Store Application Data
When the value of P1-P2 lies in the range from 0100 to 01FF, the value of P1-P2 shall be an identifier reserved for card internal tests and for proprietary services meaningful within a given application context.
Store Data Objects
When the value P1-P2 lies in the range from 0040 to 00FF, the value of P2 shall be a BER-TLV tag on a single byte. The value of 00FF is reserved for indicating that the data field carries BER-TLV data objects.

When the value of P1-P2 lies in the range 0200 to 02FF, the value of P2 shall be a SIMPLE-TLV tag. The value 0200 is RFU. The value 02FF is reserved for indicating that the data field carries SIMPLE-TLV data objects.

When the value of P1-P2 lies in the range from 4000 to FFFF, the value of P1-P2 shall be a BER-TLV tag on two bytes. The values 4000 to FFFF are RFU.

When a primitive data object is provided, the data field of the command message shall contain the value of the corresponding primitive data object.

When a constructed data object is provided, the data field of the command message shall contain the value of the constructed data object (that is, data objects including their tag, length, and value).

For a list of all the methods provided by the ISCardISO7816 interface, see ISCardISO7816.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardsrv.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardsrv.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

GetData, ISCardISO7816


ISCardISO7816::ReadBinary

The ReadBinary method constructs an APDU command that acquires a response message that gives that part of the contents of a transparent-structured elementary file.

HRESULT ReadBinary(
  BYTE byP1,
  BYTE byP2,
  LONG lBytesToRead,
  LPSCARDCMD *ppCmd
);

Parameters

byP1, byP2 [in]
The P1-P2 field, offset to the first byte to be read from the beginning of the file.

If b8=1 in P1, then b7 and b6 of P1 are set to 0 (RFU bits), b5 to b1 of P1 are a short EF identifier and P2 is the offset of the first byte to be read in data units from the beginning of the file.

If b8=0 in P1, then P1||P2 is the offset of the first byte to be read in data units from the beginning of the file.

lBytesToRead [in, defaultvalue(0)]
Number of bytes to read from the transparent EF.

If the Le field contains only zeroes, then within the limit of 256 for short length or 65536 for extended length, all the bytes until the end of the file should be read.

ppCmd [in, out]
On input, a pointer to an ISCardCmd interface object or NULL.

On return, it is filled with the APDU command constructed by this operation. If ppCmd was set to NULL, a smart card ISCardCmd object is internally created and returned via the ppCmd pointer.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

The encapsulated command can only be performed if the security status of the smart card satisfies the security attributes of the elementary file being processed.

When the command contains a valid short elementary identifier, it sets the file as current elementary file.

Elementary files without a transparent structure cannot be erased. The encapsulated command aborts if applied to an elementary file without a transparent structure.

For a list of all the methods provided by the ISCardISO7816 interface, see ISCardISO7816.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardsrv.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardsrv.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

EraseBinary, ISCardISO7816, UpdateBinary, WriteBinary


ISCardISO7816::ReadRecord

The ReadRecord method constructs an APDU command that reads either the contents of the specified record(s) or the beginning part of one record of an elementary file.

HRESULT ReadRecord(
  BYTE byRecordId,
  BYTE byRefCtrl,
  LONG lBytesToRead,
  LPSCARDCMD *ppCmd
);

Parameters

byRecordId [in, defaultvalue(NULL_BYTE)]
Record number or ID of the first record to be read (00 indicates the current record).
byRefCtrl [in]
Coding of the reference control:
Meaning 8 7 6 5 4 3 2 1
Current EF 0 0 0 0 0 - - -
Short EF ID x x x x x - - -
RFU 1 1 1 1 1 - - -
Record - - - - - 1 x x
Read Record - - - - - 1 0 0
Up to Last - - - - - 1 0 1
Up to P1 - - - - - 1 1 0
RFU - - - - - 1 1 1
Record ID - - - - - 0 x x
First Occur - - - - - 0 0 0
Last Occur - - - - - 0 0 1
Next Occur - - - - - 0 1 0
Previous - - - - - 0 1 1
Secret - - - x x x x x

Current EF = Currently selected EF.

Short EF ID = Short EF identifier.

Record # = Usage of record number in P1.

Read Record = Read record P1.

Up to Last = Read all records from P1 up to the last.

Up to P1 = Read all records from the last up to P1.

Record ID = Usage of record ID in P1.

First Occur = Read first occurrence.

Last Occur = Read last occurrence.

Next Occur = Read next occurrence.

Previous = Read previous occurrence.

lBytesToRead [in, defaultvalue(0)]
Number of bytes to read from the transparent EF.

If the Le field contains only zeroes, then depending on b3b2b1 of P2 and within the limit of 256 for short length or 65536 for extended length, the command should read completely either the single requested record or the requested sequence of records.

ppCmd [in, out]
On input, a pointer to an ISCardCmd interface object or NULL.

On return, it is filled with the APDU command constructed by this operation. If ppCmd was set to NULL, a smart card ISCardCmd object is internally created and returned via the ppCmd pointer.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

The encapsulated command can only be performed if the security status of the smart card satisfies the security attributes of the elementary file being read.

If another elementary file is currently selected at the time of issuing this command, it may be processed without identification of the currently selected file.

When the command contains a valid short elementary identifier, it sets the file as current elementary file.

Elementary files without a record structure cannot be read. The encapsulated command aborts if applied to an elementary file without a record structure.

For a list of all the methods provided by the ISCardISO7816 interface, see ISCardISO7816.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardsrv.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardsrv.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

AppendRecord, ISCardISO7816, UpdateRecord, WriteRecord


ISCardISO7816::SelectFile

The SelectFile method constructs an APDU command that sets a current elementary file within a logical channel. Subsequent commands may implicitly refer to the current file through the logical channel.

Selecting a directory (DF) within the card filestore — which may be the root (MF) of the filestore — makes it the current DF. After such a selection, an implicit current elementary file may be referred to through that logical channel.

Selecting an elementary file sets the selected file and its parent as current files.

After the answer to reset, the MF is implicitly selected through the basic logical channel, unless specified differently in the historical bytes or in the initial data string.

HRESULT SelectFile(
  BYTE byP1,
  BYTE byP2,
  LPBYTEBUFFER pData,
  LONG lBytesToRead,
  LPSCARDCMD *ppCmd
);

Parameters

byP1, byP2 [in]
Selection control.

P1 (upper byte in word):
Meaning | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1
Select File ID | 0 | 0 | 0 | 0 | 0 | 0 | x | x
EF, DF, or MF | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
child DF | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1
EF under DF | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0
parent DF of
current DF 		0 0 0 0 0 0 1 1

Meaning | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1
Select by DF Name | 0 | 0 | 0 | 0 | 0 | 1 | x | x
DFname | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0
RFU | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1
RFU | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0
RFU | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1

Meaning | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1
Select by path | 0 | 0 | 0 | 0 | 1 | 0 | x | x
from MF | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0
current DF | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1
RFU | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0
RFU | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1

When P1=00, the card knows either because of a specific coding of the file ID or because of the context of execution of the command if the file to select is the MF, a DF, or an EF.

When P1-P2=0000, if a file ID is provided, then it shall be unique in the following environments:

  • the immediate children of the current DF
  • the parent DF
  • the immediate children of the parent DF

If P1-P2=0000 and if the data field is empty or equal to 3F00, then select the MF.

When P1=04, the data field is a DF name, possibly right truncated.

When supported, successive such commands with the same data field shall select DFs whose names match with the data field (that is, start with the command data field). If the card accepts the command with an empty data field, then all or a subset of the DFs can be successively selected.

P2 (lower byte of word):
Meaning 8 7 6 5 4 3 2 1
First occur 0 0 0 0 - - 0 0
Last occur 0 0 0 0 - - 0 1
Next occur 0 0 0 0 - - 1 0
Previous occur 0 0 0 0 - - 1 1

Meaning 8 7 6 5 4 3 2 1
File Control 0 0 0 0 x x - -
Return FCI 0 0 0 0 0 0 - -
Return FCP 0 0 0 0 0 1 - -
Return FMD 0 0 0 0 1 0 - -

pData [in, defaultvalue(NULL)]
Data for operation if needed; else, NULL. Types of data that are passed in this parameter include:
  • file ID
  • path from the MF
  • path from the current DF
  • DF name
lBytesToRead [in, defaultvalue(0)]
Empty (that is, 0) or maximum length of data expected in response.
ppCmd [in, out]
On input, a pointer to an ISCardCmd interface object or NULL.

On return, it is filled with the APDU command constructed by this operation. If ppCmd was set to NULL, a smart card ISCardCmd object is internally created and returned via the ppCmd pointer.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

Unless otherwise specified, the correct execution of the encapsulated command modifies the security status according to the following rules:

  • When the current elementary file is changed, or when there is no current elementary file, the security status specific to a former current elementary file is lost.
  • When the current filestore directory (DF) is descendant of, or identical to the former current DF, the security status specific to the former current DF is lost. The security status common to all common ancestors of the previous and new current DF is maintained.

For a list of all the methods provided by the ISCardISO7816 interface, see ISCardISO7816.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardsrv.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardsrv.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

ISCardISO7816


ISCardISO7816::SetDefaultClassId

The SetDefaultClassId method assigns a standard class identifier byte that will be used in all operations when constructing an ISO 7816-4 command APDU. By default, the standard class identifier byte is 0x00.

HRESULT SetDefaultClassId(
  BYTE byClass
);

Parameters

byClass [in]
Class ID byte.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.

For a list of all the methods provided by the ISCardISO7816 interface, see ISCardISO7816.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardsrv.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardsrv.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

ISCardISO7816


ISCardISO7816::UpdateBinary

The UpdateBinary method constructs an APDU command that updates the bits present in an elementary file with the bits given in the APDU command.

HRESULT UpdateBinary(
  BYTE byP1,
  BYTE byP2,
  LPBYTEBUFFER pData,
  LPSCARDCMD *ppCmd
);

Parameters

byP1, byP2 [in]
Offset to the write (update) location into the binary from the start of the binary.

If b8=1 in P1, then b7 and b6 of P1 are set to 0 (RFU bits), b5 to b1 of P1 are a short EF identifier and P2 is the offset of the first byte to be updated in data units from the beginning of the file.

If b8=0 in P1, then P1 || P2 is the offset of the first byte to be updated in data units from the beginning of the file.

pData [in]
Pointer to the string of data units to be updated.
ppCmd [in, out]
On input, a pointer to an ISCardCmd interface object or NULL.

On return, it is filled with the APDU command constructed by this operation. If ppCmd was set to NULL, a smart card ISCardCmd object is internally created and returned via the ppCmd pointer.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

The encapsulated command can only be performed if the security status of the smart card satisfies the security attributes of the elementary file being processed.

When the command contains a valid short elementary identifier, it sets the file as current elementary file.

Elementary files without a transparent structure cannot be erased. The encapsulated command aborts if applied to an elementary file without a transparent structure.

For a list of all the methods provided by the ISCardISO7816 interface, see ISCardISO7816.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardsrv.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardsrv.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

EraseBinary, ISCardISO7816, ReadBinary, WriteBinary


ISCardISO7816::UpdateRecord

The UpdateRecord method constructs an APDU command that updates a specific record with the bits given in the APDU command.

Note When using current record addressing, the command sets the record pointer on the successfully updated record.

HRESULT UpdateRecord(
  BYTE byRecordId,
  BYTE byRefCtrl,
  LPBYTEBUFFER pData,
  LPSCARDCMD *ppCmd
);

Parameters

byRecordId [in, defaultvalue(NULL_BYTE)]
P1 value:

P1 = 00 designates the current record

P1 != '00' is the number of the specified record

byRefCtrl [in, defaultvalue(NULL_BYTE)]
Coding of the reference control P2:
Meaning 8 7 6 5 4 3 2 1
Current EF 0 0 0 0 0 - - -
Short EF ID x x x x x - - -
First Record - - - - - 0 0 0
Last Record - - - - - 0 0 1
Next Record - - - - - 0 1 0
Previous Record - - - - - 0 1 1
Record # in P1 - - - - - 1 0 0

pData [in]
Pointer to the record to be updated.
ppCmd [in, out]
On input, a pointer to an ISCardCmd interface object or NULL.

On return, it is filled with the APDU command constructed by this operation. If ppCmd was set to NULL, a smart card ISCardCmd object is internally created and returned via the ppCmd pointer.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

The encapsulated command can only be performed if the security status of the smart card satisfies the security attributes of the elementary file being processed.

When the command contains a valid short elementary identifier, it sets the file as current elementary file. If another elementary file is currently selected at the time of issuing this command, this command may be processed without identification of the currently selected file.

If the constructed command applies to a linear-fixed or cyclic-structured elementary file, it will abort if the record length is different from the length of the existing record.

If the command applies to a linear-variable structured elementary file, it may be carried out when the record length is different from the length of the existing record.

The "previous" option of the command (P2=xxxxx011), applied to a cyclic file, has the same behavior as a command constructed by AppendRecord.

Elementary files without a record structure cannot be read. The constructed command aborts if applied to an elementary file without record structure.

For a list of all the methods provided by the ISCardISO7816 interface, see ISCardISO7816.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardsrv.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardsrv.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

AppendRecord, ISCardISO7816, ReadRecord, WriteRecord


ISCardISO7816::Verify

The Verify method constructs an APDU command that initiates the comparison (in the card) of the verification data sent from the interface device with the reference data stored in the card (for example, password).

HRESULT Verify(
  BYTE byRefCtrl,
  LPBYTEBUFFER pData,
  LPSCARDCMD *ppCmd
);

Parameters

byRefCtrl [in, defaultvalue(NULL_BYTE)]
Quantifier of the reference data; coding of the reference control P2:
Meaning | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1
No Info | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
Global Ref 0 - - - - - - -
Specific Ref 1 - - - - - - -
RFU - x x - - - - -
Ref Data # - - - x x x x x

An example of Global Ref would be a password.

An example of Specific Ref is DF specific password.

P2=00 is reserved to indicate that no particular qualifier is used in those cards where the verify command references the secret data unambiguously.

The reference data number may be for example a password number or a short EF identifier.

When the body is empty, the command may be used either to retrieve the number 'X' of further allowed retries (SW1-SW2=63CX) or to check whether the verification is not required (SW1-SW2=9000).

pData [in]
Pointer to the verification data, or can be NULL (the default value).
ppCmd [in, out]
On input, a pointer to an ISCardCmd interface object or NULL.

On return, it is filled with the APDU command constructed by this operation. If ppCmd was set to NULL, a smart card ISCardCmd object is internally created and returned via the ppCmd pointer.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

The security status may be modified as a result of a comparison. Unsuccessful comparisons may be recorded in the card (for example, to limit the number of further attempts of the use of the reference data).

For a list of all the methods provided by the ISCardISO7816 interface, see ISCardISO7816.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardsrv.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardsrv.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

ISCardISO7816


ISCardISO7816::WriteBinary

The WriteBinary method constructs an APDU command that writes binary values into an elementary file.

Depending upon the file attributes, the command performs one of the following operations:

  • The logical OR of the bits already present in the card with the bits given in the command APDU (logical erased state of the bits of the file is 0).
  • The logical AND of the bits already present in the card with the bits given in the command APDU (logical erased state of the bits of the file is 1).
  • The one-time write in the card of the bits given in the command APDU.

When no indication is given in the data coding byte, the logical OR behavior applies.

HRESULT WriteBinary(
  BYTE byP1,
  BYTE byP2,
  LPBYTEBUFFER pData,
  LPSCARDCMD *ppCmd
);

Parameters

byP1, byP2 [in]
Offset to the write location from the beginning of the binary file (EF).

If b8=1 in P1, then b7 and b6 of P1 are set to 0 (RFU bits), b5 to b1 of P1 are a short EF identifier and P2 is the offset of the first byte to be written in data units from the beginning of the file.

If b8=0 in P1, then P1||P2 is the offset of the first byte to be written in data units from the beginning of the file.

pData [in]
Pointer to the string of data units to be written.
ppCmd [in, out]
On input, a pointer to an ISCardCmd interface object or NULL.

On return, it is filled with the APDU command constructed by this operation. If ppCmd was set to NULL, a smart card ISCardCmd object is internally created and returned via the ppCmd pointer.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

The encapsulated command can only be performed if the security status of the smart card satisfies the security attributes of the elementary file being processed.

When the command contains a valid short elementary identifier, it sets the file as current elementary file.

Once a write binary operation has been applied to a data unit of a one-time write EF, any further write operation referring to this data unit will be aborted if the content of the data unit or the logical erased state indicator (if any) attached to this data unit is different from the logical erased state.

Elementary files without a transparent structure cannot be written to. The encapsulated command aborts if applied to an elementary file without a transparent structure.

For a list of all the methods provided by the ISCardISO7816 interface, see ISCardISO7816.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardsrv.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardsrv.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

EraseBinary, ISCardISO7816, ReadBinary, UpdateBinary


ISCardISO7816::WriteRecord

The WriteRecord method constructs an APDU command that initiates one of the following operations:

  • The write once of a record.
  • The logical OR of the data bytes of a record already present in the card with the data bytes of the record given in the command APDU.
  • The logical AND of the data bytes of a record already present in the card with the data bytes of the record given in the command APDU.

When no indication is given in the data coding byte, the logical OR behavior applies.

Note When using current record addressing, the command sets the record pointer on the successfully updated record.

HRESULT WriteRecord(
  BYTE byRecordId,
  BYTE byRefCtrl,
  LPBYTEBUFFER pData,
  LPSCARDCMD *ppCmd
);

Parameters

byRecordId [in, defaultvalue(NULL_BYTE)]
Record identification. This is the P1 value:

P1 = '00' designates the current record.

P1 != '00' is the number of the specified record.

byRefCtrl [in, defaultvalue(NULL_BYTE)]
Coding of the reference control P2:
Meaning 8 7 6 5 4 3 2 1
Current EF 0 0 0 0 0 - - -
Short EF ID x x x x x - - -
First Record - - - - - 0 0 0
Last Record - - - - - 0 0 1
Next Record - - - - - 0 1 0
Previous Record - - - - - 0 1 1
Record # in P1 - - - - - 1 0 0

pData [in]
Pointer to the record to be written.
ppCmd [in, out]
On input, a pointer to an ISCardCmd interface object or NULL.

On return, it is filled with the APDU command constructed by this operation. If ppCmd was set to NULL, a smart card ISCardCmd object is internally created and returned via the ppCmd pointer.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

The encapsulated command can only be performed if the security status of the smart card satisfies the security attributes of the elementary file being processed.

When the command contains a valid short elementary identifier, it sets the file as current elementary file. If another elementary file is currently selected at the time of issuing this command, this command may be processed without identification of the currently selected file.

If the encapsulated command applies to a linear-fixed or cyclic-structured elementary file, it will abort if the record length is different from the length of the existing record. If it applies to a linear-variable structured elementary file, it may be carried out when the record length is different from the length of the existing record.

If P2=xxxxx011 and the elementary file is cyclic file, this command has the same behavior a command constructed using AppendRecord.

Elementary files without a record structure cannot be written to. The constructed command aborts if applied to an elementary file without a record structure.

For a list of all the methods provided by the ISCardISO7816 interface, see ISCardISO7816.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardsrv.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardsrv.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

AppendRecord, ISCardISO7816, ReadRecord, UpdateRecord


ISCardLocate

The ISCardeLocate interface provides services for locating a smart card by its name.

This interface can display the smart card user interface if it is required.

The following scenario shows a typical use of the ISCardLocate interface. The ISCardLocate interface is used to build the an APDU.

To locate a specific card using its name

  1. Create an ISCardLocate interface.
  2. Call ConfigureCardNameSearch to search for a smart card name.
  3. Call FindCard to search for the smart card.
  4. Interpret the results.
  5. Release the ISCardLocate interface.

Methods

ISCardLocate Methods | Description
ConfigureCardGuidSearch | Reserved for future use.
ConfigureCardNameSearch | Specifies the card name to be used in the search.
FindCard | Searches for the smart card and opens a valid connection to it.


ISCardLocate::ConfigureCardNameSearch

The ConfigureCardNameSearch method specifies the card names to be used in the search for the smart card.

HRESULT ConfigureCardNameSearch(
  LPSAFEARRAY pCardNames,
  LPSAFEARRAY pGroupNames,
  BSTR bstrTitle,
  LONG lFlags
);

Parameters

pCardNames
[in] Pointer to an OLE Automation safe array of card names in BSTR form.
pGroupNames
[in, defaultvalue(NULL )] Pointer to an OLE Automation safe array of names of card/reader groups in BSTR form to add to the search.
bstrTitle
[in, defaultvalue("")] Search common control dialog title.
lFlags
[in, defaultvalue(1)] Specifies when user interface is displayed:
Flag | Meaning
SC_DLG_MINIMAL_UI | Displays the dialog only if the card being searched for by the calling application is not located and available for use in a reader. This allows the card to be found, connected (either through internal dialog mechanism or the user callback functions), and returned to the calling application.
SC_DLG_NO_UI | Causes no UI display, regardless of the search outcome.
SC_DLG_FORCE_UI | Causes UI display regardless of the search outcome.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in pCardNames or pGroupNames.
E_OUTOFMEMORY | Out of memory.

Remarks

To locate the smart card, call FindCard.

For a list of all the methods provided by the ISCardLocate interface, see ISCardLocate.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardmgr.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardmgr.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

FindCard, ISCardLocate


ISCardLocate::FindCard

The FindCard method searches for the smart card and opens a valid connection to it.

HRESULT FindCard(
  SCARD_SHARE_MODES ShareMode,
  SCARD_PROTOCOLS Protocols,
  LONG lFlags,
  LPSCARDINFO *ppCardInfo
);

Parameters

ShareMode [in, defaultvalue(EXCLUSIVE)]
Mode in which to share or not share the smart card when a connection is opened to it.
Values | Description
EXCLUSIVE | No one else use this connection to the smart card.
SHARED | Other applications can use this connection.

Protocols [in, defaultvalue(T0)]
Protocol to use when connecting to the card.

T0
T1
RAW
T0|T1

lFlags [in, defaultvalue(SC_DLG_NO_UI)]
Specifies when user interface is displayed:
Flag | Meaning
SC_DLG_MINIMAL_UI | Displays the dialog only if the card being searched for by the calling application is not located and available for use in a reader. This allows the card to be found, connected (either through internal dialog mechanism or the user callback functions), and returned to the calling application.
SC_DLG_NO_UI | Causes no UI display, regardless of the search outcome.
SC_DLG_FORCE_UI | Causes UI display regardless of the search outcome.

ppCardInfo
[out, retval] Pointer to a data structure that contains/returns information about the opened smart card, if successful. Will be NULL if operation has failed.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in ppCardInfo.
E_OUTOFMEMORY | Out of memory.

Remarks

To set the search criteria of the search, call ConfigureCardNameSearch to specify a smart card's card names.

For a list of all the methods provided by the ISCardLocate interface, see ISCardLocate.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scardmgr.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scardmgr.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

ConfigureCardNameSearch, ISCardLocate


ISCardManage

The following interface definition is provided as a standard that can be followed when developing a smart card service provider.

The ISCardManage interface must be provided. It is used for attaching to a specific smart card or reader, for creating other optional interfaces to perform specific smart card functions, for locking a specific smart card for exclusive use, and for getting the status of a smart card or reader. As a set, these services can be responsible for maintaining a well-defined context within which an application can communicate with a smart card or reader.

Following is a typical use of ISCardManage interface.

To connect to a smart card

  1. Create the ISCardManage interface associated with the card.
  2. Connect to a smart card by attaching to a specific smart card reader (AttachByIFD) or by using a previously acquired handle (AttachByHandle).
  3. Create other interfaces to perform smart card operations (CreateCardAuth, CreateFileAccess, CreateCHVerification, or CreateInterface).
  4. Release the card (Detach).
  5. Release the ISCardManage interface and others as required.

Methods

ISCardManage Method | Definition
AttachByHandle | Allows an application to create a communication link to a smart card using a handle returned by the smart card resource manager.
AttachByIFD | Allows an application to request establishment of a context for a specific reader referenced with a friendly name.
CreateCardAuth | Allows the creation of a ISCardAuth interface.
CreateFileAccess | Allows the creation of a ISCardFileAccess interface.
CreateInterface | Allows the creation of a component-supported interface.
CreateCHVerification | Allows the creation of a ISCardVerify interface.
Detach | Releases the attachment to a particular smart card or reader allocated by AttachByHandle or AttachByIFD respectively.
SCardLock | Locks a connected smart card or reader for exclusive use.
SCardUnlock | Releases exclusive use of the connected smart card or reader.
Reconnect | Allows an application to reconnect to a smart card or reader without having to issue a Detach followed by AttachByHandle or AttachByIFD respectively.
Status | Allows an application to get the current status of the smart card or reader.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.


ISCardManage::AttachByHandle

The AttachByHandle method creates a communication link to a smart card (ICC) using a handle returned by the smart card resource manager.

HRESULT AttachByHandle(
  HSCARD hICC
);

Parameters

hICC [in]
Handle to a smart card.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | hICC is invalid.
E_OUTOFMEMORY | Out of memory.

Remarks

To attach a reader call AttachByIFD.

To release an attachment call Detach.

To reconnect with the smart card without calling Detach and AttachByHandle, call Reconnect.

For a list of all the methods defined by the ISCardManage interface, see ISCardManage.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

AttachByIFD, Detach, ISCardManage, Reconnect


ISCardManage::AttachByIFD

The AttachByIFD method creates a communication link to a reader, using a supplied friendly name for the reader.

HRESULT AttachByIFD(
  BSTR bstrIFDName
);

Parameters

bstrIFDName [in]
Friendly name of the reader.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | bstrIFDName is invalid.
E_OUTOFMEMORY | Out of memory.

Remarks

To attach a smart card call AttachByHandle.

To release an attachment call Detach.

To reconnect with the smart card without calling Detach and AttachByIFD, call Reconnect.

For a list of all the methods defined by the ISCardManage interface, see ISCardManage.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

AttachByHandle, Detach, ISCardManage, Reconnect


ISCardManage::CreateCardAuth

The CreateCardAuth method creates an ISCardAuth interface.

HRESULT CreateCardAuth(
  ISCardAuth **ppISCardAuth
);

Parameters

ppISCardAuth [out]
Returned pointer to the created interface.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | ppISCardAuth is invalid.
E_POINTER | A bad pointer was passed in ppISCardAuth.
E_OUTOFMEMORY | Out of memory.

Remarks

For a list of all the methods defined by the ISCardManage interface, see ISCardManage.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardManage


ISCardManage::CreateFileAccess

The CreateFileAccess method creates an ISCardFileAccess interface.

HRESULT CreateFileAccess(
  ISCardFileAccess **ppISCardFileAccess
);

Parameters

ppISCardFileAccess [out]
Returned pointer to the created ISCardFileAccess interface.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | ppISCardFileAccess is invalid.
E_POINTER | A bad pointer was passed in ppISCardFileAccess.
E_OUTOFMEMORY | Out of memory.

Remarks

For a list of all the methods defined by the ISCardManage interface, see ISCardManage.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardFileAccess, ISCardManage


ISCardManage::CreateInterface

The CreateInterface method creates of the specified interface.

HRESULT CreateInterface(
  LPGUID pguidInterface,
  BSTR bstrName,
  LONG *pUserData,
  LPUNKNOWN *ppInterface
);

Parameters

pguidInterface [in]
The GUID value of the interface to create.
bstrName [in, defaultvalue(NULL)]
The name of the interface to create if the GUID is unavailable. Standard values are "CryptoProvider".
pUserData [in, defaultvalue(NULL)]
Pointer to user-specific data to use in the creation of an interface.
ppInterface [out]
Pointer to the returned interface.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | One of the supplied parameters are invalid.
E_POINTER | A bad pointer was passed in pguidInterface or pUserData.
E_OUTOFMEMORY | Out of memory.

Remarks

For a list of all the methods defined by the ISCardManage interface, see ISCardManage.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardManage


ISCardManage::CreateCHVerification

The CreateCHVerification method creates an ISCardVerify interface.

HRESULT CreateCHVerification(
  ISCardVerify **ppISCardVerify
);

Parameters

ppISCardVerify [out]
Returned pointer to the created ISCardVerify interface.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | ppISCardVerify is invalid.
E_POINTER | A bad pointer was passed in ppISCardVerify.
E_OUTOFMEMORY | Out of memory.

Remarks

For information on the ISCardVerify interface, see ISCardVerify.

For a list of all the methods defined by the ISCardManage interface, see ISCardManage.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardManage, ISCardVerify


ISCardManage::Detach

The Detach method releases the attachment to a particular smart card or reader allocated by AttachByHandle and AttachByIFD respectively.

HRESULT Detach(void);

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_OUTOFMEMORY | Out of memory.

Remarks

To attach a smart card call AttachByHandle or AttachByIFD.

To reconnect with the smart card without calling Detach and AttachByHandle, call Reconnect.

For a list of all the methods defined by the ISCardManage interface, see ISCardManage.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

AttachByHandle, AttachByIFD, ISCardManage, Reconnect


ISCardManage::SCardLock

The SCardLock method locks a connected smart card for exclusive use.

HRESULT SCardLock(void);

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_FAIL | Operation failed to complete.

Remarks

To releases exclusive use of the connected smart card, call SCardUnlock.

For a list of all the methods defined by the ISCardManage interface, see ISCardManage.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardManage, SCardUnlock


ISCardManage::SCardUnlock

The SCardUnlock method releases exclusive use of the connected smart card.

HRESULT SCardUnlock(
  SCARD_DISPOSITIONS Disposition
);

Parameters

Disposition [in, defaultvalue(LEAVE)]
The state to leave the smart card in when the lock is released. Possible values are LEAVE, RESET, UNPOWER, and EJECT.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Disposition is invalid.

Remarks

To lock the connected smart card, call SCardLock.

For a list of all the methods defined by the ISCardManage interface, see ISCardManage.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardManage, SCardLock


ISCardManage::Reconnect

The Reconnect method allows an application to reconnect to a smart card or reader without having to issue a Detach call followed by an AttachByHandle or AttachByIFD call respectively.

HRESULT Reconnect(void);

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_OUTOFMEMORY | Out of memory.

Remarks

To attach a smart card call AttachByHandle or AttachByIFD.

To detach a smart card, call Detach.

For a list of all the methods defined by the ISCardManage interface, see ISCardManage.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

AttachByHandle, AttachByIFD, Detach, ISCardManage


ISCardManage::Status

The Status method gets the current status of the smart card or reader.

HRESULT Status(
  SCARD_STATES *pStatus,
  SCARD_PROTOCOLS *pProtocols
);

Parameters

pStatus [out]
On return, contains the current status/state.
pProtocols [out]
On return, contains the current protocol.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

For a list of all the methods defined by the ISCardManage interface, see ISCardManage.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardManage


ISCardTypeConv

The ISCardTypeConv interface provides the methods needed to support the users of the other smart card COM interfaces. Beginning with Microsoft Windows 2000, this interface is provided for backwards compatibility only and should no longer be used.

Methods

ISCardTypeConv Methods | Description
ConvertByteArrayToByteBuffer | Converts a typical C/C++ byte array into a universal buffer of bytes (IStream object).
ConvertByteBufferToByteArray | Converts a byte array mapped into a universal buffer of bytes (IStream object) into a typical C/C++ byte array.
ConvertByteBufferToSafeArray | Converts a byte array mapped into a universal buffer of bytes (IStream object) into a SAFEARRAY of unsigned char (byte).
ConvertSafeArrayToByteBuffer | Converts a byte array defined as a SAFEARRAY into a universal buffer of bytes (IStream object).
CreateByteArray | Creates an array of bytes.
CreateByteBuffer | Creates a universal buffer of bytes mapped into an IStream (IByteBuffer) object.
CreateSafeArray | Creates an OLE Automation SAFEARRAY of unsigned characters (bytes).
FreeIStreamMemoryPtr | Frees a memory pointer to the HGLOBAL memory block managed by an IStream COM interface.
GetAtIStreamMemory | Acquires a byte pointer to the HGLOBAL memory block that is managed by the IStream COM interface.
SizeOfIStream | Determines the size (how many bytes) of an IStream COM interface.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).


ISCardTypeConv::ConvertByteArrayToByteBuffer

The ConvertByteArrayToByteBuffer method converts a typical C/C++ byte array into a universal buffer of bytes (IStream object).

The byte buffer created is a stream mapped over a memory block. To access or manage the buffer, use the methods provided by the IStream interface. A unique feature about this array implementation is that when you call the IStream::Release method, the underlying memory will be released for you.

HRESULT ConvertByteArrayToByteBuffer(
  LPBYTE pbyArray,
  DWORD dwArraySize,
  LPBYTEBUFFER *ppbyBuffer
);

Parameters

pbyArray
[in] Pointer to the array of bytes to be converted.
dwArraySize
[in] Size of the byte array to be converted.
ppbyBuffer
[out, retval] Pointer to the IStream object to be returned.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Memory allocated successfully.
E_INVALIDARG | There is something wrong with one or more of the parameters passed into the function.
E_POINTER | A parameter of pointer type was incorrect.
E_OUTOFMEMORY | Not enough free memory to satisfy request.

Remarks

Memory allocated is moveable. Use the IStream::Release method to free the memory.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

Error Codes


ISCardTypeConv::ConvertByteBufferToByteArray

The ConvertByteBufferToByteArray method converts a universal buffer of bytes (IStream object) into a typical C/C++ byte array.

HRESULT ConvertByteBufferToByteArray(
  LPBYTEBUFFER pbyBuffer,
  LPBYTEARRAY *ppArray
);

Parameters

pbyBuffer
[in] Pointer to the IStream object to be converted.
ppArray
[out, retval] Pointer to the array of bytes to be returned.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Memory allocated successfully.
E_INVALIDARG | There is something wrong with one or more of the parameters passed into the function.
E_POINTER | A parameter of pointer type was incorrect.
E_OUTOFMEMORY | Not enough free memory to satisfy request.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

Error Codes


ISCardTypeConv::ConvertByteBufferToSafeArray

The ConvertByteBufferToSafeArray method converts a universal buffer of bytes (IStream object) into a SAFEARRAY of unsigned char (byte).

HRESULT ConvertByteBufferToSafeArray(
  LPBYTEBUFFER pbyBuffer,
  LPSAFEARRAY *ppbyArray
);

Parameters

pbyBuffer
[in] Pointer to the IStream object to be converted.
ppbyArray
[out, retval] Pointer to the SAFEARRAY to be returned.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Memory allocated successfully.
E_INVALIDARG | There is something wrong with one or more of the parameters passed into the function.
E_POINTER | A parameter of pointer type was incorrect.
E_OUTOFMEMORY | Not enough free memory to satisfy request.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

Error Codes


ISCardTypeConv::ConvertSafeArrayToByteBuffer

The ConvertSafeArrayToByteBuffer converts a byte array defined as a SAFEARRAY into a universal buffer of bytes (IStream object).

The byte buffer created is a stream mapped over a memory block. To access or manage the buffer, use the methods provided by the IStream interface. A unique feature about this array implementation is that when you call the IStream::Release method, the underlying memory will be released for you.

HRESULT ConvertSafeArrayToByteBuffer(
  LPSAFEARRAY pbyArray,
  LPBYTEBUFFER *ppbyBuff
);

Parameters

pbyArray
[in] Pointer to the SAFEARRAY to be converted.
ppbyBuff
[out, retval] Pointer to the IStream object to be returned.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Memory allocated successfully.
E_INVALIDARG | There is something wrong with one or more of the parameters passed into the function.
E_POINTER | A parameter of pointer type was incorrect.
E_OUTOFMEMORY | Not enough free memory to satisfy request.

Remarks

Memory allocated is moveable. Use the IStream::Release method to free the memory.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

Error Codes, IStream::Release


ISCardTypeConv::CreateByteArray

The CreateByteArray creates a typical C/C++ byte array.

HRESULT CreateByteArray(
  DWORD dwAllocSize,
  LPBYTE *ppbyArray
);

Parameters

dwAllocSize
[in] Size (in bytes) of the memory to be allocated for the array.
ppbyArray
[out, retval] Pointer to the byte array to be returned.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Memory allocated successfully.
E_INVALIDARG | There is something wrong with one or more of the parameters passed into the function.
E_OUTOFMEMORY | Not enough free memory to satisfy request.

Remarks

To create a universal buffer of bytes mapped into an IStream (IByteBuffer) object, call CreateByteBuffer.

To create a OLE Automation SAFEARRAY of unsigned characters (bytes), call CreateSafeArray.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

Error Codes, CreateByteBuffer, CreateSafeArray


ISCardTypeConv::CreateByteBuffer

The CreateByteBuffer method creates a universal buffer of bytes mapped into an IStream (IByteBuffer) object.

The byte buffer created is a stream mapped over a memory block. To access or manage the buffer, use the methods provided by the IStream interface. A unique feature about this array implementation is that when you call the IStream::Release method, the underlying memory will be released for you.

HRESULT CreateByteBuffer(
  DWORD dwAllocSize,
  LPBYTEBUFFER *ppbyBuff
);

Parameters

dwAllocSize
[in] Size in bytes of the memory to be allocated for the array.
ppbyBuff
[out, retval] Pointer to the IStream object to be returned.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Memory allocated successfully.
E_INVALIDARG | There is something wrong with one or more of the parameters passed into the function.
E_OUTOFMEMORY | Not enough free memory to satisfy request.

Remarks

Memory allocated is moveable. Use the IStream::Release method to free the memory.

To create a typical C/C++ byte array, call CreateByteArray.

To create a OLE Automation SAFEARRAY of unsigned characters (bytes), call CreateSafeArray.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

Error Codes, CreateByteArray, CreateSafeArray


ISCardTypeConv::CreateSafeArray

The CreateSafeArray method creates an OLE Automation SAFEARRAY of unsigned characters (bytes).

HRESULT CreateSafeArray(
  UINT nAllocSize,
  LPSAFEARRAY *ppArray
);

Parameters

nAllocSize
[in] Size in bytes of the memory to be allocated for the array.
ppArray
[out, retval] Pointer to the SAFEARRAY object to be returned.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Memory allocated successfully.
E_INVALIDARG | There is something wrong with one or more of the parameters passed into the function.
E_OUTOFMEMORY | Not enough free memory to satisfy request.

Remarks

To create a typical C/C++ byte array, call CreateByteArray.

To create a universal buffer of bytes mapped into an IStream (IByteBuffer) object, call CreateByteBuffer.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

Error Codes, CreateByteArray, CreateByteBuffer


ISCardTypeConv::FreeIStreamMemoryPtr

The FreeIStreamMemoryPtr frees the byte pointer pointing to the HGLOBAL memory block managed by an IStream COM interface.

HRESULT FreeIStreamMemoryPtr(
  LPSTREAM pStrm,
  LPBYTE pMem
);

Parameters

pStrm
[in] Pointer to the IStream interface that manages the memory block pointed to by pMem.
pMem
[in] Pointer to the memory block managed by the IStream interface.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Memory allocated successfully.
E_INVALIDARG | There is something wrong with one or more of the parameters passed into the function.
E_POINTER | A parameter of pointer type was incorrect.
E_OUTOFMEMORY | Not enough free memory to satisfy request.

Remarks

This function completely and cleanly releases the byte pointer pointing to the HGLOBAL memory block managed by the IStream interface. The byte pointer is acquired by a call to GetAtIStreamMemory.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

Error Codes, GetAtIStreamMemory


ISCardTypeConv::GetAtIStreamMemory

The GetAtIStreamMemory acquires a byte pointer to the HGLOBAL memory block that is managed by the IStream COM interface.

This is a way to get at the memory under the IStream without having to get the sizeof the memory block in bytes and read the bytes into a temporary byte array using the IStream interface.

HRESULT GetAtIStreamMemory(
  LPSTREAM pStrm,
  LPBYTEARRAY *ppMem
);

Parameters

pStrm
[in] Pointer to the IStream COM interface that manages the HGLOBAL memory block.
ppMem
[out, retval] Pointer to the first byte of the HGLOBAL memory block if successful; else, NULL if operation fails.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Memory allocated successfully.
E_INVALIDARG | There is something wrong with one or more of the parameters passed into the function.
E_POINTER | A parameter of pointer type was incorrect.
E_OUTOFMEMORY | Not enough free memory to satisfy request.

Remarks

The IStream's reference count will be incremented for each ppMem pointer acquired.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

Error Codes


ISCardTypeConv::SizeOfIStream

The SizeOfIStream method determines the size (in bytes) of the IStream COM interface.

HRESULT SizeOfIStream(
  LPSTREAM pStrm,
  ULARGE_INTEGER *puliSize
);

Parameters

pStrm
[in] Pointer to the IStream COM interface.
puliSize
[out, retval] Pointer to the unsigned large integer that can hold the entire 64-bit sizeof the IStream COM interface.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | The function succeeded and *puliSize is the size, in bytes, of the IStream COM interface.
E_FAIL | Unspecified failure occurred.
E_INVALIDARG | The puliSize parameter is incorrect.
E_POINTER | The pStrm parameter is incorrect.
E_UNEXPECTED | Unexpected error occurred.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Declared in Scarddat.h (Windows NT and Windows 95/98) or Scardssp.h (Windows 2000). Library: Use Scarddat.tlb (Windows NT and Windows 95/98) or Scardssp.tlb (Windows 2000).

See Also

Error Codes


ISCardVerify

The following interface definition is provided as a standard that can be followed when developing a smart card service provider. The ISCardVerify interface can provide services for setting CHV (card holder verification) code and for verifying the user.

The ISCardVerify class is defined for applications that implement application-specific CHV policy, and that have a detailed knowledge of the smart card's internal implementation.

Following is a typical use of ISCardVerify interface. In this case, the ISCardVerify interface is used to change the CHV code.

To change the CHV code of a smart card

  1. Create an ISCardVerify interface (through the corresponding ISCardManage interface method).
  2. Call ChangeCode. Provide new code, and specify if it is local or global and if it is enabled or disabled.
  3. Release the ISCardVerify interface.

Methods

ISCardVerify Method | Description
ChangeCode | Changes the current CHV code.
Unblock | Re-enable the security context.
ResetSecurityState | Resets the security context of the smart card.
Verify | Authenticates the user.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.


ISCardVerify::ChangeCode

The ChangeCode method replaces the current CHV (card holder verification) code with new CHV code.

HRESULT ChangeCode(
  LPBYTEBUFFER pOldCode,
  LPBYTEBUFFER pNewCode,
  SCARD_FLAGS Flags,
  LONG lRef
);

Parameters

pOldCode [in]
An IByteBuffer containing the user's current code.
pNewCode [in]
An IByteBuffer containing the new code that will be presented to the smart card during the change process to authenticate the user.
Flags [in]
Indicates whether the code is global or local, and whether the code should be enabled or disabled.

SC_FL_IHV_GLOBAL
SC_FL_IHV_LOCAL
SC_FL_IHV_ENABLE
SC_FL_IHV_DISABLE

lRef [in]
Smart card specific reference.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

For a list of all the methods defined by the ISCardVerify interface, see ISCardVerify.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardVerify


ISCardVerify::ResetSecurityState

The ResetSecurityState method resets the current security context of the smart card.

HRESULT ResetSecurityState(void);

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_OUTOFMEMORY | Out of memory.

Remarks

To re-enable the security context without resetting, call Unblock.

For a list of all the methods defined by the ISCardVerify interface, see ISCardVerify.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardVerify, Unblock


ISCardVerify::Unblock

The Unblock method re-enables the security context of the smart card.

HRESULT Unblock(
  LONG lData,
  SCARD_FLAGS Flags,
  LONG lRef
);

Parameters

lData [in]
Contains vendor-specific data to be used in the unblocking process.
Flags [in]
Indicates whether the code is global or local.

SC_FL_IHV_GLOBAL
SC_FL_IHV_LOCAL

lRef [in]
Smart card specific reference.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

To globally reset the security context, call Reset.

For a list of all the methods defined by the ISCardVerify interface, see ISCardVerify.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardVerify, Unblock


ISCardVerify::Verify

The Verify method request a verification of the user.

HRESULT Verify(
  LPBYTEBUFFER pCode,
  SCARD_FLAGS Flags,
  LONG lRef
);

Parameters

pCode [in]
Contains the code to be presented to the smart card in the CHV (card holder verification) process.
Flags [in]
Indicates whether the code is global or local.

SC_FL_IHV_GLOBAL
SC_FL_IHV_LOCAL

lRef [in]
Smart card specific reference.

Return Values

The possible return values are the following:

Value | Meaning
S_OK | Operation completed successfully.
E_INVALIDARG | Invalid parameter.
E_POINTER | A bad pointer was passed in.
E_OUTOFMEMORY | Out of memory.

Remarks

For a list of all the methods defined by the ISCardVerify interface, see ISCardVerify.

In addition to the COM error codes listed above, this interface may return a smart card error code if a smart card function was called to complete the request. For information on smart card error codes, see Smart Card Error Codes.

Requirements

Windows NT/2000: Requires Windows NT 4.0 SP3 or later.
Windows 95/98: Requires Windows 95 OSR2.1 or later.
Header: Vendor supplied.

See Also

ISCardVerify


Smart Card Error Codes

This section describes the primary error codes returned by smart card functions. These values are defined in scarderr.h.

Note Some error codes may have the same value as existing Win32® error codes that signify a similar condition.

Error | Definition
SCARD_E_BAD_SEEK | An error occurred in setting the smart card file object pointer.
SCARD_E_CANCELLED | The action was canceled by an SCardCancel request.
SCARD_E_CANT_DISPOSE | The system could not dispose of the media in the requested manner.
SCARD_E_CARD_UNSUPPORTED | The smart card does not meet minimal requirements for support.
SCARD_E_CERTIFICATE_UNAVAILABLE | The requested certificate could not be obtained.
SCARD_E_COMM_DATA_LOST | A communications error with the smart card has been detected.
SCARD_E_DIR_NOT_FOUND | The specified directory does not exist in the smart card.
SCARD_E_DUPLICATE_READER | The reader driver didn't produce a unique reader name.
SCARD_E_FILE_NOT_FOUND | The specified file does not exist in the smart card.
SCARD_E_ICC_CREATEORDER | The requested order of object creation is not supported.
SCARD_E_ICC_INSTALLATION | No primary provider can be found for the smart card.
SCARD_E_INSUFFICIENT_BUFFER | The data buffer for returned data is too small for the returned data.
SCARD_E_INVALID_ATR | An ATR string obtained from the registry is not a valid ATR string.
SCARD_E_INVALID_CHV | The supplied PIN is incorrect.
SCARD_E_INVALID_HANDLE | The supplied handle was invalid.
SCARD_E_INVALID_PARAMETER | One or more of the supplied parameters could not be properly interpreted.
SCARD_E_INVALID_TARGET | Registry startup information is missing or invalid.
SCARD_E_INVALID_VALUE | One or more of the supplied parameter values could not be properly interpreted.
SCARD_E_NO_ACCESS | Access is denied to the file.
SCARD_E_NO_DIR | The supplied path does not represent a smart card directory.
SCARD_E_NO_FILE | The supplied path does not represent a smart card file.
SCARD_E_NO_MEMORY | Not enough memory available to complete this command.
SCARD_E_NO_READERS_AVAILABLE | No smart card reader is available.
SCARD_E_NO_SERVICE | The smart card resource manager is not running.
SCARD_E_NO_SMARTCARD | The operation requires a smart card, but no smart card is currently in the device.
SCARD_E_NO_SUCH_CERTIFICATE | The requested certificate does not exist.
SCARD_E_NOT_READY | The reader or card is not ready to accept commands.
SCARD_E_NOT_TRANSACTED | An attempt was made to end a non-existent transaction.
SCARD_E_PCI_TOO_SMALL | The PCI receive buffer was too small.
SCARD_E_PROTO_MISMATCH | The requested protocols are incompatible with the protocol currently in use with the card.
SCARD_E_READER_UNAVAILABLE | The specified reader is not currently available for use.
SCARD_E_READER_UNSUPPORTED | The reader driver does not meet minimal requirements for support.
SCARD_E_SERVICE_STOPPED | The smart card resource manager has shut down.
SCARD_E_SHARING_VIOLATION | The smart card cannot be accessed because of other outstanding connections.
SCARD_E_SYSTEM_CANCELLED | The action was canceled by the system, presumably to log off or shut down.
SCARD_E_TIMEOUT | The user-specified timeout value has expired.
SCARD_E_UNEXPECTED | An unexpected card error has occurred.
SCARD_E_UNKNOWN_CARD | The specified smart card name is not recognized.
SCARD_E_UNKNOWN_READER | The specified reader name is not recognized.
SCARD_E_UNKNOWN_RES_MNG | An unrecognized error code was returned from a layered component.
SCARD_E_UNSUPPORTED_FEATURE | This smart card does not support the requested feature.
SCARD_E_WRITE_TOO_MANY | An attempt was made to write more data than would fit in the target object.
SCARD_F_COMM_ERROR | An internal communications error has been detected.
SCARD_F_INTERNAL_ERROR | An internal consistency check failed.
SCARD_F_UNKNOWN_ERROR | An internal error has been detected, but the source is unknown.
SCARD_F_WAITED_TOO_LONG | An internal consistency timer has expired.
SCARD_P_SHUTDOWN | The operation has been aborted to allow the server application to exit.
SCARD_S_SUCCESS | No error was encountered.
SCARD_W_CANCELLED_BY_USER | The action was cancelled by the user.
SCARD_W_CHV_BLOCKED | The card cannot be accessed because the maximum number of PIN entry attempts has been reached.
SCARD_W_EOF | The end of the smart card file has been reached.
SCARD_W_REMOVED_CARD | The smart card has been removed, so that further communication is not possible.
SCARD_W_RESET_CARD | The smart card has been reset, so any shared state information is invalid.
SCARD_W_SECURITY_VIOLATION | Access was denied because of a security violation.
SCARD_W_UNPOWERED_CARD | Power has been removed from the smart card, so that further communication is not possible.
SCARD_W_UNRESPONSIVE_CARD | The smart card is not responding to a reset.
SCARD_W_UNSUPPORTED_CARD | The reader cannot communicate with the card, due to ATR string configuration conflicts.
SCARD_W_WRONG_CHV | The card cannot be accessed because the wrong PIN was presented.


Policy Management

The policy management technologies described in the following can be used to enhance the security of your applications.

Technology | Description
LSA Policy | LSA Policy describes the parts of the Local Security Authority (LSA) which applications can use to manage local security policy information.
Service Security Attachments | Describes how to extend the Microsoft® Security Configuration tool set to support services which have specialized security configuration needs.


LSA Policy

Purpose

LSA Policy describes the part of the Local Security Authority (LSA) which applications can use to manage local security policy information. The local security policy affects user accounts and permissions, trusted domains, and auditing.

Where Applicable

You can use the LSA Policy functions to develop applications that manage user accounts, inter-domain trust relationships, and private data.

Developer Audience

The LSA Policy functions are designed for use by C/C++ programmers. Familiarity with Microsoft® Windows NT®/Windows® 2000 security protocols and procedures is required.

Run-Time Requirements

Applications that use the LSA Policy functions require Windows NT or Windows 2000. For information on which operating systems are required to use a particular function, see the Requirements section of the documentation for the function.

See Also

Group Policy

LSA Authentication

About LSA Policy

General information about LSA Policy.

Using LSA Policy

How to use the LSA Policy functions.

LSA Policy Reference

Documentation of LSA Policy objects, functions, structures, data types, return values, and enumerations.

Feedback

Make error reports and feature requests directly to Microsoft.


About LSA Policy

The Local Security Authority (LSA) is a protected subsystem of Microsoft® Windows NT®/Windows® 2000 that maintains information about all aspects of local security on a system, collectively known as the local security policy of the system.

In addition to housing policy information, the LSA provides services for translation between names and security identifiers (SIDs).


Local Security Policy

The local security policy of a system is a set of information about the security of a local computer. The information includes the following:

  • The domains trusted to authenticate logon attempts.
  • Which user accounts may access the system and how—for example, interactively, through a network, or as a service.
  • The rights and privileges assigned to accounts.
  • The security auditing policy.

The Local Security Authority (LSA) stores the local policy information in a set of LSA Policy Objects.


Built-in and Account Domains

The following sections describe domains that exist on a Windows NT or Windows 2000 system.

Windows NT 4.0 and Windows 2000 (not domain controllers):

The Security Accounts Manager (SAM) database resides on each computer and manages accounts for the built-in domain and the account domain.

Built-in Domain
This domain contains default local groups, such as the Administrators and Users groups, that are established when the operating system is installed.

The name of this domain is a localized version of "BUILTIN".

Account Domain
The account domain can contain user, group, and local group accounts. The Administrator account is in this domain. The accounts defined in the account domain of a workstation or member server are limited to accessing resources located on the physical computer where the account resides.

On a system that is not part of a network and therefore has no primary domain, the account domain is used to house all accounts that provide access to the computer. On a system that is part of a network, the computer's account domain is used to house accounts that do not access network resources. Accounts that require access to the network must be defined in the account domain of a domain controller.

The name of this domain is assigned at system installation time and is determined by the machine name. If the machine name is changed, the account domain name will not be updated until the machine is rebooted.

Windows NT 4.0 Domain Controllers:

The account domain name is the name of the controlled domain, which is also the primary domain for these systems.

The account domain contains normal user and group accounts that may be used on any system that trusts this domain for authentication.

Windows 2000 Domain Controllers:

Windows 2000 domain controllers do not have built-in or account domains. Also, instead of a SAM database, these systems use Microsoft Active Directory™ to store account access information. For more information, see Active Directory in the Platform SDK.


Primary and Trusted Domains

The following terms describe domains that exist on remote systems.

Primary Domain
A Windows NT/Windows 2000 system's primary domain is the domain that is responsible for establishing further trust relationships and performing authentication (or for passing an authentication request on to an appropriate trusted domain). The domain controllers in the primary domain handle or pass along authentication requests that originate at the workstation.

When logon occurs, the LSA checks the built-in and account domains for authentication information. If the account being logged on to is not in either of these domains, the logon request is handed off to the system's primary domain.

Trusted Domain
A trusted domain is a domain that the local system trusts to authenticate users. In other words, if a user or application is authenticated by a trusted domain, this authentication is accepted by all domains that trust the authenticating domain.

On Windows NT 4.0 systems, trust relationships are one way and must always be declared explicitly. As a result, a two-way trust is established by explicitly creating two one-way trusts. Moreover, Windows NT 4.0 trusts are not transitive, meaning that if a system trusts Domain A, it does not also automatically trust the domains that Domain A trusts.

On Windows 2000 systems, each child domain (a domain that is subordinate in a domain hierarchy) automatically has a two-way trust relationship with the parent. By default, this trust is transitive, meaning that if a system trusts Domain A, it also trusts all domains that Domain A trusts. Windows 2000 systems also support Windows NT 4.0–style, non-transitive, one-way trusts. This enables Windows 2000 systems to establish trust relationships with Windows NT 4.0 systems, which do not support transitive, two-way trusts.

The LSA has an object type, TrustedDomain, that is used to store information about trust relationships, including the name and security identifier (SID) of the trusted domain, the account in the domain to use for authentication requests, name and SID translation requests, and obtaining the names of domain controllers in the trusted domain.

On Windows NT 4.0 domain controllers and Windows 2000 systems the LSA creates an instance of a TrustedDomain object for each domain trusted by the local system. On Windows NT 4.0 systems that are not domain controllers, a TrustedDomain object is used only to hold information on the system's primary domain.

For example, if a Windows 2000 workstation trusts a Windows 2000 domain controller that in turn trusts four other systems, the workstation, (connected using transitive trust), will have five TrustedDomain objects on its local system.

In contrast, a Windows NT 4.0 workstation connected to that same Windows 2000 domain controller will have only one TrustedDomain object on its local system, because the Windows NT 4.0 system does not support transitive trust.

For more information about trusted domains and how they are supported in various versions of Windows NT/Windows 2000, see the "Active Directory Logical Structure" topic in the Microsoft® Windows® 2000 Distributed Systems Guide, which is part of the Microsoft® Windows® 2000 Server Resource Kit.


LSA Policy Objects

The LSA stores local security policy information in a set of objects. Your application can query or edit the local security policy by accessing these objects.

The set consists of the following four objects:

  • Policy contains global policy information.
  • TrustedDomain contains information about a trusted domain.
  • Account contains information about a user, group, or local group account.
  • Private Data contains protected information, such as server account passwords. This information is stored as encrypted strings.

For more information on how to use the LSA Policy functions to manage the information stored in these objects, see Using LSA Policy.


Policy Object

The Policy object is used to control access to the LSA database and contains information that applies to the entire system or establishes defaults for the system. Each system has only one Policy object. This Policy object is created by the LSA when the system boots up, and applications cannot create or destroy it.

The information stored in a Policy object includes:

  • System default memory quota. Unless otherwise specified, each user logging on to the system will be assigned this memory quota. Special memory quotas can be assigned to individuals or members of groups or local groups through an Account object.
  • System-wide security auditing requirements.
  • The name and SID of the account domain of this system.
  • Information about the primary domain of this system. This information includes the name and SID of the primary domain, the name of the account within the primary domain that is to be used for authentication requests, name and SID translations, and obtaining the names of domain controllers within the domain. These names may be out of date and should be taken only as a hint. The order of this list is assumed to be significant and will be maintained. This allows, for example, the first name in the list to represent the last-known primary domain controller.
  • Information about whether the LSA holds the master copy of the policy information or a replica. Only part of the policy information is replicated; the remainder is established on a per-system basis.

The AccountDomain and PrimaryDomain fields of the Policy object are used for different purposes depending upon the type of system and trust relationships:

  • On a Windows NT/Windows 2000 system that does not have a primary domain, the AccountDomain field contains the name and SID of the system's local account domain, which is the same as the computer name. The PrimaryDomain field contains the name of the workgroup this machine is a member of. TrustedDomain objects are ignored with one exception—there can not be a TrustedDomain object with the same name as the workgroup because it will appear as though it is the machine's primary domain.
  • On a Windows NT/Windows 2000 system that has a primary domain the AccountDomain field identifies the name and SID of the local account domain, as before. However, the PrimaryDomain field contains the name and SID of the primary domain for the system. Additionally, there should be a TrustedDomain object with the name and SID identified in the PrimaryDomain field. This TrustedDomain object contains the account and server information necessary to establish a secure channel to a domain controller in the primary domain. Any other TrustedDomain objects are ignored.
  • On Windows NT/Windows 2000 domain controllers the AccountDomain field identifies the local account domain for the system; however, the account name is user assigned rather than being a well-known name. Since the primary domain is the same as the account domain, the PrimaryDomain field must contain the same value as the AccountDomain field. Furthermore, all TrustedDomain objects are expected to be valid and represent trust relationships with other domains. If the system does not trust any other domains, there should not be any TrustedDomain objects.


TrustedDomain Object

The TrustedDomain object stores information about a trust relationship with a domain. A TrustedDomain object is created on the trusting system to identify an account within the trusted domain that may be used to submit authentication requests and to perform other operations, such as name and SID translations. There may be zero or more instances of this object type.

The information stored in a TrustedDomain object includes:

  • The SID of the trusted domain. This information is not modifiable and must be unique among all TrustedDomain objects.
  • The name of the trusted domain. This information is not modifiable and must be unique among all TrustedDomain objects.
  • The name of the account in the trusted domain used to submit authentication requests and to perform name and SID translations. This name is not modifiable.
  • The password used to submit authentication requests and perform name and SID translations.

For a Windows NT 4.0 domain controller or Windows 2000 system, there may be many instances of TrustedDomain objects. For a Windows NT 4.0 system which is not a domain controller, there should be either zero or one instance (although having more than one doesn't hurt anything). The TrustedDomain object, if present, must identify the primary domain of the machine.


Account Object

The Account object is used to assign privileges, system access, and special quotas to individual users or to members of local groups or groups.

The information stored in an Account object includes:

  • The SID of a user account, group account, or local group account.
  • A list of privileges to be assigned to the user or the members of a group. If a user is assigned privileges by several Account objects, the list includes all assigned privileges.


Private Data Object

A limited number of private data objects are available on each system for the purpose of storing information in a protected, encrypted, fashion.

Private data objects are provided primarily to support storage of server account passwords. This is useful for servers that run in a specific account. The server account's password is private data that should be secured, but is needed to log the server on.

Private data objects may be general purpose, or they may be one of three specialized types: local, global, and machine.

Local private data objects can only be read locally from the machine storing the object. Attempting to read them remotely results in an STATUS_ACCESS_DENIED error. Local private data objects have key names that begin with the prefix "L$". However, previous versions of the Windows operating system used local private data objects with key names beginning with "RasDialParms" and "RasCredentials". These are still supported, but any new local private data objects should be created with the "L$" prefix. In addition to the local private objects you create, the operating system defines the following local private objects: $machine.acc, SAC, SAI, and SANSC.

Global private data objects are global in the sense that if they are created on a domain controller, they will be automatically replicated to all domain controllers in that domain. In other words, each domain controller in that domain will have access to the values the global private data object contains. In contrast, global private data objects created on a system that is not a domain controller and non-global private data objects are not replicated. Global private data objects have key names beginning with "G$".

Machine private data objects can be accessed only by the operating system. These objects have key names that begin with "M$". However, older versions of Windows also used the prefixes: "NL$" and "_sc_". These prefixes are still supported, but if you create a machine private data object, you should use the newer prefix, "M$". Note: You can set, but you cannot retrieve, machine private data objects.

Private data objects which are not one of the preceding specialized types use key names that do not start with a prefix. These objects are not replicated and can be read either locally or remotely by applications.

Note Private information stored using a private data object is encrypted using a generated system-specific key. Operating system releases prior to Windows NT 4.0, service pack 4 do not include secure boot, and thus these operating systems have no way to securely store and later retrieve a cryptographic key. Because of this limitation, private information cannot truly be considered secure against sophisticated attacks.


Using LSA Policy

The following topics describe how to use the LSA Policy functions:

  • Using LSA Unicode Strings explains how to convert strings into the structure format used by some LSA Policy functions.
  • Opening a Policy Object Handle describes how to open a handle to the local Policy object. This handle is required by many of the LSA Policy functions as an input parameter.
  • Managing Policy Information details how to set and query global policy information for the local system and the domain.
  • Receiving Policy Change Events describes how to create and register an event to receive notifications when policy information changes.
  • Managing Account Permissions explains how to create, delete, and enumerate accounts and how to add and remove privileges for those accounts.
  • Managing Trusted Domain Information describes how to create, enumerate, and delete trusted domains, and how to set and retrieve trusted domain information.
  • Translating Between Names and SIDs explains how to map SIDs to account names and vice versa.
  • Mapping Posix Identifiers describes how to map SIDs to 32-bit Posix identifiers.
  • Storing Private Data explains how to store and retrieve private data strings.

For information about how to use the LSA to logon and authenticate users, see LSA Authentication.


Using LSA Unicode Strings

Several of the LSA Policy functions use the LSA_UNICODE_STRING structure to store string information. This structure stores the string and its length information.

The following code implements a function that converts LPWSTR data to LSA_UNICODE_STRING structures.

void InitLsaString(
  PLSA_UNICODE_STRING LsaString,
  LPWSTR String
)
{
  USHORT StringLength;

  if (String == NULL)
  {
    LsaString->Buffer = NULL;
    LsaString->Length = 0;
    LsaString->MaximumLength = 0;
    return;
  }
  // Get the length of the string without the null terminator.
  StringLength = wcslen(String);
  // Store the string.
  LsaString->Buffer = String;
  LsaString->Length =  StringLength * sizeof(WCHAR);
  LsaString->MaximumLength= (StringLength+1) * sizeof(WCHAR);
}


Opening a Policy Object Handle

Most LSA Policy functions require a handle to the Policy object for the system to query or modify. To obtain a handle to a Policy object, call LsaOpenPolicy and specify the name of the system you want to access and the set of access permissions required.

The access permissions required for your application depend on the actions it performs. For details about the permissions required for each function, see the description of the function in LSA Policy Reference.

If the call to LsaOpenPolicy is successful, it returns a handle to the Policy object for the specified system. Your application then passes this handle in subsequent LSA Policy function calls. When your application no longer needs the handle, it should call LsaClose to free it.

The following code illustrates opening a Policy object handle.

#define TARGET_SYSTEM_NAME L"mysystem"
LSA_HANDLE GetPolicyHandle()
{
  LSA_OBJECT_ATTRIBUTES ObjectAttributes;
  WCHAR SystemName[] = TARGET_SYSTEM_NAME;
  USHORT SystemNameLength;
  LSA_UNICODE_STRING lusSystemName;
  NTSTATUS ntsResult;
  LSA_HANDLE lsahPolicyHandle;

  // Object attributes are reserved, so initialize to zeroes.
  ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));

  //Initialize an LSA_UNICODE_STRING to the server name.
  SystemNameLength = wcslen(SystemName);
  lusSystemName.Buffer = SystemName;
  lusSystemName.Length = SystemNameLength * sizeof(WCHAR);
  lusSystemName.MaximumLength= (SystemNameLength+1) * sizeof(WCHAR);

  // Get a handle to the Policy object.
  ntsResult = LsaOpenPolicy(
    &lusSystemName,    //Name of the target system.
        &ObjectAttributes,
        POLICY_ALL_ACCESS, //Desired access permissions.
        &lsahPolicyHandle  //Receives the policy handle.
    );

  if (ntsResult != STATUS_SUCCESS)
  {
    // An error occurred. Display it as a win32 error code.
    wprintf(L"OpenPolicy returned %lu\n",
      LsaNtStatusToWinError(ntsResult));
    return NULL;
  }
  return lsahPolicyHandle;
}

In the preceding example, the application requested POLICY_ALL_ACCESS privileges. For details about which permissions your application should request when calling LsaOpenPolicy, see the descriptions of the functions that your application will pass the Policy object handle to.

To open a handle to the Policy object of a trusted domain, call LsaCreateTrustedDomainEx (to create a new trust relationship with a domain) or call LsaOpenTrustedDomainByName (to access an existing trusted domain). Both of these functions set a pointer to an LSA_HANDLE, which you can then specify in subsequent LSA Policy function calls. As with LsaOpenPolicy, your application should call LsaClose when it no longer needs the handle to the trusted domain's Policy object.


Managing Policy Information

The LSA provides functions that administrators can use to query and set global policy information for the local machine and the domain.

Before you can manage policy information, your application must get a handle to the local Policy object, as demonstrated in Opening a Policy Object Handle. This handle is required by the functions that manage policy information.

To retrieve information about the local security policy, call LsaQueryInformationPolicy. To set local security policy, call LsaSetInformationPolicy. The description of the POLICY_INFORMATION_CLASS enumeration details the types of policy information that can be queried or set.

The following example demonstrates how to obtain a system's account domain information, given a handle to the system's Policy object.

BOOL GetAccountDomainInfo(LSA_HANDLE PolicyHandle)
{
  NTSTATUS ntsResult;
  PPOLICY_ACCOUNT_DOMAIN_INFO pPADInfo;
  PWCHAR name;

  ntsResult = LsaQueryInformationPolicy(
    PolicyHandle,                    // Open handle to a Policy object.
    PolicyAccountDomainInformation,  // The information to get.
    &pPADInfo                        // Storage for the information.
  );

  if (ntsResult == STATUS_SUCCESS)
  {
    // There is no guarantee that the LSA_UNICODE_STRING buffer
    // is null terminated, so copy the name to a buffer that is.
    name = (WCHAR *) LocalAlloc(LPTR, pPADInfo->DomainName.Length + 1);
    wcsncpy (name, pPADInfo->DomainName.Buffer,pPADInfo->DomainName.Length);
    wprintf(L"The account domain name is %ws\n", name);
    LocalFree(name);
  }
  else
  {
    // Show the corresponding win32 error code.
    wprintf(L"Error obtaining account domain information - (win32) %lu\n",
      LsaNtStatusToWinError(ntsResult));
  }
  return !ntsResult;
}

For sample code that sets and retrieves policy information, see the Audit and Disptrus samples installed with the Platform SDK.


Receiving Policy Change Events

The LSA provides functions you can use to receive notification when there is a change in policy on the local system.

To receive notification, create a new event object by calling the CreateEvent function, and then call the LsaRegisterPolicyChangeNotification function. Your application can then call a wait function such as WaitForSingleObject, WaitForSingleObjectEx, or RegisterWaitForSingleObject to wait for the event to occur. The wait function returns when the event occurs, or when the time-out period expires. Typically, notification events are used in multi-threaded applications, in which one thread waits for an event, while other threads continue processing.

When your application no longer needs to receive notifications, it should call LsaUnregisterPolicyChangeNotification and then call CloseHandle to free the event object handle.

The following example illustrates how a single-threaded application can receive notification events when the system's auditing policy changes.

void WaitForPolicyChanges()
{
  HANDLE hEvent;
  NTSTATUS ntsResult;
  DWORD dwResult;

  // Create an event object.
  hEvent = CreateEvent(
    NULL,  // Child processes can't inherit.
    FALSE, // Automatically reset event.
    FALSE, // Start as a nonsignaled event.
    NULL   // Don't need a name.
  );

  // Check that the event was created.
  if (hEvent == NULL)
  {
    wprintf(L"Event object creation failed: %d\n",GetLastError());
    return;
  }
  // Register to receive auditing policy change notifications.
  ntsResult = LsaRegisterPolicyChangeNotification(
    PolicyNotifyAuditEventsInformation,
    hEvent
  );

  // Wait for the event to be triggered.
  dwResult = WaitForSingleObject(
    hEvent, // Handle to event object.
    300000  // Time-out interval in milliseconds.
  );

  // The wait function returned.
  if (dwResult == WAIT_OBJECT_0)
  {  // Received the notification signal.
    wprintf(L"Notification received.\n");
  }
  else
  {  // Received a time-out or error.
    wprintf(L"Notification was not received.\n");
  }
  // Unregister for notification.
  LsaUnregisterPolicyChangeNotification(
    PolicyNotifyAuditEventsInformation,
    hEvent
  );

  // Free the event handle.
  CloseHandle(hEvent);
}

For more information about Event objects, wait functions, and synchronization, see Using Event Objects.


Managing Account Permissions

The LSA provides several functions that applications can call to enumerate or set privileges for user, group, and local group accounts.

Before you can manage account information, your application must get a handle to the local Policy object, as demonstrated in Opening a Policy Object Handle. In addition, to enumerate or edit permissions for an account, you must have the security identifier (SID) for that account. Your application can locate an SID given the account name, as described in Translating Between Names and SIDs.

To access all accounts that have a particular permission, call LsaEnumerateAccountsWithUserRight. This function populates an array with the SIDs of all accounts that have the specified permission.

Once you have obtained the SID of an account, you can modify its permissions. Call LsaAddAccountRights to add permissions to the account. If the specified account does not exist, LsaAddAccountRights creates it. To remove permissions from an account, call LsaRemoveAccountRights. If you remove all permissions from an account, LsaRemoveAccountRights also deletes the account.

Your application can check the permissions currently assigned to an account by calling LsaEnumerateAccountRights. This function populates an array of LSA_UNICODE_STRING structures. Each structure contains the name of a privilege held by the specified account.

The following example adds the SeServiceLogonRight permission to an account. In this example, the AccountSID variable specifies the SID of the account. For more information about how to lookup an account SID, see Translating Between Names and SIDs.

void AddPrivileges(PSID AccountSID, LSA_HANDLE PolicyHandle)
{
  LSA_UNICODE_STRING lucPrivilege;
  NTSTATUS ntsResult;

  // Create an LSA_UNICODE_STRING for the privilege name(s).
  InitLsaString(&lucPrivilege, L"SeServiceLogonRight");

  ntsResult = LsaAddAccountRights(
    PolicyHandle,  // An open policy handle.
    AccountSID,    // The target SID.
    &lucPrivilege, // The privilege(s).
    1              // Number of privileges.
  );
  if (ntsResult == STATUS_SUCCESS)
  {
    wprintf(L"Privilege added.\n");
  }
  else
  {
    wprintf(L"Privilege was not added - %lu \n",
      LsaNtStatusToWinError(ntsResult));
  }
}

In the preceding example, the function InitLsaString converts a Unicode string to an LSA_UNICODE_STRING structure. The code for this function is shown in Using LSA Unicode Strings.


Managing Trusted Domain Information

LSA Policy provides several functions that you can use to create, enumerate, and delete trusted domains and to set and retrieve trusted domain information.

Before you can manage trusted domain information, your application must get a handle to a Policy object, as explained in Opening a Policy Object Handle.

You can enumerate the trusted domains by calling either LsaEnumerateTrustedDomains or LsaEnumerateTrustedDomainsEx. The LsaEnumerateTrustedDomainsEx function returns more information about the trusted domains.

To retrieve information about a trusted domain, call either LsaQueryTrustedDomainInfo or LsaQueryTrustedDomainInfoByName. Both functions return the same information; however, LsaQueryTrustedDomainInfo identifies the trusted domain by SID, and LsaQueryTrustedDomainInfoByName identifies the trusted domain by name.

To set information for a trusted domain, call either LsaSetTrustedDomainInformation or LsaSetTrustedDomainInfoByName. As with the query functions, LsaSetTrustedDomainInformation identifies the trusted domain by SID, while LsaSetTrustedDomainInfoByName identifies the trusted domain by name.

Your application can revoke a trust relationship for a trusted domain by calling LsaDeleteTrustedDomain.

The following example enumerates the trusted domains for the local system.

void EnumerateTrusts(LSA_HANDLE PolicyHandle)
{
  LSA_ENUMERATION_HANDLE hEnum=0;
  PLSA_TRUST_INFORMATION TrustInfo = NULL;
  ULONG ulReturned = 0;
  NTSTATUS Status = 0;
  ULONG i;
  WCHAR StringBuffer[256];

  //Enumerate the trusted domains until there are no more to return.
  do
  {
    Status = LsaEnumerateTrustedDomains(
       PolicyHandle, // An open policy handle.
       &hEnum,       // Enumeration tracker.
       &TrustInfo,   // Buffer to receive data.
       32000,        // Recommended buffer size.
       &ulReturned   // Number of items returned in TrustInfo.
    );

    //Check the return status for errors.
    if((Status != STATUS_SUCCESS) &&
       (Status != STATUS_MORE_ENTRIES) &&
     (Status != STATUS_NO_MORE_ENTRIES))
  {
    //Handle the error.
    wprintf(L"Error occurred enumerating domains %lu\n",
    LsaNtStatusToWinError(Status));
    return;
  }

  wprintf(L"Status %lu\n", LsaNtStatusToWinError(Status));
  // Process the trusted domain information.
  for (i=0;i<ulReturned; i++)
  {
    // LSA_Unicode strings may not be null terminated.
    wcsncpy(StringBuffer,
      TrustInfo[i].Name.Buffer,
      TrustInfo[i].Name.Length
    );
    wprintf(L"Enum Trusted Domain - %ws ", StringBuffer);
  }
  // Free the buffer.
  if (TrustInfo != NULL)
  {
    LsaFreeMemory(TrustInfo);
    TrustInfo = NULL;
  }
  } while (Status != STATUS_NO_MORE_ENTRIES);
  return;
}


Translating Between Names and SIDs

The LSA provides functions to translate between user, group, and local group names and their corresponding security identifier (SID) values. To locate account names, call LsaLookupNames. This function returns the SID as an RID/Domain index pair. To get the SID as a single element on Windows Whistler systems, you can call LsaLookupNames2. To locate SIDs, call LsaLookupSids.

These functions can translate name and SID information from any domain trusted by the local system.

Before you can translate between account names and SIDs, your application must get a handle to the local Policy object, as demonstrated in Opening a Policy Object Handle.

The following example looks up the SID for an account, given the account name.

void GetSIDInformation (LPWSTR AccountName,LSA_HANDLE PolicyHandle)
{
  LSA_UNICODE_STRING lucName;
  PLSA_TRANSLATED_SID ltsTranslatedSID;
  PLSA_REFERENCED_DOMAIN_LIST lrdlDomainList;
  LSA_TRUST_INFORMATION myDomain;
  NTSTATUS ntsResult;
  PWCHAR DomainString = NULL;

  // Initialize an LSA_UNICODE_STRING with the name.
  InitLsaString(&lucName, AccountName);
  ntsResult = LsaLookupNames(
     PolicyHandle,     // Handle to a Policy object.
     1,                // Number of names to look up.
     &lucName,       // Pointer to an array of names.
     &lrdlDomainList,  // Receives domain information.
     &ltsTranslatedSID // Receives relative SIDs.
  );
  // Get the domain the account resides in.
  myDomain = lrdlDomainList->Domains[ltsTranslatedSID->DomainIndex];
  DomainString = (PWCHAR) LocalAlloc(LPTR, myDomain.Name.Length + 1);
  wcsncpy(DomainString, myDomain.Name.Buffer, myDomain.Name.Length);
  // Display the relative Id.
  wprintf(L"Relative Id is %lu in domain %ws.\n",
    ltsTranslatedSID->RelativeId,
    DomainString);

  LocalFree(DomainString);
  LsaFreeMemory(ltsTranslatedSID);
  LsaFreeMemory(lrdlDomainList);
}

In the preceding example, the function InitLsaString converts a Unicode string to an LSA_UNICODE_STRING structure. The code for this function is shown in Using LSA Unicode Strings.

Note These translation functions are primarily provided for use by permissions editors to display access control list (ACL) information. A permission editor should always call these functions using the Policy object for the system where the name or security identifier SID is located. This ensures that the proper set of trusted domains is referenced during the translation.

Win32® Access Control also provides functions that perform translations between SIDs and account names, LookupAccountName and LookupAccountSID. If your application needs to look up an account name or SID and does not use additional LSA Policy functionality, use the Win32 Access Control functions instead of the LSA Policy functions. For more information about these functions, see Access Control.


Mapping Posix Identifiers

The Posix subsystem must be able to translate any security identifier (SID) it encounters to a 32-bit value, called a Posix ID. Furthermore, it must be able to categorize the ID as either a user ID or a group ID. To understand how this mapping is accomplished, let's first look at the SIDs that must be mapped.

SIDs have two components, the SID of the domain and the relative ID of the account in the domain. For example, in the SID S-1-518364-21-43-8, the last "8" is the account's relative ID (RID) and S-1-518364-21-43 is the SID of the domain.

Domain information is stored in TrustedDomain objects. Part of the information stored in a TrustedDomain object is a Posix ID offset to be used for SIDs within that domain. For example, if a TrustedDomain were defined as

    Name:    NtPgm
    Sid:    S-1-518364-21-43
    Posix Offset:    0x130000

Posix IDs for accounts in this domain would be generated by adding 130000 (hex) to the relative ID of the account. So, the Posix ID corresponding to the SID S-1-518364-21-43-8 would be 130008 (hex).

Not all Posix ID translations make use of a TrustedDomain object. The following table shows SIDs that are mapped using well-known offset values:

Source | Posix ID offset
SIDs from the built-in domain | 20000 (Hex)
SIDs from the account domain | 30000 (Hex)
SIDs from the primary domain (on Workstations only) | 40000 (Hex)

And finally, one other set of SIDs, logon SIDs, requires special processing. These values are assigned by the Windows logon process for each logon session and have the form S-1-5-5-X-Y, where X and Y are treated as a single LARGE_INTEGER that is incremented for each logon session. These SIDs are mapped to the constant Posix ID FFF (Hex). To map the Posix ID FFF(Hex), you may translate whatever logon identifier best suits the situation, or you may use S-1-5-5-0-0 by default. (For example, if a posix user applies protection to an object and specifies FFFx, it is better to substitute that user's logon identifier than just assigning S-1-5-5-0-0.)


Storing Private Data

LSA Policy provides two functions that you can use to set and retrieve private data. This data is stored as an encrypted string in the registry. For example, you can use these functions to store server account passwords and other sensitive information.

Call the LsaStorePrivateData function to store and encrypt private data. As described in Private Data Object, private data objects include three specialized types: local, global, and machine. To create a specialized object, add a prefix to the key name passed to LsaStorePrivateData: "L$" for local objects, "G$" for global objects, and "M$" for machine objects. If you are not creating one of these specialized types, you do not need to specify a key name prefix.

To retrieve and decode previously stored private data, call LsaRetrievePrivateData. Note that you cannot retrieve machine private data objects; machine objects can be retrieved only by the operating system.

Before you can store or retrieve private data, your application must get a handle to the local Policy object, as demonstrated in Opening a Policy Object Handle.

The following example creates a local private data object. Note that the function InitLsaString converts a Unicode string to an LSA_UNICODE_STRING structure. The code for this function is shown in Using LSA Unicode Strings.

BOOL CreatePrivateDataObject(LSA_HANDLE PolicyHandle)
{
  NTSTATUS ntsResult;
  LSA_UNICODE_STRING lucKeyName;
  LSA_UNICODE_STRING lucPrivateData;
  // The L$ prefix specifies a local private data object
  WCHAR wszKeyName[] = L"L$MyPrivateKey";
  WCHAR wszPrivateData[] = L"Something secret.";

  // Intializing PLSA_UNICODE_STRING structures
  InitLsaString(&lucKeyName, wszKeyName);
  InitLsaString(&lucPrivateData, wszPrivateData);

  // Store the private data.
  ntsResult = LsaStorePrivateData(
    PolicyHandle,   // handle to a Policy object
    &lucKeyName,    // key to identify the data
    &lucPrivateData // the private data
  );
  if (ntsResult != STATUS_SUCCESS)
  {
    wprintf(L"Store private object failed %lu\n",
      LsaNtStatusToWinError(ntsResult));
    return FALSE;
  }
  return TRUE;
}

Note The data stored by the LsaStorePrivateData function is not absolutely protected. The key, however, has a discretionary access-control list (DACL) that allows only the creator and administrators to read the data.


LSA Policy Reference

The following topics provide reference information for the LSA Policy API elements.

Topic | Description
Objects | Lists the access rights and protection for the Policy, TrustedDomain, Account, and Private Data objects.
Policy Functions | Details functions used to open the local Policy object and to set or retrieve global policy information.
Account Functions | Details functions used to manage account permissions, and to create and delete user accounts.
Trusted Domain Functions | Details functions used to create and delete trusted domain relationships, and to set and retrieve information about those trusted domains.
Private Data Functions | Details functions used to set and retrieve private data strings.
Miscellaneous Functions | Details functions not described elsewhere.
Structures | Details structures used by the LSA functions.
Data Types | Details data types used by the LSA functions.
Common LSA Return Values | Details values commonly returned by the LSA functions.
Enumerations | Details enumerations used by the LSA functions.


Objects

LSA policy has the following four object types, each with its particular access rights and protections:

  • The Policy Object Type
  • The TrustedDomain Object Type
  • The Account Object Type
  • The Private Data Object Type


The Policy Object Type

The Policy object is a container object. The following object types may reside within this container:

  • Account objects
  • TrustedDomain object
  • Secret object

There is only a single instance of the Policy object. It can be neither created nor destroyed.


Policy Object Access Rights

The Policy object has the following object-specific access types:

POLICY_VIEW_LOCAL_INFORMATION
This access type is needed to read the target system's miscellaneous security policy information. This includes the default quota, auditing, server state and role information, and trust information. This access type is also needed to enumerate trusted domains, accounts, and privileges.
POLICY_GET_PRIVATE_INFORMATION
This access type is needed to view sensitive information, such as the names of accounts established for trusted domain relationships.
POLICY_TRUST_ADMIN
This access type is needed to change the account domain or primary domain information. Prior to Windows 2000, this access type was also needed to create TrustedDomain objects.
POLICY_SET_DEFAULT_QUOTA_LIMITS
Set the default system quotas that are applied to user accounts.
POLICY_CREATE_SECRET
This access type is needed to create a new Private Data object.
POLICY_CREATE_ACCOUNT
This access type is needed to create a new Account object.
POLICY_SET_AUDIT_REQUIREMENTS
This access type is needed to update the auditing requirements of the system.
POLICY_AUDIT_LOG_ADMIN
This access type is needed to change the characteristics of the audit log such as its maximum size or the retention period for audit records, or to clear the log.
POLICY_VIEW_AUDIT_INFORMATION
This access type is needed to view audit log or audit requirements information.
POLICY_SERVER_ADMIN
This access type is needed to modify the server state or role (master/replica) information. It is also needed to change the replica source and account name information.
POLICY_LOOKUP_NAMES
This access type is needed to translate between names and SIDs.
POLICY_CREATE_PRIVILEGE
Not yet supported.

Generic Access Masks

The Policy object publishes the following mappings from generic access types to specific access types:

    GENERIC_READ    STANDARD_RIGHTS_READ |
                    POLICY_VIEW_AUDIT_INFORMATION |
                    POLICY_GET_PRIVATE_INFORMATION

    GENERIC_WRITE   STANDARD_RIGHTS_WRITE |
                    POLICY_TRUST_ADMIN |
                    POLICY_CREATE_ACCOUNT |
                    POLICY_CREATE_SECRET |
                    POLICY_CREATE_PRIVILEGE |
                    POLICY_SET_DEFAULT_QUOTA_LIMITS |
                    POLICY_SET_AUDIT_REQUIREMENTS |
                    POLICY_AUDIT_LOG_ADMIN |
                                        POLICY_SERVER_ADMIN

    GENERIC_EXECUTE STANDARD_RIGHTS_EXECUTE |
                    POLICY_VIEW_LOCAL_INFORMATION |
                    POLICY_LOOKUP_NAMES

Standard Access Types

This object does not support the (optional) SYNCHRONIZE standard access type. All required access types are supported. The mask of all supported access types for this object type is:

    POLICY_ALL_ACCESS STANDARD_RIGHTS_REQUIRED |
                    POLICY_VIEW_LOCAL_INFORMATION |
                    POLICY_VIEW_AUDIT_INFORMATION |
                    POLICY_GET_PRIVATE_INFORMATION |
                    POLICY_TRUST_ADMIN |
                    POLICY_CREATE_ACCOUNT |
                    POLICY_CREATE_SECRET |
                    POLICY_CREATE_PRIVILEGE |
                    POLICY_SET_DEFAULT_QUOTA_LIMITS |
                    POLICY_SET_AUDIT_REQUIREMENTS |
                    POLICY_AUDIT_LOG_ADMIN |
                    POLICY_SERVER_ADMIN
                    POLICY_LOOKUP_NAMES


Policy Object Protection

The Policy object is protected by default in the following fashion:

  • The local group WORLD has GENERIC_EXECUTE access.
  • The well-known ID System is granted POLICY_ALL_ACCESS.
  • The local group LOCAL_ADMIN has GENERIC_READ, GENERIC_WRITE, and GENERIC_EXECUTE access.
  • The group LOCAL_ADMIN is assigned as owner and primary group of this object.

The Policy object cannot be created or destroyed.


The TrustedDomain Object Type

Windows NT 4.0 domain controllers and Windows 2000 systems may have multiple instances of the TrustedDomain object type.

A Windows NT 4.0 system that is not a domain controller is expected to have either zero or one instance (although having more than one doesn't hurt anything). In systems that are not domain controllers the trusted domain object, if present, is expected to identify the system's primary domain.

TrustedDomain objects have two fields which must be unique among all TrustedDomain objects: the trusted domain's name and the trusted domain's SID. An attempt to create a new TrustedDomain object with either a name or an SID that is already in use by another TrustedDomain object will be rejected.


TrustedDomain Object Access Rights

The TrustedDomain object type has the following access types:

TRUSTED_QUERY_DOMAIN_NAME
This access type is needed to query the name of the trusted domain.
TRUSTED_SET_CONTROLLERS
This access type is needed to set the list of controllers of the trusted domain.
TRUSTED_QUERY_POSIX
This access type is needed to retrieve the Posix ID offset of a trusted domain.
TRUSTED_SET_POSIX
This access type is needed to set the Posix ID offset of a trusted domain.

Generic Access Masks

This object type has the following generic access mappings:

    GENERIC_READ        STANDARD_RIGHTS_READ |
                    TRUSTED_QUERY_DOMAIN_NAME

    GENERIC_WRITE        STANDARD_RIGHTS_WRITE |
                    TRUSTED_SET_POSIX

    GENERIC_EXECUTE    STANDARD_RIGHTS_EXECUTE |
                    TRUSTED_QUERY_POSIX

Standard Access Types

This object does not support the (optional) SYNCHRONIZE standard access type. All required access types are supported. The mask of all supported access types for this object type is:

    TRUSTED_ALL_ACCESS    STANDARD_RIGHTS_REQUIRED |
                    TRUSTED_QUERY_DOMAIN_NAME |
                    TRUSTED_QUERY_CONTROLLERS |
                    TRUSTED_SET_CONTROLLERS


TrustedDomain Object Protection

When a TrustedDomain object is created, it is assigned a standard protection. That protection is:

  • The WORLD local group is granted GENERIC_EXECUTE access.
  • The LOCAL_ADMIN local group is granted DELETE, GENERIC_READ, GENERIC_WRITE, and GENERIC_EXECUTE access.
  • The LOCAL_ADMIN local group is assigned as owner and primary group of the object.


The Account Object Type

Account objects are used to signify privileges, or system access rights that are to be bestowed upon a user or members of groups or local groups.

Account objects reside within the Policy object. There may be zero or more of these objects.

The Account object has no object-specific data types.


Account Object Access Rights

The Account object type has the following access types:

ACCOUNT_VIEW
This access type is required to read the account information. This includes the privileges assigned to the account, memory quotas assigned, and any special access types granted.
ACCOUNT_ADJUST_PRIVILEGES
This access type is required to assign privileges to or remove privileges from an account.
ACCOUNT_ADJUST_QUOTAS
This access type is required to change the system quotas assigned to an account.
ACCOUNT_ADJUST_SYSTEM_ACCESS
This access type is required to update the system access flags for the account.

Generic Access Masks

The Account object publishes the following mappings from generic access types to specific access types:

    GENERIC_READ        STANDARD_RIGHTS_READ |
                        ACCOUNT_VIEW

    GENERIC_WRITE       STANDARD_RIGHTS_WRITE |
                        ACCOUNT_ADJUST_PRIVILEGES |
                        ACCOUNT_ADJUST_QUOTAS |
                        ACCOUNT_ADJUST_SYSTEM_ACCESS

    GENERIC_EXECUTE        STANDARD_RIGHTS_EXECUTE

Standard Access Types

This object does not support the (optional) SYNCHRONIZE standard access type. All required access types are supported. The mask of all supported access types for this object type is:

    ACCOUNT_ALL_ACCESS  STANDARD_RIGHTS_REQUIRED |
                        ACCOUNT_VIEW |
                        ACCOUNT_ADJUST_PRIVILEGES |
                        ACCOUNT_ADJUST_QUOTAS |
                        ACCOUNT_ADJUST_SYSTEM_ACCESS


Account Object Protection

Account objects are protected in the following fashion:

  • The group WORLD has GENERIC_EXECUTE
  • The group LOCAL_ADMIN has DELETE, GENERIC_READ, GENERIC_WRITE, GENERIC_EXECUTE, and WRITE_DACL access.
  • The group LOCAL_ADMIN is assigned as owner and primary group of Account objects.


The Private Data Object Type

You can use Private Data objects to store a data strings in an encrypted form. A system can contain multiple Private Data objects. Private Data objects are provided primarily to support storage of server account passwords.

Note Information stored in Private Data objects is encrypted using a generated system-specific key. Because versions of Windows NT before the Windows NT 4.0, service pack 4 release do not include secure boot and thus have no way to securely store and later retrieve a cryptographic key, private information cannot truly be considered secure against sophisticated attacks.


Private Data Object Access Rights

The access types of this object type are:

SECRET_QUERY_VALUE
This access type is needed to retrieve a secret.
SECRET_SET_VALUE
This access type is needed to modify a secret.

Generic Access Masks

This object type has the following generic access mappings:

    GENERIC_READ    STANDARD_RIGHTS_READ |
                    SECRET_QUERY_VALUE

    GENERIC_WRITE   STANDARD_RIGHTS_WRITE |
                    SECRET_SET_VALUE

    GENERIC_EXECUTE STANDARD_RIGHTS_EXECUTE

Standard Access Types:

This object does not support the (optional) SYNCHRONIZE standard access type. All required access types are supported. The mask of all supported access types for this object type is:

    SECRET_ALL_ACCESS    STANDARD_RIGHTS_REQUIRED |
                    SECRET_QUERY_VALUE |
                    SECRET_SET_VALUE


Private Data Object Initial Protection

When a Private Data object is created, it is assigned a standard protection. That protection is:

  • The WORLD local group is granted GENERIC_EXECUTE access.
  • The LOCAL_ADMIN local group is granted DELETE, GENERIC_READ, GENERIC_WRITE, and GENERIC_EXECUTE access.
  • The LOCAL_ADMIN local group is assigned as owner and primary group of the object.


Policy Functions

You can use the following functions to enumerate user accounts and trusted domains, receive policy change notifications, and lookup account names and SIDs.

Function | Description
LsaEnumerateAccountsWithUserRight | Enumerates all the accounts that have a specified user permission.
LsaEnumerateTrustedDomains | Enumerates the trusted domains.
LsaEnumerateTrustedDomainsEx | Enumerates the trusted domains. This function returns more information than LsaEnumerateTrustedDomains.
LsaLookupNames | Maps the specified names to their SIDs. Returns the SID as an RID/Domain SID pair.
LsaLookupNames2 | Maps the specified names to their SIDs. Returns the SID as a single element.
LsaLookupSids | Maps the specified account names to their SIDs.
LsaRegisterPolicyChangeNotification | Registers an Event object to receive notifications when the local policy information changes.
LsaUnregisterPolicyChangeNotification | Unregisters an Event object that is receiving policy change notifications.


LsaEnumerateAccountsWithUserRight

The LsaEnumerateAccountsWithUserRight function returns the accounts in an LSA Policy object's database that hold a specified privilege.

NTSTATUS LsaEnumerateAccountsWithUserRight(
  LSA_HANDLE PolicyHandle,
  PLSA_UNICODE_STRING UserRights,
  PVOID *EnumerationBuffer,
  PULONG CountReturned
);

Parameters

PolicyHandle
Handle to a Policy object. The handle must have POLICY_LOOKUP_NAMES and POLICY_VIEW_LOCAL_INFORMATION access rights. For more information, see Opening a Policy Object Handle.
UserRights
Pointer to an LSA_UNICODE_STRING structure that specifies the name of a privilege. For a list of privileges, see Windows NT Privileges and Account Rights.

If this parameter is NULL, the function enumerates all accounts in the LSA database of the system associated with the Policy object.

EnumerationBuffer
Pointer to a variable that receives a pointer to an array of LSA_ENUMERATION_INFORMATION structures. The Sid member of each structure is a pointer to the SID of an account that holds the specified privilege.

When you no longer need the information, pass the returned pointer to LsaFreeMemory.

CountReturned
Pointer to a variable that receives the number of entries returned in the EnumerationBuffer parameter.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code, which can be one of the following values or one of the common LSA return values.

Value | Meaning
STATUS_NO_SUCH_PRIVILEGE | The privilege string specified was not a valid privilege.
STATUS_NO_MORE_ENTRIES | There were no accounts with the specified privilege.

You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.

See Also

LSA_ENUMERATION_INFORMATION, LSA_UNICODE_STRING, LsaFreeMemory, LsaOpenPolicy


LsaLookupNames

The LsaLookupNames function retrieves the security identifiers (SIDs) that correspond to an array of user, group, or local group names.

Windows 2000: The LsaLookupNames function can also retrieve machine accounts.

NTSTATUS LsaLookupNames(
  LSA_HANDLE PolicyHandle,
  ULONG Count,
  PLSA_UNICODE_STRING Names,
  PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains,
  PLSA_TRANSLATED_SID *Sids
);

Parameters

PolicyHandle
Handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. For more information, see Opening a Policy Object Handle.
Count
Specifies the number of names in the Names array. This is also the number of entries returned in the Sids array.
Names
Pointer to an array of LSA_UNICODE_STRING structures that contain the names to lookup. The strings in these structures can be the names of user, group, or local group accounts, or the names of domains. Domain names can be DNS domain names or NetBIOS domain names.

For more information about the format of the name strings, see the following Remarks section.

ReferencedDomains
Receives a pointer to an LSA_REFERENCED_DOMAIN_LIST structure. The Domains member of this structure is an array containing an entry for each domain in which a name was found. The DomainIndex member of each entry in the Sids array is the index of the Domains array entry for the domain in which the name was found.

When you no longer need the information, pass the returned pointer to LsaFreeMemory.

Sids
Receives a pointer to an array of LSA_TRANSLATED_SID structures. Each entry in the Sids array contains the SID information for the corresponding entry in the Names array.

When you no longer need the information, pass the returned pointer to LsaFreeMemory.

Return Values

If the function succeeds, the return value is one of the following NTSTATUS values.

Value | Meaning
STATUS_SOME_NOT_MAPPED | Some of the names could not be translated. This is an informational-level return value.
STATUS_SUCCESS | All of the names were found and successfully translated.

If the function fails, the return value is the following NTSTATUS code or one of the common LSA return values.

Value | Meaning
STATUS_NONE_MAPPED | None of the names were translated.

Use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Remarks

The strings in the Names array can be either isolated names (for example, JohnH) or composite names containing both the domain name and account name (for example, Acctg\JohnH). An isolated name may be either an account name (user, group, or local group) or a domain name. Composite names must include a backslash character separating the domain name from the account name.

Translation of isolated names introduces the possibility of name collisions (because the same name may be used in multiple domains). The LsaLookupNames function uses the following algorithm to translate isolated names:

  1. If the name is a well-known name, such as Local or Interactive, the function returns the corresponding well-known security identifier (SID).
  2. If the name is the built-in domain's name, the function returns that domain's SID.
  3. If the name is the account domain's name, the function returns that domain's SID.
  4. If the name is the primary domain's name, the function returns that domain's SID.
  5. If the name is one of the trusted domain's names, the function returns that domain's SID.
  6. If the name is a user, group, or local group account in the built-in domain, the function returns the SID of that account.
  7. If the name is a user, group, or local group account in the account domain on the local system, the function returns the SID of that account.
  8. If the name is a user, group or a local group in the primary domain, the function returns the SID of that account.
  9. After looking in the primary domain, the primary domain looks in each of its trusted domains.
  10. Otherwise, the name is not translated.

For an example that demonstrates calling this function, see Translating Between Names and SIDs.

Note Windows NT: The LsaLookupNames function cannot translate proxy or trust user accounts. It can only translate normal user accounts. To retrieve other account types, use networking functions, such as NetUserGetInfo.

Windows 2000: In addition to looking up local accounts, local domain accounts, and explicitly trusted domain accounts, LsaLookupNames can look up the name for any account in any domain in the Windows 2000 forest.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.

See Also

LsaFreeMemory, LsaLookupSids, LSA_REFERENCED_DOMAIN_LIST, LSA_TRANSLATED_SID, LSA_UNICODE_STRING


LsaLookupNames2

[This is preliminary documentation and subject to change.]

The LsaLookupNames2 function retrieves the SIDs for specified account names. LsaLookupNames2 can look up the SID for any account in any domain in a Windows 2000 forest.

This function differs from the LsaLookupNames function in that LsaLookupNames2 returns each SID as a single element, while LsaLookupNames divides each SID into an RID/domain pair.

NTSTATUS LsaLookupNames2(
  LSA_HANDLE PolicyHandle,
  ULONG Count,
  PLSA_UNICODE_STRING Names,
  PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains,
  PLSA_TRANSLATED_SID2 *Sids
);

Parameters

PolicyHandle
[in] Handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. For more information, see Opening a Policy Object Handle.
Count
[in] Specifies the number of names in the Names array. This is also the number of entries returned in the Sids array.
Names
[in] Pointer to an array of LSA_UNICODE_STRING structures that contain the names to look up. These strings can be the names of user, group, or local group accounts, or the names of domains. Domain names can be DNS domain names or NetBIOS domain names.

For more information about the format of the name strings, see the following Remarks section.

ReferencedDomains
[out] Receives a pointer to an LSA_REFERENCED_DOMAIN_LIST structure. The Domains member of this structure is an array containing an entry for each domain in which a name was found. The DomainIndex member of each entry in the Sids array is the index of the Domains array entry for the domain in which the name was found.

When you no longer need the information, pass the returned pointer to LsaFreeMemory.

Sids
[out] Receives a pointer to an array of LSA_TRANSLATED_SID2 structures. Each entry in the Sids array contains the SID information for the corresponding entry in the Names array.

When you no longer need the information, pass the returned pointer to the LsaFreeMemory function.

Return Values

If the function succeeds, the return value is one of the following NTSTATUS values.

Value | Meaning
STATUS_SOME_NOT_MAPPED | Some of the names could not be translated. This is an informational-level return value.
STATUS_SUCCESS | All of the names were found and successfully translated.

If the function fails, the return value is the following NTSTATUS error code or one of the common LSA return values.

Value | Meaning
STATUS_NONE_MAPPED | None of the names were translated.

Use the LsaNtStatusToWinError function to convert NTSTATUS code to a Win32 error code.

Remarks

The strings in the Names array can be either isolated names (for example, JohnH) or composite names containing both the domain name and account name (for example, Acctg\JohnH). An isolated name may be either an account name (user, group, or local group) or a domain name. Composite names must include a backslash character separating the domain name from the account name.

Translation of isolated names introduces the possibility of name collisions (because the same name may be used in multiple domains). The LsaLookupNames2 function uses the following algorithm to translate isolated names:

  1. If the name is a well-known name, such as Local or Interactive, the function returns the corresponding well-known SID.
  2. If the name is the built-in domain's name, the function returns that domain's SID.
  3. If the name is the account domain's name, the function returns that domain's SID.
  4. If the name is the primary domain's name, the function returns that domain's SID.
  5. If the name is one of the trusted domain's names, the function returns that domain's SID.
  6. If the name is a user, group, or local group account in the built-in domain, the function returns the SID of that account.
  7. If the name is a user, group, or local group account in the account domain on the local system, the function returns the SID of that account.
  8. If the name is a user, group or a local group in the primary domain, the function returns the SID of that account.
  9. After looking in the primary domain, the primary domain looks in each of its trusted domains.
  10. Otherwise, the name is not translated.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.

See Also

LsaFreeMemory, LSA_REFERENCED_DOMAIN_LIST, LSA_TRANSLATED_SID2, LSA_UNICODE_STRING


LsaLookupSids

The LsaLookupSids function looks up the names that correspond to an array of SIDs. If LsaLookupSids cannot find a name corresponding to a SID, the function returns the SID in character form.

NTSTATUS LsaLookupSids(
  LSA_HANDLE PolicyHandle,
  ULONG Count,
  PSID *Sids,
  PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains,
  PLSA_TRANSLATED_NAME *Names
);

Parameters

PolicyHandle
Handle to a Policy object. This handle must have the POLICY_LOOKUP_NAMES access right. For more information, see Opening a Policy Object Handle.
Count
Specifies the number of SIDs in the Sids array. This is also the number of entries returned in the Names array.
Sids
Pointer to an array of SID pointers to look up. The SIDs can be well-known SIDs, user, group, or local group account SIDs, or domain SIDs.
ReferencedDomains
Receives a pointer to an LSA_REFERENCED_DOMAIN_LIST structure. The Domains member of this structure is an array containing an entry for each domain in which a SID was found. The entry for each domain contains the SID and flat name of the domain. For Windows NT domains, the flat name is the NetBIOS name. For links with non–Windows NT domains, the flat name is the identifying name of that domain or it is NULL.

When you no longer need the information, pass the returned pointer to LsaFreeMemory.

Names
Receives a pointer to an array of LSA_TRANSLATED_NAME structures. Each entry in the Names array contains the name information for the corresponding entry in the Sids array. For account SIDs, the Name member of each structure contains the isolated name of the account. For domain SIDs, the Name member is not valid.

The DomainIndex member of each entry in the Names array is the index of an entry in the Domains array returned in the ReferencedDomains parameter. The index identifies the Domains array for the domain in which the SID was found.

When you no longer need the information, pass the returned pointer to LsaFreeMemory.

Return Values

If the function succeeds, the return value is one of the following NTSTATUS values.

Value | Meaning
STATUS_SOME_NOT_MAPPED | Some of the SIDs could not be translated. This is an informational-level return value.
STATUS_SUCCESS | All of the SIDs were found and successfully translated.

If the function fails, the return value is an NTSTATUS code, which can be one of the following values or one of the common LSA return values.

Value | Meaning
STATUS_NONE_MAPPED | None of the SIDs were translated. This is an error-level return value.

You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Remarks

For account SIDs, the string returned in the Name member is the isolated name of the account (for example, JohnH). If you need the composite name of the account (for example, Acctg\JohnH), get the domain name from the ReferencedDomains buffer and append a backslash and the isolated name.

If the LsaLookupNames function cannot translate a SID, the function uses the following algorithm:

  1. If the SID's domain is known, the ReferencedDomains buffer contains an entry for the domain and the string returned in the Names parameter is a Unicode representation of the account's relative identifier (RID) from the SID.
  2. If the SID's domain is not known, the string returned in the Names parameter is a Unicode representation of the entire SID and there is no domain record for this SID in the ReferencedDomains buffer.

Windows 2000: In addition to looking up SIDs for local accounts, local domain accounts, and explicitly trusted domain accounts, LsaLookupSids can look up SIDs for any account in any domain in the Windows 2000 forest, including SIDs that appear only in the SIDhistory field of an account in the forest. The SIDhistory field stores the former SID(s) of an account that has been moved from another domain. To perform these look ups, the function queries the global catalog of the forest. However, these look ups require that the computer from which LsaLookupSids is called be either running Windows 2000 or in a domain running in Windows 2000 native mode. Account lookup by SIDhistory is not possible if the calling computer is a Windows NT 4.0 system in either a Windows NT 4.0 domain or a mixed-mode Windows 2000 domain.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.

See Also

LSA_REFERENCED_DOMAIN_LIST, LSA_TRANSLATED_NAME, LsaOpenPolicy


LsaOpenPolicy

The LsaOpenPolicy function opens a handle to the Policy object on a local or remote system.

NTSTATUS LsaOpenPolicy(
  PLSA_UNICODE_STRING SystemName,
  PLSA_OBJECT_ATTRIBUTES ObjectAttributes,
  ACCESS_MASK DesiredAccess,
  PLSA_HANDLE PolicyHandle
);

Parameters

SystemName
Pointer to an LSA_UNICODE_STRING structure containing the name of the target system. The name can have the form "machinename" or "\\machinename". If this parameter is NULL, the function opens the Policy object on the local system.
ObjectAttributes
Pointer to an LSA_OBJECT_ATTRIBUTES structure that specifies the connection attributes. The structure members are not used; initialize them to NULL or zero.
DesiredAccess
An access mask that specifies the requested access rights. The function fails if the DACL of the target system does not allow the caller the requested access. To determine the access rights that you need, see the documentation for the LSA functions with which you want to use the policy handle.
PolicyHandle
Pointer to an LSA_HANDLE variable that receives a handle to the Policy object.

When you no longer need this handle, pass it to the LsaClose function to close it.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code. For more information, see Common LSA Return Values.

You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Remarks

To administer the local security policy of a local or remote system, you must call the LsaOpenPolicy function to establish a session with that system's LSA subsystem. LsaOpenPolicy connects to the LSA of the target system and returns a handle to the Policy object of that system. You can use this handle in subsequent LSA function calls to administer the local security policy information of the target system.

For an example that demonstrates calling this function see Opening a Policy Object Handle.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.

See Also

LSA_HANDLE, LSA_OBJECT_ATTRIBUTES, LSA_UNICODE_STRING, LsaClose, LsaNtStatusToWinError


LsaQueryInformationPolicy

The LsaQueryInformationPolicy function retrieves information about a Policy object.

NTSTATUS LsaQueryInformationPolicy(
  LSA_HANDLE PolicyHandle,
  POLICY_INFORMATION_CLASS InformationClass,
  PVOID *Buffer
);

Parameters

PolicyHandle
Handle to a Policy object. The required access rights for this handle depend on the value of the InformationClass parameter. For more information, see Opening a Policy Object Handle.
InformationClass
Specifies one of the following values from the POLICY_INFORMATION_CLASS enumeration type. The value indicates the type of information to retrieve.
Information Level | Required Access Type
PolicyAuditEventsInformation | Retrieves the system's auditing rules. The handle passed in the PolicyHandle parameter must have the POLICY_VIEW_AUDIT_REQUIREMENTS access right. The Buffer parameter receives a pointer to a POLICY_AUDIT_EVENTS_INFO structure.
PolicyPrimaryDomainInformation | Retrieves the name and SID of the system's primary domain. The handle passed in the PolicyHandle parameter must have the POLICY_VIEW_LOCAL_INFORMATION access right. The Buffer parameter receives a pointer to a POLICY_PRIMARY_DOMAIN_INFO structure.
PolicyAccountDomainInformation | Retrieves the name and SID of the system's account domain. The handle passed in the PolicyHandle parameter must have the POLICY_VIEW_LOCAL_INFORMATION access right. The Buffer parameter receives a pointer to a POLICY_ACCOUNT_DOMAIN_INFO structure.
PolicyLsaServerRoleInformation | Retrieves the role of an LSA server. The handle passed in the PolicyHandle parameter must have the POLICY_VIEW_LOCAL_INFORMATION access right. The Buffer parameter receives a pointer to a POLICY_LSA_SERVER_ROLE_INFO structure.
PolicyModificationInformation | Retrieves information about the creation time and last modification of the LSA database. The handle passed in the PolicyHandle parameter must have the POLICY_VIEW_LOCAL_INFORMATION access right. The Buffer parameter receives a pointer to a POLICY_MODIFICATION_INFO structure.
PolicyDnsDomainInformation | Retrieves the Domain Name System (DNS) information about the primary domain associated with the Policy object. The handle passed in the PolicyHandle parameter must have the POLICY_VIEW_LOCAL_INFORMATION access right. The Buffer parameter receives a pointer to a POLICY_DNS_DOMAIN_INFO structure.

Buffer
Pointer to a variable that receives a pointer to a structure containing the requested information. The type of structure depends on the value of the InformationClass parameter.

When you no longer need the information, pass the returned pointer to LsaFreeMemory.

Return Values

If the LsaQueryInformationPolicy function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code. For more information, see Common LSA Return Values.

You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Remarks

For an example that demonstrates calling this function see Managing Policy Information..

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.

See Also

LsaFreeMemory, LsaSetInformationPolicy, POLICY_ACCOUNT_DOMAIN_INFO, POLICY_AUDIT_EVENTS_INFO, POLICY_DNS_DOMAIN_INFO, POLICY_INFORMATION_CLASS, POLICY_LSA_SERVER_ROLE_INFO, POLICY_MODIFICATION_INFO, POLICY_PRIMARY_DOMAIN_INFO


LsaRegisterPolicyChangeNotification

The LsaRegisterPolicyChangeNotification function registers an event handle with the local security authority (LSA). This event handle is signaled whenever the indicated LSA policy is modified.

NTSTATUS LsaRegisterPolicyChangeNotification(
  POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass,
  HANDLE NotificationEventHandle
);

Parameters

InformationClass
A POLICY_NOTIFICATION_INFORMATION_CLASS value that specifies the type of policy changes about which your application will be notified. Specify one of the following values.
Information class | Description
PolicyNotifyAuditEventsInformation | Auditing policy changes.
PolicyNotifyAccountDomainInformation | Account domain information changes.
PolicyNotifyServerRoleInformation | Server role changes.
PolicyNotifyDomainEfsInformation | EFS policy information changes.
PolicyNotifyDomainKerberosTicketInformation | Kerberos ticket policy information changes.
PolicyNotifyDnsDomainInformation | Domain Name System (DNS) information, name, or SID of the system's primary domain changes.

NotificationEventHandle
Handle to an event obtained by calling the CreateEvent function. The event can be either named or unnamed.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code. For more information, see Common LSA Return Values.

You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Remarks

For an example that demonstrates calling this function, see Receiving Policy Change Events.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.
Library: Use Secur32.lib.

See Also

LsaUnregisterPolicyChangeNotification


LsaSetInformationPolicy

The LsaSetInformationPolicy function modifies information in a Policy object.

NTSTATUS LsaSetInformationPolicy(
  LSA_HANDLE PolicyHandle,
  POLICY_INFORMATION_CLASS InformationClass,
  PVOID Buffer
);

Parameters

PolicyHandle
Handle to a Policy object. The required access rights for this handle depend on the value of the InformationClass parameter. For more information, see Opening a Policy Object Handle.
InformationClass
Specifies one of the following values from the POLICY_INFORMATION_CLASS enumeration type. The value indicates the type of information to set.
Information Level | Required Access Type
PolicyAuditEventsInformation | Sets the system's auditing rules. The handle passed in the PolicyHandle parameter must have the POLICY_SET_AUDIT_REQUIREMENTS access right. The Buffer parameter must be a pointer to a POLICY_AUDIT_EVENTS_INFO structure.
PolicyPrimaryDomainInformation | Sets the name and SID of the system's primary domain. The handle passed in the PolicyHandle parameter must have the POLICY_TRUST_ADMIN access right. The Buffer parameter must be a pointer to a POLICY_PRIMARY_DOMAIN_INFO structure.
PolicyAccountDomainInformation | Sets the name and SID of the system's account domain. The handle passed in the PolicyHandle parameter must have the POLICY_TRUST_ADMIN access right. The Buffer parameter must be a pointer to a POLICY_ACCOUNT_DOMAIN_INFO structure.
PolicyDnsDomainInformation | Sets Domain Name System (DNS) information about the primary domain associated with the Policy object. The handle passed in the PolicyHandle parameter must have the POLICY_TRUST_ADMIN access right. The Buffer parameter must be a pointer to a POLICY_DNS_DOMAIN_INFO structure.
PolicyLsaServerRoleInformation Sets the role of an LSA server. The handle passed in the PolicyHandle parameter must have the POLICY_SERVER_ADMIN access right. The Buffer parameter must be a pointer to a POLICY_LSA_SERVER_ROLE_INFO structure.

Windows 2000:
Changing a server's role from primary to backup has no effect (although the function returns STATUS_SUCCESS). Changing a server's role from backup to primary requires extensive network operations, and may be slow.

Buffer
Pointer to a structure containing the information to set. The type of structure depends on the value of the InformationClass parameter.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code. For more information, see Common LSA Return Values.

You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.

See Also

POLICY_ACCOUNT_DOMAIN_INFO, POLICY_AUDIT_EVENTS_INFO, POLICY_DNS_DOMAIN_INFO, POLICY_LSA_SERVER_ROLE_INFO, POLICY_PRIMARY_DOMAIN_INFO


LsaUnregisterPolicyChangeNotification

The LsaUnregisterPolicyChangeNotification function disables a previously registered notification event.

NTSTATUS LsaUnregisterPolicyChangeNotification(
  POLICY_NOTIFICATION_INFORMATION_CLASS InformationClass,
  HANDLE NotificationEventHandle
);

Parameters

InformationClass
Specifies the policy changes that your application will stop receiving notifications for. Specify one of the following values.
Information class | Event description
PolicyNotifyAuditEventsInformation | Auditing policy changes.
PolicyNotifyAccountDomainInformation | Account domain information changes.
PolicyNotifyServerRoleInformation | Server role changes.
PolicyNotifyDomainEfsInformation | EFS policy information changes.
PolicyNotifyDomainKerberosTicketInformation | Kerberos ticket policy information changes.
PolicyNotifyDnsDomainInformation | Domain Name System (DNS) information, name, or SID of the system's primary domain changes.

NotificationEventHandle
Handle to the notification event to unregister.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code. For more information, see Common LSA Return Values.

You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Remarks

For an example that demonstrates calling this function see Receiving Policy Change Events.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.
Library: Use Secur32.lib.

See Also

LsaRegisterPolicyChangeNotification


Account Functions

You can use the following functions to add, enumerate, and delete permissions for an account.

Function | Description
LsaAddAccountRights | Add permissions to an account. If the account does not already exist, it is created.
LsaEnumerateAccountRights | Enumerate the permissions granted to an account.
LsaRemoveAccountRights | Remove permissions from an account. When all the permissions are removed, the account is deleted.


LsaAddAccountRights

The LsaAddAccountRights function assigns one or more privileges to an account. If the account does not exist, LsaAddAccountRights creates it.

NTSTATUS LsaAddAccountRights(
  LSA_HANDLE PolicyHandle,
  PSID AccountSid,
  PLSA_UNICODE_STRING UserRights,
  ULONG CountOfRights
);

Parameters

PolicyHandle
Handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. If the account identified by the AccountSid parameter does not exist, the handle must have the POLICY_CREATE_ACCOUNT access right. For more information, see Opening a Policy Object Handle.
AccountSid
Pointer to the SID of the account to which the function assigns privileges.
UserRights
Pointer to an array of LSA_UNICODE_STRING structures. Each structure contains the name of a privilege to add to the account. For a list of privilege names, see Windows NT Privileges.
CountOfRights
Specifies the number of elements in the UserRights array.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code, which can be the following value or one of the common LSA return values.

Value | Meaning
STATUS_NO_SUCH_PRIVILEGE | One of the privilege names is invalid.

You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Remarks

If you specify privileges already granted to the account, they are ignored.

For an example that demonstrates calling this function, see Managing Account Permissions.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.

See Also

LsaEnumerateAccountRights, LsaRemoveAccountRights, LSA_UNICODE_STRING


LsaEnumerateAccountRights

The LsaEnumerateAccountRights function enumerates the privileges assigned to an account.

NTSTATUS LsaEnumerateAccountRights(
  LSA_HANDLE PolicyHandle,
  PSID AccountSid,
  PLSA_UNICODE_STRING *UserRights,
  PULONG CountOfRights
);

Parameters

PolicyHandle
Handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. For more information, see Opening a Policy Object Handle.
AccountSid
Pointer to the SID of the account for which to enumerate privileges.
UserRights
Receives a pointer to an array of LSA_UNICODE_STRING structures. Each structure contains the name of a privilege held by the account. For a list of privilege names, see Windows NT Privileges.

When you no longer need the information, pass the returned pointer to LsaFreeMemory.

CountOfRights
Pointer to a variable that receives the number of privileges in the UserRights array.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code. For more information, see Common LSA Return Values.

You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.

See Also

LsaAddAccountRights, LsaFreeMemory, LsaRemoveAccountRights, LSA_UNICODE_STRING


LsaRemoveAccountRights

The LsaRemoveAccountRights function removes one or more privileges from an account. You can specify the privileges to be removed, or you can set a flag to remove all privileges. When you remove all privileges, the function deletes the account. If you specify privileges not held by the account, the function ignores them.

NTSTATUS LsaRemoveAccountRights(
  LSA_HANDLE PolicyHandle,
  PSID AccountSid,
  BOOLEAN AllRights,
  PLSA_UNICODE_STRING UserRights,
  ULONG CountOfRights
);

Parameters

PolicyHandle
Handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. For more information, see Opening a Policy Object Handle.
AccountSid
Pointer to the security identifier (SID) of the account from which the privileges are removed.
AllRights
If TRUE, the function removes all privileges and deletes the account. In this case, the function ignores the UserRights parameter. If FALSE, the function removes the privileges specified by the UserRights parameter.
UserRights
Pointer to an array of LSA_UNICODE_STRING structures. Each structure contains the name of a privilege to be removed from the account. For a list of privilege names, see Windows NT Privileges.
CountOfRights
Specifies the number of elements in the UserRights array.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code, which can be one of the following values or one of the common LSA return values.

Value | Meaning
STATUS_NO_SUCH_PRIVILEGE | One of the privilege names is invalid.
STATUS_INVALID_PARAMETER | Indicates the UserRights parameter was NULL and the AllRights parameter was FALSE.

You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.

See Also

LsaAddAccountRights, LsaEnumerateAccountRights, LSA_UNICODE_STRING


Trusted Domain Functions

You can use the following functions to create, enumerate, and delete trusted domains and to set and retrieve trusted domain information.

Function | Description
LsaCreateTrustedDomainEx | Creates a new TrustedDomain object.
LsaDeleteTrustedDomain | Removes a TrustedDomain object.
LsaEnumerateTrustedDomains | Enumerates the domains currently trusted by the local system.
LsaEnumerateTrustedDomainsEx | Enumerates the domains currently trusted by the local system.
LsaOpenTrustedDomainByName | Opens a handle to a TrustedDomain object.
LsaQueryTrustedDomainInfo | Retrieves information about a trusted domain. The domain is specified by SID.
LsaQueryTrustedDomainInfoByName | Retrieves information about a trusted domain. The domain is specified by name.
LsaSetTrustedDomainInfoByName | Sets information for a trusted domain. The domain is specified by name.
LsaSetTrustedDomainInformation | Sets information for a trusted domain. The domain is specified by SID.


LsaCreateTrustedDomainEx

The LsaCreateTrustedDomainEx function establishes a new trusted domain by creating a new TrustedDomain object.

NTSTATUS LsaCreateTrustedDomainEx(
  LSA_HANDLE PolicyHandle,
  PTRUSTED_DOMAIN_INFORMATION_EX TrustedDomainInformation,
  PTRUSTED_DOMAIN_AUTH_INFORMATION AuthenticationInformation,
  ACCESS_MASK DesiredAccess,
  PLSA_HANDLE TrustedDomainHandle
);

Parameters

PolicyHandle
Handle to a Policy object. Prior to Windows 2000, this handle had to have the POLICY_TRUST_ADMIN access right. Beginning with Windows 2000, this right is no longer required. The security descriptor of the trusted domain determines whether or not the object is created. For information on policy object handles, see Opening a Policy Object Handle.
TrustedDomainInformation
Pointer to a TRUSTED_DOMAIN_INFORMATION_EX structure containing the name and SID of the new trusted domain.
AuthenticationInformation
Pointer to a TRUSTED_DOMAIN_AUTH_INFORMATION structure containing authentication information for the new trusted domain.
DesiredAccess
An ACCESS_MASK structure that specifies the accesses to be granted for the new trusted domain.
TrustedDomainHandle
Receives the LSA policy handle of the remote trusted domain. You can pass this handle into LSA function calls in order to manage the LSA policy of the trusted domain.

When your application no longer needs this handle, it should call LsaClose to delete the handle.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code, which can be one of the following values or one of the common LSA return values.

Error code | Description
STATUS_DIRECTORY_SERVICE_REQUIRED | Windows 2000: The target system (specified in the TrustedDomainInformation parameter) for the TrustedDomain object is not a domain controller.
STATUS_INVALID_SID | The specified SID is not valid.
STATUS_UNSUCCESSFUL | Unable to determine whether the target system is a domain controller.

You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Remarks

LsaCreateTrustedDomainEx does not check whether the specified domain name matches the specified SID, or that the SID and name represent an actual domain.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.

See Also

LsaSetTrustedDomainInformation, LsaSetTrustedDomainInfoByName, LsaDeleteTrustedDomain, LsaClose,TRUSTED_DOMAIN_AUTH_INFORMATION, TRUSTED_DOMAIN_INFORMATION_EX


LsaDeleteTrustedDomain

The LsaDeleteTrustedDomain function removes a trusted domain from the list of trusted domains for a system and deletes the associated TrustedDomain object.

NTSTATUS LsaDeleteTrustedDomain(
  LSA_HANDLE PolicyHandle,
  PSID TrustedDomainSid
);

Parameters

PolicyHandle
Handle to a Policy object. For more information, see Opening a Policy Object Handle.
TrustedDomainSid
Pointer to the SID of the trusted domain to be removed.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code. For more information, see Common LSA Return Values.

You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.

See Also

LsaQueryTrustedDomainInfo, LsaSetTrustedDomainInformation


LsaEnumerateTrustedDomains

The LsaEnumerateTrustedDomains function retrieves the names and SIDs of domains trusted to authenticate logon credentials. LsaEnumerateTrustedDomains is intended for use on systems running Windows NT, 4.0 or earlier versions of Windows NT. Use DsEnumerateDomainTrusts for any other trust enumeration purpose. Specifically, LsaEnumerateTrustedDomains can only be used if one or more of the following is true:

  • The calling system is running Windows NT 4.0 or an earlier version of Windows NT.
  • The target system (specified using the PolicyHandle parameter), is a domain controller running Windows NT 4.0 or an earlier version.
  • The calling system is running Windows NT 4.0 or earlier version and is not a domain controller, and the target system is a domain controller in the calling system's domain. The target system can be running any version of Windows NT, including Windows 2000.
NTSTATUS LsaEnumerateTrustedDomains(
  LSA_HANDLE PolicyHandle,
  PLSA_ENUMERATION_HANDLE EnumerationContext,
  PVOID *Buffer,
  ULONG PreferedMaximumLength,
  PULONG CountReturned
);

Parameters

PolicyHandle
Handle to a Policy object. The handle must have the POLICY_VIEW_LOCAL_INFORMATION access right. For more information, see Opening a Policy Object Handle.
EnumerationContext
Pointer to an enumeration handle that enables you to make multiple calls to enumerate all the trusted domains. On the first call to LsaEnumerateTrustedDomains, EnumerationContext must point to a variable that has been initialized to zero. On subsequent calls to LsaEnumerateTrustedDomains, EnumerationContext must point to the enumeration handle returned by the previous call.
Buffer
Receives a pointer to an array of LSA_TRUST_INFORMATION structures that contain the names and SIDs of one or more trusted domains.

When you no longer need the information, pass the returned pointer to LsaFreeMemory.

PreferedMaximumLength
Specifies the preferred maximum size, in bytes, of the returned buffer. This information is approximate; the actual number of bytes returned may be greater than this value.
CountReturned
Pointer to a variable that receives the number of elements returned in the Buffer parameter.

Return Values

If the function is successful, the return value is one of the following NTSTATUS values.

Value | Meaning
STATUS_SUCCESS | The enumeration has been successfully completed.
STATUS_MORE_ENTRIES | The call was successful, but there are more trusted domains to be enumerated. Call LsaEnumerateTrustedDomains again, passing the value returned in the EnumerationContext parameter.
STATUS_NO_MORE_ENTRIES | There are no more trusted domains to enumerate.

If the function fails, the return value is an NTSTATUS code. For more information, see Common LSA Return Values.

You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Remarks

For domains with domain controllers running only Windows NT 4.0 or earlier versions of Windows NT, LsaEnumerateTrustedDomains returns a list of all trusted domains. In releases of Windows NT up to and including release 4.0, all trusted domains are directly trusted.

In Windows 2000 mixed-mode domains, domain controllers may be running Windows NT or Windows 2000. Therefore, in mixed-mode domains, some trusted domains are directly trusted and others are indirectly trusted. When enumerating the trusted domains of a system in a mixed-mode domain, LsaEnumerateTrustedDomains returns only directly trusted domains.

In contrast, Windows 2000 native-mode domains contain only Windows_2000 domain controllers, even though there may be members in the domain running Windows NT 4.0 or earlier versions. When enumerating the trusted domains of a system in a native-mode Windows 2000 domain, LsaEnumerateTrustedDomains returns both directly trusted and indirectly trusted domains.

Retrieving all trust information may require more than a single LsaEnumerateTrustedDomains call. You can use the EnumerationContext parameter to make multiple calls, as follows: On the first call, set the variable pointed to by EnumerationContext to zero. If LsaEnumerateTrustedDomains returns STATUS_SUCCESS or STATUS_MORE_ENTRIES, call the function again, passing in the EnumerationContext value returned by the previous call. The enumeration is complete when the function returns STATUS_NO_MORE_ENTRIES.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.

See Also

LSA_TRUST_INFORMATION, LsaOpenPolicy, LsaEnumerateTrustedDomainsEx, LsaFreeMemory, LSA_TRUST_INFORMATION


LsaEnumerateTrustedDomainsEx

The LsaEnumerateTrustedDomainsEx function returns information about the domains trusted by the local system. This function returns more information than LsaEnumerateTrustedDomains. LsaEnumerateTrustedDomainsEx returns information only on direct trusts. DsEnumerateDomainTrusts is recommended for more complete trust enumeration purposes.

NTSTATUS LsaEnumerateTrustedDomainsEx(
  LSA_HANDLE PolicyHandle,
  PLSA_ENUMERATION_HANDLE EnumerationContext,
  PVOID *Buffer,
  ULONG PreferredMaximumLength,
  PULONG CountReturned
);

Parameters

PolicyHandle
Handle to a Policy object. This call requires POLICY_VIEW_LOCAL_INFORMATION access to the Policy object. For more information, see Opening a Policy Object Handle.
EnumerationContext
A pointer to an LSA_ENUMERATION_HANDLE that you can use to make multiple calls to LsaEnumerateTrustedDomainsEx in order to retrieve all of the trusted domain information. For more information, see the Remarks section at the end of this topic.
Buffer
Pointer to a buffer that receives a list of TRUSTED_DOMAIN_INFORMATION_EX structures that contain information about the enumerated trusted domains.

Your application should free this buffer when it is no longer needed by calling LsaFreeMemory.

PreferredMaximumLength
Preferred maximum length of returned data, in bytes. This is not a hard upper limit, but serves as a guide. Due to data conversion between systems with different natural data sizes, the actual amount of data returned may be greater than this value.
CountReturned
Pointer to a LONG that receives the number of trusted domain objects returned.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code, which can be one of the following values or one of the common LSA return values.

Error code | Description
STATUS_ACCESS_DENIED | Caller does not have the appropriate access to complete the operation.
STATUS_NO_MORE_ENTRIES | There are no more entries. This warning is returned if no objects have been enumerated because the EnumerationContext value is too high.

You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Remarks

Retrieving all trust information may require more than a single LsaEnumerateTrustedDomainsEx call. You can use the EnumerationContext parameter to make multiple calls, as follows: On the first call, set the variable pointed to by EnumerationContext to zero. If LsaEnumerateTrustedDomainsEx returns STATUS_SUCCESS or STATUS_MORE_ENTRIES, call the function again, passing in the EnumerationContext value returned by the previous call. The enumeration is complete when the function returns STATUS_NO_MORE_ENTRIES.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.

See Also

LsaEnumerateTrustedDomains, LSA_ENUMERATION_HANDLE, LsaFreeMemory, TRUSTED_DOMAIN_INFORMATION_EX


LsaOpenTrustedDomainByName

The LsaOpenTrustedDomainByName function opens the LSA policy handle of a remote trusted domain. You can pass this handle into LSA function calls in order to set or query the LSA policy of the remote machine.

NTSTATUS LsaOpenTrustedDomainByName(
  LSA_HANDLE PolicyHandle,
  PLSA_UNICODE_STRING TrustedDomainName,
  ACCESS_MASK DesiredAccess,
  PLSA_HANDLE TrustedDomainHandle
);

Parameters

PolicyHandle
Handle to a Policy object. This is the policy handle of the local machine. For more information, see Opening a Policy Object Handle.
TrustedDomainName
Name of the trusted domain. This name can be either the flat name, or the Domain Name System (DNS) domain name.
DesiredAccess
An ACCESS_MASK structure that specifies the access permissions requested on the remote trusted domain object.
TrustedDomainHandle
Pointer that receives the address of the LSA policy handle of the remote trusted domain. You can pass this handle into LSA function calls in order to query and manage the LSA policy of the remote machine.

When your application no longer needs this handle, it should call LsaClose to delete the handle.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code, which can be one of the following values or one of the common LSA return values.

Error Code | Description
STATUS_ACCESS_DENIED | Caller does not have the appropriate access to complete the operation.
STATUS_TRUSTED_DOMAIN_NOT_FOUND | There is no Trusted Domain object in the target system's LSA Database having the specified name.

You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.

See Also

LsaClose


LsaQueryTrustedDomainInfo

The LsaQueryTrustedDomainInfo function retrieves information about a trusted domain.

NTSTATUS LsaQueryTrustedDomainInfo(
  LSA_HANDLE PolicyHandle,
  PSID TrustedDomainSid,
  TRUSTED_INFORMATION_CLASS InformationClass,
  PVOID *Buffer
);

Parameters

PolicyHandle
Handle to the Policy object of a domain controller that has a trust relationship with the domain identified by the TrustedDomainSid parameter. The handle must have the POLICY_VIEW_LOCAL_INFORMATION access right. For more information, see Opening a Policy Object Handle.
TrustedDomainSid
Pointer to the SID of the trusted domain to query.
InformationClass
Specifies one of the following values from the TRUSTED_INFORMATION_CLASS enumeration type. The value indicates the type of information being requested.
Value | Description
TrustedDomainNameInformation | Retrieves the name of the trusted domain. The Buffer parameter receives a pointer to a TRUSTED_DOMAIN_NAME_INFO structure.
TrustedPosixOffsetInformation | Retrieves the value used to generate Posix user and group identifiers for the trusted domain. The Buffer parameter receives a pointer to a TRUSTED_POSIX_OFFSET_INFO structure.
TrustedPasswordInformation | Retrieves the password for the trusted domain The Buffer parameter receives a pointer to a TRUSTED_PASSWORD_INFO structure. The handle passed in the PolicyHandle parameter must have the POLICY_GET_PRIVATE_INFORMATION access right.
TrustedDomainInformationEx | Retrieves extended information for the trusted domain. The Buffer parameter receives a pointer to a TRUSTED_DOMAIN_INFORMATION_EX structure.
TrustedDomainInformationBasic Retrieves the name and SID for the trusted domain. The Buffer parameter receives a pointer to a TRUSTED_DOMAIN_INFORMATION_BASIC structure.

Not supported as of Windows 2000.

TrustedDomainFullInformation | Retrieves complete information for the trusted domain. This information includes the Posix offset information, authentication information, and the extended information returned for the TrustedDomainInformationEx value. The Buffer parameter receives a pointer to a TRUSTED_DOMAIN_FULL_INFORMATION structure.

Buffer
Pointer to a buffer that receives a pointer to a structure containing the requested information. The type of structure depends on the value of the InformationClass parameter.

When you no longer need the information, pass the returned pointer to LsaFreeMemory.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code. For more information, see Common LSA Return Values.

You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.

See Also

LsaSetTrustedDomainInformation, POLICY_ACCOUNT_DOMAIN_INFO, POLICY_AUDIT_EVENTS_INFO, POLICY_DNS_DOMAIN_INFO, POLICY_LSA_SERVER_ROLE_INFO, POLICY_MODIFICATION_INFO, POLICY_PRIMARY_DOMAIN_INFO, TRUSTED_INFORMATION_CLASS


LsaQueryTrustedDomainInfoByName

The LsaQueryTrustedDomainInfoByName function returns information about a trusted domain.

NTSTATUS LsaQueryTrustedDomainInfoByName(
  LSA_HANDLE PolicyHandle,
  PLSA_UNICODE_STRING TrustedDomainName,
  TRUSTED_INFORMATION_CLASS InformationClass,
  PVOID *Buffer
);

Parameters

PolicyHandle
Handle to a Policy object. This handle must have the POLICY_VIEW_LOCAL_INFORMATION access right. For more information, see Opening a Policy Object Handle.
TrustedDomainName
String that contains the name of the trusted domain. This can either be the domain name or the flat name.
InformationClass
Specifies the type of information to retrieve. The information classes are specified in the following table.
Information class | Description
TrustedDomainNameInformation | Name of the trusted domain.
TrustedPosixInformation | Posix offset of the trusted domain.
TrustedPasswordInformation | Returns the password on the outbound side of the trust.
TrustedDomainInformationBasic Basic trust information, including only the domain name and domain SID.

Not supported as of Windows 2000.
TrustedDomainInformationEx | Extended trust information, including the basic information and DNS domain name, and attributes about the trust.
TrustedDomainFullInformation | Full information, including the Posix offset and the authentication information.

Buffer
Receives a pointer to the returned buffer containing the requested information. The format and content of this buffer depend on the information class. For example, if InformationClass is set to TrustedDomainInformationEx, Buffer receives a pointer to a TRUSTED_DOMAIN_INFORMATION_EX structure. For more information, see TRUSTED_INFORMATION_CLASS.

Your application should free this buffer using LsaFreeMemory when the buffer is no longer needed.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code, which can be one of the following values or one of the common LSA return values.

Error code | Description
STATUS_ACCESS_DENIED | Caller does not have the appropriate access to complete the operation. For a list of the required access types, see the description of the InformationClass parameter.
STATUS_INSUFFICIENT_ RESOURCES | Insufficient system resources, such as memory, to complete the call.

You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.

See Also

LsaFreeMemory, LsaQueryTrustedDomainInfo, LsaSetTrustedDomainInfoByName, TRUSTED_DOMAIN_INFORMATION_EX, TRUSTED_INFORMATION_CLASS


LsaSetTrustedDomainInfoByName

The LsaSetTrustedDomainInfoByName function sets values for a TrustedDomain object.

NTSTATUS LsaSetTrustedDomainInfoByName(
  LSA_HANDLE PolicyHandle,
  PLSA_UNICODE_STRING TrustedDomainName,
  TRUSTED_INFORMATION_CLASS InformationClass,
  PVOID Buffer
);

Parameters

PolicyHandle
Handle to a Policy object. Prior to Windows 2000, this handle had to have the POLICY_TRUST_ADMIN access right. Beginning with Windows 2000, this right is no longer required. The security descriptor of the trusted domain determines whether or not the caller's changes are accepted. For information on policy object handles, see Opening a Policy Object Handle.
TrustedDomainName
Name of the trusted domain to set values for. This can either be the domain name or the flat name.
InformationClass
Specifies the type of information to set. Specify one of the following values.
Information class | Description
TrustedPosixInformation | Posix offset of the trusted domain.
TrustedDomainInformationEx | Extended trust information, including the basic information and DNS domain name, and attributes about the trust.
TrustedDomainAuthInformation | Authentication information for the trust, including authentication information for both the inbound and outbound side of the trust (if it exists).
TrustedDomainFullInformation | Full information, including the Posix offset and the authentication information.

Buffer
Receives a pointer to the returned buffer containing the requested information. The format and content of this buffer depend on the value of the InformationClass parameter. For example, if InformationClass is set to TrustedDomainInformationEx, then Buffer receives a pointer to a TRUSTED_DOMAIN_INFORMATION_EX structure. For more information, see TRUSTED_INFORMATION_CLASS.

Your application should free this buffer using LsaFreeMemory when the buffer is no longer needed.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code. For more information, see Common LSA Return Values.

You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.

See Also

LsaQueryTrustedDomainInfoByName, TRUSTED_DOMAIN_INFORMATION_EX, TRUSTED_INFORMATION_CLASS


LsaSetTrustedDomainInformation

The LsaSetTrustedDomainInformation function modifies a Policy object's information about a trusted domain.

NTSTATUS LsaSetTrustedDomainInformation(
  LSA_HANDLE PolicyHandle,
  PSID TrustedDomainSid,
  TRUSTED_INFORMATION_CLASS InformationClass,
  PVOID Buffer
);

Parameters

PolicyHandle
Handle to the Policy object of a domain controller. The required access rights for this handle depend on the value of the InformationClass parameter. For more information, see Opening a Policy Object Handle.
TrustedDomainSid
Pointer to the SID of the trusted domain whose information is modified. If the InformationClass parameter is set to TrustedDomainNameInformation, this parameter must point to the SID of the domain to add to the list of trusted domains.
InformationClass
Specifies one of the following values from the TRUSTED_INFORMATION_CLASS enumeration type. The value indicates the type of information being requested.
Value | Description
TrustedDomainNameInformation If the specified domain is not in the list of trusted domains, the LsaSetTrustedDomainInformation function adds it. The TrustedDomainSid parameter must be the SID of the domain to add. The Buffer parameter must be a pointer to a TRUSTED_DOMAIN_NAME_INFO structure containing the name of the domain to add. Prior to Windows 2000, The handle passed in the PolicyHandle parameter needed to have the POLICY_TRUST_ADMIN access right.

If the specified domain is already in the list of trusted domains, the function fails.
TrustedPosixOffsetInformation | Sets the value used to generate Posix user and group identifiers. The Buffer parameter must be a pointer to a TRUSTED_POSIX_OFFSET_INFO structure.
TrustedPasswordInformation | Sets the password for the trusted domain. The Buffer parameter must be a pointer to a TRUSTED_PASSWORD_INFO structure containing the old and new passwords for the specified domain. The handle passed in the PolicyHandle parameter must have the POLICY_CREATE_SECRET access right. The old password string can be NULL.

Buffer
Pointer to a structure containing the information to set. The type of structure depends on the value of the InformationClass parameter.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code. For more information, see Common LSA Return Values.

You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.

See Also

LsaDeleteTrustedDomain, LsaQueryTrustedDomainInfo, LsaSetTrustedDomainInformation, TRUSTED_DOMAIN_NAME_INFO, TRUSTED_INFORMATION_CLASS, TRUSTED_PASSWORD_INFO, TRUSTED_POSIX_OFFSET_INFO


Private Data Functions

You can use the following functions to store and retrieve encrypted private data strings. These functions are typically used to store server passwords.

Function | Description
LsaRetrievePrivateData | Retrieves and decrypts a string.
LsaStorePrivateData | Encrypts and stores a string.


LsaRetrievePrivateData

The LsaRetrievePrivateData function retrieves private data that was stored by the LsaStorePrivateData function.

NTSTATUS LsaRetrievePrivateData(
  LSA_HANDLE PolicyHandle,
  PLSA_UNICODE_STRING KeyName,
  PLSA_UNICODE_STRING *PrivateData
);

Parameters

PolicyHandle
Handle to a Policy object. The handle must have the POLICY_GET_PRIVATE_INFORMATION access right. For more information, see Opening a Policy Object Handle.
KeyName
Pointer to an LSA_UNICODE_STRING structure containing the name of the key under which the private data is stored.

To create a specialized object, add a prefix to the key name: "L$" for local objects, "G$" for global objects, and "M$" for machine objects. If you are not creating one of these specialized types, you do not need to specify a key name prefix. For more information, see Private Data Object.

PrivateData
Pointer to a variable that receives a pointer to an LSA_UNICODE_STRING structure containing the private data.

When you no longer need the information, pass the returned pointer to LsaFreeMemory.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code, which can be the following value or one of the common LSA return values.

Value | Meaning
STATUS_OBJECT_NAME_NOT_FOUND | No private data is stored under the name specified by the KeyName parameter.

You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.

See Also

LsaFreeMemory, LsaStorePrivateData, LSA_UNICODE_STRING


LsaStorePrivateData

The LsaStorePrivateData function stores or deletes a Policy object's private data under a specified registry key.

NTSTATUS LsaStorePrivateData(
  LSA_HANDLE PolicyHandle,
  PLSA_UNICODE_STRING KeyName,
  PLSA_UNICODE_STRING PrivateData
);

Parameters

PolicyHandle
Handle to a Policy object. The handle must have the POLICY_CREATE_SECRET access right if this is the first time data is being stored under the key specified by the KeyName parameter. For more information, see Opening a Policy Object Handle.
KeyName
Pointer to an LSA_UNICODE_STRING structure containing the name of the key under which the private data is stored.
PrivateData
Pointer to an LSA_UNICODE_STRING structure containing the private data to store. The function encrypts this data before storing it.

If this parameter is NULL, the function deletes any private data stored under the key and deletes the key. Subsequent attempts to retrieve data from the key will return the STATUS_OBJECT_NAME_NOT_FOUND error code.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code. For more information, see Common LSA Return Values.

You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Remarks

The LsaStorePrivateData function can be used by server applications to store client and machine passwords.

As described in Private Data Object, private data objects include three specialized types: local, global, and machine. Specialized objects are identified by a prefix in the key name: "L$" for local objects, "G$" for global objects, and "M$" for machine objects. Local objects cannot be accessed remotely. Machine objects can be accessed only by the operating system.

In addition to these prefixes, the following values also indicate local or machine objects. These values are supported for compatibility with earlier versions of Windows and should not be used when you create new local or machine objects. The key name of local private data objects may also be "$machine.acc", "SAC", "SAI", "SANSC", or start with "RasDialParms" or "RasCredentials". The key name for machine objects may also start with, "NL$" or "_sc_".

Private data objects which do not use any of the preceding key name conventions can be accessed remotely and are not replicated to other domains.

The data stored by the LsaStorePrivateData function is not absolutely protected. However, the data is encrypted before being stored, and the key has a DACL that allows only the creator and administrators to read the data.

Use the LsaRetrievePrivateData function to retrieve the value stored by LsaStorePrivateData.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.

See Also

LsaRetrievePrivateData, LSA_UNICODE_STRING


Miscellaneous Functions

The LSA Policy API has the following three functions that do not fit into any of the other LSA Policy function categories.

Function | Description
LsaClose | Closes a handle to a Policy or TrustedDomain object.
LsaFreeMemory | Frees a buffer allocated by an LSA function.
LsaNtStatusToWinError | Converts an NTSTATUS code to a Windows error code.


LsaClose

The LsaClose function closes a handle to a Policy or TrustedDomain object.

NTSTATUS LsaClose(
  LSA_HANDLE ObjectHandle
);

Parameters

ObjectHandle
Handle to a Policy object returned by the LsaOpenPolicy function or to a TrustedDomain object returned by the LsaOpenTrustedDomainByName function. Following the completion of this call, the handle is no longer valid.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code. For more information, see Common LSA Return Values.

You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.

See Also

LsaOpenPolicy


LsaFreeMemory

The LsaFreeMemory function frees memory allocated for an output buffer by an LSA function call. LSA functions that return variable-length output buffers always allocate the buffer on behalf of the caller. The caller must free this memory by passing the returned buffer pointer to LsaFreeMemory when the memory is no longer required.

NTSTATUS LsaFreeMemory(
  PVOID Buffer
);

Parameters

Buffer
Pointer to memory buffer that was allocated by an LSA function call. If LsaFreeMemory is successful, this buffer is freed.

Return Values

If the function succeeds, the return value is STATUS_SUCCESS.

If the function fails, the return value is an NTSTATUS code, which can be the following value or one of the common LSA return values.

Value | Meaning
STATUS_UNSUCCESSFUL | Memory could not be freed because it was not allocated by an LSA function call.

You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Win32 error code.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.


LsaNtStatusToWinError

The LsaNtStatusToWinError function converts an NTSTATUS code returned by an LSA function to a Windows error code.

ULONG LsaNtStatusToWinError(
  NTSTATUS Status
);

Parameters

Status
An NTSTATUS code returned by an LSA function call. This value will be converted to a Win32 error code.

Return Values

The return value is the Win32 error code that corresponds to the Status parameter. If there is no corresponding Win32 error code, the return value is ERROR_MR_MID_NOT_FOUND.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.
Library: Use Advapi32.lib.

See Also

Common LSA Return Values


Structures

The following structures are used by the LSA policy management functions.

Structure | Description
LSA_AUTH_INFORMATION | Contains authentication information for a trusted domain.
LSA_ENUMERATION_INFORMATION | Contains a pointer to a SID.
LSA_OBJECT_ATTRIBUTES | Specifies the attributes of a connection to the Policy object.
LSA_REFERENCED_DOMAIN_LIST | Contains information about the domains referenced in a lookup operation.
LSA_TRANSLATED_NAME | Contains information about the account identified by a SID.
LSA_TRANSLATED_SID | Contains information about the SID that identifies an account.
LSA_TRANSLATED_SID2 | Contains information about the SID that identifies an account.
LSA_TRUST_INFORMATION | Identifies a domain.
LSA_UNICODE_STRING | Contains a string and its length information.
POLICY_ACCOUNT_DOMAIN_INFO | Used to set and query the name and SID of the system's account domain.
POLICY_AUDIT_EVENTS_INFO | Used to set and query the system's auditing rules.
POLICY_DNS_DOMAIN_INFO | Used to set and query Domain Name System (DNS) information about the primary domain associated with a Policy object.
POLICY_LSA_SERVER_ROLE_INFO | Used to set and query the role of an LSA server.
POLICY_MODIFICATION_INFO | Used to query information about the creation time and last modification of the LSA database.
POLICY_PD_ACCOUNT_INFO | Obsolete. Workstations use the workstation name followed by a $ as the account name.
POLICY_PRIMARY_DOMAIN_INFO | Used to set and query the name and SID of the system's primary domain.
TRUSTED_DOMAIN_AUTH_INFORMATION | Used to retrieve authentication information for a trusted domain.
TRUSTED_DOMAIN_FULL_INFORMATION | Used to retrieve complete information about a trusted domain.
TRUSTED_DOMAIN_INFORMATION_BASIC | Information about a trusted domain. This structure is identical to LSA_TRUST_INFORMATION.
TRUSTED_DOMAIN_INFORMATION_EX | Used to retrieve extended information about a trusted domain.
TRUSTED_DOMAIN_NAME_INFO | Used to query or set the name of a trusted domain.
TRUSTED_PASSWORD_INFO | Used to query or set the password for a trusted domain.
TRUSTED_POSIX_OFFSET_INFO | Used to query or set the value used to generate Posix user and group identifiers.

The following structure types are obsolete or are reserved for future use:

  • POLICY_AUDIT_FULL_QUERY_INFO
  • POLICY_AUDIT_FULL_SET_INFO
  • POLICY_AUDIT_LOG_INFO
  • POLICY_DEFAULT_QUOTA_INFO
  • POLICY_REPLICA_SOURCE_INFO
  • TRUSTED_CONTROLLERS_INFO


LSA_AUTH_INFORMATION

The LSA_AUTH_INFORMATION structure contains authentication information for a trusted domain.

typedef struct _LSA_AUTH_INFORMATION {
  LARGE_INTEGER LastUpdateTime;
  ULONG AuthType;
  ULONG AuthInfoLength;
  PUCHAR AuthInfo;
} LSA_AUTH_INFORMATION, *PLSA_AUTH_INFORMATION;

Members

LastUpdateTime
A LARGE_INTEGER structure that uses the Universal Coordinated Time (UTC) format to indicate the time that this value was set. For more information about UTC time, see the FILETIME structure.
AuthType
Specifies one of the following values to indicate the type of authentication information in the AuthInfo buffer.
Value | Meaning
TRUST_AUTH_TYPE_NONE | The format is unknown and will be ignored.
TRUST_AUTH_TYPE_NT4OWF The Windows NT 4.0 one-way format (OWF) of a clear text password. Note that you cannot derive the clear password back from the OWF form of the password.

The system sets this information.

TRUST_AUTH_TYPE_CLEAR | Clear text password to use for the trust.
TRUST_AUTH_TYPE_VERSION | Clear text password version number.

AuthInfoLength
Specifies the size, in bytes, of the AuthInfo member.
AuthInfo
Pointer to an array of bytes containing the type of authentication information indicated by the AuthType member.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.


LSA_ENUMERATION_INFORMATION

The LSA_ENUMERATION_INFORMATION structure is used with the LsaEnumerateAccountsWithUserRight function to return a pointer to a SID.

typedef struct _LSA_ENUMERATION_INFORMATION {
  PSID Sid;
} LSA_ENUMERATION_INFORMATION, *PLSA_ENUMERATION_INFORMATION;

Members

Sid
Pointer to a SID.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LsaEnumerateAccountsWithUserRight


LSA_OBJECT_ATTRIBUTES

The LSA_OBJECT_ATTRIBUTES structure is used with the LsaOpenPolicy function to specify the attributes of the connection to the Policy object.

When you call LsaOpenPolicy, initialize the members of this structure to NULL or zero because the function does not use the information.

typedef struct _LSA_OBJECT_ATTRIBUTES {
  ULONG Length;
  HANDLE RootDirectory;
  PLSA_UNICODE_STRING ObjectName;
  ULONG Attributes;
  PVOID SecurityDescriptor;
  PVOID SecurityQualityOfService;
} LSA_OBJECT_ATTRIBUTES, *PLSA_OBJECT_ATTRIBUTES;

Members

Length
Specifies the size, in bytes, of the LSA_OBJECT_ATTRIBUTES structure.
RootDirectory
Should be NULL.
ObjectName
Should be NULL.
Attributes
Should be zero.
SecurityDescriptor
Should be NULL.
SecurityQualityOfService
Should be NULL.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LsaOpenPolicy, SECURITY_QUALITY_OF_SERVICE


LSA_REFERENCED_DOMAIN_LIST

The LSA_REFERENCED_DOMAIN_LIST structure contains information about the domains referenced in a lookup operation.

typedef struct _LSA_REFERENCED_DOMAIN_LIST {
  ULONG Entries;
  PLSA_TRUST_INFORMATION Domains;
} LSA_REFERENCED_DOMAIN_LIST, *PLSA_REFERENCED_DOMAIN_LIST;

Members

Entries
Specifies the number of entries in the Domains array.
Domains
Pointer to an array of LSA_TRUST_INFORMATION structures that identify the referenced domains.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LSA_TRUST_INFORMATION, LsaLookupNames, LsaLookupSids


LSA_TRANSLATED_NAME

The LSA_TRANSLATED_NAME structure is used with the LsaLookupSids function to return information about the account identified by a SID.

typedef struct _LSA_TRANSLATED_NAME {
  SID_NAME_USE Use;
  LSA_UNICODE_STRING Name;
  LONG DomainIndex;
} LSA_TRANSLATED_NAME, *PLSA_TRANSLATED_NAME;

Members

Use
A value from the SID_NAME_USE enumeration that identifies the type of SID.

If Use has one of the following values, one or both of the Name or DomainIndex members of LSA_TRANSLATED_NAME is invalid. These members are valid if Use has any other value.
Value | Meaning
SidTypeDomain | The DomainIndex member is valid, but the Name member is not valid and must be ignored.
SidTypeInvalid | Both DomainIndex and Name are invalid and must be ignored.
SidTypeUnknown | Both DomainIndex and Name are invalid and must be ignored.
SidTypeWellKnownGroup | The Name member is valid, but the DomainIndex member is not valid and must be ignored.

Name
An LSA_UNICODE_STRING structure that contains the isolated name of the translated SID. An isolated name is a user, group, or local group account name without the domain name (for example, JohnH, rather than Acctg\JohnH).
DomainIndex
Specifies the zero-based index of an entry in the LSA_REFERENCED_DOMAIN_LIST structure returned by the LsaLookupSids function. The entry contains the name and SID of the domain in which the account was found.

If there is no corresponding domain for an account, this member contains a negative value.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LsaLookupSids, LSA_REFERENCED_DOMAIN_LIST, LSA_UNICODE_STRING, SID_NAME_USE


LSA_TRANSLATED_SID

The LSA_TRANSLATED_SID structure is used with the LsaLookupNames function to return information about the SID that identifies an account.

typedef struct _LSA_TRANSLATED_SID {
  SID_NAME_USE Use;
  ULONG RelativeId;
  LONG DomainIndex;
} LSA_TRANSLATED_SID, *PLSA_TRANSLATED_SID;

Members

Use
A value from the SID_NAME_USE enumeration type that identifies the type of SID.

If Use has one of the following values, one or both of the RelativeId or DomainIndex members of LSA_TRANSLATED_SID is invalid. These members are valid if Use has any other value.
Value | Meaning
SidTypeDomain | The DomainIndex member is valid, but the RelativeId member is not valid and must be ignored.
SidTypeInvalid | Both DomainIndex and RelativeId are invalid and must be ignored.
SidTypeUnknown | Both DomainIndex and RelativeId members are invalid and must be ignored.

RelativeId
Specifies the relative identifier (RID) of the account's SID. The RID identifies the account relative to the domain referenced by the DomainIndex member. The account's complete SID consists of the domain SID followed by the RID.
DomainIndex
Specifies the zero-based index of an entry in the LSA_REFERENCED_DOMAIN_LIST structure returned by the LsaLookupNames function. This entry contains the name and SID of the domain in which the account was found.

If there is no corresponding domain for an account, this member contains a negative value.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LSA_REFERENCED_DOMAIN_LIST, LsaLookupNames, SID_NAME_USE


LSA_TRANSLATED_SID2

[This is preliminary documentation and subject to change.]

The LSA_TRANSLATED_SID2 structure contains SIDs that are retrieved based on account names. This structure is used by the LsaLookupNames2 function.

typedef struct _LSA_TRANSLATED_SID2 {
  SID_NAME_USE Use;
  PSID         Sid;
  LONG         DomainIndex;
  ULONG        Flags;
} LSA_TRANSLATED_SID2, *PLSA_TRANSLATED_SID2;

Members

Use
An SID_NAME_USE enumeration value that identifies the use of the SID. If this value is SidUnknown or SidInvalid, the rest of the information in the structure is invalid and should be ignored.
Sid
The complete SID of the account.
DomainIndex
The index of an entry in a related LSA_REFERENCED_DOMAIN_LIST data structure which describes the domain that owns the account. If there is no corresponding reference domain for an entry, then DomainIndex will contain a negative value.
Flags
Not used.

Requirements

Windows NT/2000 or later: Requires Whistler.
Header: Declared in Ntsecapi.h.


LSA_TRUST_INFORMATION

The LSA_TRUST_INFORMATION structure identifies a domain. This structure is used by the LsaEnumerateTrustedDomains function.

typedef struct _LSA_TRUST_INFORMATION {
  LSA_UNICODE_STRING Name;
  PSID Sid;
} LSA_TRUST_INFORMATION, *PLSA_TRUST_INFORMATION;

Members

Name
An LSA_UNICODE_STRING structure that contains the name of the domain.
Sid
Pointer to the SID of the domain.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LSA_REFERENCED_DOMAIN_LIST, LsaEnumerateTrustedDomains, LSA_UNICODE_STRING


LSA_UNICODE_STRING

The LSA_UNICODE_STRING structure is used by various LSA functions to specify a Unicode string.

typedef struct _LSA_UNICODE_STRING {
  USHORT Length;
  USHORT MaximumLength;
  PWSTR  Buffer;
} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING;

Members

Length
Specifies the length, in bytes, of the string pointed to by the Buffer member, not including the terminating NULL character, if any.
MaximumLength
Specifies the total size, in bytes, of the memory allocated for Buffer. Up to MaximumLength bytes may be written into the buffer without trampling memory.
Buffer
Pointer to a wide character string. Note that the strings returned by the various LSA functions might not be null-terminated.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.1 or later.
Header: Declared in Ntsecapi.h.


UNICODE_STRING

The UNICODE_STRING structure is used by various LSA functions to specify a Unicode string.

typedef struct _LSA_UNICODE_STRING {
  USHORT Length;
  USHORT MaximumLength;
  PWSTR  Buffer;
} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING;

typedef LSA_UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING;

Members

Length
Specifies the length, in bytes, of the string pointed to by the Buffer member, not including the terminating NULL character, if any.
MaximumLength
Specifies the total size, in bytes, of memory allocated for Buffer. Up to MaximumLength bytes may be written into the buffer without trampling memory.
Buffer
Pointer to a wide-character string. Note that the strings returned by the various LSA functions might not be null terminated.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.


POLICY_ACCOUNT_DOMAIN_INFO

The POLICY_ACCOUNT_DOMAIN_INFO structure is used to set and query the name and SID of the system's account domain. The LsaQueryInformationPolicy and LsaSetInformationPolicy functions use this structure when their InformationClass parameters are set to PolicyAccountDomainInformation.

typedef struct _POLICY_ACCOUNT_DOMAIN_INFO {
  LSA_UNICODE_STRING DomainName;
  PSID DomainSid;
} POLICY_ACCOUNT_DOMAIN_INFO, *PPOLICY_ACCOUNT_DOMAIN_INFO;

Members

DomainName
An LSA_UNICODE_STRING structure that specifies the name of the account domain.
DomainSid
Pointer to the SID of the account domain.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LsaQueryInformationPolicy, LsaSetInformationPolicy, LSA_UNICODE_STRING, POLICY_INFORMATION_CLASS


POLICY_AUDIT_EVENTS_INFO

The POLICY_AUDIT_EVENTS_INFO structure is used to set and query the system's auditing rules. The LsaQueryInformationPolicy and LsaSetInformationPolicy functions use this structure when their InformationClass parameters are set to PolicyAuditEventsInformation.

typedef struct _POLICY_AUDIT_EVENTS_INFO {
  BOOLEAN AuditingMode;
  PPOLICY_AUDIT_EVENT_OPTIONS EventAuditingOptions;
  ULONG MaximumAuditEventCount;
} POLICY_AUDIT_EVENTS_INFO, *PPOLICY_AUDIT_EVENTS_INFO;

Members

AuditingMode
Indicates whether auditing is enabled.

If this flag is TRUE, the system generates audit records according to the event auditing options specified in the EventAuditingOptions member.

If this flag is FALSE, the system does not generate audit records. However, note that set operations update the event auditing options as specified in the EventAuditingOptions member even when AuditingMode is FALSE.

EventAuditingOptions
Pointer to an array of POLICY_AUDIT_EVENT_OPTIONS variables. Each element in this array specifies the auditing options for an audit event type. The index of each array element corresponds to an audit event type value in the POLICY_AUDIT_EVENT_TYPE enumeration type.

Each POLICY_AUDIT_EVENT_OPTIONS variable in the array can specify the following auditing options. You can also combine the success and failure options, POLICY_AUDIT_EVENT_SUCCESS and POLICY_AUDIT_EVENT_FAILURE.

When LSASetInformationPolicy is called to change the audit policy, any new POLICY_AUDIT_EVENT_OPTIONS array elements are added to any existing audit options. Adding a new POLICY_AUDIT_EVENT_OPTIONS element combined with the POLICY_AUDIT_EVENT_NONE audit option cancels all previous audit options and begins a new set of options.
Audit option | Meaning
POLICY_AUDIT_EVENT_UNCHANGED | For set operations, specify this value to leave the current options unchanged. This is the default.
POLICY_AUDIT_EVENT_SUCCESS | Generate audit records for successful events of this type.
POLICY_AUDIT_EVENT_FAILURE | Generate audit records for failed attempts to cause an event of this type to occur.
POLICY_AUDIT_EVENT_NONE | Do not generate audit records for events of this type.

MaximumAuditEventCount
Specifies the number of elements in the EventAuditingOptions array. For set operations, if this value is less than the number of audit event types supported by the system, the system does not change the auditing options for event types with indexes equal to or higher than the value specified in MaximumAuditEventCount.

Remarks

LSA Policy defines a mask for the valid event auditing options. The POLICY_AUDIT_EVENT_MASK mask evaluates to TRUE if it is set equal to any of the preceding event auditing options.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LsaQueryInformationPolicy, LsaSetInformationPolicy, POLICY_AUDIT_EVENT_TYPE, POLICY_INFORMATION_CLASS


POLICY_DNS_DOMAIN_INFO

The POLICY_DNS_DOMAIN_INFO structure is used to set and query Domain Name System (DNS) information about the primary domain associated with a Policy object. The LsaQueryInformationPolicy and LsaSetInformationPolicy functions use this structure when their InformationClass parameters are set to PolicyDnsDomainInformation.

typedef struct _POLICY_DNS_DOMAIN_INFO {
  LSA_UNICODE_STRING Name;
  LSA_UNICODE_STRING DnsDomainName;
  LSA_UNICODE_STRING DnsForestName;
  GUID DomainGuid;
  PSID Sid;
} POLICY_DNS_DOMAIN_INFO, *PPOLICY_DNS_DOMAIN_INFO;

Members

Name
An LSA_UNICODE_STRING structure that specifies the name of the primary domain. This is the same as the primary domain name in the POLICY_PRIMARY_DOMAIN_INFO structure.
DnsDomainName
An LSA_UNICODE_STRING structure that specifies the DNS name of the primary domain.
DnsForestName
An LSA_UNICODE_STRING structure that specifies the DNS forest name of the primary domain. This is the DNS name of the domain at the root of the enterprise.
DomainGuid
A GUID structure that contains the GUID of the primary domain.
Sid
Pointer to the SID of the primary domain. This is the same as the primary domain SID in the POLICY_PRIMARY_DOMAIN_INFO structure.

Remarks

The POLICY_DNS_DOMAIN_INFO structure is an extended version of the POLICY_PRIMARY_DOMAIN_INFO structure. Setting POLICY_DNS_DOMAIN_INFO information will overwrite the corresponding values in the POLICY_PRIMARY_DOMAIN_INFO (name and SID), and vice versa.

If the computer associated with the Policy object is not a member of a domain, all structure members except Name are NULL or zero.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LsaQueryInformationPolicy, LsaSetInformationPolicy, LSA_UNICODE_STRING, POLICY_INFORMATION_CLASS, POLICY_PRIMARY_DOMAIN_INFO


POLICY_LSA_SERVER_ROLE_INFO

The POLICY_LSA_SERVER_ROLE_INFO structure is used to set and query the role of an LSA server. The LsaQueryInformationPolicy and LsaSetInformationPolicy functions use this structure when their InformationClass parameters are set to PolicyLsaServerRoleInformation.

typedef struct _POLICY_LSA_SERVER_ROLE_INFO {
  POLICY_LSA_SERVER_ROLE LsaServerRole;
} POLICY_LSA_SERVER_ROLE_INFO, *PPOLICY_LSA_SERVER_ROLE_INFO;

Members

LsaServerRole
Specifies one of the values from the POLICY_LSA_SERVER_ROLE enumeration type to indicate a primary or backup LSA server.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LsaQueryInformationPolicy, LsaSetInformationPolicy, POLICY_INFORMATION_CLASS, POLICY_LSA_SERVER_ROLE


POLICY_MODIFICATION_INFO

The POLICY_MODIFICATION_INFO structure is used to query information about the creation time and last modification of the LSA database. The LsaQueryInformationPolicy function uses this structure when its InformationClass parameter is set to PolicyModificationInformation.

typedef struct _POLICY_MODIFICATION_INFO {
  LARGE_INTEGER ModifiedId;
  LARGE_INTEGER DatabaseCreationTime;
} POLICY_MODIFICATION_INFO, *PPOLICY_MODIFICATION_INFO;

Members

ModifiedId
A LARGE_INTEGER structure containing a 64-bit unsigned integer that is incremented each time anything in the LSA database is modified. This value is modified only on primary domain controllers.
DatabaseCreationTime
A LARGE_INTEGER structure that indicates the date and time the LSA database was created. This is a UTC-based time that uses the FILETIME format. On backup domain controllers, this value is replicated from the primary domain controller. For more information about UTC-based time, see System Time.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

FILETIME, LsaQueryInformationPolicy, LsaSetInformationPolicy, POLICY_INFORMATION_CLASS


POLICY_PD_ACCOUNT_INFO

The POLICY_PD_ACCOUNT_INFO structure is obsolete.


POLICY_PRIMARY_DOMAIN_INFO

The POLICY_PRIMARY_DOMAIN_INFO structure is used to set and query the name and SID of the system's primary domain. The LsaQueryInformationPolicy and LsaSetInformationPolicy functions use this structure when their InformationClass parameters are set to PolicyPrimaryDomainInformation.

Windows 2000: The PolicyPrimaryDomainInformation value and POLICY_PRIMARY_DOMAIN_INFO structure are obsolete. Use the PolicyDnsDomainInformation and POLICY_DNS_DOMAIN_INFO structure instead.

typedef struct _POLICY_PRIMARY_DOMAIN_INFO {
  LSA_UNICODE_STRING Name;
  PSID Sid;
} POLICY_PRIMARY_DOMAIN_INFO, *PPOLICY_PRIMARY_DOMAIN_INFO;

Members

Name
An LSA_UNICODE_STRING structure that specifies the name of the primary domain.
Sid
Pointer to the SID of the primary domain.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LsaQueryInformationPolicy, LsaSetInformationPolicy, LSA_UNICODE_STRING, POLICY_DNS_DOMAIN_INFO, POLICY_INFORMATION_CLASS


TRUSTED_DOMAIN_AUTH_INFORMATION

The TRUSTED_DOMAIN_AUTH_INFORMATION structure is used to retrieve authentication information for a trusted domain. The LsaQueryTrustedDomainInfo function uses this structure when its InformationClass parameter is set to TrustedDomainAuthInformation.

typedef struct _TRUSTED_DOMAIN_AUTH_INFORMATION {
  ULONG IncomingAuthInfos;
  PLSA_AUTH_INFORMATION IncomingAuthenticationInformation;
  PLSA_AUTH_INFORMATION IncomingPreviousAuthenticationInformation;
  ULONG OutgoingAuthInfos;
  PLSA_AUTH_INFORMATION OutgoingAuthenticationInformation;
  PLSA_AUTH_INFORMATION OutgoingPreviousAuthenticationInformation;
} TRUSTED_DOMAIN_AUTH_INFORMATION, *PTRUSTED_DOMAIN_AUTH_INFORMATION;

Members

IncomingAuthInfos
Specifies the number of entries in the IncomingAuthenticationInformation and IncomingPreviousAuthenticationInformation arrays.
IncomingAuthenticationInformation
Pointer to an array of LSA_AUTH_INFORMATION structures containing the authentication information for the incoming side of a trust relationship.
IncomingPreviousAuthenticationInformation
Pointer to an array of LSA_AUTH_INFORMATION structures containing the previous authentication information (or old password) for the incoming side of a trust relationship. There must be one of these for every entry in the IncomingAuthenticationInformation array.
OutgoingAuthInfos
Specifies the number of entries in the OutgoingAuthenticationInformation and OutgoingPreviousAuthenticationInformation arrays.
OutgoingAuthenticationInformation
Pointer to an array of LSA_AUTH_INFORMATION structures containing the authentication information for the outgoing side of a trust relationship.
OutgoingPreviousAuthenticationInformation
Pointer to an array of LSA_AUTH_INFORMATION structures containing the previous authentication information (or old password) for the outgoing side of a trust relationship. There must be one of these for every entry in the OutgoingAuthenticationInformation array.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.

See Also

LSA_AUTH_INFORMATION, LsaCreateTrustedDomainEx, LsaQueryTrustedDomainInfo, LsaSetTrustedDomainInfoByName, LsaQueryTrustedDomainInfoByName, TRUSTED_INFORMATION_CLASS


TRUSTED_DOMAIN_FULL_INFORMATION

The TRUSTED_DOMAIN_FULL_INFORMATION structure is used to retrieve complete information about a trusted domain. The LsaQueryTrustedDomainInfo function uses this structure when its InformationClass parameter is set to TrustedDomainFullInformation.

typedef struct _TRUSTED_DOMAIN_FULL_INFORMATION {
  TRUSTED_DOMAIN_INFORMATION_EX   Information;
  TRUSTED_POSIX_OFFSET_INFO       PosixOffset;
  TRUSTED_DOMAIN_AUTH_INFORMATION AuthInformation;
} TRUSTED_DOMAIN_FULL_INFORMATION, *PTRUSTED_DOMAIN_FULL_INFORMATION;

Members

Information
A TRUSTED_DOMAIN_INFORMATION_EX structure containing extended information for a trusted domain.
PosixOffset
A TRUSTED_POSIX_OFFSET_INFO structure containing the value used to generate Posix user and group identifiers for a trusted domain.
AuthInformation
A TRUSTED_DOMAIN_AUTH_INFORMATION structure containing authentication information for a trusted domain.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LsaQueryTrustedDomainInfo, TRUSTED_DOMAIN_AUTH_INFORMATION, TRUSTED_DOMAIN_INFORMATION_EX, TRUSTED_INFORMATION_CLASS, TRUSTED_POSIX_OFFSET_INFO


TRUSTED_DOMAIN_INFORMATION_BASIC

The TRUSTED_DOMAIN_INFORMATION_BASIC structure identifies a domain. This structure is used by the LsaQueryTrustedDomainInfo function when its InformationClass parameter is set to TrustedDomainInformationBasic.

typedef struct _LSA_TRUST_INFORMATION {
  LSA_UNICODE_STRING Name;
  PSID Sid;
} LSA_TRUST_INFORMATION, *PLSA_TRUST_INFORMATION;

typedef  LSA_TRUST_INFORMATION TRUSTED_DOMAIN_INFORMATION_BASIC;

Members

Name
An LSA_UNICODE_STRING structure that contains the name of the domain.
Sid
Pointer to the SID of the domain.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LSA_REFERENCED_DOMAIN_LIST, LSA_UNICODE_STRING, LsaQueryTrustedDomainInfo


TRUSTED_DOMAIN_INFORMATION_EX

The TRUSTED_DOMAIN_INFORMATION_EX structure is used to retrieve extended information about a trusted domain. The LsaQueryTrustedDomainInfo function uses this structure when its InformationClass parameter is set to TrustedDomainInformationEx.

typedef struct _TRUSTED_DOMAIN_INFORMATION_EX {
  LSA_UNICODE_STRING Name;
  LSA_UNICODE_STRING FlatName;
  PSID  Sid;
  ULONG TrustDirection;
  ULONG TrustType;
  ULONG TrustAttributes;
} TRUSTED_DOMAIN_INFORMATION_EX, *PTRUSTED_DOMAIN_INFORMATION_EX;

Members

Name
An LSA_UNICODE_STRING structure that contains the name of the trusted domain. For Windows 2000 trusted domains, this is the DNS domain name. For Windows NT 4.0 and earlier trusted domains, this is the NetBIOS domain name. For non-Windows NT trusted domains, this is the identifying name of the domain.
FlatName
An LSA_UNICODE_STRING structure that contains the flat name of the trusted domain. For Windows NT trusted domains, this is the NetBIOS domain name. For non-Windows NT trusted domains, this is the identifying name of the domain or it is NULL
Sid
Pointer to the SID of the trusted domain. For non-Windows NT trusted domains, this member can be NULL.
TrustDirection
Indicates the direction of the trust, as one of the following values.
Value | Meaning
TRUST_DIRECTION_DISABLED | The trust relationship exists but it has been disabled.
TRUST_DIRECTION_INBOUND | The trusted domain trusts the primary domain to perform operations such as name lookups and authentication.
TRUST_DIRECTION_OUTBOUND | The primary domain trusts the trusted domain to perform operations such as name lookups and authentication.
TRUST_DIRECTION_BIDIRECTIONAL | Both domains trust each other.

TrustType
Indicates the type of the trust relationship, as one of the following values.
Value | Meaning
TRUST_TYPE_DOWNLEVEL | The domain controller of the trusted domain is a Windows NT 4.0 or earlier system.
TRUST_TYPE_UPLEVEL | The domain controller of the trusted domain is a Windows 2000 or later system.
TRUST_TYPE_MIT | The trusted domain is an MIT Kerberos realm.
TRUST_TYPE_DCE | The trusted domain is a DCE realm.
0x5 - 0x000FFFFF | Reserved for future use.
0x00100000 to 0xFFF00000 | Provider-specific trust levels.

TrustAttributes
Indicates the attributes of a trust relationship, as one of the following values.
Value | Meaning
TRUST_ATTRIBUTE_NON_TRANSITIVE | Disallow transitivity.
TRUST_ATTRIBUTE_TREE_PARENT | The trust is to the parent in the organization tree.
TRUST_ATTRIBUTE_TREE_ROOT | The trust is to another tree root in a forest.
TRUST_ATTRIBUTE_UPLEVEL_ONLY | Trust link valid only for Windows 2000 clients.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LsaQueryTrustedDomainInfo, LsaCreateTrustedDomainEx, LsaSetTrustedDomainInfoByName, LsaQueryTrustedDomainInfoByName, LSA_UNICODE_STRING, TRUSTED_INFORMATION_CLASS


TRUSTED_DOMAIN_NAME_INFO

The TRUSTED_DOMAIN_NAME_INFO structure is used to query or set the name of a trusted domain. The LsaQueryTrustedDomainInfo and LsaSetTrustedDomainInformation functions use this structure when their InformationClass parameters are set to TrustedDomainNameInformation.

typedef struct _TRUSTED_DOMAIN_NAME_INFO {
  LSA_UNICODE_STRING Name;
} TRUSTED_DOMAIN_NAME_INFO, *PTRUSTED_DOMAIN_NAME_INFO;

Members

Name
An LSA_UNICODE_STRING structure that contains the name of a trusted domain.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LsaQueryTrustedDomainInfo, LsaSetTrustedDomainInformation, LSA_UNICODE_STRING, TRUSTED_INFORMATION_CLASS


TRUSTED_PASSWORD_INFO

The TRUSTED_PASSWORD_INFO structure is used to query or set the password for a trusted domain. The LsaQueryTrustedDomainInfo and LsaSetTrustedDomainInformation functions use this structure when their InformationClass parameters are set to TrustedPasswordInformation.

typedef struct _TRUSTED_PASSWORD_INFO {
  LSA_UNICODE_STRING Password;
  LSA_UNICODE_STRING OldPassword;
} TRUSTED_PASSWORD_INFO, *PTRUSTED_PASSWORD_INFO;

Members

Password
An LSA_UNICODE_STRING structure that contains the password to use when creating an authenticated connection to the domain.
OldPassword
An LSA_UNICODE_STRING structure that contains the old password. On set operations, if the Buffer member of this structure is NULL, the old password is set to the current password.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LsaQueryTrustedDomainInfo, LsaSetTrustedDomainInformation, LSA_UNICODE_STRING, TRUSTED_INFORMATION_CLASS


TRUSTED_POSIX_OFFSET_INFO

The TRUSTED_POSIX_OFFSET_INFO structure is used to query or set the value used to generate Posix user and group identifiers. The LsaQueryTrustedDomainInfo and LsaSetTrustedDomainInformation functions use this structure when their InformationClass parameters are set to TrustedPosixOffsetInformation.

typedef struct _TRUSTED_POSIX_OFFSET_INFO {
  ULONG Offset;
} TRUSTED_POSIX_OFFSET_INFO, *PTRUSTED_POSIX_OFFSET_INFO;

Members

Offset
An offset that the system uses to generate Posix user and group identifiers that correspond to a given SID. To generate a Posix identifier, the system adds the RID from the SID to the Posix offset of the trusted domain identified by the SID.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LsaQueryTrustedDomainInfo, LsaSetTrustedDomainInformation, TRUSTED_INFORMATION_CLASS


Data Types

The following data types are used by the LSA policy management functions.

Data type | Description
LSA_ENUMERATION_HANDLE | Used to track enumerations in which multiple function calls are required.
LSA_HANDLE | Handle to a Policy object.


LSA_ENUMERATION_HANDLE

The LSA_ENUMERATION_HANDLE data type is used by the LSA functions that enumerate TrustedDomain objects: LsaEnumerateTrustedDomains and LsaEnumerateTrustedDomainsEx. The enumeration functions are designed so you can make multiple calls to enumerate all the objects of a given type in the database. On the initial enumeration function call, you pass in a pointer to an LSA_ENUMERATION_HANDLE variable that is initialized to zero. The function updates this value. If the function returns a value that indicates there are more objects to enumerate, call the function again and pass in the updated LSA_ENUMERATION_HANDLE value to obtain an enumeration continuing from the point where the previous enumeration left off.

typedef ULONG LSA_ENUMERATION_HANDLE, *PLSA_ENUMERATION_HANDLE;

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LsaEnumerateTrustedDomains, LsaEnumerateTrustedDomainsEx


LSA_HANDLE

The LSA_HANDLE data type is a handle to the local Policy object.

typedef PVOID LSA_HANDLE, *PLSA_HANDLE;

Remarks

Before you can use the local policy API your application must open a handle to a Policy object. To do this, call LsaOpenPolicy. This function returns a handle that your application can then specify in subsequent LSA policy function calls.

Each handle has an associated set of permissions that determine the operations your application can perform on the Policy object by using the handle. Your application can open more than one handle to the policy object at a time. When a handle is no longer required, your application should close it by calling LsaClose.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LsaClose, LsaOpenPolicy


Enumerations

The following enumeration types are used by the LSA policy management functions.

Enumeration | Description
POLICY_AUDIT_EVENT_TYPE | Defines the types of events the system can audit.
POLICY_INFORMATION_CLASS | Defines the types of information that can be set or queried for a Policy object.
POLICY_LSA_SERVER_ROLE | Indicate the role of an LSA server.
TRUSTED_INFORMATION_CLASS | Defines the types of information that can be set or queried for a trusted domain.
POLICY_NOTIFICATION_INFORMATION_CLASS | Defines the types of policy information and policy domain information for which your application can request notification of changes.
POLICY_SERVER_ENABLE_STATE | Represents the state of the LSA server, that is, whether it is enabled or disabled.


POLICY_AUDIT_EVENT_TYPE

The POLICY_AUDIT_EVENT_TYPE enumeration type defines values that indicate the types of events the system can audit. The LsaQueryInformationPolicy and LsaSetInformationPolicy functions use this enumeration type when their InformationClass parameters are set to PolicyAuditEventsInformation.

typedef enum _POLICY_AUDIT_EVENT_TYPE {
  AuditCategorySystem,
  AuditCategoryLogon,
  AuditCategoryObjectAccess,
  AuditCategoryPrivilegeUse,
  AuditCategoryDetailedTracking,
  AuditCategoryPolicyChange,
  AuditCategoryAccountManagement,
  AuditCategoryDirectoryServiceAccess,
  AuditCategoryAccountLogon
} POLICY_AUDIT_EVENT_TYPE, *PPOLICY_AUDIT_EVENT_TYPE;

Enumerator Values

AuditCategorySystem
Audit attempts to shutdown or restart the computer. Also, audit events that affect system security or the security log.
AuditCategoryLogon
Audit attempts to log on to or log off from the system. Also, audit attempts to make a network connection.
AuditCategoryObjectAccess
Audit attempts to access securable objects, such as files.
AuditCategoryPrivilegeUse
Audit attempts to use Windows NT/Windows 2000 privileges.
AuditCategoryDetailedTracking
Audit events such as program activation, some forms of handle duplication, indirect access to an object, and process exit.
AuditCategoryPolicyChange
Audit attempts to change Policy object rules.
AuditCategoryAccountManagement
Audit attempts to create, delete, or change user or group accounts. Also, audit password changes.
AuditCategoryDirectoryServiceAccess
Audit attempts to access the directory service.
AuditCategoryAccountLogon
Audit logon attempts by privileged accounts that log on to the domain controller. These audit events are generated when the Kerberos Key Distribution Center logs on to the domain controller and by MSV1_0 for Windows NT 4.0 – style logons.

Remarks

The preceding enumeration may expand in future versions of Windows. Because of this, you should not compute the number of elements in this type directly. Instead, you should obtain the count of elements by calling LsaQueryInformationPolicy with the InformationClass parameter set to PolicyAuditEventsInformation and extract the count from the MaximumAuditEventCount member of the returned POLICY_AUDIT_EVENTS_INFO structure.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LsaQueryInformationPolicy, LsaSetInformationPolicy, POLICY_INFORMATION_CLASS


POLICY_INFORMATION_CLASS

The POLICY_INFORMATION_CLASS enumeration type defines values that indicate the type of information to set or query in a Policy object.

typedef enum _POLICY_INFORMATION_CLASS {
  PolicyAuditLogInformation = 1,
  PolicyAuditEventsInformation,
  PolicyPrimaryDomainInformation,
  PolicyPdAccountInformation,
  PolicyAccountDomainInformation,
  PolicyLsaServerRoleInformation,
  PolicyReplicaSourceInformation,
  PolicyDefaultQuotaInformation,
  PolicyModificationInformation,
  PolicyAuditFullSetInformation,
  PolicyAuditFullQueryInformation,
  PolicyDnsDomainInformation
} POLICY_INFORMATION_CLASS, *PPOLICY_INFORMATION_CLASS;

Enumerator Values

PolicyAuditLogInformation
This value is obsolete.
PolicyAuditEventsInformation
Query or set the system's auditing rules. You can enable or disable auditing, and specify the types of events that are audited. Use the POLICY_AUDIT_EVENTS_INFO structure.
PolicyPrimaryDomainInformation
Query or set the name and SID of the system's primary domain. Use the POLICY_PRIMARY_DOMAIN_INFO structure.

Windows 2000: This value is obsolete. Use the PolicyDnsDomainInformation value instead.

PolicyPdAccountInformation
This value is obsolete.
PolicyAccountDomainInformation
Query or set the name and SID of the system's account domain. Use the POLICY_ACCOUNT_DOMAIN_INFO structure.
PolicyLsaServerRoleInformation
Query or set the role of an LSA server. Use the POLICY_LSA_SERVER_ROLE_INFO structure.
PolicyReplicaSourceInformation
This value is obsolete.
PolicyDefaultQuotaInformation
This value is obsolete.
PolicyModificationInformation
Query or set information about the creation time and last modification of the LSA database. Use the POLICY_MODIFICATION_INFO structure.
PolicyAuditFullSetInformation
This value is obsolete.
PolicyAuditFullQueryInformation
This value is obsolete.
PolicyDnsDomainInformation
Windows 2000: Query or set Domain Name System (DNS) information about the account domain associated with a policy object. Use the POLICY_DNS_DOMAIN_INFO structure.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LsaQueryInformationPolicy, LsaSetInformationPolicy, POLICY_ACCOUNT_DOMAIN_INFO, POLICY_AUDIT_EVENTS_INFO, POLICY_DNS_DOMAIN_INFO, POLICY_LSA_SERVER_ROLE_INFO, POLICY_MODIFICATION_INFO, POLICY_PRIMARY_DOMAIN_INFO


POLICY_LSA_SERVER_ROLE

The POLICY_LSA_SERVER_ROLE enumeration type defines values that indicate the role of an LSA server. The LsaQueryInformationPolicy and LsaSetInformationPolicy functions use this enumeration type when their InformationClass parameters are set to PolicyLsaServerRoleInformation.

typedef enum _POLICY_LSA_SERVER_ROLE {
  PolicyServerRoleBackup = 2,
  PolicyServerRolePrimary
} POLICY_LSA_SERVER_ROLE, *PPOLICY_LSA_SERVER_ROLE;

Enumerator Values

PolicyServerRoleBackup
Indicates a backup LSA server.
PolicyServerRolePrimary
Indicates a primary LSA server, a workstation, or a stand alone computer.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LsaQueryInformationPolicy, LsaSetInformationPolicy, POLICY_LSA_SERVER_ROLE_INFO


POLICY_NOTIFICATION_INFORMATION_CLASS

The POLICY_NOTIFICATION_INFORMATION_CLASS enumeration defines the types of policy information and policy domain information for which your application can request notification of changes.

typedef enum _POLICY_NOTIFICATION_INFORMATION_CLASS {
  PolicyNotifyAuditEventsInformation = 1,
  PolicyNotifyAccountDomainInformation,
  PolicyNotifyServerRoleInformation,
  PolicyNotifyDnsDomainInformation,
  PolicyNotifyDomainEfsInformation,
  PolicyNotifyDomainKerberosTicketInformation,
  PolicyNotifyMachineAccountPasswordInformation
} POLICY_NOTIFICATION_INFORMATION_CLASS, *PPOLICY_NOTIFICATION_INFORMATION_CLASS;

Enumerator Values

PolicyNotifyAuditEventsInformation
Notify when any of the audited categories are changed.
PolicyNotifyAccountDomainInformation
Notify when the account domain information changes.
PolicyNotifyServerRoleInformation
Notify when the LSA server changes its role from primary to backup, or vice versa.
PolicyNotifyDnsDomainInformation
Notify when the DNS domain information changes or if the primary domain information changes.
PolicyNotifyDomainEfsInformation
Notify when the encrypted file system (EFS) domain information changes.
PolicyNotifyDomainKerberosTicketInformation
Notify when the Kerberos ticket for the domain changes.
PolicyNotifyMachineAccountPasswordInformation
Notify when the machine account password changes.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Ntsecapi.h.

See Also

LsaRegisterPolicyChangeNotification, LsaUnregisterPolicyChangeNotification


POLICY_SERVER_ENABLE_STATE

The POLICY_SERVER_ENABLE_STATE enumeration represents the state of the LSA server—that is, whether it is enabled or disabled. Some operations may only be performed on an enabled LSA server.

typedef enum _POLICY_SERVER_ENABLE_STATE {
  PolicyServerEnabled = 2,
  PolicyServerDisabled
} POLICY_SERVER_ENABLE_STATE, *PPOLICY_SERVER_ENABLE_STATE;

Enumerator Values

PolicyServerEnabled
The LSA server is enabled.
PolicyServerDisabled
The LSA server is disabled.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.


TRUSTED_INFORMATION_CLASS

The TRUSTED_INFORMATION_CLASS enumeration defines values that indicate the type of information to set or query for a trusted domain.

Each value has an associated structure that the LsaQueryTrustedDomainInfo and LsaSetTrustedDomainInformation functions use to store the information.

typedef enum _TRUSTED_INFORMATION_CLASS {
  TrustedDomainNameInformation = 1,
  TrustedControllersInformation,
  TrustedPosixOffsetInformation,
  TrustedPasswordInformation,
  TrustedDomainInformationBasic,
  TrustedDomainInformationEx,
  TrustedDomainAuthInformation,
  TrustedDomainFullInformation
} TRUSTED_INFORMATION_CLASS, *PTRUSTED_INFORMATION_CLASS;

Enumeration Values

TrustedDomainNameInformation
Query or set the name of a trusted domain. Use the TRUSTED_DOMAIN_NAME_INFO structure.
TrustedControllersInformation
This value is obsolete.
TrustedPosixOffsetInformation
Query or set the value used to generate Posix user and group identifiers. Use the TRUSTED_POSIX_OFFSET_INFO structure.
TrustedPasswordInformation
Query or set the password for a trusted domain. Use the TRUSTED_PASSWORD_INFO structure.

Windows 2000: This value has been superseded by the TrustedDomainAuthInformation value.

TrustedDomainInformationBasic
Query the name and SID of a trusted domain. Use the LSA_TRUST_INFORMATION structure.

Windows 2000: This value is obsolete.

TrustedDomainInformationEx
Query extended information for a trusted domain. Use the TRUSTED_DOMAIN_INFORMATION_EX structure.
TrustedDomainAuthInformation
Query authentication information for a trusted domain. Use the TRUSTED_DOMAIN_AUTH_INFORMATION structure.
TrustedDomainFullInformation
Query complete information for a trusted domain. This information includes the Posix offset information, authentication information, and the extended information returned for the TrustedDomainInformationEx value. Use the TRUSTED_DOMAIN_FULL_INFORMATION structure.

Requirements

Windows NT/2000 or later: Requires Windows NT 3.51 or later.
Header: Declared in Ntsecapi.h.

See Also

LsaQueryTrustedDomainInfo, LsaSetTrustedDomainInformation, TRUSTED_DOMAIN_AUTH_INFORMATION, TRUSTED_DOMAIN_FULL_INFORMATION, TRUSTED_DOMAIN_INFORMATION_EX, TRUSTED_DOMAIN_NAME_INFO, TRUSTED_PASSWORD_INFO, TRUSTED_POSIX_OFFSET_INFO, LSA_TRUST_INFORMATION


Common LSA Return Values

Most LSA functions return an NTSTATUS value to indicate success or failure. The various NTSTATUS values are defined in NTSTATUS.H, which is distributed with the Windows Device Driver Kit (DDK).

To convert an NTSTATUS return value to a Win32 error code, use the LsaNtStatusToWinError function.

The following table lists the NTSTATUS values that might be returned by any LSA function. (The return value sections for some of the LSA functions list additional error codes that the function might return.) This table also lists the Win32 error code that corresponds to each NTSTATUS value.

NTSTATUS code (Win32 error code) | Meaning
STATUS_SUCCESS (ERROR_SUCCESS) | The function was successful.
STATUS_ACCESS_DENIED (ERROR_ACCESS_DENIED) | Caller does not have the appropriate access to complete the operation.
STATUS_INSUFFICIENT_RESOURCES (ERROR_NO_SYSTEM_ RESOURCES) | There are not enough system resources (such as memory to allocate buffers) to complete the call.
STATUS_INTERNAL_DB_ERROR (ERROR_INTERNAL_DB_ERROR) | The LSA database contains an internal inconsistency.
STATUS_INVALID_HANDLE (ERROR_INVALID_HANDLE) | Indicates an object or RPC handle is not valid in the context used.
STATUS_INVALID_SERVER_STATE (ERROR_INVALID_SERVER_ STATE) | Indicates the LSA server is currently disabled.
STATUS_INVALID_PARAMETER (ERROR_INVALID_PARAMETER) | One of the parameters is not valid.
STATUS_OBJECT_NAME_NOT_FOUND (ERROR_FILE_NOT_FOUND) | An object in the LSA policy database was not found. The object may have been specified either by SID or by name, depending on its type.
STATUS_UNSUCCESSFUL (ERROR_GEN_FAILURE) | Generic failure, such as RPC connection failure.

See Also

LsaNtStatusToWinError


Service Security Attachments

The Microsoft® Security Configuration tool set is a set of Microsoft Management Console (MMC) tools that simplify configuration and analysis of Microsoft® Windows NT/Windows 2000 system security. This tool set handles standard security settings. Some services, however, have specialized configuration needs that go beyond the security settings provided by the standard tool set. To handle those needs, you can extend the functionality of the tool set by writing an attachment that handles the service-specific security tasks.

For example, Spooler is a Windows NT service that defines private objects, which need to be secured, that is printers. This functionality is not handled by the standard tool set and thus requires an attachment to handle configuration and analysis of printer objects. Configuration of general security parameters, such as the service invocation policy, is still handled by the Microsoft Security Configuration tool set.

The following document describes how to implement and install an attachment. For more information about using the Microsoft Security Configuration tool set, see http://www.microsoft.com and search for Security Configuration.


About Attachments

Security service attachments extend the functionality of the Security Configuration tool set to support service-specific configurations.

An attachment has two components: an MMC snap-in extension that implements the attachment user interface and an attachment engine that processes the service-specific security configuration and analysis tasks.

The attachment snap-in extension is hosted by the Security Configuration snap-ins. These are MMC snap-ins which provide the user with interfaces to configure and analyze the general security settings for a service. Service-specific settings are configured using the attachment snap-in extension.

When the user changes a configuration setting, the Security Configuration snap-ins store the new information and then pass the request to the Security Configuration Engine. The Engine processes the request and sets the service to the new configuration. If the request affects a standard security setting, it is handled by the Engine. If the request is service-specific, the Engine calls the appropriate attachment engine to handle the request.

The diagram below illustrates how the attachment engine and snap-in extension work within the framework of the Security Configuration tool set.


Attachment Snap-In Extensions

An attachment snap-in extension is the component of an attachment that displays the service-specific user interface. The snap-in extension is hosted by the Security Configuration snap-ins. The communication between the attachment extension and its snap-in host is handled by the standard MMC mechanisms described in the Microsoft Management Console documentation in the Platform SDK.

In addition to the interfaces that the snap-in extension must support in order to be an MMC snap-in extension, an attachment snap-in extension must also support the COM interface, ISceSvcAttachmentPersistInfo. This interface implements methods that indicate whether there is service-specific data that should be saved to the security database, and if so, retrieve and save this new data. The Security Configuration snap-ins call methods of this interface regularly in order to update the security database.

The Security Configuration snap-ins implement an interface, ISceSvcAttachmentData, that provides methods to retrieve service-specific data from the security database. Attachment snap-in extensions can call methods of this interface to retrieve data from the security database.

This architecture is illustrated in the following diagram.

When you create an attachment snap-in extension, you must install it and register it with the Security Configuration snap-ins. You do this by adding keys to the registry, as explained in Registering an Attachment Snap-in Extension. When a Security Configuration snap-in starts, it checks the registry and loads any registered snap-in extensions. The extensions appear as nodes under the security area for each service in the Security Configuration snap-in.

Note An attachment snap-in extension can only extend Services nodes. The Services node is the MMC snap-in for Windows NT/Windows 2000 that contains tools to administer services installed on the system. The attachment snap-in extension declares itself as being a subordinate to a specific Services node type, and then for each occurrence of that Services node type, the MMC console automatically adds the related snap-in extensions.

Each attachment snap-in extension owns one scope pane node and the related result pane in MMC.

For more information about how to write an MMC snap-in, see the Microsoft Management Console documentation in the Platform SDK.


Attachment Engines

An attachment engine is a DLL that handles service-specific configuration and analysis requests.

The user makes a service-specific configuration and analysis request using the attachment snap-in extension. This request is then passed through the Security Configuration snap-ins to the general Security Configuration Engine, which in turn passes the service-specific processing to the appropriate attachment engine. The attachment engine then connects to the service and changes its configuration. In other words, the attachment engine provides the back-end processing that supports the attachment snap-in extension.

An attachment engine must implement the following three functions:

  • SceSvcAttachmentAnalyze, which computes the difference between the service's configuration and the configuration stored in the security database. The differences are written to the security database.
  • SceSvcAttachmentConfig, which configures the service as specified in the snap-in user interface.
  • SceSvcAttachmentUpdate, which updates the base configuration and configuration analysis for the service in the security database.

To simplify implementation of the preceding functions, the Security Configuration tool set provides support functions and structures that your application can use to query and set information in the security database. For more information, see Attachment Callback Functions.

When you create an attachment engine DLL, you must install it and then register it with the Security Configuration Engine. To register the DLL, you add a specific key to the registry. When the Security Configuration Engine starts, it checks the registry and loads all registered attachment engine DLLs. It then passes service-specific configuration and analysis requests to the appropriate attachment engine. Standard configuration and analysis requests, those that are not service-specific, are handled by the Security Configuration Engine.


Security Templates

The Security Templates is a standalone snap-in tool that users can use to define machine-independent security configurations. These configurations are saved as text-based .inf files.

The Security Templates and the Security Configuration and Analysis comprise the Security Configuration snap-ins.


Security Configuration and Analysis

The Security Configuration and Analysis is a stand-alone snap-in tool that users can use to import one or more saved configurations to a private security database. Importing configurations builds a machine-specific security database that stores a composite configuration. You can apply this composite configuration to the computer and analyze the current system configuration against the stored composite configuration stored in the database.

The Security Templates and the Security Configuration and Analysis comprise the Security Configuration snap-ins.


Using Service Security Attachments

This section describes how to create the attachment components required to support a service-specific configuration in the Security Configuration snap-ins. You will need to implement and register two components: a extension snap-in to display a user interface and an attachment engine to process configuration and analysis requests.

For more information see the following topics:

  • Creating an Attachment Snap-in Extension
  • Registering an Attachment Snap-in Extension
  • Creating an Attachment Engine
  • Registering an Attachment Engine


Creating an Attachment Snap-in Extension

An attachment snap-in extension provides an interface that users can use to change service-specific configuration settings. The attachment snap-in extension must fulfill the MMC requirements to be a valid snap-in extension. For more information on those requirements, see the Microsoft Management Console documentation in the Platform SDK.

In addition to the interfaces required by MMC, an attachment snap-in extension must implement the COM interface ISceSvcAttachmentPersistInfo. The Security Configuration snap-ins call methods of this interface to determine whether the configuration data has changed, and if so, to update the security database. The attachment snap-in must store any configuration changes until the Security Configuration snap-ins retrieves that data.

An attachment snap-in extension must provide the following functionality:

  • Display Configuration and Analysis Information
  • Modify Configuration Information in the User Interface
  • Modify Configuration Information in the Security Database

To assist your snap-in extension in performing these tasks, the Security Configuration snap-ins implement a COM interface, ISceSvcAttachmentData, which provides methods your snap-in extension can call in order to initialize itself and query information from the security database.

After you have created your attachment snap-in extension, you must register it with the Security Configuration snap-ins as described in Registering an Attachment Snap-in Extension.


Implementing ISceSvcAttachmentPersistInfo

Attachment snap-in extensions must implement the ISceSvcAttachmentPersistInfo interface. The Security Configuration snap-ins query this interface periodically, such as when saving the configuration or closing the snap-in. This allows the snap-in extension to save any modifications that the user may have made to the inspection database or to the associated configuration.

The following example shows one way to implement ISceSvcAttachmentPersistInfo.

class CSceSvcAttachmentPersistInfo:
  public ISceSvcAttachmentPersistInfo,
  public CComObjectRoot
{
BEGIN_COM_MAP(CSceSvcAttachmentPersistInfo)
  COM_INTERFACE_ENTRY(ISceSvcAttachmentPersistInfo)
END_COM_MAP()

  friend class CDataObject;
  friend class CComponentDataImpl;

  CSceSvcAttachmentPersistInfo();
  ~CSceSvcAttachmentPersistInfo();

public:

  // ISceSvcAttachmentPersistInfo interface members
  STDMETHOD(IsDirty)(LPTSTR lpTemplateName);
  STDMETHOD(Save)(LPTSTR lpTemplateName, SCESVC_HANDLE *pscesvcHandle, PVOID *ppvData, PBOOL pbOverwriteAll );
  STDMETHOD(FreeBuffer)(PVOID pvData);

  ...

};

//
// Implementing IsDirty
//
STDMETHODIMP CSceSvcAttachmentPersistInfo::IsDirty(LPTSTR lpTemplateName)
{
  if ( m_pSnapin == NULL ) {
return S_FALSE;
  }
  //
  // just calling the snapin's main IsDirty
  //
  return m_pSnapin->IsDirty();
}

//
// Implementing Save
//
STDMETHODIMP CSceSvcAttachmentPersistInfo::Save(LPTSTR lpTemplateName,
       SCE_HANDLE *psceHandle,
       PVOID *ppvData,
       PBOOL pbOverwriteAll )
{
  if ( psceHandle == NULL || ppvData == NULL ||
pbOverwriteAll == NULL ) {
    return E_INVALIDARG;
  }

  if ( m_pSnapin != NULL ) {

    m_pSnapin->SaveDataInBuffer(lpTemplateName, psceHandle,
ppvData, pbOverwriteAll);

    *psceHandle = m_sceHandle;

  }

  return S_OK;
}

//
// Implementing FreeBuffer
//
STDMETHODIMP CSceSvcAttachmentPersistInfo::FreeBuffer(PVOID pvData)
{
  if ( pvData == NULL ) {
    return S_OK;
  }

  PSCESVC_ANALYSIS_INFO pTempInfo=(PSCESVC_ANALYSIS_INFO)pvData;

  if ( pTempInfo->Lines != NULL ) {

    for ( DWORD i=0; i < pTempInfo->Count; i++ ) {

      if ( pTempInfo->Lines[i].Key != NULL )
        LocalFree(pTempInfo->Lines[i].Key);

      if ( pTempInfo->Lines[i].Value != NULL )
        LocalFree(pTempInfo->Lines[i].Value);
    }

    LocalFree( pTempInfo->Lines);
  }

  LocalFree(pTempInfo);

  return S_OK;
}


Displaying Configuration and Analysis Information

Your snap-in extension must display the current configuration and analysis information to the users.

To display information, the attachment snap-in extension node must extend the Security Configuration snap-ins using the Services node. The Services node is the MMC snap-in that administers services installed on the system. The node types that can be extended are:

Configuration Services NodeType={24a7f717-1f0c-11d1-affb-00c04fb984f9}
Inspection Services NodeType={678050c7-1ff8-11d1-affb-00c04fb984f9}

When the Services node is expanded, the MMC notifies all registered snap-in extensions. Each attachment snap-in should insert itself under the Services node, and perform the following tasks:

  • Call QueryInterface to get a pointer to the ISceSvcAttachmentData interface exposed by the Security Configuration snap-ins.
  • Call ISceSvcAttachmentData::Initialize to inform the Security Configuration snap-ins that the snap-in extension is loaded and to establish a context for communications.
  • Call ISceSvcAttachmentData::GetData to retrieve configuration information from the database. This step can be performed either when the snap-in extension initializes itself or when the user opens its node.

For more information, see Adding an Attachment Snap-in Extension Node.


Adding an Attachment Snap-in Extension Node

An attachment snap-in extension must add itself under the Services node when that node is expanded by a user. This topic describes how your snap-in extension can do that.

When a user expands the Services node under one of the Security Configuration snap-ins, MMC uses IComponentData::Notify and the MMCN_EXPAND event to notify the Security Configuration snap-in, plus all its extensions.

The Security Configuration snap-in then extracts its internal format from the lpDataObject, which is passed in from the MMC main framework as type LPDATAOBJECT. It stops processing when it sees the Services node type. The attachment snap-in extension then extracts the node type from the lpDataObject. If the node type is one of the service's defined node types, the attachment snap-in extension inserts its root nodes under the specified parent node. This is illustrated in the following example. (Note that in this example, ExtractNodeType, is a private function that the extension implements. It looks at the data object to get the node type. The implementation of this function is not shown.)

// Detect which extension node to expand.
GUID* nodeType = ExtractNodeType(lpdataObject);

if (nodeType == NULL)
{
  return S_OK
}

if (::IsEqualGUID(*nodeType, cNodetypeSceTemplateServices) == TRUE)
{
  folderType =ATTACHMENT_STATIC;    // defined by attachment writer
}

else if (::IsequalGUID(*nodeType, cNodetypeSceAnalysisServices) == TRUE)
{
  folderType = ATTACHMENT_STATIC_ANALYSIS;    // defined by attachment writer
}

// Free resources.
::GlobalFree(reinterpret_cast<HANDLE>(nodeType));

// Add service attachment root node and remember it as the
// root of the SMB extension name space.
CheckAndInsertRootNodeToMMCScopePane


Establishing Communication with Configuration Snap-ins

Once your attachment snap-in extension has added itself to the Services node, it should establish communication with the Security Configuration snap-in. This is necessary because the attachment snap-in extension gets its data, as well as any changes made by the user, from the Security Configuration snap-in. This can be done as described in the following procedure:

To establish communication with the Security Configuration snap-ins

  1. Obtain the configuration name using the clipboard format described in Clipboard Format. If the attachment is inserted under a configuration type node, the attachment needs to know which configuration it is. (It communicates this information to the Security Configuration snap-ins during interface initialization.) This is illustrated in the following code:
    PWSTR * TemplateName = ExtractTemplateFromDataObject(lpDataObject);
  2. Set up the context with the Security Configuration snap-ins. Once the configuration name is known, or if the service node is an analysis node, the attachment snap-in extension must call ISceSvcAttachmentdata::Initialize to set up the context. This is illustrated in the following example:
    LPSCESVCATTACHMENTPERSISTINFO pSceInfo;

    HRESULT hr = ((LPSCESVCATTACHMENTPERSISTINFO)this)->QueryInterface(IID_ISceSvcAttachmentPersistInfo,(void**)&pSceInfo);

    if ( SUCCEEDED(hr) ) {

        hr = m_pSceData->Initialize(strServiceName, TemplateName, pSceInfo, &ThisHandle);

Note When you are done with the handle returned by Initialize, you should call CloseHandle to close the handle. This is typically done when the user closes the MMC console.


Getting Data from the Configuration Snap-ins

The attachment snap-in extension has no way to directly query the security database to retrieve information. Instead, it must query this information from the Security Configuration snap-ins using ISceSvcAttachmentData::GetData.

The attachment snap-in can retrieve all of the data when it initializes itself, or it can retrieve information when its node is opened.

Note You must use the ISceSvcAttachmentData::FreeBuffer method to free the buffer allocated by the Security Configuration snap-in method ISceSvcAttachmentData::GetData.


Modifying Configuration Information in the User Interface

An attachment snap-in extension must allow the user to modify configuration information about the service. The modified information should be stored by the attachment snap-in extension until the Security Configuration snap-in calls methods of the ISceSvcAttachmentPersistInfo interface to retrieve the information.

To avoid memory leaks, free memory allocated by the snap-in extension by calling ISceSvcAttachmentPersistInfo::FreeBuffer.


Modifying Configuration Information in the Database

The attachment snap-in extension must enable users to change configuration information through its analysis node. This allows users to make changes and then re-apply the configuration over time. The logic to do this should be identical to modifying information in the configuration files. The changes made will take effect on the saved configuration in the security database.


Registering an Attachment Snap-in Extension

After you create an attachment snap-in extension, you must register it in order for the MMC and the Security Configuration snap-ins to locate and use it.

Your attachment snap-in must extend the Security Configuration snap-ins namespace by adding its own node as described in the following procedure.

To install and register the attachment snap-in extension

  1. Register the snap-in extension under the following registry key. Do not create a StandAlone key under the snap-in; attachment snap-ins extensions must only be extensions.

    HKEY_LOCAL_MACHINE\

    software\

    Microsoft\

    MMC\

    Snapins

  2. Register the attachment snap-in extension under the following subkeys. This can be done as part of your DllRegisterServer and DllUnregisterServer function implementations.

    Security Templates namespace:

    HKLM

    software\

    Microsoft\

    MMC\

    NodeTypes\

    24a7f717-1f0c-11d1-affb-00c04fb984f9\

    Extensions\

    NameSpace

    Security Configuration and Analysis namespace:

    HKLM

    software\

    Microsoft\

    MMC\

    NodeTypes\

    678050c7-1ff8-11d1-affb-00c04fb984f9\

    Extensions\

    NameSpace


Creating an Attachment Engine

An attachment engine is a DLL that processes service-specific configuration and analysis requests. In other words, it handles the processing that cannot be handled by the standard Security Configuration tool set.

To create an attachment engine, you must implement the following three functions:

  • SceSvcAttachmentAnalyze, which computes the difference between the service's configuration and the configuration stored in the security database. These differences are written to the security database. For more information, see Implementing SceSvcAttachmentAnalyze.
  • SceSvcAttachmentConfig, which configures the service as specified in the snap-in user interface. For more information, see Implementing SceSvcAttachmentConfig.
  • SceSvcAttachmentUpdate, which updates the base configuration and configuration analysis for the service in the security database. For more information, see Implementing SceSvcAttachmentUpdate.

The Security Configuration tool set implements a set of support functions that your application can call to query and set information in the security database. For more information, see Attachment Callback Functions.

After you create an attachment engine DLL, you must register it with the Security Configuration tool set. This process is described in Registering an Attachment Engine.

In addition to creating an attachment engine, you must also create an attachment snap-in extension. The snap-in extension provides a user interface for service-specific tasks. When the user specifies a new configuration using a snap-in extension, the request is passed to the appropriate attachment engine. The engine then connects to the service and changes its configuration. If you do not implement a snap-in extension, users will have no way to change the service configuration or analysis. For more information on how to create an attachment snap-in extension, see Creating an Attachment Snap-in Extension.


Implementing ISceSvcAttachmentAnalyze

Platform SDK: Security

Implementing SceSvcAttachmentAnalyze

The SceSvcAttachmentAnalyze function must retrieve configuration information from the security database and the service, compare the two sets of information, and then update the analysis section of the security database with any differences. You can ensure this by using the following algorithm.

To implement SceSvcAttachmentAnalyze

  1. Define the variables needed to retrieve and set the security information and return codes.
  2. Call the pfQueryInfo callback function in the callback structure to retrieve configuration information from the security database.
  3. Retrieve the corresponding information from the service.
  4. Compare the configuration data retrieved from the service with that retrieved from the security database.
  5. If the information is not the same, call the pfSetInfo callback function in the callback structure to update the database.
  6. Free all buffers used to retrieve information. Call the pfFreeInfo callback function in the callback structure to free memory used for returned database information.
  7. If there is any message that the extension wants to add to the analysis log file, call the pfLogInfo callback function in the callback structure.
  8. Return the appropriate SCESTATUS codes.

The following code illustrates one possible implementation of SceSvcAttachmentAnalyze. Note that in this example, the functions QueryConfigurationLine and CompareValue respectively query information from the service and compare those values with those retrieved from the security database. The implementation of these functions is not shown.

SCESTATUS
WINAPI
SceSvcAttachmentAnalyze (
IN PSCESVC_CALLBACK_INFO pSceCbInfo
)
  {

  ////////////////////////////////////////////////////
  // Define variables.
  ////////////////////////////////////////////////////
  PSCESVC_CONFIGURATION_INFO     pConfigInfo = NULL;
  SCESTATUS                      retCode;
  SCE_ENUMERATION_CONTEXT        EnumContext = 0;

if ( pSceCbInfo == NULL ||
         pSceCbInfo->sceHandle == NULL ||
         pSceCbInfo->pfQueryInfo == NULL ||
         pSceCbInfo->pfSetInfo == NULL ||
         pSceCbInfo->pfFreeInfo == NULL ) {
return(SCESTATUS_INVALID_PARAMETER);
    }

  ////////////////////////////////////////////////////
  // Retrieve information from security database.
  ///////////////////////////////////////////////////
  do
  {
    retCode =  (*(pSceCbInfo->pfQueryInfo))(
                              pSceCbInfo->sceHandle,
                              SceSvcConfigurationInfo,
                              NULL,
                              FALSE,
                              &pConfigInfo,
                              &EnumContext
                              );
    if(retCode == SCESTATUS_SUCCESS && pConfigInfo != NULL)
    {
      ULONG i;
      for(i = 0;i < pConfigInfo->Count; i++)
      {
        if(pConfigInfo->Line[I].Key == NULL) continue;

        //////////////////////////////////////////////
        // Query service for corresponding key.
        //////////////////////////////////////////////
        QueryConfigurationLine(
                               pConfigInfo->Line[i].Key,
                               &SystemValue);

        //////////////////////////////////////////////
        // Compare values.
        //////////////////////////////////////////////
        CompareValue(
                     pConfigInfo->Line[i].Key,
                     SystemValue,
                     pConfigInfo->Line[i].Value,
                     &Result);

        //////////////////////////////////////////////
        // Write to security database if values are
        // not equal.
        //////////////////////////////////////////////
        if(Result != NULL)
        {
          retCode =  (*(pSceCbInfo->pfSetInfo))(pSceCbInfo->sceHandle,
                                  SceSvcAnalysisInfo,
                                  pConfigInfo->Line[i].Key,
                                  TRUE,
                                  Result);
          if(retCode != SCESTATUS_SUCCESS)
          {
            //////////////////////////////////////////
            // Add code to handle other return codes.
            //////////////////////////////////////////
          }
        }
      }

      //////////////////////////////////////////////
      // Free all buffers used to retrieve
      // SceSvcFree frees memory allocated by call
      // to SceSvcQueryQueryInfo.
      /////////////////////////////////////////
(*(pSceCbInfo->pfFreeInfo)) (PVOID)pConfigInfo);
      pConfigInfo = NULL;
    }
  } while (retCode == SCESTATUS_SUCCESS && pConfigInfo != NULL);

  //////////////////////////////////////////////////
  // If the return code is not SCESTATUS_SUCCESS, add code to
  // set error message appropriately.
  //////////////////////////////////////////////////
  return retCode;
  }


Implementing ISceSvcAttachmentConfig

Platform SDK: Security

Implementing SceSvcAttachmentConfig

The SceSvcAttachmentConfig function must retrieve information from the security database and then use that information to configure the service.

When implementing SceSvcAttachmentConfig, you can either retrieve all of the information and then configure the service, or retrieve and configure the service in steps. The following algorithm retrieves all of the information and then configures the service.

To implement SceSvcAttachmentConfig

  1. Define the variables needed to retrieve information and return codes.
  2. Call the pfQueryInfo callback function in the callback structure to retrieve configuration information from the security database.
  3. Configure the system with the returned information.
  4. Call the pfFreeInfo callback function in the callback structure to free memory used for returned information.
  5. If there is any message that the extension wants to add to the analysis log file, call the pfLogInfo callback function in the callback structure.
  6. Return the appropriate SCESTATUS codes.

The following code illustrates one possible implementation of SceSvcAttachmentConfig. Note that in this example, the function ProcessConfigurationLine sets the service configuration. The implementation of this function is not shown.

SCESTATUS
WINAPI
SceSvcAttachmentConfig (IN PSCESVC_CALLBACK_INFO pSceCbInfo
)
  {

  ////////////////////////////////////////////////////
  // Define variables.
  ////////////////////////////////////////////////////
  PSCESVC_CONFIGURATION_INFO     pConfigInfo = NULL;
  SCESTATUS                      retCode;
  SCE_ENUMERATION_CONTEXT        EnumContext = 0;

     if ( pSceCbInfo == NULL ||
         pSceCbInfo->sceHandle == NULL ||
         pSceCbInfo->pfQueryInfo == NULL ||
         pSceCbInfo->pfSetInfo == NULL ||
         pSceCbInfo->pfFreeInfo == NULL ) {

return(SCESTATUS_INVALID_PARAMETER);
  }

  ////////////////////////////////////////////////////
  // Retrieve configuration information and configure
  // system.
  ////////////////////////////////////////////////////
  do
  {
    retCode = (*(pSceCbInfo->pfQueryInfo))( pSceCbInfo->sceHandle,
                              SceSvcConfigurationInfo,
                              NULL,
                              FALSE,
                              (PVOID *)&pConfigInfo,
                              &EnumContext
                             );
    if (retCode == SCESTATUS_SUCCESS && pConfigInfo != NULL)
    {
      ULONG i:
      //////////////////////////////////////////////////
      // Configure system.
      /////////////////////////////////////////////////
      For(i = 0; < pConfigInfo->Count; i++)
      {
        if(pConfigInfo->Line[i].Key == NULL) continue;
        ProcessConfigurationLine(pConfigInfo->Line[i]);
      }

      //////////////////////////////////////////////////
      // Free data returned.
      /////////////////////////////////////////////////
      (*(pSceCbInfo->pfFreeInfo)) ((PVOPID)pConfigInfo);
      pConfigInfo = NULL;
    }
  } while (retCode == SCESTATUS_SUCCESS && CountReturned > 0);

  ////////////////////////////////////////////////////
  // Add code for other return codes if retCode is
  // not SCESTATUS_SUCCESS.
  ///////////////////////////////////////////////////
  return retCode;
}


Implementing SceSvcAttachmentUpdate

The SceSvcAttachmentUpdate function takes as a parameter a set of supplied configuration information. It then retrieves information from the security database, computes a new base configuration using the supplied configuration information, computes new analysis information based on the database information and the supplied configuration information, and updates the database with new base configuration and analysis information. You can implement SceSvcAttachmentUpdate by using the following algorithm.

To implement SceSvcAttachmentUpdate

  1. Define the variables needed to retrieve information, set information, and return codes.
  2. Call the pfQueryInfo callback function in the callback structure to retrieve the current configuration information from the security database.
  3. Compare the values:
    • If the data differs, call the pfSetInfo callback function in the callback structure to update the configuration data in the database.
    • If the data is the same, call the pfSetInfo callback function in the callback structure to update the analysis data in the database.
  4. Repeat until all data is processed.

The following code illustrates one possible implementation of SceSvcAttachmentUpdate.

SCESTATUS
WINAPI
SceSvcAttachmentUpdate (
IN PSCESVC_CALLBACK_INFO pSceCbInfo,
IN SCESVC_CONFIGURATION_INFO *ServiceInfo
)
  {

  ////////////////////////////////////////////////////
  // Define variables.
  ////////////////////////////////////////////////////
  SCESTATUS                      retCode;
  SCE_ENUMERATION_CONTEXT        EnumContext = 0;
 if ( pSceCbInfo == NULL ||
         pSceCbInfo->sceHandle == NULL ||
         pSceCbInfo->pfQueryInfo == NULL ||
         pSceCbInfo->pfSetInfo == NULL ||
         pSceCbInfo->pfFreeInfo == NULL ||
         ServiceInfo == NULL ) {
return(SCESTATUS_INVALID_PARAMETER);
  }

  ////////////////////////////////////////////////////
  // Process supplied configuration information.
  ////////////////////////////////////////////////////
  for (i=0; i < ServiceInfo->Count; i++)
  {
    retCode = (*(pSceCbInfo->pfQueryInfo))( pSceCbInfo->sceHandle,
                              SceSvcConfigurationInfo,
                              ServiceInfo->Line[I].Key,
                              TRUE,
                              (PVOID *)&pConfigInfo,
                              &EnumContext
                              );
    if(retCode != SCESTATUS_SUCCESS &&
       retCode != SCESTATUS_RECORD_NOT_FOUND)
    {
      ////////////////////////////////////////////////
      // Add code to handle errors
      ////////////////////////////////////////////////
      break;
    }

    //////////////////////////////////////////////////
    // If the supplied key is NULL, delete corresponding
    // key from configuration information and update
    // analysis information if needed.
    //////////////////////////////////////////////////
    if(ServiceInfo->Line[I].Value == NULL)
    {
      if(retCode == SCESTATUS_SUCCESS)
      {
        EnumContext = 0;
        retCode = (*(pSceCbInfo->pfQueryInfo))( pSceCbInfo->sceHandle,
                                  SceSvcAnalysisInfo,
                                  ServiceInfo->Line [i].Key,
                                  TRUE,
                                  (PVOID *)&pAnalInfo,
                                  &EnumContext
                                  );
        if(retCode == SCESTATUS_RECORD_NOT_FOUND)
        {
          ////////////////////////////////////////////
          // Analysis information for key was not found.
          // Update analysis information to include
          // deleted key.
          /////////////////////////////////////////////
          UpdateInfo->Count = 1;
          UpdateInfo->Line = &UpdateLine;
          UpdateLine.Key = pConfigInfo->Line[0].Key;
          UpdateLine.Value = (PBYTE)pConfigInfo->Line[0].Value;
          retCode = (*(pSceCbInfo->pfSetInfo))( pSceCbInfo->sceHandle,
                                  SceSvcAnalysisInfo,
                                  NULL,
                                  TRUE,
                                  &UpdateInfo
                                  );
          if(retCode != SCESTATUS_SUCCESS)
          {
            //////////////////////////////////////////
            // Add code for error return codes.
            //////////////////////////////////////////
          }
        }
        elseif (retCode == SCESTATUS_SUCCESS)
        {
          ////////////////////////////////////////////
          // Add code to delete configuration (analysis
          // information is already in place.
          ////////////////////////////////////////////
        }
        else
        {
          //////////////////////////////////////////
          // Add code for error return codes.
          //////////////////////////////////////////
        }

        //////////////////////////////////////////////
        // Delete key.
        //////////////////////////////////////////////
        retCode = (*(pSceCbInfo->pfSetInfo))( pSceCbInfo->sceHanlde,
                                SceSvcConfigurationInfo,
                                ServiceInfo->Line[I].Key,
                                TRUE,
                                NULL
                                );
        if(retCode != SCESTATUS_SUCCESS)
        {
          //////////////////////////////////////////
          // Add code for error return codes.
          //////////////////////////////////////////
        }

      }
    else
   {
     /////////////////////////////////////////////////
     // Supplied value is non-NULL; therefore. compare
     // with current analysis information. If both are
     // the same, delete current analysis. If they are
     // not the same, update security database with new
     // value.
     //////////////////////////////////////////

   }

   //////////////////////////////////////////////////
   // Free data returned.
   /////////////////////////////////////////////////
 (*(pSceCbInfo->pfFreeInfo))(pConfigInfo);
   pConfigInfo = NULL;

 (*(pSceCbInfo->pfSetInfo))(pAnalInfo);
   pAnalInfo = NULL;

  ////////////////////////////////////////////////////
  // Add code for other return codes if retCode is
  // not SCESTATUS_SUCCESS.
  ///////////////////////////////////////////////////
  return retCode;
  }

  }


Registering an Attachment Engine

Before the Security Configuration Engine can call your attachment engine to process service-specific tasks, you must install your attachment engine and register it with the Security Configuration Engine.

To install and register the attachment engine DLL

  1. Copy the attachment engine DLL to a directory on the system. The preferred directory is %windir%\secedit\attachments. If this directory does not exist, you should create it.
  2. Create a registry key under the following node. The service name entered here is the registered name for the attachment, and must be the same service name used in the Service Control Manager, a component which manages the stopping and starting of services. The name must also be unique so it does not conflict with the names of other attachments. (Items in italics should be replaced with your text.)

    HKEY_LOCAL_MACHINE\

    software\

    Microsoft\

    Windows NT\

    CurrentVersion\

    SecEdit\Service\

    service_name

  3. Create the following values in the new registry key. (Items in italics should be replaced with your text.)
    Value Name = ServiceAttachmentPath
Value Type = REG_SZ
Value = Full path to the attachment engine DLL (for example,
        %windir%\secedit\attachments\myEngine.DLL)


Attachment Reference

This reference section details the interfaces implemented by attachments, the functions provided by the configuration tool set, and related data structures.

For information on | See
The functions an attachment engine must support. | Attachment Engine Interface
The COM interface an attachment snap-in extension must support. | Attachment Snap-in Interfaces
The support functions provide by the Security Configuration tool set. | Attachment Callback Functions
The data structures used by the functions and interfaces | Structures
Values returned by Security Configuration functions and methods. | Return Values
The clipboard format used to extract the configuration file name from the Security Configuration snap-ins. | Clipboard Format

The SceSvcConvertSDToText and SceSvcConvertTextToSD functions are obsolete. Instead, use the Win32 API functions ConvertSecurityDescriptorToStringSecurityDescriptor and ConvertStringSecurityDescriptorToSecurityDescriptor, which provide the same functionality.


Attachment Engine Interface

A Security Configuration attachment engine DLL must implement the following functions.

Functions | Description
SceSvcAttachmentAnalyze | Implemented by the attachment engine DLL. The Security Configuration Engine calls this function when the system is analyzed.
SceSvcAttachmentConfig | Implemented by the attachment engine DLL. The Security Configuration Engine calls this function when the system is configured.
SceSvcAttachmentUpdate | Implemented by the attachment engine DLL. The Security Configuration Engine calls this function when it receives a configuration update request from the attachment snap-in extension.


SceSvcAttachmentAnalyze

The SceSvcAttachmentAnalyze function is called by the Security Configuration Engine when the system is configured.

SCESTATUS WINAPI SceSvcAttachmentAnalyze(
  PSCESVC_CALLBACK_INFO pSceCbInfo
);

Parameters

pSceCbInfo
Pointer to a SCESVC_CALLBACK_INFO structure which contains an opaque database handle and callback function pointers to query, set, and free information.

Return Value

If this function succeeds, it returns SCESTATUS_SUCCESS. Otherwise it returns an error code. For more information about the Security Configuration error codes, see Return Values.

Remarks

The SceSvcAttachmentAnalyze function must do the following:

  • Directly query configuration information from the service.
  • Call the callback function pointed to by the pfQueryInfo member of the SCESVC_CALLBACK_INFO structure (pSceCbInfo->pfQueryInfo) to retrieve information from the security database.
  • Compute the differences between the information based on type and syntax.
  • Call the callback function pointed to by the pfSetInfo member of the SCESVC_CALLBACK_INFO structure (pSceCbInfo->pfSetInfo) to update the security database with the retrieved service information that is different.

For more information, see Implementing SceSvcAttachmentAnalyze.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.

See Also

SCESVC_CALLBACK_INFO, SceSvcAttachmentConfig, Implementing SceSvcAttachmentAnalyze


SceSvcAttachmentConfig

The SceSvcAttachmentConfig function is called by the Security Configuration Engine when the system is configured.

SCESTATUS WINAPI SceSvcAttachmentConfig(
  PSCESVC_CALLBACK_INFO pSceCbInfo
);

Parameters

pSceCbInfo
Pointer to a SCESVC_CALLBACK_INFO structure that contains the database handle and the callback functions to query, set, and free information.

Return Value

If this function succeeds, it returns SCESTATUS_SUCCESS. Otherwise it returns an error code. For more information about the Security Configuration error codes, see Return Values.

Remarks

When implementing this function, use the callback function pointed to by the pfQueryInfo member of the SCESVC_CALLBACK_INFO structure (pSceCbInfo->pfQueryInfo) to retrieve configuration information. Then configure the service using the returned information.

This function must do the following:

  • Query configuration information from the Security Configuration tool set using the callback function pointed to by the pfQueryInfo member of the SCESVC_CALLBACK_INFO structure (pSceCbInfo->pfQueryInfo).
  • Configure the service using the configuration information.

For more information, see Implementing SceSvcAttachmentConfig

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.

See Also

SCESVC_CALLBACK_INFO, SceSvcAttachmentAnalyze


SceSvcAttachmentUpdate

The SceSvcAttachmentUpdate function is called by the Security Configuration snap-ins to pass configuration changes to the security database.

SCESTATUS WINAPI SceSvcAttachmentUpdate(
  PSCESVC_CALLBACK_INFO pSceCbInfo,
  SCESVC_CONFIGURATION_INFO *ServiceInfo
);

Parameters

pSceCbInfo
Pointer to a SCESVC_CALLBACK_INFO structure which contains the callback handle and function pointers to SCE.
ServiceInfo
Updated configuration information. The data structure used for this information is SCESVC_CONFIGURATION_INFO.

Return Value

If this function succeeds, it returns SCESTATUS_SUCCESS. Otherwise it returns an error code. For more information about the Security Configuration error codes, see Return Values.

Remarks

The SceSvcAttachmentUpdate function must do the following:

  • Call the callback function pointed to by the pfQueryInfo member of the SCESVC_CALLBACK_INFO structure (pSceCbInfo->pfQueryInfo) to retrieve the current base configuration information from the security database.
  • Call the callback function pointed to by the pfQueryInfo member of the SCESVC_CALLBACK_INFO structure (pSceCbInfo->pfQueryInfo) to retrieve the last set of differences (analysis information) from the security database.
  • Use the supplied service information (see ServiceInfo) to compute the new base configuration.
  • Use the supplied service information (see ServiceInfo) and the analysis to compute the new difference information.
  • Call the callback function pointed to by the pfSetInfo member of the SCESVC_CALLBACK_INFO structure (pSceCbInfo->pfSetInfo)to set the new base configuration in the security database.
  • Call the callback function pointed to by the pfSetInfo member of the SCESVC_CALLBACK_INFO structure (pSceCbInfo->pfSetInfo) to set the new analysis information in the security database.

For more information, see Implementing SceSvcAttachmentUpdate

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.

See Also

SCESVC_CALLBACK_INFO, SCESVC_CONFIGURATION_INFO


Attachment Snap-in Interfaces

In addition to the COM interfaces that all snap-ins extensions must implement, an attachment snap-in extension must also implement the ISceSvcAttachmentPersistInfo interface. The Security Configuration snap-ins calls this interface to retrieve any modified information from the attachment snap-in extension. The Security Configuration snap-in then stores this data appropriately in the security database.

The Security Configuration snap-ins expose an interface, ISceSvcAttachmentData, which attachment snap-in extensions call to query configuration or analysis information.

For more information about the COM interfaces that must be implemented by snap-in extensions, see the Microsoft Management Console documentation in the Platform SDK.


ISceSvcAttachmentData

The ISceSvcAttachmentData interface retrieves configuration and analysis data about a specified security service from the Security Configuration snap-ins.

When to Implement

You do not need to implement this interface, it is implemented by both Security Templates and Security Configuration and Analysis, in Wsecedit.dll.

When to Use

Call the methods of ISceSvcAttachmentData to retrieve configuration or analysis information.

Methods in Vtable Order

IUnknown method | Description
QueryInterface | Returns pointers to supported interfaces.
AddRef | Increments reference count.
Release | Decrements reference count.

IsceSvcAttachmentData method | Description
GetData | Retrieves data from the Security Configuration snap-in.
Initialize | Initializes a connection to the Security Configuration snap-in.
FreeBuffer | Frees a data buffer allocated by the Security Configuration snap-in.
CloseHandle | Closes the handle to the Security Configuration snap-in.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Scesvc.h.

See Also

ISceSvcAttachmentPersistInfo


ISceSvcAttachmentData::GetData

The GetData method retrieves configuration information from the Security Configuration snap-in.

HRESULT GetData(
  SCESVC_HANDLE sceHandle,
  SCESVC_INFO_TYPE sceType,
  PVOID *ppvData,
  PSCE_ENUMERATION_CONTEXT psceEnumHandle
);

Parameters

sceHandle
[in] A SCESVC_HANDLE returned during a previous call to ISceSvcAttachmentData::Initialize.
sceType
[in] A SCESVC_INFO_TYPE value that indicates the type of information requested from the security database. It can be one of the following values:
SCE_SERVICE_CONFIGURATION_INFO
Requests configuration information from the database.
SCE_SERVICE_ANAYLISYS_INFO
Requests analysis information from the database.
ppvData
[out] Pointer to a buffer which receives the data.
psceEnumHandle
[in out] An opaque handle used to navigate through the security database.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Scesvc.h.

See Also

SCESVC_INFO_TYPE, ISceSvcAttachmentData::Initialize


ISceSvcAttachmentData::Initialize

The Initialize method informs the Security Configuration snap-in that the snap-in extension is loaded, and it establishes a context for communications.

HRESULT Initialize(
  LPCTSTR ServiceName,
  LPCTSTR TemplateName,
  LPSCESVCATTACHMENTPERSISTINFO lpSceSvcPersistInfo,
  SCESVC_HANDLE *sceHandle
);

Parameters

ServiceName
[in] String that specifies the name of the security service to retrieve information about.
TemplateName
[in] String that specifies the name of the template.
lpSceSvcPersistInfo
[in] Pointer to the ISceSvcAttachmentPersistInfo interface of the attachment snap-in extension.
sceHandle
[out] Pointer that receives an SCESVC_HANDLE that represents the communication context between the Security Configuration snap-in and the snap-in extension. This handle is passed in as a parameter to the other ISceSvcAttachmentData methods. When the attachment snap-in extension no longer needs this handle, free it by calling ISceSvcAttachmentData::CloseHandle.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Scesvc.h.

See Also

SCESVC_HANDLE, ISceSvcAttachmentData::CloseHandle, ISceSvcAttachmentPersistInfo


ISceSvcAttachmentData::FreeBuffer

The FreeBuffer method frees memory allocated by the Security Configuration snap-in.

HRESULT FreeBuffer(
  PVOID pvData
);

Parameters

pvData
[in] Void pointer to the buffer to be freed.

Remarks

You should call this method to free the data buffer returned by ISceSvcAttachmentData::GetData.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Scesvc.h.

See Also

ISceSvcAttachmentData::GetData


ISceSvcAttachmentData::CloseHandle

The CloseHandle method closes a handle opened during a previous call to ISceSvcAttachmentData::Initialize.

HRESULT CloseHandle(
  SCESVC_HANDLE sceHandle
);

Parameters

sceHandle
[in] The SCESVC_HANDLE to close.

Remarks

You should call this method when your attachment snap-in extension no longer requires the handle returned by ISceSvcAttachmentData::Initialize.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Scesvc.h.

See Also

ISceSvcAttachmentData::Initialize


ISceSvcAttachmentPersistInfo

The ISceSvcAttachmentPersistInfo interface retrieves any modified configuration or analysis information from an attachment snap-in.

When to Implement

You must implement this interface if you are writing an attachment snap-in extension.

When to Use

Called by the Security Configuration snap-ins to retrieve modified data from the attachment snap-in extension.

Methods in Vtable Order

IUnknown method | Description
QueryInterface | Returns pointers to supported interfaces.
AddRef | Increments reference count.
Release | Decrements reference count.

ISceSvcAttachmentPersistInfo method | Description
IsDirty | Indicates whether data stored in the attachment snap-in extension has changed since the last time the snap-in extension's data was saved.
Save | Gets the data that needs to be saved from the snap-in extension.
FreeBuffer | Frees memory allocated by the attachment snap-in extension.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Scesvc.h.

See Also

ISceSvcAttachmentData


ISceSvcAttachmentPersistInfo::IsDirty

The IsDirty method returns a value indicating whether data in the attachment snap-in has been modified since it was last saved.

HRESULT IsDirty(
  LPTSTR lpTemplateName
);

Parameters

lpTemplateName
A security template name. Multiple security templates can be modified so that each service extension can be expanded under multiple templates.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Scesvc.h.

See Also

ISceSvcAttachmentPersistInfo::Save


ISceSvcAttachmentPersistInfo::Save

The Save method causes the snap-in extension to return information about the data that needs to be saved. The caller is responsible for saving the data.

HRESULT Save(
  LPTSTR lpTemplateName,
  SCESVC_HANDLE *sceHandle,
  PVOID *ppvData,
  PBOOL pbOverWriteAll
);

Parameters

lpTemplateName
[in] The security template name to save data to.
sceHandle
[in] Pointer that receives the SCESVC_HANDLE the attachment snap-in extension is using to communicate with the Security Configuration snap-ins.
ppvData
[out] Pointer that receives a buffer containing the data to be saved.
pbOverWriteAll
[out] Pointer to a BOOL that receives a value indicating whether preexisting data should be overwritten.

Remarks

The caller should free the buffer set in ppvData by calling ISceSvcAttachmentPersistInfo::FreeBuffer.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Scesvc.h.

See Also

SCESVC_HANDLE, ISceSvcAttachmentPersistInfo::IsDirty, ISceSvcAttachmentPersistInfo::FreeBuffer


ISceSvcAttachmentPersistInfo::FreeBuffer

The FreeBuffer method frees memory allocated by the attachment snap-in extension.

HRESULT FreeBuffer(
  PVOID pvData
);

Parameters

pvData
[in] Pointer to the buffer to free.

Remarks

You should call this method to free the data buffer returned by ISceSvcAttachmentPersistInfo::Save.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Scesvc.h.

See Also

ISceSvcAttachmentPersistInfo::Save


Attachment Callback Functions

The following support functions are provided by the Security Configuration tool set and may be used by attachment engines and extension snap-ins to read and write configuration data.

Callback function | Description
PFSCE_QUERY_INFO | Used to query the configuration and analysis information for a specific service.
PFSCE_SET_INFO | Used to set configuration and analysis information for a specific service.
PFSCE_FREE_INFO | Used to free memory allocated by these support functions.
PFSCE_LOG_INFO | Used to log message to the configuration log file or analysis log file.


PFSCE_QUERY_INFO

The PFSCE_QUERY_INFO callback function queries service-specific information from the Security Configuration file or analysis database.

Typedef SCESTATUS (*PFSCE_QUERY_INFO)(
  SCE_HANDLE sceHandle,
  SCESVC_INFO_TYPE sceType,
  LPTSTR lpPrefix,
  BOOL bExact,
  PVOID *ppvInfo,
  PSCE_ENUMERATION_CONTEXT psceEnumHandle
);

Parameters

sceHandle
[in] Specifies the opaque handle passed to the attachment by the Security Configuration tool set during the call to ISceSvcAttachmentData::Initialize. This handle is used to store the queried information.
sceType
[in] Specifies the type of information to be queried. Specify one of the following flags:
SCE_SERVICE_CONFIGURATION_INFO
Requests configuration information from the database.
SCE_SERVICE_ANAYLISYS_INFO
Requests analysis information from the database.
lpPrefix
[in, optional] Specifies a prefix or key (see bExact) for limiting the query. When a string is supplied, only those keys (and their corresponding values) that match the string are returned. When set to NULL, all keys are returned.
bExact
[in] Specifies whether the string provided by lpPrefix should be treated as a specific key or a prefix. This parameter is ignored if lpPrefix is set to NULL. Specify one of the following values:
TRUE
The string specified in lpPrefix represents a specific key. Only records matching that key are returned.
FALSE
The string specified by lpPrefix represents a prefix. All keys (and their values) that have this same prefix are returned.
ppvInfo
[out] Returns a pointer to one of the following structures. The Security Configuration tool set (not the attachment) allocates the buffer for the information; therefore, this pointer must point to NULL.
SCESVC_CONFIGURATION_INFO
When sceType is set to SCE_SERVICE_CONFIGURATION_INFO.
SCESVC_ANALYSIS_INFO
When sceType is set to SCE_SERVICE_ANALYSIS_INFO.
psceEnumHandle
[out] Returns a handle that can be used in successive calls to this function. Due to the large number of keys that may be present, not all keys are returned in a single call. The maximum number of keys that may be returned in a single call is 256.

Return Values

An SCESTATUS value that indicates the result of the function call. If the function succeeds, it returns SCESTATUS_SUCCESS. Otherwise it returns an error value which can be one of the following.

Error code | Description
SCESTATUS_INVALID_PARAMETER | One of the parameters passed into the function was not valid.
SCESTATUS_RECORD_NOT_FOUND | The specified record was not found in the security database.
SCESTATUS_BAD_FORMAT | The format is not valid.
SCESTATUS_OTHER_ERROR | An unspecified error has occurred.
SCESTATUS_NOT_ENOUGH_RESOURCE | There is insufficient memory.

Remarks

The Security Configuration tool set allocates buffers when PFSCE_QUERY_INFO is called. To free these buffers call PFSCE_FREE_INFO after the returned information is no longer needed.

Examples

For an example of | See
Retrieving configuration information | Implementing SceSvcAttachmentConfig
Retrieving analysis information | Implementing SceSvcAttachmentAnalyze
Retrieving configuration and analysis information | Implementing SceSvcAttachmentUpdate

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Scesvc.h.

See Also

PFSCE_FREE_INFO, SCESVC_ANALYSIS_INFO, SCESVC_CONFIGURATION_INFO,


PFSCE_SET_INFO

The PFSCE_SET_INFO callback function sets or overwrites service-specific configuration and analysis information.

Typedef SCESTATUS (*PFSCE_SET_INFO)(
  SCE_HANDLE sceHandle,
  SCESVC_INFO_TYPE sceType,
  LPTSTR lpPrefix,
  BOOL bExact,
  PVOID ppvInfo,
);

Parameters

sceHandle
[in] Specifies the opaque SCE handle passed to the attachment by the Security Configuration tool set during the call to ISceSvcAttachmentData::Initialize. This handle is used to set or overwrite the information.
sceType
[in] Specifies the type of information to be set. Specify one of the following flags:
SCE_SERVICE_CONFIGURATION_INFO
Indicates that configuration information is set.
SCE_SERVICE_ANAYLISYS_INFO
Indicates that analysis information is set.
lpPrefix
[in, optional] Specifies what information should be set or overwritten. This string can specify a specific key (see bExact) or a prefix for a set of keys. When a string is supplied, only information for those keys (and their corresponding values) that match the string is set. When set to NULL, all information for the service is set.
bExact
[in] Specifies whether the string provided by lpPrefix should be treated as a specific key or a prefix for a set of keys. This parameter is ignored if lpPrefix is set to NULL:

Specify one of the following values:

TRUE
The string specified in lpPrefix represents a specific key. Only that key is set.
FALSE
The string specified by lpPrefix represents a prefix for a set of keys. All keys (and their values) that have the same prefix is set.
ppvInfo
[in] Returns a pointer to one of the following structures. The Security Configuration tool set (not the attachment) allocates the buffer for the information; therefore, this pointer must point to NULL.
SCESVC_CONFIGURATION_INFO
When sceType is set to SCE_SERVICE_CONFIGURATION_INFO.
SCESVC_ANALYSIS_INFO
When sceType is set to SCE_SERVICE_ANALYSIS_INFO.

Return Values

If the function succeeds, it returns SCESTATUS_SUCCESS. Otherwise, it returns an error value which can be one of the following.

Error value | Description
SCESTATUS_ACCESS_DENIED | The caller does not have sufficient privileges to complete this action.
SCESTATUS_BAD_FORMAT | The format is bad.
SCE_DATA_OVERFLOW | There is more data than the buffer can hold.
SCESTATUS_INVALID_PARAMETER | One of the parameters passed into the function was not valid.
SCESTATUS_NOT_ENOUGH_RESOURCE | There is insufficient memory.
SCESTATUS_OTHER_ERROR | An unspecified error has occurred.
SCESTATUS_RECORD_NOT_FOUND | The specified record was not found in the security database.

Examples

For an example of | See
Setting analysis information | Implementing SceSvcAttachmentAnalyze
Setting configuration and analysis information | Implementing SceSvcAttachmentUpdate

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Scesvc.h.

See Also

SCESVC_ANALYSIS_INFO, SCESVC_CONFIGURATION_INFO, PFSCE_QUERY_INFO


PFSCE_FREE_INFO

The PFSCE_FREE_INFO callback function frees the memory for buffers allocated by the Security Configuration tool set when it calls PFSCE_QUERY_INFO.

Typedef SCESTATUS (*PFSCE_FREE_INFO)(
  PVOID pvServiceInfo
);

Parameters

pvServiceInfo
[in] Specifies a pointer to the buffer allocated by the Security Configuration tool set.

Return Values

If the function succeeds, it returns SCESTATUS_SUCCESS. Otherwise, an error code is returned. This can be the following.

Error value | Description
SCSTATUS_INVALID_PARAMETER | One of the parameters passed into the function was not valid.

Examples

For an example of | See
Freeing retrieved configuration information | Implementing SceSvcAttachmentConfig
Freeing retrieved analysis information | Implementing SceSvcAttachmentAnalyze
Freeing retrieved configuration and analysis information | Implementing SceSvcAttachmentUpdate

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Scesvc.h.

See Also

PFSCE_QUERY_INFO


PFSCE_LOG_INFO

The PFSCE_LOG_INFO callback function logs messages to the configuration log file or analysis log file.

Typedef SCESTATUS (*PFSCE_LOG_INFO)(
  INT ErrLevel,
  DWORD  Win32rc,
  LPTSTR pErrFmt,
  ...
);

Parameters

ErrLevel
[in] Specifies the level of information to log. This can be one of the following values.
Value | Description
SCE_LOG_LEVEL_ALWAYS | Records all actions in the log file.
SCE_LOG_LEVEL_ERROR | Records errors in the log file.
SCE_LOG_LEVEL_DETAIL | Records detailed information in the log file.
SCE_LOG_LEVEL_DEBUG | Records debug information in the log file.

Win32rc
[in] Specifies the Win32 result code to log.
pErrFmt
[in] Specifies the result format. This parameter uses the same format conventions as the C library function printf.
…
[in] Additional parameters for the callback function. Their type and number are specified by pErrFmt. For example, if the string pointed to by pErrFmt is "%d%s%d", pErrFmt is followed by three additional arguments: a DWORD, a string, and another DWORD.

Return Values

If the function succeeds, it returns SCESTATUS_SUCCESS. Otherwise an error code is returned.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Scesvc.h.


Structures

The following structure are used by the Security Configuration attachment DLLs and their supporting functions. They are defined in scesvc.h.

Structure | Description
SCESVC_CONFIGURATION_INFO | Used by support functions to retrieve or provide configuration information.
SCESVC_CONFIGURATION_LINE | Used by SCESVC_CONFIGURATION_INFO to retrieve or provide a single line of configuration information.
SCESVC_ANALYSIS_INFO | Used by support functions to retrieve or provide analysis information.
SCESVC_ANALYSIS_LINE | Used by SCESVC_ANALYSIS_INFO to retrieve or provide a single line of analysis information.
SCESVC_CALLBACK_INFO | Used by attachment engine interfaces


SCESVC_CONFIGURATION_INFO

The SCESVC_CONFIGURATION_INFO structure provides configuration information for a service. This structure is used by the PFSCE_QUERY_INFO and PFSCE_SET_INFO functions when the configuration information is specified.

typedef struct _SCESVC_CONFIGURATION_INFO_ {
  DWORD Count;
  PSCESVC_CONFIGURATION_LINE Lines;
} SCESVC_CONFIGURATION_INFO, *PSCESVC_CONFIGURATION_INFO;

Members

Count
Indicates the number of lines of data returned in the Lines array.
Lines
Pointer to an array of SCESVC_CONFIGURATION_LINE structures which contains the configuration data for this service. Each element represents a line in the security template or database.

Remarks

When analysis information is specified, the PFSCE_QUERY_INFO and PFSCE_SET_INFO functions use the SCESVC_ANALYSIS_INFO structure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Scesvc.h.

See Also

SCESVC_CONFIGURATION_LINE, SCESVC_INFO_TYPE, PFSCE_QUERY_INFO, PFSCE_SET_INFO.


SCESVC_CONFIGURATION_LINE

The SCESVC_CONFIGURATION_LINE structure contains information about a line of configuration data. It is used by the SCESVC_CONFIGURATION_INFO structure.

typedef struc _SCESVC_CONFIGURATION_LINE_ {
  LPTSTR  Key;
  LPTSTR  Value;
  DWORD  ValueLen;
} SCESVC_CONFIGURATION_LINE, *PSCESVC_CONFIGURATION_LINE;

Members

Key
A string that contains data key. Typically this is the name of the configuration parameter the Value data applies to.
Value
String that contains data describing the configuration.
ValueLen
Length of the data stored in Value, in bytes.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Scesvc.h.

See Also

SCESVC_CONFIGURATION_INFO


SCESVC_ANALYSIS_INFO

The SCESVC_ANALYSIS_INFO structure contains the analysis information. It contains a SCESVC_ANALYSIS_LINE structure that contains lines of analysis information, and it also contains a counter that indicates the number of lines.

A pointer to this structure is returned by calls to PFSCE_QUERY_INFO and PFSCE_SET_INFO when analysis information is specified.

typedef struct _SCESVC_ANALYSIS_INFO_ {
  DWORD Count;
  PSCESVC_ANALYSIS_LINE Lines;
} SCESVC_ANALYSIS_INFO, *PSCESVC_ANALYSIS_INFO;

Members

Count
A DWORD that indicates the number of lines in the array.
Lines
Pointer to an array of SCESVC_ANALYSIS_LINE structures which contain the analysis information.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Scesvc.h.

See Also

SCESVC_ANALYSIS_LINE, SCESVC_INFO_TYPE, PFSCE_QUERY_INFO, PFSCE_SET_INFO


SCESVC_ANALYSIS_LINE

The SCESVC_ANALYSIS_LINE structure specifies the key, value, and value length for a specific line specified by an SCESVC_ANALYSIS_INFO structure.

typedef struc _SCESVC_ANALYSIS_LINE_ {
  LPTSTR  Key;
  PBYTE Value;
  DWORD   ValueLen;
} SCESVC_ANALYSIS_LINE, *PSCESVC_ANALYSIS_LINE;

Members

Key
A string that contains data key. Typically this is the name of the configuration parameter the Value data applies to.
Value
The data describing the analysis result for the key. This can be binary data.
ValueLen
The length of the data stored in Value, in bytes.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Scesvc.h.

See Also

SCESVC_ANALYSIS_INFO


SCESVC_CALLBACK_INFO

The SCESVC_CALLBACK_INFO structure contains an opaque database handle and callback function pointers to query, set, and free information.

typedef struct _SCESVC_CALLBACK_INFO_ {
  SCE_HANDLE              sceHandle;
  PFSCE_QUERY_INFO        pfQueryInfo;
  PFSCE_SET_INFO          pfSetInfo;
  PFSCE_FREE_INFO         pfFreeInfo;
  PFSCE_LOG_INFO          pfLogInfo;
} SCESVC_CALLBACK_INFO, *PSCESVC_CALLBACK_INFO;

Members

sceHandle
Specifies the opaque handle passed to the attachment by the Security Configuration tool set. This handle is used by support functions to read information from and write information to the security database.
pfQueryInfo
Pointer to a PFSCE_QUERY_INFO callback function that queries information in the security database.
pfSetInfo
Pointer to a PFSCE_SET_INFO callback function that sets information in the security database.
pfFreeInfo
Pointer to a PFSCE_FREE_INFO callback function that frees information in the security database.
pfLogInfo
Pointer to a PFSCE_LOG_INFO callback function that logs messages to the configuration log file or analysis log file.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Scesvc.h.

See Also

SCE_HANDLE


Data Types

The following data types are used by the Security Configuration attachment DLLs and their supporting functions. They are defined in scesvc.h.

Data type | Description
SCE_HANDLE | Opaque handle used to pass information between the attachment and the security database.
SCESVC_HANDLE | Opaque handle that represents the communication context between the Security Configuration snap-in and the snap-in extension.
SCE_ENUMERATION_CONTEXT | Opaque handle used to navigate through the security database.
SCESVC_INFO_TYPE | Used to specify configuration or analysis information.
SCESTATUS | Data type of the return values returned by the configuration DLLs.


SCE_HANDLE

The SCE_HANDLE structure is an opaque handle provided by the Security Configuration tool set. It is used by PFSCE_QUERY_INFO and PFSCE_SET_INFO support functions to pass information between the attachment and the security database.

typedef PVOID SCE_HANDLE;

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Scesvc.h.

See Also

PFSCE_QUERY_INFO, PFSCE_SET_INFO


SCESVC_HANDLE

The SCE_HANDLE structure is an opaque handle provided by the Security Configuration tool set. It is used by methods of the ISceSvcAttachmentData and ISceSvcAttachmentPersistInfo interfaces to pass information between the Security Configuration snap-in and the snap-in extension.

typedef PVOID SCESVC_HANDLE;

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Scesvc.h.

See Also

ISceSvcAttachmentData, ISceSvcAttachmentPersistInfo


SCE_ENUMERATION_CONTEXT

The SCE_ENUMERATION_CONTEXT data type is an opaque handle provided by the Security Configuration tool set. It is used by PFSCE_QUERY_INFO to navigate through the security database.

typedef ULONG SCE_ENUMERATION_CONTEXT, *PSCE_ENUMERATION_CONTEXT;

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Scesvc.h.

See Also

PFSCE_QUERY_INFO


SCESVC_INFO_TYPE

The SCESVC_INFO_TYPE enumeration is used by PFSCE_QUERY_INFO and PFSCE_SET_INFO to indicate the type of information requested from or passed to the security database. It can be one of the following values.

Value | Description
SceSvcConfigurationInfo | The data is configuration information.
SceSvcMergedPolicyInfo | The data is merged policy information.
SceSvcAnalysisInfo | The data is analysis information.
SceSvcInternalUse | Reserved. Do not use.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Scesvc.h.

See Also

SCESVC_ANALYSIS_INFO, SCESVC_CONFIGURATION_INFO, PFSCE_QUERY_INFO, PFSCE_SET_INFO


SCESTATUS

The SCESTATUS data type is used by the Security Configuration tool set API to return information about the results of a function call. For more information about the defined status code values, see Return Values.

Typedef DWORD SCESTATUS;

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Header: Declared in Scesvc.h.


Return Values

The Security Configuration tool set supports the following SCESTATUS return values. These values are returned by the attachment support functions and should be returned by the attachment functions you implement to create an attachment engine or snap-in.

For more detailed information about the values returned by a specific function, see the reference topic for that function.

Return value | Description
SCESTATUS_SUCCESS | The function succeeded.
SCESTATUS_INVALID_PARAMETER | One of the parameters passed into the function was not valid.
SCESTATUS_RECORD_NOT_FOUND | The specified record was not found in the security database.
SCESTATUS_INVALID_DATA | The function failed because some data was invalid.
SCESTATUS_OBJECT_EXISTS | The object already exists.
SCESTATUS_BUFFER_TOO_SMALL | The buffer passed into the function to receive data is not large enough to receive all of the data.
SCESTATUS_PROFILE_NOT_FOUND | The specified profile was not found.
SCESTATUS_BAD_FORMAT | The format is not valid.
SCESTATUS_NOT_ENOUGH_RESOURCE | There is insufficient memory.
SCESTATUS_ACCESS_DENIED | The caller does not have sufficient privileges to complete this action.
SCESTATUS_CANT_DELETE | The function cannot delete the specified item.
SCESTATUS_PREFIX_OVERFLOW | A prefix overflow occurred.
SCESTATUS_OTHER_ERROR | An unspecified error has occurred.
SCESTATUS_ALREADY_RUNNING | The service is already running.
SCESTATUS_SERVICE_NOT_SUPPORT | The specified service is not supported.
SCESTATUS_MOD_NOT_FOUND | An attachment engine DLL listed in the registry either cannot be found or cannot be loaded.
SCESTATUS_EXCEPTION_IN_SERVER | An exception occurred in the server.


Clipboard Format

Attachment snap-in extensions use the following clipboard format to extract the configuration file name from the Security Templates.

#define CCF_SCESVC_ATTACHMENT (l'CCF_SCESVC_ATTACHMENT" )

The configuration file name is stored as a PWSTR. This name is also used when the attachment snap-in calls the Security Templates' ISceSvcAttachmentdata::Initialize method.


Security Glossary

This section provides a glossary of technical terms used in the Security documentation.

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z


A

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

absolute security descriptor
A security descriptor structure that contains pointers to the security information associated with an object.

See also security descriptor and self-relative security descriptor.

Abstract Syntax Notation One
(ASN.1) A method used to specify abstract objects that are intended for serial transmission.
access block
A key BLOB that contains the key of the symmetric cipher used to encrypt a file or message.

The access block can only be opened with a private key.

access-control entry
(ACE) An entry in an access-control list (ACL). An ACE contains a set of access rights and a security identifier (SID) that identifies a trustee for whom the rights are allowed, denied, or audited.

See also access-control list, security identifier, and trustee.

access-control list
(ACL) A list of security protections that applies to an object. (An object can be a file, process, event, or anything else having a security descriptor.) An entry in an access-control list (ACL) is an access-control entry (ACE). There are two types of access-control list, discretionary and system.

See also access-control entry, discretionary access-control list, security descriptor, and system access-control list.

access mask
A 32-bit value that specifies the rights that are allowed or denied in an access-control entry (ACE). An access mask is also used to request access rights when an object is opened.

See also access-control entry.

access token
An access token contains the security information for a logon session. The system creates an access token when a user logs on, and every process executed on behalf of the user has a copy of the token. The token identifies the user, the user's groups, and the user's privileges. The system uses the token to control access to securable objects and to control the ability of the user to perform various system-related operations on the local computer. There are two kinds of access token, primary and impersonation.

See also impersonation token, primary token, privilege, process, and security identifier.

ACE
See access-control entry.
ACL
See access-control list.
ALG_CLASS_DATA_ENCRYPT
The CryptoAPI algorithm class for data encryption algorithms.

Typical data encryption algorithms include RC2 and RC4.

ALG_CLASS_HASH
The CryptoAPI algorithm class for hashing algorithms.

Typical hashing algorithms include MD2, MD5, SHA-1, and MAC.

ALG_CLASS_KEY_EXCHANGE
The CryptoAPI algorithm class for key exchange algorithms.

A typical key exchange algorithm is RSA_KEYX.

ALG_CLASS_SIGNATURE
The CryptoAPI algorithm class for signature algorithms.

A typical digital signature algorithm is RSA_SIGN.

APDU
See application protocol data unit.
application protocol data unit
(APDU) A command sequence (an Application Protocol Data Unit) that can be sent by the smart card or returned by the application.

See also reply APDU.

application protocol
A protocol that normally resides on top of the transport layer. For example, HTTP, TELNET, FTP, and SMTP are all application protocols.
ASN.1
See Abstract Syntax Notation One.
ASCII
American Standard Code for Information Interchange. A coding scheme that assigns numeric values to letters, numbers, punctuation marks, and certain other characters.
asymmetric algorithm
See public-key algorithm.
ATR string
A sequence of bytes returned from a smart card when it is turned on. These bytes are used to identify the card to the system.
attribute
An element of a relative distinguished name (RDN). Some typical attributes include common name, surname, e-mail address, street address, and country name.

With respect to the CryptoAPI, each attribute is defined by a CERT_RDN_ATTR structure.

attribute BLOB
An encoded representation of the attribute information stored in a certificate request.
authenticate
To determine the identity of the entity that signed a message (entity authentication), or to verify that a message was not altered (data authentication).
authentication package
A DLL that encapsulates the authentication logic used to determine whether to permit a user to log on. LSA authenticates a user logon by sending the request to an authentication package. The authentication package then examines the logon information and either authenticates or rejects the user logon attempt.


B

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

backup authority
A trusted application running on a secure computer that provides secondary storage for the session keys of its clients.

The backup authority stores session keys as key BLOBs that are encrypted with the backup authority's public key.

base content type
A type of data contained in a PKCS #7 message. Base content types only contain data, no cryptographic enhancements such as hashes or signatures.

Currently, the only base content type is the Data content type.

base cryptographic functions
The lowest level of functions in the CryptoAPI architecture. They are used by applications and other high-level CryptoAPI functions to provide access to CSP-provided cryptographic algorithms, secure key generation, and secure storage of secrets.

See also cryptographic service providers.

Basic Encoding Rules
(BER) The set of rules used to encode ASN.1 defined data into a stream of bits (zeros or ones) for external storage or transmission. A single ASN.1 object may have several equivalent BER encodings.

BER is defined in CCITT Recommendation X.209. This is one of the two encoding methods currently used by the CryptoAPI.

big-endian
A data format where the least significant byte is placed in the highest memory address.

See also little endian.

BER
See Basic Encoding Rules.
BLOB
A generic sequence of bits that contain one or more fixed-length header structures plus context specific data.

See also key BLOBs, certificate BLOBs, certificate name BLOBs, and attribute BLOBs.

block cipher
A cipher algorithm that encrypts data in discrete units (called blocks), rather than as a continuous stream of bits. The most common block size is 64 bits. For example, DES is a block cipher.

Block ciphers are considered more secure than stream ciphers; however, block ciphers tend to execute much slower.

See also stream cipher.

bulk encryption key
A session key derived from a master key. Bulk encryption keys are used in SChannel encryption.


C

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

CA
See Certification Authority.
CA certificate
Identifies the Certification Authority (CA) that issues server and/or client authentication certificates to the servers and clients that request these certificates. Because it contains a public key used in digital signatures, it is also referred to as a signature certificate. If the CA is a root authority, the CA certificate may be referred to as a root certificate. Also sometimes known as a site certificate.
CA hierarchy
A Certification Authority (CA) hierarchy contains multiple CAs. It is organized such that each CA is certified by another CA in a higher level of the hierarchy until the top of the hierarchy, also known as the root authority, is reached.
CALG_DH_EPHEM
The CryptoAPI algorithm identifier for the Diffie-Hellman key-exchange algorithm when used for the generation of ephemeral keys.

See also Diffie-Hellman (ephemeral) key-exchange algorithm.

CALG_DH_SF
The CryptoAPI algorithm identifier for the Diffie-Hellman key-exchange algorithm when used for the generation of store-and-forward keys.

See also Diffie-Hellman (store and forward) key-exchange algorithm.

CALG_HMAC
The CryptoAPI algorithm identifier for the Hash-Based Message Authentication Code algorithm.

See also HMAC.

CALG_MAC
The CryptoAPI algorithm identifier for the Message Authentication Code algorithm.

See also Message Authentication Code algorithm.

CALG_MD2
The CryptoAPI algorithm identifier for the MD2 hash algorithm.

See also MD2 algorithm.

CALG_MD5
The CryptoAPI algorithm identifier for the MD5 hash algorithm.

See also MD5 algorithm.

CALG_RC2
The CryptoAPI algorithm identifier for the RC2 block cipher algorithm.

See also RC2 block algorithm.

CALG_RC4
The CryptoAPI algorithm identifier for the RC4 stream cipher algorithm.

See also RC4 stream algorithm.

CALG_RSA_KEYX
The CryptoAPI algorithm identifier for the RSA public-key algorithm when used for key exchange.

See also RSA public-key algorithm.

CALG_RSA_SIGN
The CryptoAPI algorithm identifier for the RSA public-key algorithm when used to generate digital signatures.

See also RSA public-key algorithm.

CALG_SHA
The CryptoAPI algorithm identifier for the Secure Hash Algorithm (SHA-1).

See also Secure Hash Algorithm.

CAST
A family of DES-like symmetric block ciphers developed by C. M. Adams and S. E. Tavares.

PROV_MS_EXCHANGE provider types specify a particular CAST algorithm that uses a 64-bit block size.

CBC
See Cipher Block Chaining.
certificate
A digitally signed statement that contains information about an entity and the entity's public key, thus binding these two pieces of information together. A certificate is issued by a trusted organization (or entity) called a Certification Authority (CA) after the CA has verified that the entity is who it says it is.

Certificates can contain different types of data. For example, an X.509 certificate includes the format of the certificate, the serial number of the certificate, the algorithm used to sign the certificate, the name of the CA that issued the certificate, the name and public key of the entity requesting the certificate, and the CA's signature.

certificate BLOB
A BLOB containing the certificate data.

A certificate BLOB is created by calls to CryptEncodeObject. The process is complete when the output of the call contains all the certificate data.

certificate context
A CERT_CONTEXT structure that contains a handle to a certificate store, a pointer to the original encoded certificate BLOB, a pointer to a CERT_INFO structure, and an encoding type member. It is the CERT_INFO structure that contains most of the certificate information.
certificate encode/decode functions
Functions that manage the translation of certificates and related material into standard, binary formats that can be used in different environments.
certificate encoding type
Defines how the certificate is encoded. The certificate encoding type is stored in the low-order word of the encoding type (DWORD) structure.
certificate name BLOB
An encoded representation of the name information that is included in certificates. Each name BLOB is mapped to a CERT_NAME_BOLB structure.

For example, the issuer and subject information referenced by a CERT_INFO structure is stored in two CERT_NAME_BLOB structures.

certificate policy
A named set of rules indicating the applicability of certificates for a specific class of applications with common security requirements. Such a policy might, for example, limit certain certificates to electronic data interchange transactions within given price limits.
certificate request
A specially formatted electronic message (sent to a CA) used to request a certificate. The request must contain the information required by the CA to authenticate the request, plus the public key of the entity requesting the certificate.

All the information necessary to create the request is mapped to a CERT_REQUEST_INFO structure.

certificate revocation list
(CRL) A document maintained and published by a certification authority (CA) that lists certificates issued by the CA that are no longer valid.
certificate server
A server that issues certificates for a particular CA. The certificate server software provides customizable services for issuing and managing certificates used in security systems employing public-key cryptography.
Certificate Services
A service in Microsoft® Windows NT®/Windows® 2000 that enables a certificate server to manage the process of issuing certificates across the Internet, corporate intranets, and other networks.
certificate store
Typically, a permanent storage where certificates, certificate revocation lists (CRLs), and certificate trust lists (CTLs) are stored. It is possible, however, to create and open a certificate store solely in memory when working with certificates that do not need to be put in permanent storage.

The certificate store is central to much of the certificate functionality in the CryptoAPI.

certificate store functions
Functions that manage the storage and retrieval data such as certificates, certificate revocation lists (CRLs), and certificate trust lists (CTLs).

These functions can be separated into common certificate functions, certificate revocation list functions, and certificate trust list functions.

certificate trust list
(CTL) A predefined list of items that have been signed by a trusted entity. A CTL can be anything, such as a list of hashes of certificates, or a list of file names. All the items in the list are authenticated (approved) by the signing entity.
certification authority
(CA) An entity entrusted to issue certificates asserting that the recipient individual, machine or organization requesting the certificate fulfills the conditions of an established policy.
CFB
See Cipher Feedback.
chaining mode
A block cipher mode that introduces feedback by combining ciphertext and plaintext.

See also Cipher Block Chaining.

cipher
A cryptographic algorithm used to encrypt data, to transform plaintext into ciphertext using a predefined key.
Cipher Block Chaining
(CBC) A method of operating a symmetric block cipher that uses feedback to combine previously generated ciphertext with new plaintext.

Each plaintext block is combined with the ciphertext of the previous block by a bitwise XOR before it is encrypted. Combining ciphertext and plaintext ensures that even if the plaintext contains many identical blocks, they will each encrypt to a different ciphertext block.

When the Microsoft Base Cryptographic Provider is used, CBC is the default cipher mode.

Cipher Block Chaining MAC
A block cipher method that encrypts the base data with a block cipher and then uses the last encrypted block as the hash value. The encryption algorithm used to build the MAC is the one that was specified when the session key was created.
Cipher Feedback
(CFB) A block cipher mode that processes small increments of plaintext into ciphertext, instead of processing an entire block at a time.

This mode uses a shift register that is one block size in length and divided into sections. For example, if the block size is 64 bits with eight bits processed at a time, then the shift register would be divided into eight sections.

cipher mode
A block cipher mode (each block is encrypted individually) that can be specified via the CryptSetKeyParam function. If the application does not explicitly specify one of these modes, then the cipher block chaining (CBC) cipher mode is used.

ECB: A block cipher mode that uses no feedback.

CBC: A block cipher mode that introduces feedback by combining ciphertext and plaintext.

CFB: A block cipher mode that processes small increments of plaintext into ciphertext, instead of processing an entire block at a time.

OFB: A block cipher mode that uses feedback similar to CFB.

ciphertext
A message that has been encrypted.
cleartext
See plaintext.
client
The application, rather than the server application, that initiates a connection to a server.

Compare with server.

client certificate
Refers to a certificate used for client authentication, such as authenticating a Web browser on a Web server. When a Web browser client attempts to access a secured Web server, the client sends its certificate to the server to allow it to verify the client's identity.
CMC
Certificate management protocol using cryptographic message syntax.
communication protocol
The method in which data is serialized (converted to a string of ones and zeros) and deserialized. The protocol is controlled by both software and data-transmission hardware.

Typically discussed in terms of layers, a simplified communication protocol might consist of an application layer, encode/decode layer, and hardware layer.

context
The security data relevant to a connection. A context contains information such as a session key, duration of the session.
context function
Functions used to connect to a cryptographic service provider (CSP). These functions enable applications to choose a specific CSP by name, or get one with a needed class of functionality.
countersignature
A signature added to an existing signature in a message. A countersignature is used to sign an existing signature's encrypted hash or time stamp a message.

A countersignature is added by calling CryptMsgCountersign or CryptCountersignEncoded.

credentials
Previously authenticated logon data used by a security principal to establish its own identity, such as a password, or a Kerberos protocol ticket.
CRL
See Certificate Revocation List.
CRYPT_ASN_ENCODING
Specifies certificate encoding. Certificate encoding types are stored in the low-order word of a DWORD (value is: 0x00000001).

Functionally the same as X509_ASN_ENCODING.

cryptoanalysis
Cryptoanalysis is the art and science of breaking ciphertext. In contrast, the art and science of keeping messages secure is cryptography.
CryptoAPI
Microsoft® Cryptographic API, an application programming interface that enables application developers to add authentication, encoding, and encryption to Win32®-based applications.
cryptographic algorithm
A mathematical function used for encryption and decryption. Most cryptographic algorithms are based on a substitution cipher, a transposition cipher, or a combination of both.
Cryptographic API
See CryptoAPI.
Cryptographic Digest
A one-way hash function that takes a variable-length input string and converts it to a fixed-length output string (called a cryptographic digest.) This fixed-length output string is probabilistically unique for every different input string and thus can act as a fingerprint of a file. When a file with a cryptographic digest is downloaded, the receiver recomputes the digest. If the output string matches the digest contained in the file, the receiver has proof that the received file was not tampered with and is identical to the file originally sent.
cryptographic key
The session (symmetric) key used during the encryption and decryption processes, and the public and private keys used during the authentication process. Of these three keys, the session key and private key must always remain secret.
cryptographic service provider
(CSP) An independent software module that actually performs cryptography algorithms for authentication, encoding, and encryption.
cryptography
The art and science of information security. It includes information confidentiality, data integrity, entity authentication, and data origin authentication.
cryptology
The branch of mathematics that encompasses both cryptography and cryptoanalysis.
CryptoSPI
The system program interface used with a cryptographic service provider (CSP).
CSP
See cryptographic service provider.
CSP family
A unique group of CSPs that use the same set of data formats and perform their function in the same way. Even when two CSP families use the same algorithm (for example, the RC2 block cipher), their different padding schemes, keys lengths, or default modes make each group distinct.

The CryptoAPI has been designed so that each CSP type represents a particular family.

CSP name
The textual name of the CSP. If the CSP has been signed by Microsoft, this name must exactly match the CSP name that was specified in the Export Compliance Certificate (ECC).
CSP type
Indicates the CSP family associated with a provider. When an application connects to a CSP of a particular type, each of the CryptoAPI functions will, by default, operate in a way prescribed by the family that corresponds to that CSP type.
CTL
See certificate trust list.
CYLINK_MEK
An encryption algorithm that uses a 40-bit variant of a DES key where 16 bits of the 56-bit DES key are set to zero. This algorithm is implemented as specified in the IETF Draft specification for 40-bit DES. The draft specification, at the time of this writing can be found at ftp://ftp.ietf.org/internet-drafts/draft-hoffman-des40-02.txt. This algorithm is used with the ALG_ID value CALG_CYLINK_MEK


D

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

DACL
See discretionary access-control list.
data content type
A base content type defined by PKCS #7. Data content is simply an octet (byte) string.
data encryption
See encryption.
data encryption function
See encryption and decryption functions.
Data Encryption Standard
(DES) A block cipher that encrypts data in 64-bit blocks. DES is a symmetric algorithm that uses the same algorithm and key for encryption and decryption.

Developed in the early 1970s, DES is also known as the DEA (Data Encryption Algorithm) by ANSI and the DEA-1 by ISO.

datagram
A communication channel that uses information routed through a packet-switching network. This information includes separate packets of information and the delivery information associated with those packets, such as the destination address. In a packet-switching network, data packets are routed independently of one another and may follow different routes. They may also arrive in a different order from the one in which they were sent.
decoding
The process of translating an encoded object (such as a certificate) or data back to its original format.

In general terms, data is decoded by the Encoding/Decoding layer of the communication protocol. Certificates are decoded by a call to CryptDecodeObject.

decryption
The process in which ciphertext is converted to plaintext.
default mode
Default settings, such as the block encryption cipher mode or the block encryption padding method.
DER
See Distinguished Encoding Rules.
derived key
A cryptographic key created by a call to CryptDeriveKey. A derived key can be created from a password, or any other user data.

Derived keys allow applications to create session keys as needed, eliminating the need to store a particular key.

DES
See Data Encryption Standard.
DH
See Diffie-Hellman algorithm.
DH_KEYX
The CryptoAPI algorithm name for the Diffie-Hellman key-exchange algorithm.

See also Diffie-Hellman algorithm.

Diffie-Hellman algorithm
(DH) A public-key algorithm used for secure key exchange. Diffie-Hellman cannot be used for data encryption.

This algorithm is specified as the key exchange algorithm for PROV_DSS_DH provider types.

See also Diffie-Hellman (store and forward) key-exchange algorithm and Diffie-Hellman (ephemeral) key-exchange algorithm.

Diffie-Hellman (store and forward) key-exchange algorithm
A Diffie-Hellman algorithm where the exchange key values are retained (in the CSP) after the key handle has been destroyed.

See also Diffie-Hellman (ephemeral) key-exchange algorithm.

Diffie-Hellman (ephemeral) key-exchange algorithm
A Diffie-Hellman algorithm where the exchange key value is purged from the CSP when the key handle is destroyed.

See also Diffie-Hellman (store and forward) key-exchange algorithm.

digested data
A data content type defined by PKCS #7 that consists of any type of data plus a message hash (digest) of the content.
digital certificate
See certificate.
digital envelope
Private messages encrypted using the recipient's public key. Enveloped messages can only be decrypted by using the recipient's private key, allowing only the recipient to understand the message.
digital signature
A digital string that is bundled with the message or transmitted separately. They are used to authenticate messages. A valid digital signature confirms that the message has not been tampered with, and may also identify the entity who signed the message. Signing a message does not alter the message itself.
Digital Signature Algorithm
(DSA) A public-key algorithm specified by Digital Signature Standard (DSS). DSA is only used to generate digital signatures. It cannot be used for data encryption.
digital signature key pair
See signature key pair.
Digital Signature Standard
(DSS) A standard that specifies the Digital Signature Algorithm (DSA) for its signature algorithm and SHA-1 as its message hash algorithm. DSA is a public-key cipher that is only used to generate digital signatures and cannot be used for data encryption.

DSS is specified by PROV_DSS, PROV_DSS_DH, and PROV_FORTEZZA provider types.

discretionary access-control list
(DACL) An access-control list that is controlled by the owner of an object and that specifies the access particular users or groups can have to the object.

See also access-control list and system access-control list.

Distinguished Encoding Rules
(DER) A set of rules for encoding ASN.1 defined data as a stream of bits for external storage or transmission. Every ASN.1 object has exactly one corresponding DER encoding. DER is defined in CCITT Recommendation X.509, Section 8.7. This is one of two encoding methods currently used by the CryptoAPI.
DLL
See dynamic-link library.
DSA
See Digital Signature Algorithm.
DSS
See Digital Signature Standard.
dynamic-link library
A file that contains executable routines that can be called from other applications.


E

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

ECB
See Electronic Codebook.
EKU
See enhanced key usage.
electronic codebook
(ECB) A block cipher mode (each block is encrypted individually) that uses no feedback. This means any blocks of plaintext that are identical (either in the same message or in a different message that is encrypted with the same key) is transformed into identical ciphertext blocks.

Initialization vectors cannot be used with this cipher mode.

If a single bit of the ciphertext block is garbled, then the entire corresponding plaintext block is also garbled.

encoding
The process of turning data into a stream of bits. Encoding is part of the serialization process that converts data into a stream of ones and zeros so that it can be transmitted over a serial line.
encoding type
Refers to which type of encoding is used for certificate and message encoding. The encoding types are specified as a DWORD, with the type of certificate encoding stored in the low-order word and the type of message encoding stored in the high-order word.

Although some functions or structure fields require only one of the encoding types, it is always acceptable to specify both.

encryption
The process in which data (plaintext) is translated into something that appears to be random and meaningless (ciphertext). Cipertext is difficult to unscramble without a secret key.
encrypted data
Data that has been converted from plaintext into ciphertext. Encrypted messages are used to disguise the content of a message when it is sent or stored.
encryption and decryption functions
Simplified message functions used to encode and encrypt (or decode and decrypt) data. As a set, these functions include support for simultaneously encrypting and decrypting data.

See also simplified message functions.

enhanced content type
A class of data contained in a PKCS #7 message that contains data (possibly encrypted), plus cryptographic enhancements such as hashes or signatures.

Types of enhanced data defined by PKCS #7 include signed data, enveloped data, signed-and-enveloped data, and digested (hashed) data.

enhanced key usage
(EKU) Both a certificate extension and a certificate extended property value. An EKU specifies the uses for which a certificate is valid.
enveloped data content type
A PKCS #7 enhanced content that consists of encrypted content (of any type) and content-encryption keys (for one or more recipients). The combination of encrypted content and encryption key for a recipient is called a digital envelope for that recipient.

This type of message should be used when you want to keep the contents of the message secret and allow only specified persons or entities to retrieve the contents.

exchange key
See exchange key pair .
exchange key pair
A public/private key pair used to encrypt session keys so that they can be safely stored and exchanged with other users. Exchange key pairs are created by calling CryptGenKey.

Compare signature key pair.

external store
A certificate store that maintains its certificates, CRLs, and CTLs in a location external to cached memory, such as in a database on a network server.

An external store does not read and decode its certificates, CRLs, and CTL when CertOpenStore is called. Reading and decoding is deferred until an enumeration or find.


G

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

GDI
See Graphics Device Interface.
GINA
A Graphical Identification and Authentication dynamic-link library (DLL). The GINA is a replaceable DLL component that is loaded by the Winlogon executable. The GINA implements the authentication policy of the interactive logon model and is expected to perform all identification and authentication user interactions.
Graphics Device Interface
The executable program that processes graphical function calls from a Windows®-based application and passes those calls to the appropriate device driver, which performs the hardware-specific functions that generate output.


H

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

handle
A token used to identify or access an object, such as the handle to a cryptographic provider, certificate store, message, or key pair.
hash
A fixed-size result obtained by applying a mathematical function (the hashing algorithm) to an arbitrary amount of data. (Also known as "message digest.")

See also hashing functions.

hash object
An object used to hash messages or session keys. The hash object is created by a call to CryptCreateHash. The definition of the object is defined by the CSP specified in the call.
hashing algorithm
An algorithm used to produce a hash value of some piece of data, such as a message or session key. Typical hashing algorithms include MD2, MD4, MD5, and SHA-1.
hashing functions
A set of functions used to create and destroy hash objects, get or set the parameters of a hash object, and hash data and session keys.
Hash-Based Message Authentication Code
(HMAC) A keyed hashing algorithm implemented by Microsoft cryptographic service providers. It is a more complex algorithm than the simple CBC MAC algorithm because it uses a secret symmetric key to create the hash.

It can be used with any iterated cryptographic hash algorithm, such as MD5 or SHA-1.

HCSBC
Data type which serves as a handle to a Certificate Services backup context. Its role is to maintain context state between the server and the backup APIs when a backup is being performed.
HMAC
The CryptoAPI algorithm name for the Hash-based Message Authentication Code algorithm when used with a specified hash algorithm. The CryptoAPI also references this algorithm by its algorithm identifier (CALG_HMAC) and class (ALG_CLASS_HASH).

See also Message Authentication Code algorithm.


I

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

IIS
Microsoft® Internet Information Server.
impersonation token
An access token that has been created to capture the security information of a client process, allowing a server to "impersonate" the client process in security operations.

See also access token and primary token.

initialization vector
(IV) A sequence of random bytes appended to the front of the plaintext before encryption by a block cipher. Adding the initialization vector to the beginning of the plaintext eliminates the possibility of having the initial ciphertext block the same for any two messages.

For example, if messages always start with a common header (a letterhead or "From" line) their initial ciphertext would always be the same, assuming that the same cryptographic algorithm and symmetric key was used. Adding a random initialization vector eliminates this from happening.

inner data
Any encoded data used as the message for another encoded message. For example, an enveloped message and its hash value may be the inner data for a second message.
inner content
Data that is enhanced, such as with a digital signature. This term is used primarily when discussing enhanced data in a PKCS #7 message.
integrity
The completeness and accuracy of a message after it has been sent or stored.
IV
See initialization vector.


K

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

KCA
See Key Certification Authority.
KEA
See Key Exchange Algorithm.
Kerberos_protocol
A protocol that defines how clients interact with a network authentication service. Clients obtain tickets from the Kerberos Key Distribution Center (KDC), and they present these tickets to servers when connections are established. Kerberos tickets represent the client's network credentials.
key BLOB
A BLOB containing an encrypted private key. Key BLOBs provide a way to store keys outside the CSP.

Key BLOBs are created by exporting an existing key from the CSP by calling CryptExportKey. Later, the key BLOB can be imported into a provider (often a different CSP on a different computer) by calling CryptImportBlob. This creates a key in the CSP that is a duplicate of the one that was exported.

See also simple key BLOB, public key BLOB, and private key BLOB.

key BLOB format
The format of the key BLOB when a public or session key is exported from a CSP. The format is specified by the provider type of the exporting CSP. A key BLOB is created by calling CryptExportKey.

See also public key BLOB and simple key BLOB.

key certification authority
(KCA) A trusted entity that typically keeps a secure database of compound messages signed with the KCA's private key. In practical implementations, the compound messages consist of the user's name, the user's public key, and any other important information about the user.

When the receiving application gets a signed message from a user, the application can then verify the public key received with the message by comparing it to the public key stored in the KCA database.

key container
A part of the key database that contains all the key pairs (exchange and signature key pairs) belonging to a specific user.

Each container has a unique name that is used when calling CryptAcquireContext to get a handle to the container.

key database
A database that contains the persistent cryptographic keys for a specific CSP. The database contains one or more key containers, which individually store all the cryptographic key pairs for a specific user.

See also key container.

key exchange algorithm
An algorithm used to encrypt and decrypt exchange keys (symmetric session keys). Some common key exchange algorithms include DH and KEA.

Each provider type can specify only one key exchange algorithm.

Key Exchange Algorithm
(KEA) The key exchange algorithm specified by a PROV_FORTEZZA provider type. This algorithm is an improved version of the Diffie-Hellman algorithm.
key exchange certificate
A certificate used to encrypt information sent to another party. The certification authority (CA) key exchange certificate can be used by a client to encrypt information sent to the CA.
key exchange functions
A set of functions used to exchange or transmit keys. Key exchange functions can also be used to implement fully authenticated three-phase key exchanges.
key-exchange key pair
See exchange key pair.
key exchange private key
The private key of an exchange key pair.

See also exchange key pair.

key exchange protocol
A protocol by which two parties exchange information to establish a shared secret. The shared secret is then typically used as a symmetric encryption key.
key exchange public key
The public key of an exchange key pair.

See also exchange key pair.

key generation functions
A set of functions used by applications to generate and customize cryptographic keys. These functions include full support for changing chaining modes, initialization vectors, and other encryption features.
key length
Values specified by some providers that indicate the length of the public/private key pairs and session keys used with that provider.
key pair
A private key and its related public key.


L

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

LDAP
See Lightweight Directory Access Protocol
Lightweight Directory Access Protocol
A more easily implemented subset of the X.500 DAP standard for directory services.
little-endian
A data format where the most significant byte is placed in the highest memory address.

See also big endian.

locally unique identifier (LUID)
A 64-bit value guaranteed to be unique on the operating system that generated it (until the system is restarted).
Local Registration Authority
(LRA) An intermediary between a publisher and a certification authority (CA). The LRA can, for example, verify a publisher's credentials before sending them to the CA.
Local Security Authority
(LSA) A protected subsystem of Microsoft® Windows NT/Windows® 2000 that authenticates and logs users onto the local system. In addition, LSA maintains information about all aspects of local security on a system, collectively known as the Local Security Policy of the system.
logical store
See virtual store.
logon data
Information presented to the system by a security principal for authentication.
logon identifier
An LUID that identifies a logon session. A logon ID is valid until the user logs off. A logon ID is unique while the computer is running; no other logon session will have the same logon ID. However, the set of possible logon IDs is reset when the computer starts up. To retrieve the logon ID from an access token, call the GetTokenInformation function for TokenStatistics; the logon ID is in the AuthenticationId member.
logon session
A logon session begins whenever a user logs on to a computer. All processes in a logon session have the same primary access token . The access token contains information about the security context of the logon session, including the user's SID, the logon identifier, and the logon SID.
logon SID
A security identifier (SID) that identifies a logon session. You can use the logon SID in a DACL to control access during a logon session. A logon SID is valid until the user logs off. A logon SID is unique while the computer is running; no other logon session will have the same logon SID. However, the set of possible logon SIDs is reset when the computer starts up. To retrieve the logon SID from an access token, call the GetTokenInformation function for TokenGroups.
low-level message functions
Message management functions that operate at a higher level than the base cryptographic functions. These functions provide functionality for encoding data for transmission and for decoding data that has been received.

Low-level message functions provide more flexibility than simplified message functions, but require more function calls.

See also simplified message functions.

LUID
See locally unique identifier.


M

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

MAC
The CryptoAPI algorithm name for the Message Authentication Code algorithm. The CryptoAPI also references this algorithm by its algorithm identifier (CALG_MAC) and class (ALG_CLASS_HASH).

See also Message Authentication Code algorithm.

MAC key
A message authentication code key used with SChannel protocols.
master key
The key used by the client and server for all session key generation. The master key is used to generate the client-read key, the client-write key, the server-read key, and the server-write key.

Master keys can be exported as simple key BLOBs.

MD2
The CryptoAPI algorithm name for the MD2 hash algorithm. Other hashing algorithms include MD4, MD5, and SHA.

See also MD2 algorithm.

MD2 algorithm
(MD2) A hashing algorithm that creates a 128-bit hash value, which is twice the size of the block (64 bits).

CryptoAPI references this algorithm by its type (CALG_MD2), name (MAC), and class (ALG_CLASS_HASH).

MD2 was developed by RSA Data Security, Inc.

See also MD4 algorithm, MD5 algorithm.

MD4
The CryptoAPI algorithm name for the MD4 hash algorithm. Other hashing algorithms include MD2, MD5, and SHA.

See MD4 algorithm.

MD4 algorithm
(MD4) A hashing algorithm that creates a 128-bit hash value, which is twice the size of the block (64 bits).

MD4 was developed by RSA Data Security, Inc.

See also MD2 algorithm, MD5 algorithm.

MD5
The CryptoAPI algorithm name for the MD5 hash algorithm. Other hashing algorithms include MD2, MD4, and SHA.

See also MD5 algorithm.

MD5 algorithm
(MD5) A hashing algorithm that creates a 128-bit hash value, which is twice the size of the block (64 bits).

CryptoAPI references this algorithm by its algorithm identifier (CALG_MD5), name (MD5), and class (ALG_CLASS_HASH).

MD5 was developed by RSA Data Security, Inc. and is specified by PRON_RSA_FULL, PROV_RSA_SIG, PROV_DSS, PROV_DSS_DH, and PROV_MS_EXCHANGE provider types.

See also MD2 algorithm, MD4 algorithm.

message
Any data that has been encoded for transmission to or received from a person or entity. Messages may be encrypted for privacy, digitally signed for authentication purposes, or both.
message digest
See hash.
Message Authentication Code algorithm
(MAC) A keyed hashing algorithm that uses a symmetric session key. When using this type of algorithm, the receiving application must also posses the session key to recompute the hash value so it can verify that the base data has not changed.

The CryptoAPI references this algorithm by its type (CALG_MAC), name (MAC) and class (ALG_CLASS_HASH).

message encoding type
Defines how the message is encoded. The message encoding type is stored in the high-order word of the encoding type structure.

Current defined encoding types are: CRYPT_ASN_ENCODING, X509_ASN_ENCODING, and PKCS_7_ASN_ENCODING.

message management functions
Functions that provide two levels of message management: low-level message functions and simplified message functions. The low-level message functions provide more flexibility than the simplified message functions; however, they require more function calls.
message signing functions
Functions used to sign messages and data.

See also simplified message functions.

Multiple Provider Router
(MPR) A system component that handles communications between the system and all network providers.

The MPR calls the network provider functions that are exposed by each network provider.


N

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

National Institute of Standards and Technology
(NIST) A division of the United States Department of Commerce that publishes official standards for both government and private sector computer systems. These standards are published as Federal Information Processing Standards(FIPS) publications.

In 1987, NIST was directed to define standards for ensuring the security of sensitive but unclassified information in government computer systems.

Negotiate
A specialized security support provider (SSP) that acts as an application layer between security support provider interface (SSPI) and the other SSPs. When an application calls into SSPI to log on to a network, it can specify an SSP to process the request. If the application specifies Negotiate, Negotiate analyzes the request and picks the best SSP to handle the request.
NIST
See National Institute of Standards and Technology.
nonce
A randomly generated value used to defeat "replay" attacks.


O

OFB
See Output Feedback.
OID
Object identifier (ASN.1) for abstract objects specified by ASN.1.

The object identifier is a sequence of integers that identifies objects such as algorithms or attribute types.

See also Abstract Syntax Notation 1.

opaque BLOB
A sequence of bytes used to store session keys. Opaque BLOBs contain the base key material and all current state information. This includes information such as the salt value, the initialization vector, and the key table. The format of opaque BLOBs is unpublished. Each CSP vendor determines its own BLOB format which should include encrypting the opaque BLOBs with some sort of symmetric key.
outer content
The enhancements for some encapsulated data. This term is used primarily when discussing enhanced data (the inner content) in PKCS #7 messages.
Output Feedback
(OFB) A block cipher mode that uses feedback similar to the Cipher Feedback (CFB) mode. The only difference between the two modes is how the shift register is filled.

See also Cipher Feedback.


P

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

padding
A string, typically added when the last plaintext block is short. For example, if the block length is 64 bits and the last block contains only 40 bits, then 24 bits of padding must be added to the last block. The padding string may contain zeros, alternating zeros and ones, or some other pattern.

Applications using the CryptoAPI need not add padding to their plaintext before it is encrypted, nor do they have to remove it after decrypting. This is all handled automatically.

password filter
A DLL that provides password policy enforcement and change notification. The functions implemented by password filters are called by the Local Security Authority.
persistent storage
Any storage medium that remains intact when the power to it is disconnected. Many certificate store databases are forms of persistent storage.
PKCS
See Public-Key Cryptography Standards.
PKCS #7 Signed Data
A Public Key Certificate Standard #7 (PKCS #7) signed-data object encapsulates the information used to sign a file. Typically, it includes the signer's certificate and the root certificate.
PKCS #7 STANDARD
A standard that defines a general syntax for encryption and authentication, as well as adding other message attributes, such as timestamps, to the message.
PKCS_7_ASN_ENCODING
Specifies message encoding. Message encoding types are stored in the high-order word of a DWORD (value is: 0x00010000).
plaintext
A message that is not encrypted. Plaintext messages are also referred to as cleartext messages.
Portable Executable (PE) Image
The standard Win32® executable format.
PRF
See Pseudo-Random Function.
primary credentials
The MsV1_0 authentication package defines a primary credential key string value: The primary credentials string holds the credentials provided at initial logon time. It includes the user name and both case-sensitive and case-insensitive forms of the user's password.

See also supplemental credentials.

principal
See security principal.
primary service provider
The service provider that supplies the control interfaces to the card. Each smart card can register its primary service provider in the smart card database.
primary token
An access token that is typically created only by the Windows NT® executive layer. It may be assigned to a process to represent the default security information for that process.

See also access token, impersonation token.

privacy
The condition of being isolated from view or secret. With respect to messages, private messages are encrypted messages whose text is hidden from view. With respect to keys, a private key is a secret key concealed from others.
private key
The secret half of a key pair used in a public key algorithm. Private keys are typically used to encrypt a symmetric session key, digitally sign a message, or decrypt a message that has been encrypted with the corresponding public key.

See also public key.

private key BLOB
A key BLOB that contains a complete public/private key pair. Private key BLOBs are used by administrative programs to transport key pairs. As the private key portion of the key pair is extremely confidential, these BLOBs are typically kept encrypted with a symmetric cipher.

These key BLOBs can also be used by advanced applications where the key pairs are stored within the application, rather than relying on the CSP's storage mechanism.

A key BLOB is created by calling CryptExportKey.

privilege
The right of a user to perform various system-related operations, such as shutting down the system, loading device drivers, or changing the system time. A user's access token contains a list of the privileges held by either the user or the user's groups.

See also Privileges and Account Rights.

process
The security context under which an application runs. Typically, the security context is associated with a user, so all applications running under a given process take on the permissions and privileges of the owning user.
PROV_DSS
See PROV_DSS provider type.
PROV_DSS Provider Type
Predefined provider type that only supports digital signatures and hashes. It specifies the DSA signature algorithm, and the MD5 and SHA-1 hashing algorithms.
PROV_DSS_DH
See PROV_DSS_DH provider type .
PROV_DSS_DH provider type
Predefined provider type that provides key exchange, digital signature, and hashing algorithms. It is similar to the PROV_DSS provider type.
PROV_FORTEZZA
See PROV_FORTEZZA provider type.
PROV_FORTEZZA provider type
Predefined provider type that provides key exchange, digital signature, encryption, and hashing algorithms. The cryptographic protocols and algorithms specified by this provider type are owned by the National Institute of Standards and Technology (NIST).
PROV_MS_EXCHANGE
See PROV_MS_EXCHANGE provider type.
PROV_MS_EXCHANGE provider type
Predefined provider type designed for the needs of Microsoft Exchange, as well as other applications that are compatible with Microsoft Mail. It provides key exchange, digital signature, encryption, and hashing algorithms.
PROV_RSA_FULL
See PROV_RSA_FULL provider type.
PROV_RSA_FULL provider type
Predefined provider type defined by Microsoft and RSA Data Security, Inc. This general purpose provider type provides key exchange, digital signature, encryption, and hashing algorithms.

The key exchange, digital signature, and encryption algorithms are based on RSA public-key cryptography.

PROV_RSA_SIG
See PROV_RSA_SIG provider type.
PROV_RSA_SIG provider type
Predefined provider type defined by Microsoft and RSA Data Security. This provider type is a subset of PROV_RSA_FULL that provides only digital signature and hashing algorithms.

The digital signature algorithm is an RSA public-key algorithm.

PROV_SSL
See PROV_SSL provider type.
PROV_SSL provider type
Predefined provider type that supports the Secure Sockets Layer (SSL) protocol. This type provides key encryption, digital signature, encryption, and hashing algorithms.

A specification explaining SSL is available from Netscape Communications Corp.

provider
See Cryptographic Service Provider.
provider name
A name used to identify a CSP. For example, the Microsoft® Base Cryptographic Provider version 1.0.

The provider name is typically used when calling CryptAcquireContext to connect to a CSP.

provider type
A term used to identify a type of cryptographic service provider (CSP). CSPs are grouped into different provider types that represent a specific families of standard data formats and protocols. In contrast to a CSP's unique provider name, provider types are not unique for a given CSP.

The provider type is typically used when calling CryptAcquireContext to connect to a CSP.

Pseudo-Random Function
(PRF) A function that takes a key, label, and seed as input, then produces an output of arbitrary length.
public/private key pair
A set of cryptographic keys used for public-key cryptography. For each user, a CSP usually maintains two public/private key pairs: an exchange key pair and a digital signature key pair. Both key pairs are maintained from session to session.

See exchange key pair and signature key pair.

public key
A cryptographic key typically used when decrypting a session key or a digital signature.

The public key can also be used to encrypt a message, guaranteeing that only the person with the corresponding private key can decrypt the message.

See also private key.

public-key algorithm
An asymmetric cipher that uses two keys, one for encryption, the public key, and the other for decryption, the private key.

As implied by the key names, the public key used to encode plaintext can be made available to anyone. However, the private key must remain secret. Only the private key can decrypt the ciphertext.

The public-key algorithm used in this process is slow (on the order of 1,000 times slower than symmetric algorithms), and is typically used to encrypt session keys or digitally sign a message.

See also public key and private key.

public-key BLOB
A BLOB used to store the public key portion of a public/private key pair. Public key BLOBs are not encrypted as the public key contained within is not secret

A public-key BLOB is created by calling CryptExportKey.

Public-Key Cryptography Standards
(PKCS) A set of syntax standards for public-key cryptography covering security functions, including methods for signing data, exchanging keys, requesting certificates, public-key encryption and decryption, and other security functions.
public-key encryption
Encryption that uses a pair of keys, one key to encrypt data and the other key to decrypt data. In contrast, symmetric encryption algorithms that use the same key for both encryption and decryption.

In practice, public-key cryptography is typically used to protect the session key used by a symmetric encryption algorithm. In this case, the public key is used to encrypt the session key, which in turn was used to encrypt some data, and the private key is used for decryption.

In addition to protecting session keys, public-key cryptography may also be used to digitally sign a message (using the private key) and validate the signature (using the public key).

See also public-key algorithm.


R

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

RC2
The CryptoAPI algorithm name for the RC2 algorithm.

See also RC2 block algorithm.

RC2 block algorithm
A data encryption algorithm based on the RC2 64-bit symmetric block cipher. RC2 is specified by PROV_RSA_FULL provider types.

The CryptoAPI references this algorithm by its identifier (CALG_RC2), name (RC2), and class (ALG_CLASS_DATA_ENCRYPT).

RC4
The CryptoAPI algorithm name for the RC4 algorithm.

See also RC4 stream algorithm.

RC4 stream algorithm
A data encryption algorithm based on the RC4 symmetric stream cipher. RC4 is specified by PROV_RSA_FULL provider types.

The CryptoAPI references this algorithm by its identifier (CALG_RC4), name (RC4), and class (ALG_CLASS_DATA_ENCRYPT).

RDN
See relative distinguished name.
reader
A standard device within the smart card subsystem. An interface device (IFD) that supports bi-directional input/output to a smart card. It may be associated with an entire system, one or more reader groups, or with a specific terminal.

The smart card subsystem allows a reader to be dedicated to the terminal to which it is assigned. However, currently only one terminal exists on a computer.

reader driver
A specific driver that maps driver services to a specific hardware reader device. It must communicate card insertion and removal events to the smart card class driver for forwarding to the smart card resource manager, and provide data exchange capabilities to the card by any raw, T=0, T=1, or PTS protocol.
reader group
A logical group of readers. Reader groups can be defined by the system or created by users or administrators. Reader groups are used by smart card functions that can act upon groups of readers.

To avoid naming collisions with user-defined groups, Microsoft reserves the use of any name containing the $ symbol.

reader helper driver
Provides common smart card driver support routines and additional T=0 and T=1 protocol support to specific drivers as needed.
reference count
An integer value associated with a certificate, certificate store, hash, or other cryptographic entity. It is used to keep track of the lifetime of the entity. When an entity is created, its reference count is set to one. Each time the entity is duplicated or copied, its reference count is incremented. Each time the entity or one of its duplicates is released or destroyed, its reference count is decremented. Memory used to store the entity is released when the reference count of the entity reaches zero.
relative distinguished name
(RDN) An entity included as the Subject in a request for a certificate. The elements in an RDN are defined by its attributes and do not need to include a name.

With respect to the CryptoAPI, an RDN is defined by a CERT_RDN structure, which in turn points to an array of CERT_RDN_ATTR attribute structures. Each attribute structure specifies a single attribute.

relative identifier
(RID) The portion of a security identifier (SID) that identifies a user or group in relation to the authority that issued the SID.

See also security identifier.

relocated store
A certificate store that has been moved from its default registry location to a different location in the registry.
remote store
A certificate store located on another computer, such as a file server or some other shared remote computer.
reply APDU
An application protocol data unit (APDU) sent in reply to a received APDU.

See also APDU.

resource manager
The component of the smart card subsystem that manages access to multiple readers and smart cards.

The resource manager identifies and tracks resources, allocates readers and resources across multiple applications, and supports transaction primitives for accessing services available on a given card.

resource manager API
A set of Win32® functions that provide direct access to the resource manager's services.
resource manager context
The context used by the resource manager when accessing the smart card database. The resource manager context is primarily used by the query and management functions when accessing the database.

The scope of the resource manager context can be the current user or the system.

revocation list
See Certificate Revocation List.
RID
See relative identifier.

root authority
The certification authority (CA) at the top of a CA hierarchy. The root authority certifies CAs in the next level of the hierarchy.
root certificate
A self-signed certification authority (CA) certificate that identifies a CA. It is called a root certificate because it is the certificate for the root CA. The root CA must sign its own CA certificate because by definition there is no higher certifying authority to sign its CA certificate.
RSA
RSA Data Security, Inc., a major developer and publisher of public-key cryptography standards (PKCS). The "RSA" in the name stands for the names of the company's three developers and the owners: Rivest, Shamir, and Adelman.
RSA_KEYX
The CryptoAPI algorithm name for the RSA key exchange algorithm. The CryptoAPI also references this algorithm by its algorithm identifier (CALG_RSA_KEYX) and class (ALG_CLASS_KEY_EXCHANGE).
RSA_SIGN
The CryptoAPI algorithm name for the RSA signature algorithm. The CryptoAPI also references this algorithm by its algorithm identifier (CALG_RSA_SIGN) and class (ALG_CLASS_SIGNATURE).
RSA Public-Key algorithm
A key exchange and signature algorithm based on the popular RSA Public-Key cipher. This algorithm is used by PROV_RSA_FULL, PROV_RSA_SIG, PROV_MS_EXCHANGE, and PROV_SSL provider types.

The CryptoAPI references this algorithm by its identifiers (CALG_RSA_KEYX and CALG_RSA_SIGN), names (RSA_KEYX and RSA_SIGN) and class (ALG_CLASS_KEY_EXCHANGE).


S

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

S/MIME
See Secure/Multipurpose Internet Mail Extensions.
SACL
See system access control list .
salt value
Random data that is sometimes include as part of a session key. When added to a session key, the plaintext salt data is placed in front of the encrypted key data.

Salt values are added to increase the work required to mount a brute-force (dictionary) attack against data encrypted with a symmetric-key cipher.

Salt values are generated by calling CryptGenRandom.

sanitized name
The form of a certification authority (CA) name that is used in file names (such as for a certificate revocation list) and in registry keys. The process of sanitizing the CA name is necessary to remove characters that are illegal for file names, registry key names, or Distinguished Name values, or that are illegal for technology-specific reasons.

In Certificate Services, the sanitization process converts any illegal character in the common name of the CA to a 5 character representation in the format '!xxxx', where '!' is used as an escape character and 'xxxx' represents four hexidecimal integers that uniquely identify the character being converted.

SAS
See secure attention sequence.
SCard$DefaultReaders
A terminal reader group that contains all readers assigned to that terminal, however, it is not reserved for this specific use.
SCard$AllReaders
A Smart Card system-wide reader group that includes all readers introduced to the smart card resource manager. Readers are automatically added to the group when they are introduced to the system.
SCARD_AUTOALLOCATE
A Smart Card system constant that tells the smart card resource manager to allocate sufficient memory itself, returning a pointer to the allocated buffer instead of filling in a user-supplied buffer. The returned buffer must then eventually be freed by calling SCardFreeMemory.
SChannel
A security package that provides authentication between clients and servers.
secure attention sequence
(SAS) A key sequence that begins the process of logging on or off. The default sequence is CTRL+ALT+DEL.
Secure Electronic Transaction
(SET) A protocol for secure electronic transactions over the Internet.
Secure Hash Algorithm (SHA-1)
A hashing algorithm that generates a 160-bit hash value. SHA-1 is used with the Digital Signature Algorithm (DSA) in the Digital Signature Standard (DSS), among other places.

CryptoAPI references this algorithm by its identifier (CALG_SHA), name (SHA), and class (ALG_CLASS_HASH).

SHA-1 was developed by the National Institute of Standards and Technology (NIST) and by the National Security Agency (NSA).

Secure Hash Standard
A standard designed by NIST and NSA. This standard defines the Secure Hash Algorithm (SHA-1) for use with the Digital Signature Standard (DSS).

See also Secure Hash Algorithm.

Secure Sockets Layer protocol
(SSL) A protocol for secure network communications using a combination of public and secret key technology.
Secure/Multipurpose Internet Mail Extensions
(S/MIME) An e-mail security standard that makes use of public key encryption.
security context
The security attributes or rules that are currently in effect. For example, the current user logged on to the computer or the personal identification number entered by the smart card user. For SSPI, a security context is an opaque data structure that contains security data relevant to a connection, such as a session key or an indication of the duration of the session.
security descriptor
A structure and associated data that contains the security information for a securable object. A security descriptor identifies the object's owner and primary group. It can also contain a DACL that controls access to the object, and a SACL that controls the logging of attempts to access the object.

See also absolute security descriptor, discretionary access-control list, self-relative security descriptor, system access-control list.

security identifier
(SID) A structure of variable length that uniquely identifies a user or group on all Windows NT® implementations.
security package
The software implementation of a security protocol. Security packages are contained in security support provider DLLs or security support provider/authentication package DLLs.
security protocol
A specification that defines security-related data objects and rules about how the objects are used to maintain security on a computer system.
security principal
An entity recognized by the security system. Principals can include human users as well as autonomous processes.
security support provider
(SSP) A dynamic-link library (DLL) that implements the SSPI by making one or more security packages available to applications. Each security package provides mappings between an application's SSPI function calls and an actual security model's functions. Security packages support security protocols such as Kerberos authentication and the Microsoft® LAN Manager.
Security Support Provider Interface
(SSPI) A common interface between transport-level applications, such as Microsoft Remote Procedure Call (RPC), and security providers, such as Windows Distributed Security. SSPI allows a transport application to call one of several security providers to obtain an authenticated connection. These calls do not require extensive knowledge of the security protocol's details.
self-relative security descriptor
A security descriptor that stores all its security information in a contiguous block of memory.

See also security descriptor.

server certificate
Refers to a certificate used for server authentication, such as authenticating a Web server to a Web browser. When a Web browser client attempts to access a secured Web server, the server sends its certificate to the browser to allow it to verify the server's identity.
service principal name
(SPN) The name by which a client uniquely identifies an instance of a service. If you install multiple instances of a service on computers throughout a forest, each instance must have its own SPN. A given service instance can have multiple SPNs if there are multiple names that clients might use for authentication
serialize
The process of converting data into a string of ones and zeros so that it can be transmitted serially. Encoding is part of this process.
server
A computer that responds to commands from a client computer. The client and server work together to perform distributive application functionality.

See also client.

service provider (Smart Card)
A Smart Card subsystem component that provides access to specific smart card services by means of COM interfaces.

See also primary service provider.

session
An exchange of messages under the protection of a single piece of keying material. For example, SSL sessions use a single key to send multiple messages back and forth under that key.
session key
A key used primarily for data encryption and decryption. Session keys are typically used with symmetric encryption algorithms where the same key is used for both encryption and decryption. For this reason, session and symmetric keys usually refer to the same type of key.

A session key consists of a random number of approximately 40 to 2000 bits. Session keys can be derived from hash values by calling CryptDeriveKey.

session-key derivation scheme
Specifies when a key is derived from a hash. Methods used depend on the CSP type.
SET
See Secure Electronic Transaction.
SHA
The CryptoAPI name for the Secure Hash algorithm. Other hashing algorithms include MD2, MD4, and MD5.

See also Secure Hash Algorithm.

SHS
See Secure Hash Standard.
SID
See security identifier.
signature and data verification functions
Simplified message functions used to sign outgoing messages and verify the authenticity of applied signatures in received messages and related data.

See simplified message functions.

signature certificate
A certificate containing a public key that is used to verify digital signatures.
signature file
A file that contains the signature of a particular CSP. The signature file is necessary to ensure that the CryptoAPI recognizes the CSP. The CryptoAPI validates this signature periodically to make certain the CSP has not been tampered with.
signature functions
Functions used to create and verify digital signatures.

See also simplified message functions.

signature key pair
The public/private key pair used for authenticating (digitally signing) messages. Signature key pairs are created by calling CryptGenKey.

See also exchange key pair.

signature private key
The private key of a signature key pair.

See signature key pair.

signed and enveloped data
A data content type defined by PKCS #7. This data type consists of encrypted content of any type, encrypted content-encryption keys for one or more recipients, and doubly encrypted message hash(es) for one or more signers. The double encryption consists of an encryption with a signer's private key followed by an encryption with the content-encryption key.
signed data
A data content type defined by PKCS #7. This data type consists of any type of content plus encrypted message hashes (digests) of the content for zero or more signers. The resulting hash(es) can be used to confirm who signed the message. These hashes also confirm that the original message has not been modified since the message was signed.
simple key BLOB
A session key encrypted with the key-exchange public key of the destination user. This key BLOB type is used when storing a session key or transmitting a session key to another user. A key BLOB is created by calling CryptExportKey.
simplified message functions
Message management functions such as message encryption, decryption, signing and signature verification functions. Simplified message functions operate at a higher level than the base cryptographic functions or the low-level message functions.

Simplified message functions wrap several of the base cryptographic, low-level message, and certificate functions into a single function that performs a specific task in a specific manner, such as encrypting a PKCS #7 message or signing a message.

See also low-level message functions.

site certificate
Both server certificates and certification authority (CA) certificates are sometimes called site certificates. When referring to a server certificate, the certificate identifies the Web server presenting the certificate. When referring to a CA certificate, the certificate identifies the CA that issues server and/or client authentication certificates to the servers and clients that request these certificates.
Skipjack
An encryption algorithm specified as part of the Fortezza encryption suite. Skipjack is a symmetric cipher with a fixed key length of 80 bits.

Skipjack is a classified algorithm created by the United States National Security Agency (NSA). The technical details of the Skipjack algorithm are secret.

smart card
An integrated circuit card (ICC) owned by an individual or a group whose information must be protected according to specific ownership assignments. It provides its own physical access control; without the smart card subsystem placing additional access control on the smart card.

A smart card is a plastic card containing an integrated circuit that is compatible with ISO 7816.

smart card common dialog
A common dialog that assists the user in selecting and locating a smart card. It works with the smart card database management services and reader services to help the application, and if necessary the user, to identify which smart card to use for a given purpose.
smart card database
The database used by the resource manager to manage resources. It contains a list of known smart cards, the interfaces and primary service provider of each card, and known smart card readers and reader groups.
smart card subsystem
The subsystem used to provide a link between smart card readers and smart card aware applications running within the PC environment. This subsystem is designed specifically for Microsoft® Windows® 95 OSR2.1 and Microsoft Windows 2000, with support for CryptoAPI and the Windows driver model.
Software Publishing Certificate
(SPC) A PKCS #7 signed-data object containing X.509 certificates.
SPN
See service principal name.
SSL
See Secure Sockets Layer protocol.
SSL3 Client Authentication algorithm
An algorithm used for client authentication in Secure Sockets Layer(SSL) version 3. In the SSL3 protocol, a concatenation of an MD5 hash and a SHA-1 hash is signed with an RSA private key. CryptoAPI and the Microsoft Base and Enhanced Cryptographic Providers support SSL3 with the hash type CALG_SSL3_SHAMD5.
SSL3 protocol
Version 3 of the Secure Sockets Layer (SSL) protocol.
SSP
See security support provider.
SSPI
See Security Support Provider Interface.
state
The set of all persisted values associated with a cryptographic entity such as a key or a hash. This set can include such things as the initialization vector (IV) being used, the algorithm being used, or the value of the entity already calculated.
stream cipher
A cipher that serially encrypts data, one bit at a time.

See also block cipher.

subauthentication package
An optional DLL that provides additional authentication functionality, usually by extending the authentication algorithm. If a subauthentication package is installed, the authentication package will call the subauthentication package before returning its authentication result to the Local Security Authority (LSA).

See also Local Security Authority.

supplemental credentials
Credentials for use in authenticating a security principal to foreign security domains.

See also primary credentials.

symmetric algorithm
A cryptographic algorithm that typically uses a single key, often referred to as a session key, for encryption and decryption. Symmetric algorithms can be divided into two categories, stream algorithms and block algorithms (also called stream and block ciphers).

See also stream cipher and block cipher.

symmetric encryption
Encryption that uses a single key for both encryption and decryption. Symmetric encryption is preferred when encrypting large amounts of data. Some of the more common symmetric encryption algorithms are RC2, RC4, and Data Encryption Standard (DES).

See also public-key encryption.

symmetric key
A single key, typically a session key, used for both encryption and decryption.

See also session key.

system access-control list
(SACL) An ACL that controls the generation of audit messages for attempts to access a securable object. The ability to get or set an object's SACL is controlled by a privilege typically held only by system administrators.

See also access-control list (ACL), discretionary access-control list (DACL), privilege.

system program interface
The set of functions provided by a cryptographic service provider (CSP) that implements an application's functions.


T

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

T=0 protocol
An asynchronous, character-oriented half-duplex transmission protocol.
T=1 protocol
An asynchronous, block-oriented half-duplex transmission protocol.
terminal
A combination of monitor, keyboard, mouse, and co-located peripherals, such as smart card readers. Multiple processes may be associated with a single terminal, but only one process controls the terminal at any given time.
three-phase key-exchange protocol
A protocol used to generate an authenticated and encrypted connection between two users on a nonsecure network.

Users exchange a set of messages to negotiate a pair of encryption keys. One key is used by the sender to encrypt messages sent to the receiver and the other is used by the receiver to encrypt messages sent to the sender. This protocol ensures that both users are active and are sending messages directly to each other.

TLS
See Transport Layer Security protocol.
token
See access token.
transaction
An operation that allows you to perform multiple interactions as a single operation. Intermediate steps are not actually taken until all interactions are completed successfully. If any interaction fails, all steps are returned to their original setting.
transport layer
The network layer that is responsible for both quality of service and accurate delivery of information. Among the tasks performed in this layer are error detection and correction.
Transport Layer Security protocol
(TLS) A protocol that provides communications privacy and security between two applications communicating over a network.
triple DES
A variation of the DES block cipher algorithm that encrypts plain text with one key, encrypts the resulting ciphertext with a second key, and finally, encrypts the result of the second encryption with a third key. Triple DES is a symmetric algorithm that uses the same algorithm and keys for encryption and decryption.
trustee
In Microsoft® Windows NT® security, a trustee is the user account, group account, or logon session to which an access-control entry (ACE) applies. Each ACE in an access-control list (ACL) applies to one trustee.

See also access-control entry and access-control list.

trust list
See certificate trust list.
trust provider
The software that decides whether or not a given file is trusted. This decision is based on the certificate associated with the file.


U

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

UCS
See Universal Character Set.
unicode
A worldwide character-encoding standard that allows more information to be contained in each string by defining 16-byte character strings rather than the standard 8-byte character strings. Unicode allows universal data exchange and improves multilingual text processing. Unicode strings are also called wide strings.
Uniform Resource Locator
An encoding scheme used by the World Wide Web (WWW) for accessing data on the Internet. The general format is service://example.microsoft.com.
Universal Character Set
(UCS) A 16-bit character set.
universal well-known security identifier
A security identifier (SID) that is meaningful on all secure systems using the security model implemented in Microsoft® Windows NT®.

See also security identifier.

URL
See Uniform Resource Locator.
user
A user of a system is identified by a login procedure, which establishes a process by which applications can run and access other security-relevant objects. An example of a login procedure is to use a smart card, possibly in conjunction with a password or personal identification number (PIN).
user interface (Smart Card)
A common dialog box that lets the user connect to a smart card and use it in an application. Using the dialog box, the user can specify a specific card or search for the smart card to open.


V

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

virtual store
A certificate store that consists of a collection of other certificate stores.

A single search or enumeration function on a virtual store will search all of the stores that are members of the virtual stores collection. Any addition to a virtual store will add an element to one of the members of that store.


W

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

Winlogon
A component of the Microsoft® Windows NT®/Windows® 2000 operating system that provides interactive logon support. Winlogon is designed around an interactive logon model that consists of three components: the Winlogon executable, a Graphical Identification and Authentication dynamic-link library (DLL) — referred to as the GINA — and any number of network providers.


X

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

X.200
An Open Systems Interconnect (OSI) standard.
X.208
The ITU standard defining ASN.1.
X.209
The ITU standard that defines BER encodings for ASN.1 objects.

See also Basic Encoding Rules.

X.400
The ITU standard that defines message tokens.
X.500
The ITU standard that defines the structure of a global dictionary.
X.509
An internationally recognized standard for certificates that defines their required parts.
X509_ASN_ENCODING
Specifies certificate encoding. Certificate encoding types are stored in the low-order word of a DWORD (value is: 0x00000001).

Functionally the same as CRYPT_ASN_ENCODING.

XOR
Exclusive OR. A Boolean operation that yields true only if one of its operands are true and the other is false. If both operands are the same (either True or False), the operation yields false.


Topic Not Found

No matching topic was found. Some possible reasons and remedies are as follows:

  • The file (.chm) that contains the destination topic is not in the expected location.

    Remedy: Rerun the MSDN Library Setup.

  • The file (.chm) that contains the current topic or destination topic is out-of-date and the link is no longer valid.

    Remedy: Install the latest version of the MSDN Library.

  • The MSDN Library CD is not in the CD-ROM drive.

    Remedy: Insert the MSDN Library CD into the CD-ROM drive.