Giter VIP home page Giter VIP logo

pkcs11interop.x509store's Introduction

Pkcs11Interop.X509Store

Easy to use PKCS#11 based X.509 certificate store

License AppVeyor NuGet Stack Overflow Twitter

WARNING: Pkcs11Interop.X509Store is still in a very early stage of development and its API may fundamentally change with any subsequent release.

Table of Contents

Overview

PKCS#11 is cryptography standard maintained by the OASIS PKCS 11 Technical Committee (originally published by RSA Laboratories) that defines ANSI C API to access smart cards and other types of cryptographic hardware.

Pkcs11Interop is managed library written in C# that brings full power of PKCS#11 API to the .NET environment. It loads unmanaged PKCS#11 library provided by the cryptographic device vendor and makes its functions accessible to .NET application.

Pkcs11Interop.X509Store is managed library built on top of Pkcs11Interop. It's main goal is to provide easy to use PKCS#11 based read-only X.509 certificate store that can be easily integrated with standard .NET ecosystem.

Architecture

Pkcs11Interop.X509Store architecture

Documentation

Pkcs11Interop.X509Store API is fully documented with the inline XML documentation that is displayed by the most of the modern IDEs during the application development.

Download

Archives with the source code and binaries can be downloaded from our releases page. Official NuGet packages are published in nuget.org repository. All official items are signed with GnuPG key or code-signing certificate of Jaroslav Imrich.

License

Pkcs11Interop.X509Store is available under the terms of the Apache License, Version 2.0.
Human friendly license summary is available at tldrlegal.com but the full license text always prevails.

Support

Pkcs11Interop.X509Store is still in a very early stage of development so if you need help, please open an issue in our public issue tracker.

Related projects

  • Pkcs11Interop
    Managed .NET wrapper for unmanaged PKCS#11 libraries.
  • Pkcs11Admin
    GUI tool for administration of PKCS#11 enabled devices based on Pkcs11Interop library.
  • PKCS11-LOGGER
    PKCS#11 logging proxy module useful for debugging of PKCS#11 enabled applications.
  • SoftHSM2-for-Windows
    Pure software implementation of a cryptographic store accessible through a PKCS#11 interface.

About

Pkcs11Interop.X509Store has been written for the Pkcs11Interop project by Jaroslav Imrich.
Please visit project website - pkcs11interop.net - for more information.

pkcs11interop.x509store's People

Contributors

ci-pkcs11interop avatar jariq avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pkcs11interop.x509store's Issues

Pkcs11X509Store In .net core

Hello,

I am trying to develop a .netCore application that communicates with my TPM chip. I would like to integrate the management of X509 certificates inside for security reasons.
So I am using Pkcs11X509Store and Pkcs11Interop. However, Pkcs11X509Store is not available in .netCore

Is a .net core version of Pkcs11 X509 Store planned?

Thank you by adavance for you reply

System.TypeLoadException: Could not load type 'Net.Pkcs11Interop.HighLevelAPI.Pkcs11' from assembly 'Pkcs11Interop, Version=5.1.1.0, Culture=neutral, PublicKeyToken=c10e9c2d8c006d2a'.
at Net.Pkcs11Interop.X509Store.Pkcs11X509Store.GetStoreContext(String libraryPath, IPinProvider pinProvider)
at Net.Pkcs11Interop.X509Store.Pkcs11X509Store..ctor(String libraryPath, IPinProvider pinProvider)
at Lectra.Mob.Pki.Client.Services.TpmService.GetCertificat() in C:\community\vault-pki\cutter\src\Lectra.Mob.Pki.Client\Services\TpmService.cs:line 88
at Lectra.Mob.Pki.Client.Services.ProvisioningCertificateService.ProvisionCertificateAsync(String commonName) in C:\community\vault-pki\cutter\src\Lectra.Mob.Pki.Client\Services\ProvisioningCerfificateService.cs:line 97
at Lectra.Mob.Pki.Client.PkiClient.ProvisionCertificates(String cn) in C:\community\vault-pki\cutter\src\Lectra.Mob.Pki.Client\PkiClient.cs:line 59
at Lectra.Mob.Pki.WebApp.Controllers.CertificatesFactoryController.PostCertificateProvisioningAsync(String commonName) in C:\community\vault-pki\cutter\src\Lectra.Mob.Pki.WebApp\Controllers\CertificatesFactoryController.cs:line 40

