everyone
I am writeng .dll for getting thumbprint string, using packages:
packages.config:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Aktiv.RutokenPkcs11Interop" version="2.0.11" targetFramework="net45" />
<package id="Pkcs11Interop" version="4.1.2" targetFramework="net45" />
</packages>
App.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Pkcs11Interop" publicKeyToken="c10e9c2d8c006d2a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
When i run code directly in VS2022, it works fine, but when i build it and try to call from python VS Code – it dumps with error:
Traceback (most recent call last):
…
print(com_object.GetThumbsString())
File “”, line 3, in GetThumbsString
pywintypes.com_error: (-2147352567, ‘Error.’, (0, ‘GetThumbsCrypto’, ‘Failed to load file or assembly “Pkcs11Interop, Version=4.1.1.0, Culture=neutral, PublicKeyToken=c10e9c2d8c006d2a” or one of its dependencies. The specified file cannot be found.’, None, 0, -2147024894), None)
Python
import win32com.client
def main():
com_object = win32com.client.Dispatch("GetThumbsCrypto.GetCertificateThumbs")
print(com_object.GetThumbsString())
if __name__ == "__main__":
main()
C#
using System;
using System.Collections.Generic;
using System.Linq;
using Net.Pkcs11Interop.Common;
using Net.Pkcs11Interop.HighLevelAPI;
using RutokenPkcs11Interop;
using RutokenPkcs11Interop.HighLevelAPI;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
namespace GetThumbsCrypto
{
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[Guid("0EA9F9D3-7AE9-4816-8717-E6F0FAF67887")]
public interface IGetCertificateThumbs
{
[DispId(1)]
string GetThumbsString();
[DispId(2)]
string TestSub();
}
[ComVisible(true)]
[Guid("8DD66953-3247-4206-B37E-3C3F7B5850F6"),
ClassInterface(ClassInterfaceType.None)]
public class GetCertificateThumbs : IGetCertificateThumbs
{
// Certificate search template
static readonly List<ObjectAttribute> CertificateAttributes = new List<ObjectAttribute>
{
// Certificate object
new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_CERTIFICATE),
// Certificate is a token object
new ObjectAttribute(CKA.CKA_TOKEN, true),
// Certificate is accessible without authentication
new ObjectAttribute(CKA.CKA_PRIVATE, false),
// Certificate type is X.509
new ObjectAttribute(CKA.CKA_CERTIFICATE_TYPE, CKC.CKC_X_509),
};
public string TestSub()
{
return "Test is ok";
}
public string GetThumbsString()
{
string res = "";
try
{
Console.WriteLine("Library initialization");
using (var pkcs11 = new Net.Pkcs11Interop.HighLevelAPI.Pkcs11(Settings.RutokenEcpDllDefaultPath, AppType.MultiThreaded))
{
Console.WriteLine("Checking tokens available");
Slot slot = GetUsableSlot(pkcs11);
Console.WriteLine("Opening RW session");
using (Session session = slot.OpenSession(SessionType.ReadWrite))
{
try
{
Console.WriteLine("Getting information...");
Console.WriteLine(" Getting certificates...");
List<ObjectAttribute> publicKeyAttributes = new List<ObjectAttribute>();
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_CERTIFICATE));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_TOKEN, true));
publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_CERTIFICATE_TYPE, CKC.CKC_X_509));
var certificates = session.FindAllObjects(CertificateAttributes);
Errors.Check(" Certificates not found", certificates != null);
Errors.Check(" Certificates not found", certificates.Any());
List<string> thumbprints = new List<string>();
foreach (var certificateObject in certificates)
{
byte[] certificateData = session.GetAttributeValue(certificateObject, new List<CKA> { CKA.CKA_VALUE })[0].GetValueAsByteArray();
byte[] thumbprintBytes;
using (SHA1Managed sha1 = new SHA1Managed())
{
thumbprintBytes = sha1.ComputeHash(certificateData);
}
string thumbprint = BitConverter.ToString(thumbprintBytes).Replace("-", "");
thumbprints.Add(thumbprint);
}
Console.WriteLine("Thumbprints of found certificates:");
foreach (var thumbprint in thumbprints)
{
Console.WriteLine(thumbprint);
res = string.Join("$", thumbprints);
}
string certificateInfo = session.GetCertificateInfoText(certificates[0]);
Errors.Check(" Certificate info not found", !string.IsNullOrEmpty(certificateInfo));
Console.WriteLine(certificateInfo);
Console.WriteLine("Information has been acquired successfully");
}
finally
{
session.Logout();
}
}
}
}
catch (Pkcs11Exception ex)
{
Console.WriteLine($"Operation failed [Method: {ex.Method}, RV: {ex.RV}]");
}
catch (Exception ex)
{
Console.WriteLine($"Operation failed [Message: {ex.Message}]");
}
return res;
}
public static Slot GetUsableSlot(Net.Pkcs11Interop.HighLevelAPI.Pkcs11 pkcs11)
{
List<Slot> slots = pkcs11.GetSlotList(SlotsType.WithTokenPresent);
if (slots == null)
throw new NullReferenceException("No available slots");
if (slots.Count <= 0)
throw new InvalidOperationException("No available slots");
Slot slot = slots[0];
return slot;
}
}
public static class Errors
{
public static void Check(string errorMessage, bool condition)
{
if (!condition)
throw new InvalidOperationException(errorMessage);
}
}
}
I have tried to call TestSub() from com using python – it works fine.
I have reinstalled nuget packages.
I have changed target platform to 4.7.2 and then back to 4.5 – I don’t know why.
Sergey Khusainov is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.