Pkcs11Interop

repository·master·Indexed 43 days ago

https://github.com/pkcs11interop/pkcs11interop

A managed .NET wrapper for unmanaged PKCS#11 cryptographic libraries, enabling .NET applications to interact with HSMs, smart cards, and other cryptographic hardware. Compliant with PKCS#11 v2.40 and RFC 7512, it supports .NET Framework 2.0+, .NET Core, Mono, and Xamarin across Windows, Linux, macOS, Android, and iOS. The library provides both a LowLevelAPI for manual memory management and a HighLevelAPI for automatic memory management, with Pkcs11InteropFactories serving as the recommended entry point for platform-dependent API instantiation.

Tokens
7.1K
Snippets
6
Records
37
Agent score
55%

What's inside Pkcs11Interop

  1. Overview of Pkcs11Interop

    master

    Pkcs11Interop is a managed .NET wrapper for unmanaged PKCS#11 libraries. It allows .NET applications to interact with cryptographic hardware (like smart cards and HSMs) by loading the vendor-provided unmanaged PKCS#11 library and exposing its functions through a managed C# API.

    Key Features:

    • Compliance: Compliant with PKCS#11 v2.40 and RFC 7512 (PKCS#11 URI scheme).
    • Compatibility: Works with .NET Framework 2.0+, .NET Core, Mono, and Xamarin.
    • Platform Support: Windows, Linux, macOS, Android, and iOS (both 32-bit and 64-bit).
    • Open Source: Licensed under Apache License 2.0.
  2. What is PKCS11-MOCK

    master

    PKCS11-MOCK is a minimalistic C library that implements the PKCS#11 v3.1 API. It is a dummy mock object designed specifically for unit testing the Pkcs11Interop library.

    Key characteristics:

    • It is not a real cryptographic module.
    • It does not depend on any hardware or external configuration.
    • It can be easily modified to return specific responses or data to simulate various testing scenarios.
  3. LowLevelAPI vs HighLevelAPI

    master

    The library is divided into two distinct API layers:

    1. LowLevelAPI: Closely follows the ANSI C PKCS#11 specification. It requires a C-like coding style and involves manual memory management. Use this when you need exact parity with the C API or specific low-level control.
    2. HighLevelAPI: Built on top of the LowLevelAPI. It uses the .NET garbage collector for automatic memory management and provides developer-friendly constructs like collections and streams. This is the preferred API for most .NET developers.
  4. Deciding when to use Pkcs11Interop

    master

    Choose Pkcs11Interop if you are developing cross-platform applications (beyond just Windows) that need to perform cryptographic operations with keys stored in hardware devices like smartcards or HSMs.

    Do NOT use Pkcs11Interop if:

    • Your application is intended only for Windows and your device integrates with Windows via CAPI/CNG (CSP, KSP, minidriver, etc.).
    • You only need to perform simple RSA or EC signing/encryption. In this case, use the Pkcs11Interop.X509Store library instead for a simpler developer experience.
  5. How Pkcs11Interop core abstractions work together

    master

    The Net.Pkcs11Interop.HighLevelAPI namespace follows a hierarchical relationship to interact with unmanaged PKCS#11 libraries. The workflow typically follows this chain:

    1. Pkcs11InteropFactories: The entry point used to load unmanaged PKCS#11 libraries and create IPkcs11Library instances.
    2. IPkcs11Library: Represents a loaded unmanaged library. It provides access to available hardware/software slots via ISlot.
    3. ISlot: Represents a logical reader (like a smartcard reader). It provides information about the token present (ITokenInfo) and allows opening an ISession.
    4. ISession: Represents a connection to a token. This is where you perform cryptographic operations using IMechanism and manage objects like keys via IObjectHandle.
    5. IObjectHandle: Represents a specific item on the token (e.g., a private key or certificate) and is used to interact with its IObjectAttributes.
    6. IMechanism: Represents the cryptographic algorithm (e.g., AES, RSA) used during a session operation.
  6. Manage Session Lifetime and Object Visibility

    master

    All threads within a single application share access to the same sessions and session objects.

    Object Destruction Rule: Session objects are tied to the lifetime of the session that created them. If a session is closed, any session objects created within that session are destroyed, even if those objects were being used or were visible through other open sessions in the same application.

  7. Understand PKCS#11 objects, sessions, and mechanisms

    master

    Beyond the physical hardware components, PKCS#11 uses three key logical abstractions:

    • Object: Represents data stored on a token (permanent) or within a session (temporary). This includes certificates, public keys, private keys, or secret keys. Cryptographic operations are performed using these objects without exposing their raw values.
    • Session: A logical connection between your application and a token. An application typically manages one or more sessions to interact with the token.
    • Mechanism: Represents a specific cryptographic algorithm (e.g., RSA encryption). The availability and constraints (like key bit length) of mechanisms vary depending on the specific token being used.
  8. Understand PKCS#11 Sessions

    master

    A Session represents a logical connection between an application and a token. In Pkcs11Interop, sessions are identified by a ulong session handle stored within the ISession interface. This handle is used by PKCS#11 functions to specify which session the operation should act upon.

    Best Practice: While sessions can be shared across multiple application threads using locking mechanisms, it is safer to create a new session for each cryptographic operation to avoid concurrency issues.

  9. Distinguish between Public and Private objects

    master

    Access requirements are defined by the CKA_PRIVATE attribute:

    • Public objects: CKA_PRIVATE is set to CK_FALSE. Applications can access these without logging into the token.
    • Private objects: CKA_PRIVATE is set to CK_TRUE. Applications must log into the token to access these objects.
  10. Understanding API naming conventions (Fours, Eights, Zeros, and Ones)

    master

    Because PKCS#11 structures and types vary based on platform architecture (bitness) and alignment requirements, Pkcs11Interop provides multiple sets of APIs. You can identify the correct set by the numbers in the API name:

    Bit-width (Fours and Eights)

    Refers to the size of the C ulong type used by the underlying PKCS#11 library:

    • 4: Uses the .NET uint (4 bytes) for platforms where C ulong is 4 bytes (e.g., Win32, Win64, Unix32).
    • 8: Uses the .NET ulong (8 bytes) for platforms where C ulong is 8 bytes (e.g., Unix64).

    Alignment (Zeros and Ones)

    Refers to the byte alignment (packing) of the Cryptoki structures:

    • 0: Uses default byte alignment (controlled by StructLayoutAttribute.Pack = 0).
    • 1: Uses 1-byte alignment (controlled by StructLayoutAttribute.Pack = 1).

    Combined Naming Example

    An API named HighLevelAPI41 would use 4-byte uint types and 1-byte structure alignment.

  11. Understand PKCS#11 Object Handles

    master

    In Pkcs11Interop, every object (such as a certificate, public key, or secret key) is identified by a handle. This handle is a ulong identifier represented by the IObjectHandle interface.

    Key considerations:

    • The handle is passed to PKCS#11 functions to specify which object to act upon.
    • Handles can be used by all application threads.
    • Warning: Handles are not permanent identifiers. They are not guaranteed to remain the same between consecutive PKCS#11 library loads.
    IObjectHandle objectHandle;