Can't get keys from HSM

I need to get private key to use as SignedXml.SigningKey. We use HSM to store keys and I used Pkcs11Interop.X509Store to get certifates:
var store = new Pkcs11X509Store(pkcs11LibraryPath, new ConstPinProvider("Pin"));
Pkcs11X509Certificate cert = store.Slots[0].Token.Certificates[0];
RSA rsaPrivateKey = cert.GetRSAPrivateKey();
But GetRSAPrivateKey() returns null.
When I use Pkcs11Interop to get private key,I am able to get the key and use it in signing.
But I can't use ObjectHandle in SignedXml functions.
Is there any way to use Private key as SignedXml.SigningKey?Do I have to implement custom class inherited from RSA as you adviced there?

System.IO.FileNotFoundException has been thrown while setting up the package

I am using .NET core 3.1 on Mac and installed Pkcs11Interop.X509Store 0.2.0 version to read attached smart card certificates.

string pkcs11LibraryPath = @"/Library/OpenSC/lib/opensc-pkcs11.so";
using (var store = new Pkcs11X509Store(pkcs11LibraryPath, new SimplePinProvider("000000")))
{
}

I get the following exception

Could not load file or assembly 'Pkcs11Interop, Version=4.0.0.0, Culture=neutral, PublicKeyToken=c10e9c2d8c006d2a'. The system cannot find the file specified

I have not installed Pkcs11Interop package but even if I do, I get the same error.

Pkcs11Exception: Method C_Initialize returned CKR_GENERAL_ERROR

Has anyone ever experienced this?

I am running the Pkcs11Interop.X509Store code inside an MVC client application to access the HSM device's private key in order to generate file signatures with BouncyCastle. The following error occurred:

Inner Exception 1:
Pkcs11Exception: Method C_Initialize returned CKR_GENERAL_ERROR

System.TypeInitializationException

This exception was originally thrown at this call stack:
[External Code]
Net.Pkcs11Interop.X509Store.SoftHsm2Manager.InitializeTokens() in SoftHsm2Manager.cs
Net.Pkcs11Interop.X509Store.SoftHsm2Manager.Soft

It takes too much time to load private Key

I try pkcs11Interop.X509Store with the HSM Securosys. It can sign the XML file ok but It takes too much time to load the private key (over 20 seconds).
pkcs11x509_time2
pkcs11x509_time1.
It finds the certificate in 2 seconds and does GetRSAPrivateKey() in over 20 seconds.
What is the problem?

FindKey includes label

Hi,
on my card private key and public key of the certificate are not found. I dug into it and found that your search for keys in FindKeys in Pkcs11X509Certificate includes CKA_ID and also CKA_Label. On my card however Label is only set on the certificate - not on either of the keys - when importing the certificate using the provider tool (Thales SafeNet). Do you think it is a good idea to exclude label search not only for me but everyone?
BR and thanks for your work.

Edit: Tested with another type of card (ACOS). When putting a certificate on that card label is not set for either certificate, private key or public key. All empty.

Private Key

First of all, congratulations on sharing. very successful business. My problem is I can't get the private key.

Slot slot;
using (Pkcs11 pkcs11 = new Pkcs11(@"C:\Windows\System32\akisp11.dll", AppType.SingleThreaded))
{
	List<Slot> slots = pkcs11.GetSlotList(SlotsType.WithOrWithoutTokenPresent);
	slot = slots[0];
	
	using (Session session = slot.OpenSession(SessionType.ReadOnly))
	{
		session.Login(CKU.CKU_USER, "000000");

		List<ObjectAttribute> searchTemplate = new List<ObjectAttribute>();
		searchTemplate.Add(new ObjectAttribute(CKA.CKA_CLASS, (uint)CKO.CKO_CERTIFICATE));

		List<ObjectHandle> certObjectHandles = session.FindAllObjects(searchTemplate);


		foreach (ObjectHandle certObjectHandle in certObjectHandles)
		{
			List<CKA> attributes = new List<CKA>();
			attributes.Add(CKA.CKA_VALUE);

			List<ObjectAttribute> objectAttributes = session.GetAttributeValue(certObjectHandle, attributes);

			byte[] certData = objectAttributes[0].GetValueAsByteArray();

			X509Certificate2 x509Certificate2 = new X509Certificate2(certData);     
								   
			RSA rsaPrivateKey = x509Certificate2.GetRSAPrivateKey();

			//PRIVATE KEY NULL ?
		}

		session.CloseSession();
		list.Add(new kayit
		{
			Base64 = bytesStr
		});
	}
}

