I recently created a Console app which held the context of Pkcs11Interop library, along with HSM dll. It worked fine, however I needed to rewrite the code to Windows Service (I hosted it as gRPC service since it's .NET Core). After hosting WS, it ocurred that the slot list on factories.Pkcs11LibraryFactory.LoadPkcs11Library(factories, libraryPath, AppType.MultiThreaded).GetSlotList(SlotsType.WithOrWithoutTokenPresent).Find(slot => slot.SlotId == slotId) returns an empty list of slots, even though it returned list of 3 elements in console app.
public Pkcs11Signature(string libraryPath, ulong slotId)
{
Pkcs11InteropFactories factories = new Pkcs11InteropFactories();
_pkcs11Library = factories.Pkcs11LibraryFactory.LoadPkcs11Library(factories, libraryPath, AppType.MultiThreaded);
_slot = _pkcs11Library.GetSlotList(SlotsType.WithOrWithoutTokenPresent).Find(slot => slot.SlotId == slotId);
}
public Pkcs11Signature Select(string alias, string certLabel, string pin, bool login)
{
List<CKA> pkAttributeKeys = new List<CKA>();
pkAttributeKeys.Add(CKA.CKA_KEY_TYPE);
pkAttributeKeys.Add(CKA.CKA_LABEL);
pkAttributeKeys.Add(CKA.CKA_ID);
List<CKA> certAttributeKeys = new List<CKA>();
certAttributeKeys.Add(CKA.CKA_VALUE);
certAttributeKeys.Add(CKA.CKA_LABEL);
//CloseSession();
_session = _slot.OpenSession(SessionType.ReadWrite);
if (login)
_session.Login(CKU.CKU_USER, pin);
ObjectAttributeFactory objectAttributeFactory = new ObjectAttributeFactory();
List<IObjectAttribute> attributes = new List<IObjectAttribute>();
attributes.Add(objectAttributeFactory.Create(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY));
List<IObjectHandle> keys = _session.FindAllObjects(attributes);
bool found = false;
foreach (IObjectHandle key in keys)
{
List<IObjectAttribute> keyAttributes = _session.GetAttributeValue(key, pkAttributeKeys);
ulong type = keyAttributes[0].GetValueAsUlong();
string encryptionAlgorithm;
switch (type)
{
case (ulong)CKK.CKK_RSA:
encryptionAlgorithm = "RSA";
break;
case (ulong)CKK.CKK_DSA:
encryptionAlgorithm = "DSA";
break;
case (ulong)CKK.CKK_ECDSA:
encryptionAlgorithm = "ECDSA";
break;
default:
continue;
}
string thisAlias = keyAttributes[1].GetValueAsString();
if (thisAlias == null || thisAlias.Length == 0)
thisAlias = keyAttributes[2].GetValueAsString();
if (alias != null && !alias.Equals(thisAlias))
continue;
attributes.Clear();
attributes.Add(objectAttributeFactory.Create(CKA.CKA_CLASS, CKO.CKO_CERTIFICATE));
attributes.Add(objectAttributeFactory.Create(CKA.CKA_CERTIFICATE_TYPE, CKC.CKC_X_509));
if (certLabel == null && thisAlias != null && thisAlias.Length > 0)
certLabel = thisAlias;
if (certLabel != null)
attributes.Add(objectAttributeFactory.Create(CKA.CKA_LABEL, certLabel));
List<IObjectHandle> certificates =_session.FindAllObjects(attributes);
if (certificates.Count != 1)
continue;
IObjectHandle certificate = certificates[0];
List<IObjectAttribute> certificateAttributes =_session.GetAttributeValue(certificate, certAttributeKeys);
X509Certificate x509Certificate =
new X509Certificate(X509CertificateStructure.GetInstance(certificateAttributes[0].GetValueAsByteArray()));
List<X509Certificate> x509Certificates = new List<X509Certificate>();
x509Certificates.Add(x509Certificate);
attributes.Clear();
attributes.Add(objectAttributeFactory.Create(CKA.CKA_CLASS, CKO.CKO_CERTIFICATE));
attributes.Add(objectAttributeFactory.Create(CKA.CKA_CERTIFICATE_TYPE, CKC.CKC_X_509));
List<IObjectHandle> otherCertificates =_session.FindAllObjects(attributes);
foreach (IObjectHandle otherCertificate in otherCertificates)
{
if (!certificate.ObjectId.Equals(otherCertificate.ObjectId))
{
certificateAttributes =_session.GetAttributeValue(otherCertificate, certAttributeKeys);
X509Certificate otherX509Certificate =
new X509Certificate(X509CertificateStructure.GetInstance(certificateAttributes[0].GetValueAsByteArray()));
x509Certificates.Add(otherX509Certificate);
}
}
found = true;
_alias = thisAlias;
_encryptionAlgorithm = encryptionAlgorithm;
_privateKeyHandle = key;
_chain = x509Certificates.ToArray();
break;
}
if (!found)
{
Console.WriteLine("Havent found");
_alias = null;
_encryptionAlgorithm = null;
_privateKeyHandle = null;
_chain = null;
}
return this;
}
Executing the library:
using (var signature = new Pkcs11Signature(#"C:\Program Files (x86)\hsm\hsm.dll", 3).
Select(null, "CERT LABEL", "PIN", true)
{
(...DO THE WORK HERE...)
}
I've seen this, but changing the "Log On As" to "Local Service" for Windows Service gives no effect:
C_GetSlotList Failing when called from IIS but not from IIS express
Pkcs11Interop returns slots received by calling C_GetSlotList function of unmanaged PKCS#11 library. So if you get 0 slots then C_GetSlotList returned 0 slots. You need to discuss this situation with the vendor of your PKCS#11 library who might know why their library does not see any slots.
Related
Introduction
I'm developing a .NET 6 environment that has an API for transferring ether from one wallet to another wallet. It uses the Nethereum library for that.
Issue
I'm getting the Transaction Hash of the ether transfer. But when I'm trying to see it on Etherscan (see here) it doesn't appear. In addition to that, in my wallet, the value isn't transferred.
Workflow
The controller calls Transfer method, which calls TransferWaitingTxHashAsync method.
public bool Transfer(int ecommerceId, EtherWallet senderWallet, TransferRequestVO transferRequest)
{
string transactionHash = null;
bool thrownError = false;
try
{
transactionHash = _hdWalletManager.TransferWaitingTxHashAsync(senderWallet, transferRequest).Result;
}
catch (Exception)
{
thrownError = true;
}
if(thrownError || transactionHash == null)
return false;
EthereumTransactionReceipt pendingTransactionReceipt = new()
{
From = senderWallet.Address,
To = transferRequest.AddressDestination,
EcommerceId = ecommerceId,
TransactionHash = transactionHash,
Status = EthereumTransactionReceiptAvailableStatus.Pending.Value
};
_ethereumTransactionReceiptRepository.Insert(pendingTransactionReceipt);
bool saveChanges = _ethereumTransactionReceiptRepository.SaveChanges();
return saveChanges;
}
As you can see below, I'm doubling both Gas and GasPrice.
The Nonce is being summed to avoid transaction replacement underpriced (changing it on the debugger each time I run).
public Task<string> TransferWaitingTxHashAsync(EtherWallet senderWallet, TransferRequestVO transferRequest)
{
NethereumAccount senderAccount = new(senderWallet.PrivateKey);
Web3 web3 = new(senderAccount, _httpAddress);
HexBigInteger gasPrice = web3.Eth.GasPrice.SendRequestAsync().Result;
decimal gasPriceDecimal = Math.Round(gasPrice.ToLong() * 2m);
gasPriceDecimal = Web3.Convert.FromWei(BigInteger.Parse(gasPriceDecimal.ToString()), UnitConversion.EthUnit.Gwei);
BigInteger gas = web3.Eth.GetEtherTransferService()
.EstimateGasAsync(transferRequest.AddressDestination,
transferRequest.EtherAmount)
.Result;
gas = BigInteger.Add(gas, gas);
BigInteger nonce = senderAccount.NonceService.GetNextNonceAsync().Result;
BigInteger nextNonce = nonce + 131;
return web3.Eth.GetEtherTransferService()
.TransferEtherAsync(transferRequest.AddressDestination,
transferRequest.EtherAmount,
gasPriceDecimal,
gas,
nextNonce);
}
Environment
I'm running it locally using Infura as the provider (https://goerli.infura.io/v3/YOUR-API-KEY) for Goerli network.
Summarized
How can I fix it, and successfully complete my transaction or either see it on Etherscan (Goerli)?
I have copied the code from Save Data.
which is like this:
void addScoreToLeaders(string name, int score ,string
key,Dictionary<string,object> childUpdates){
reference.Child ("leaders").KeepSynced (true);
reference.Child ("leaders").RunTransaction(mutableData =>{
List<Dictionary<string,object>> leaders = mutableData.Value as
List<Dictionary<string,object>>;
if(leaders == null){
leaders = new List<Dictionary<string,object>>();
} else if(mutableData.ChildrenCount >= MAX_SCORE){
int minScore = int.MaxValue;
Dictionary<string,object> minValue = null;
foreach(var child in leaders){
if(!(child is Dictionary<string,object>)) continue;
int childScore = (int)((Dictionary<string,object>)child)
["score"];
if(childScore < minScore){
minScore = childScore;
minValue = child;
}
}
if(minScore > score){
return TransactionResult.Abort ();
}
leaders.Remove (minValue);
}
//Add the new high score
Dictionary<string ,object> newScoreMap = new
Dictionary<string,object> ();
LeaderBoardEntry entry = new LeaderBoardEntry (name, score);
newScoreMap = entry.ToDictionary ();
leaders.Add (newScoreMap);
mutableData.Value = leaders;
return TransactionResult.Success (mutableData);
});
}
okay, there's two things not happens correctly :
TransactionResult.Success(mutableData) does not store the new data at the location
Return mutableData null for every first time i call the method
[Solved] after examining the code and several attempts of testing found the solution .
line number five (5) of the code causing problem which is :
List<Dictionary<string,object>> leaders = mutableData.Value as
List<Dictionary<string,object>>;
replace with :
Dictionary<string,object> leaders = mutableData.Value as
Dictionary<string,object>;
because mutableData.Value returned the data contained in this instance as native types, and i saved the data like Dictionary<.string,object>;
I want to adjust the brightness of my monitor on Windows.
I follow this page:
How to use GetMonitorCapabilities and GetMonitorBrightness functions
but, the GetMonitorCapabilities function returns false.
I printed using qDebug, hPhysicalMonitor is NULL. Is this point wrong?
(The GetPhysicalMonitorsFromHMONITOR function returns true)
How can I fix this code?
HMONITOR hMonitor = NULL;
DWORD cPhysicalMonitors = 1;
LPPHYSICAL_MONITOR pPhysicalMonitors;
HWND hWnd = GetDesktopWindow();
// Get the monitor handle.
hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTOPRIMARY);
// Get the number of physical monitors.
BOOL bSuccess = GetNumberOfPhysicalMonitorsFromHMONITOR(hMonitor, &cPhysicalMonitors);
if (bSuccess)
{
// Allocate the array of PHYSICAL_MONITOR structures.
pPhysicalMonitors = (LPPHYSICAL_MONITOR)malloc(cPhysicalMonitors* sizeof(PHYSICAL_MONITOR));
if (pPhysicalMonitors != NULL)
{
// Get the array.
bSuccess = GetPhysicalMonitorsFromHMONITOR( hMonitor, cPhysicalMonitors, pPhysicalMonitors);
if (bSuccess == FALSE)
{
qDebug("GetPhysicalMonitorsFromHMONITOR");
}
// Get physical monitor handle.
HANDLE hPhysicalMonitor = pPhysicalMonitors[0].hPhysicalMonitor;
DWORD pdwMonitorCapabilities = 0;
DWORD pdwSupportedColorTemperatures = 0;
bSuccess = GetMonitorCapabilities(hPhysicalMonitor, &pdwMonitorCapabilities, &pdwSupportedColorTemperatures);
if (bSuccess == FALSE)
{
qDebug("GetMonitorCapabilities");
}
DWORD pdwMinimumBrightness = 0;
DWORD pdwCurrentBrightness = 0;
DWORD pdwMaximumBrightness = 0;
bSuccess = GetMonitorBrightness(hPhysicalMonitor, &pdwMinimumBrightness, &pdwCurrentBrightness, &pdwMaximumBrightness);
if (bSuccess == FALSE)
{
qDebug("GetMonitorBrightness");
}
qDebug(QByteArray::number(bSuccess));
qDebug(QByteArray::number((WORD)pdwMinimumBrightness));
qDebug(QByteArray::number((WORD)pdwCurrentBrightness));
qDebug(QByteArray::number((WORD)pdwMaximumBrightness));
// Close the monitor handles.
bSuccess = DestroyPhysicalMonitors(cPhysicalMonitors, pPhysicalMonitors);
// Free the array.
free(pPhysicalMonitors);
}
}
If you want to adjust the brightness using WmiMonitorBrightnessMethods use the code below.
public static void SetWmiMonitorBrightness(byte targetBrightness)
{
ManagementScope scope = new ManagementScope("root\\WMI");
SelectQuery query = new SelectQuery("WmiMonitorBrightnessMethods");
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query))
{
using (ManagementObjectCollection objectCollection = searcher.Get())
{
foreach (ManagementObject mObj in objectCollection)
{
mObj.InvokeMethod("WmiSetBrightness",
new Object[] { UInt32.MaxValue, targetBrightness });
break;
}
}
}
}
Doing GetMonitorBrightness on the specific monitor I have causes ERROR_GRAPHICS_I2C_ERROR_TRANSMITTING_DATA.
So I used WmiSetBrightness instead. It works fine.
If you got a tip related to ERROR_GRAPHICS_I2C_ERROR_TRANSMITTING_DATA, please share it with me.
I should be able to figure this out, but I've been fighting with it for quite a while now.
I have a popup page that has several available requests that a user can select from. Based upon the page that the user is accessing, there could be one request or multiple requests available for that user. The single and multiple request are both saved on different session variables.
I need to know the single request that the user selected at the beginning of the process. It works fine except when the user is allowed to add multiple requests, the single request session variable is also updated.
For example, single request variable has "Florida"; then, the user reaches the multiple request page and adds GA and LA to the multiple request session variable. The single request variable is also updated to include GA and LA even though the flag is false and never reached that line. I don't want it to be updated. I need that single request to be available at all the time, so the user can see it if and when requested.
Here is a sample code where the issue is happening:
List<Request> temp = new List<Request>();
List<Request> mySearchRequest = new List<Request>();
List<Request> listSingleRequest = new List<Request>();
if (SessionWrapper.currentRequest.AvailableRequests != null)
{
mySearchRequest = (List<Request>)SessionWrapper.currentRequest.AvailableRequests;
}
if (SessionWrapper.currentRequest.MultipleRequests != null)
{
temp = (List<Request>)SessionWrapper.currentRequest.MultipleRequests;
var test = temp.Find(delegate(Request req) { return req.RequestId == id && req.Desc == description; });
// Checking if we have on the container already
if (mySearchRequest.Any(r => r.RequestId == id && r.Desc == description) == false)
{
mySearchRequest.Add(test);
if (SessionWrapper.currentRequest.SingleRequest == true && mySearchRequest.Count() == 1)
{
listSingleRequest.Add(test);
SessionWrapper.currentRequest.singleRequest = listSingleRequest ;
listSingleRequest = null;
}
}
}
//Set multiple request session here
Your help is greatly appreciated.
Thanks,
JF
After playing around with it almost all night, I was able to fix it. I am not sure if that is the most efficient way of doing it, but it works for now.
if (SessionWrapper.currentRequest.MultipleRequests != null)
{
temp = (List<Request>)SessionWrapper.currentRequest.MultipleRequests;
var test = temp.Find(delegate(Request req) { return req.RequestId == id && req.Desc == description; });
// Checking if we have on the container already
if (mySearchRequest.Any(r => r.RequestId == id && r.Desc == description) == false)
{
mySearchRequest.Add(test);
if (SessionWrapper.currentRequest.SingleRequestPage == true && mySearchRequest.Count() == 1)
{
foreach (var item in test)
{
//Create a new request object and add it to the list
Request request = new Request();
request.RequestId == item.RequestId;
request.Description == item.Description;
listSingleRequest.Add(request);
}
SessionWrapper.currentRequest.singleRequest = listSingleRequest ;
listSingleRequest = null;
}
}
}
if (SessionWrapper.currentRequest.singleRequest != null)
{
tempRequest = SessionWrapper.currentRequest.singleRequest.ToList();
foreach (var test in tempRequest)
{
Request request = new Request();
request.RequestId == item.RequestId;
request.Description == item.Description;
listSingleRequest.Add(request);
}
SessionWrapper.currentRequest.ViewRequest = listSingleRequest;
listSingleRequest = null;
}
Using org.as3commons.reflect I can look-up the class name, and instantiate a class at runtime. I also have (non-working) code which invokes a method. However, I really want to set a property value. I'm not sure if properties are realized as methods internally in Flex.
I have a Metadata class which stores 3 pieces of information: name, value, and type (all are strings). I want to be able to loop through an Array of Metadata objects and set the corresponding properties on the instantiated class.
package com.acme.reporting.builders
{
import com.acme.reporting.model.Metadata;
import mx.core.UIComponent;
import org.as3commons.reflect.ClassUtils;
import org.as3commons.reflect.MethodInvoker;
public class UIComponentBuilder implements IUIComponentBuilder
{
public function build(metadata:Array):UIComponent
{
var typeClass:Class = ClassUtils.forName(getTypeName(metadata));
var result:* = ClassUtils.newInstance(typeClass);
for each (var m:Metadata in metadata)
{
if (m.name == "type")
continue;
// Attempting to invoke as method,
// would really like the property though
var methodInvoker:MethodInvoker = new MethodInvoker();
methodInvoker.target = result;
methodInvoker.method = m.name;
methodInvoker.arguments = [m.value];
var returnValue:* = methodInvoker.invoke(); // Fails!
}
return result;
}
private static function getTypeName(metadata:Array):String
{
if (metadata == null || metadata.length == 0)
throw new ArgumentError("metadata is null or empty");
var typeName:String;
// Type is usually the first entry
if (metadata.length > 1 && metadata[0] != null && metadata[0].name == "type")
{
typeName = metadata[0].value;
}
else
{
var typeMetadata:Array = metadata.filter(
function(element:*, index:int, arr:Array):Boolean
{
return element.name == "type";
}
);
if (typeMetadata == null || typeMetadata.length != 1)
throw new ArgumentError("type entry not found in metadata");
typeName = typeMetadata[0].value;
}
if (typeName == null || typeName.length == 0)
throw new Error("typeName is null or blank");
return typeName;
}
}
}
Here's some usage code:
var metadata:Array = new Array();
metadata[0] = new Metadata("type", "mx.controls.Text", null);
metadata[1] = new Metadata("text", "Hello World!", null);
metadata[2] = new Metadata("x", "77", null);
metadata[3] = new Metadata("y", "593", null);
this.addChild(new UIComponentBuilder().build(metadata));
I realize that I have to declare a dummy variable of the type I was to instantiate, or use the -inculde compiler directive. An unfortunate drawback of Flex.
Also, right now there's code to account for typecasting the value to it's specified type.
Dynamic execution in AS3 is much simpler than in other languages. This code:
var methodInvoker:MethodInvoker = new MethodInvoker();
methodInvoker.target = result;
methodInvoker.method = m.name;
methodInvoker.arguments = [m.value];
var returnValue:* = methodInvoker.invoke(); // Fails!
can be simplified to this:
var returnValue:* = result[method](m.value);
EDIT:
Since it's a property, it would be done like this:
result[method] = m.value;
and there is no return value (well, you can call the getter again but it should just return m.value unless the setter/getter do something funky.