Pkcs11Interop 5.1.0 and Pkcs11Interop.X509Store v 0.2.0 Can't Integrate

Hi, currently I want to get the specific certificate based on the Key Usage of the certificate.
Basically what I try to do is--

  1. Using Pkcs11Interop.X509Store to get the Pkcs11X509Certificate's raw data, then convert it to the X509Certificate2, use the X509Certificate2.Extensions to get the Key Usage and find the specific cert.
  2. Use Reflection to get the PrivateKeyHandle in the Pkcs11X509Certificate (which is proved to work on my side).
  3. Try to use this PrivateKeyHandle and Pkcs11Interop to do the Encryption.

The first problem is, Pkcs11Interop 5.1.0 can't integrate with Pkcs11Interop.X509Store v 0.2.0.
"Could not load type 'Net.Pkcs11Interop.HighLevelAPI.Pkcs11' from assembly 'Pkcs11Interop, Version=5.1.0.0, Culture=neutral, PublicKeyToken=c10e9c2d8c006d2a'." I have this error message when trying to load library using Pkcs11Interop 5.1.0 and Pkcs11Interop.X509Store v 0.2.0.
Only Pkcs11Interop version 4.0.0 seems can work along with Pkcs11Interop.X509Store. But I don't have the documentation on how to use Pkcs11Interop v 4.0.0, like loading the library seems to be quite different from v 5.1.0. Is there a way to use Pkcs11Interop v 5.1.0 and pkcs11Interop.X509Store v 0.2.0 at the same time?

The second problem is, in the third step, to use two libraries, I need to call it separately. Code is like below.
Open Pkcs11X509Store:
using (var store = new Pkcs11X509Store(libraryPath, pinProvider))
{
....//Get PrivateKeyHandle
}
Open Pkcs11Interop :
using (IPkcs11Library pkcs11Library = Settings.Factories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Factories, Settings.Pkcs11LibraryPath, Settings.AppType))
{
// Find first slot with token present
ISlot slot = Helpers.GetUsableSlot(pkcs11Library);

            // Open RW session
            using (ISession session = slot.OpenSession(SessionType.ReadWrite))
        {
            ...//Use PrivateKeyHandle 
        }
     }

My question is, will the PrivateKeyHandle refer to the same key under these two separate bracket{}? My concern is I open two separate sessions, so will the object handle of the same key be different in these two session? This is the part I'm not sure.

Thank you.

Using ECDSA with SignedXML

Hi,

I'm getting the following error when attempting to sign XML with an ECDSA keypair:

Unhandled exception. System.Security.Cryptography.CryptographicException: Failed to create signing key.
   at System.Security.Cryptography.Xml.SignedXml.ComputeSignature()

Any ideas?

Does X509Store is only in read-only session?

Hi Guys,
i was recently thinking about using this library in my project to remove openssl dependency, but from what i have read in the code, the store's session is only in read-only state. Correct me if i'm wrong.

Cannot Initialize Pkcs11X509Store instance "Unable to load 64-bit unmanaged library into 32-bit runtime"

Hi,
I am using Pkcs11X509Store (0.2.0.0) with .Net Framework 4.7.2 and trying to initialize the instance but I got the error "Unable to load 64-bit unmanaged library into 32-bit runtime" do you have any idea or suggestion on that ?
I only wanted to load the certificate stored in my HSM.

string libPath = @"C:\Program Files\SafeNet\LunaClient\cryptoki.dll";
using (var store = new Pkcs11X509Store(libPath, new PinProvider("111111")))
{
     Pkcs11X509Certificate cert = store.Slots[0].Token.Certificates[0];
}

and here is my PinProvider Class

public class PinProvider : IPinProvider
{
    private byte[] _pin = null;

    public PinProvider(string pin)
    {
        _pin = Encoding.UTF8.GetBytes(pin);
    }

    public GetPinResult GetKeyPin(Pkcs11X509StoreInfo storeInfo, Pkcs11SlotInfo slotInfo, Pkcs11TokenInfo tokenInfo, Pkcs11X509CertificateInfo certificateInfo)
    {
        return new GetPinResult(false, false, _pin);
    }

    public GetPinResult GetTokenPin(Pkcs11X509StoreInfo storeInfo, Pkcs11SlotInfo slotInfo, Pkcs11TokenInfo tokenInfo)
    {
        return new GetPinResult(false, false, _pin);
    }
}

Update : I changed to load the dll in 32-bit I got this error "Value of attribute CKA_ALWAYS_AUTHENTICATE could not be read"

Unable to get private key from Luna HSM via X509Store

Hi,

I need to use a RA certificate stored in a Luna HSM to add 2nd signature and the RA cert to CSRs generated from a client app.

After running OpenSSL commands to process the RA cert in .pfx format, I got the private key in PKCS8 format, then imported both the RA cert and private key into the HSM.

Using the X509CertificateParser, X509Certificate, AsymmetricKeyParameter and RsaKeyParameter from BouncyCastle, I derived the public key.

I did look at #1 and double checked that CKA_LABEL and CKA_ID have the same values for all 3 objects (private key, public key and certificate). In Pkcs11Admin, I did see all 3 objects after I logged into my HSM via menu Token > Login > User login.

Next , I tried the following code with a Luna HSM...

var store = new Pkcs11X509Store(LunaHsmManager.LibraryPath, LunaHsmManager.PinProvider);
Pkcs11X509Certificate cert = store.Slots[0].Token.Certificates[0];

I was able to retrieve the cert and public key. The cert.Info.KeyType value is RSA, but cert.HasPrivateKeyObject still shows FALSE.

What am I missing?

Thanks

Pkcs11X509Store certificate throw unauthorized (Anonymous) with client WCF authentication

Hello,

I'm trying to assign X509Certificate witch was returned by Pkcs11X509Store:

Dim pinProvider As IPinProvider = New PinProvider()
            Try
                Using store As New Pkcs11X509Store(libraryPath, pinProvider)
                    Dim slots As IEnumerable(Of Pkcs11Slot) = store.Slots.Where(Function(s) s?.Token IsNot Nothing)
                    If slots?.Count > 0 Then
                        For Each slot As Pkcs11Slot In slots
                            If slot?.Token?.Certificates.Count > 0 Then
                                For Each cert As Pkcs11X509Certificate In slot?.Token?.Certificates
                                    If cert?.Info IsNot Nothing Then
                                        result.Add(cert.Info.ParsedCertificate)
                                    End If
                                Next
                            End If
                        Next
                    End If
                End Using
            Catch ex As Exception
               
            End Try

The user chooses the certificate who want to use and the system try to assign it in ClientCredential:

Dim b As New BasicHttpBinding()
            b.Security.Mode = SecurityMode.Transport
            b.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate
            b.MessageEncoding = WSMessageEncoding.Mtom
            b.MaxReceivedMessageSize = 2147483647

            ' Create an EndPointAddress.
            Dim ea As New EndpointAddress(New Uri(Servidor & /ServiciosWCF/OVCWcfCDYG/OVCCertifDYG.svc"))

            ' Create the client.
            Dim proxy As New OVCCertificacionDescriptivaGrafica.OVCCertifDYGClient(b, ea)

            proxy.ClientCredentials.ClientCertificate.Certificate = Me.certificado

This is my IPinProvider

Public Class PinProvider
    Implements IPinProvider

    Public Function GetTokenPin(storeInfo As Pkcs11X509StoreInfo, slotInfo As Pkcs11SlotInfo, tokenInfo As Pkcs11TokenInfo) As GetPinResult Implements IPinProvider.GetTokenPin
        Return New GetPinResult(True, False, Nothing)
    End Function

    Public Function GetKeyPin(storeInfo As Pkcs11X509StoreInfo, slotInfo As Pkcs11SlotInfo, tokenInfo As Pkcs11TokenInfo, certificateInfo As Pkcs11X509CertificateInfo) As GetPinResult Implements IPinProvider.GetKeyPin
        Return New GetPinResult(True, False, Nothing)
    End Function

End Class

And Finally proxy throw Exception 403 (Anonymous)

Can you help me, please?

Add code sample for `CertificateRequest` signing

As shown in #28, CA cert/key managed by Pkcs11Interop.X509Store can be used for issuing/generation of X.509 certificates via System.Security.Cryptography.X509Certificates.CertificateRequest::Create method. Let's explore this as a feature.

Soap SSL

Is it possible to define the SSL connection with Pkcs11Interop? I couldn't find anything about it in the C # codes. Can someone help me?

Fails to load tokens when there are unrecognized ones

After configuring Windows Hello for business, a certificate was created in my PC which is somehow identified as a token by Bit4Id (PKCS#11 library).

image

Since then I'm unable to access my actual PKCS#11 USB Token because Pkcs11X509Store.Slots throws an exception due to the bogus Windows Hello token. The error happens in Pkcs11Token.GetTokenContext when calling Slot.GetTokenInfo() which throws a Pkcs11Exception exception => CKR_TOKEN_NOT_RECOGNIZED.

The error handling below allows "good" tokens to be loaded regardless of the presence of "invalid" ones.

private List<Pkcs11Slot> GetSlots()
{
	var slots = new List<Pkcs11Slot>();

	foreach (ISlot slot in _storeContext.Pkcs11Library.GetSlotList(SlotsType.WithTokenPresent))
	{
		try
		{
			var pkcs11Slot = new Pkcs11Slot(slot, _storeContext);
			slots.Add(pkcs11Slot);
		}
		catch (Pkcs11Exception ex)
		{
			if (ex.RV != CKR.CKR_TOKEN_NOT_RECOGNIZED && ex.RV != CKR.CKR_TOKEN_NOT_PRESENT)
			{
				throw;
			}
		}
	}

	return slots;
}

NotSupportedException thrown when sign xml file from SignedXmlTest

When run SignedXmlTest on real HSM device, a NotSupportedException thrown at Pkcs11RsaProvider.DecryptValue method

using (var store = new Pkcs11X509Store(Hsm2Manager.LibraryPath, Hsm2Manager.PinProvider))
            {
                // Find signing certificate
                Pkcs11X509Certificate cert = Helper.GetCertificate(store, Hsm2Manager.Token1Label, Hsm2Manager.Token1CertLabel);

                // Get PKCS#11 based private key
                RSA rsaPrivateKey = cert.GetRSAPrivateKey();

                // Get software based public key
                RSA rsaPublicKey = cert.Info.ParsedCertificate.PublicKey.Key as RSA;

                // Sign the XML that was just created and save it in a new file
                SignXmlFile("input.xml", "signed.xml", rsaPrivateKey);

            }

and

public static void SignXmlFile(string FileName, string SignedFileName, RSA Key)
        {
            // Create a new XML document.
            XmlDocument doc = new XmlDocument();

            // Load the passed XML file using its name.
            doc.Load(new XmlTextReader(FileName));

            // Create a SignedXml object.
            SignedXml signedXml = new SignedXml(doc);

            // Add the key to the SignedXml document. 
            signedXml.SigningKey = Key;

            // Create a reference to be signed.
            Reference reference = new Reference();
            reference.Uri = "";

            // Add an enveloped transformation to the reference.
            XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
            reference.AddTransform(env);

            // Add the reference to the SignedXml object.
            signedXml.AddReference(reference);

            // Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate).
            KeyInfo keyInfo = new KeyInfo();
            keyInfo.AddClause(new RSAKeyValue((RSA)Key));
            signedXml.KeyInfo = keyInfo;

            // Compute the signature.
            signedXml.ComputeSignature();

            // Get the XML representation of the signature and save
            // it to an XmlElement object.
            XmlElement xmlDigitalSignature = signedXml.GetXml();

            // Append the element to the XML document.
            doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true));

            if (doc.FirstChild is XmlDeclaration)
            {
                doc.RemoveChild(doc.FirstChild);
            }

            // Save the signed XML document to a file specified
            // using the passed string.
            XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false));
            doc.WriteTo(xmltw);
            xmltw.Close();
        }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.