Cryptoki dll causing application to crash - c#

I'm using cryptoki in a C# app. The problem I have is the following:
I initialize cryptoki using the following code:
public static bool InitializeCryptoki(string criptokilib)
{
if (cryptoki != null)
throw new PdfSignException(PdfSignExceptionCode.PDF_EXCEPTION_NOT_FINALIZED);
try
{
cryptoki = new Cryptoki(criptokilib);
if (cryptoki.Initialize() == 0)
{
isInitialized = true;
return true;
}
return false;
}
catch (CryptokiException ex)
{
Log.Log(log, LogState.ERROR, UserId, "Initialize", null, ex.Message);
return false;
}
}
criptokilib value is equal to "eTPKCS11.dll".
After cryptoki is initialized, I check if at least one card reader exists using the following code:
public static bool HasCardReaders
{
get
{
if (cryptoki == null)
throw new PdfSignException(PdfSignExceptionCode.PDF_EXCEPTION_NOT_INITIALIZED);
return cryptoki.Slots.Count != 0;
}
}
When running the app in debug mode from the compiler (VS 2012), an error message is displayed (no app crash) saying that no card reader has been detected.
When running the app outside the compiler (VS 2012) - by double clicking the exe in debug folder, my application crashes. Looking at the log files, sometimes the app crashes while initializing cryptoki, and sometimes the app crashes while checking if at least one card reader exists.
In debug mode, I discovered that cryptoki.Slots[i].Token throws error n. 224 - this error means that no token is present. Can this error cause my app to crash? Do you have any idea how to overcame this issue?
Thank you very much,
Gica G.

if (cryptoki != null)
This looks wrong. That should read:
if (cryptoki == null)

It seems that upgrading to the last NCryptoki.dll resolves the issue.
However I still didn't understood why that error was causing my app to crash.

Related

How can I have an exception show in debugging output that doesn't cause a "catch"

This may be a basic question but I have not been able to find an answer from searching. I have code that is causing an exception to be written to the Output -> Debug window in Visual Studio. My try...catch is proceeding to the next line of code anyway. The exception is with a NuGet package.
Does this mean an exception is happening in the NuGet package and is handled by the Nuget package? How can I troubleshoot this further?
private void HandleStorageWriteAvailable(IXDocument doc)
{
using IStorage storage = doc.OpenStorage(StorageName, AccessType_e.Write);
{
Debug.WriteLine("Attempting to write to storage.");
try
{
using (Stream str = storage.TryOpenStream(EntityStreamName, true))
{
if (str is not null)
{
try
{
string test = string.Concat(Enumerable.Repeat("*", 100000));
var xmlSer = new XmlSerializer(typeof(string));
xmlSer.Serialize(str, test);
}
catch (Exception ex)
{
Debug.WriteLine("Something bad happened when trying to write to the SW file.");
Debug.WriteLine(ex);
}
}
else
{
Debug.WriteLine($"Failed to open stream {EntityStreamName} to write to.");
}
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
}
The exception happens on the line using (Stream str = storage.TryOpenStream(EntityStreamName, true)) when the exception happens the code proceeds to the next line not the catch.
Is this normal behaviour if that exception is being handled by something else? I've never seen this before.
In general, a method called TrySomething will be designed so that it won't throw an exception, but return some sort of error code instead.
Check for example the Dictionary class : it has an Add method which can throw an ArgumentException if the key already exists, and a TryAdd method which instead just returns false.
Chances are, your IStorage implementation of TryOpenStream also has an OpenStream method, and the Try version is just a try/catch wrapper which outputs the error to the Console in case of error.
How do you know it happens on that line?
However there is a setting that enables breaking handled exception in "Exception Settings" dialog (Ctrl+Alt+E). For each type of exception you can control. Here is a link that explain how it works : https://learn.microsoft.com/en-us/visualstudio/debugger/managing-exceptions-with-the-debugger?view=vs-2022

Eat exception or check null?

I have the following code:
private async Task <string>IsolatedStorageReadTextFile(string uFileName)
{
string sRet = "";
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync(uFileName);
if (file != null)
{
using (var inputStream = await file.OpenReadAsync())
using (var classicStream = inputStream.AsStreamForRead())
using (var streamReader = new StreamReader(classicStream))
{
while (streamReader.Peek() >= 0)
{
sRet = streamReader.ReadLine();
}
}
}
return sRet;
}
When the file in question doesn't exist, the IDE throws an error:
Should I
1) let the IDE debug warner ignore this error (say "Don't break on this exception"), and I should just let "if (file != null)" do the job
2) or should I check if the file actually exists
3) use try-catch?
I had to add an important part of code according to the answers:
private async Task <bool> LocalExists(string uFileName)
{
bool b = false;
//https://stackoverflow.com/questions/8626018/how-to-check-if-file-exists-in-a-windows-store-app
try
{
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync(uFileName);
b = (file != null);
}
catch (Exception ex)
{
b = false;
}
return b;
}
This throws the same exception since in UWP, there seems no other way of checking if a file actually exists than trying to access it:
How to check if file exists in a Windows Store App?
So the question remains.
You should check if the file exists unless it should always be there,e.g. Because it's part of your program.
Nevertheless, you should use try catch around the whole thing because even if the file exists, it could be locked or a different reading error could occur.
Of the three solutions you proposed (ignore the error, check the file exists first, or catch the exception), only catching the exception will work. Ignoring the exception will let the app crash. Checking if the file exists before calling GetFileAsync has a timing issue where the file may be removed after the check but before opening it.
The fourth and best solution is to use StorageFile.TryGetItemAsync to return the file if it exists or null if it doesn't.
StorageFile file = await ApplicationData.Current.LocalFolder.TryGetItemAsync(uFileName) as StorageFile;
if (file != null)
{
//...
}
The linked thread which says there's no way to check was correct for Windows Store apps in 2011. It's out of date for UWP apps in 2017.
You can either check the file exists before, or handle the exception.
When you don't catch the exception, the next line will not be executed so you can't check file for null (not like other programming language like C++).
The option, don't break on this option, only don't pause (activate a breakpoint) the application when exception is thrown only, doesn't change the behaviour of the program.

c# Console Application referenced DLL variable remains null

I have read through many posts on this type of situation and I can't figure out the solution or what I am doing wrong.
I have a code that references a DLL. It is added as a reference in Visual Studio and it is copied locally along with the target exe file. It runs for me, but when I deploy it to another computer it causes a NullReference exception at the below line of code (see comment):
Unhandled Exception: System.NullReferenceException: Object reference
not set to an instance of an object.
at CheckUpdate.Program.checkUpdate() in Program.cs:line 28
at CheckUpdate.Program.Main(String[] args) in Program.cs:line 22
Here is my code, see comments where the error is reported on the stack trace:
using System;
using System.Collections.Generic;
using System.Text;
using Com.Idiominc.Webservices.Client;
using System.Diagnostics;
using System.IO;
using System.Net;
namespace CheckUpdate
{
class Program
{
private static WSContext _UpdateWScontext { get; set; }
private static string wsUrl = "https://www.myWorldServer.com/ws";
private static string[] myArgs;
static int Main(string[] args)
{
myArgs=args;
if (myArgs.GetUpperBound(0) != 1) return 9;
return checkUpdate();
}
public static int checkUpdate()
{
string testStr = "password1";
while (_UpdateWScontext == null && testStr != "")
{
try
{
_UpdateWScontext = new WSContext("user", testStr, wsUrl + "/services");
}
catch
{
if (_UpdateWScontext == null)
{
if (testStr == "password1") testStr = "password2";
else if (testStr == "password2") testStr = "password3";
else testStr = "";
}
}
}
if (_UpdateWScontext.token == string.Empty) return 0;
string currentversion = myArgs[0];
string latestver = getLatestVersion();
if (latestver == null)
{
return 0;
}
else if (!currentversion.Equals(latestver))
{
if (getLatestDownload()) return 1;
else return 0;
}
else
{
_UpdateWScontext.logout(_UpdateWScontext.token);
return 2;
}
}
}
}
The DLL (WSWebServices.dll) is copied locally along with the executable. It runs on my own station, but when I port it to another station, it causes the exception.
Any advice or clue would be appreciated, thanks.
Edit:
Based on comments the NullReference exception was on the line
if (_UpdateWScontext.token == string.Empty) return 0;
I have now modified this to
if (_UpdateWScontext == null || _UpdateWScontext.token == string.Empty) return 0;
With this no more NullReference Exception, however the exit code now is always 0, meaning the variable is still null.
Any suggestion as to why the connection is not working to the URL? It does work from the browser on the same computer.
Update - solved
I traced the error by outputting the Exception stack trace to the console on the station where the app was not working, and it turned out that the WSWebServices.dll is referencing the Microsoft.Web.Services2.dll (part of the WSE package) and for some reason this was missing from the installation on the misbehaving station.
I added it as a reference and made sure that the dll is copied to the application folder and it now works as intended. Documented here for others in the same mystery why the WorldServer web services would not work.
Within while loop, firstly you try with Password1, you get exception on creating WSContext, then in catch block you set testStr to Password2. With Password2 you again get an exception, and this time in catch block you set testStr to an empty string, and you leave out of while loop without creation of _UpdateWScontext.
I think you null ref exception exactly at this point of code if (_UpdateWScontext.token == string.Empty) return 0;.
You should log exception details in the catch block within the while loop, it can give clue about the error.

Connection must be valid and open -> Error occurs but connection is valid?

I have some problems with my database connection in my application.
My application stores some data into a mysql database and now I got the error mentioned in the title.
The problem is:
Right before I call the method that throws this exception I call another method which also connects to the database but successfully.
At first I thought that there is an error in my source but there is no error.
Here is the bad method:
public static bool checkExistence(object obj)
{
MySqlCommand checkQuery = new MySqlCommand(MySQLQueries.getCheckQueryByObject(obj), connection);
object checkResult = null;
if (connection.State == System.Data.ConnectionState.Closed)
{
OpenConnection();
try
{
checkResult = checkQuery.ExecuteScalar();
}
catch (MySqlException ex)
{
ErrorHandler(ex);
return true;
}
catch (Exception ex)
{
ErrorHandler(ex);
return true;
}
finally
{
CloseConnection();
}
}
else
{
checkResult = checkQuery.ExecuteScalar();
}
if (checkResult != null)
return true;
else
return false;
}
As you can see I first create a new command which later will check if an object exists.
The result of the query will be stored in object checkResult and at the end I simply check if checkResult == null.
Because of some problems with opening / closing the connection I decided to check if the connection is opened or not.
Now if the bad method is called the connection is closed.
Then after calling OpenConnection() the connection is opened again with the same settings as before.
As soon as the application executes checkResult = checkQuery.ExecuteScalar(); the exception is thrown.
I really don't know what actually is the problem.
To ensure that the connection is valid from my point of view I put connection into the watchlist and tracked every change made to it by the application.
Nothing was different than in any other method that successfully used the database.
A friend of mine said that there might be a kind of optimization error while building the application.
He himself doesn't work with C# but sometime with C so it was just a vague guess.
Is there maybe any error in the code that I missed or any guess why this happens?
Thanks in advance!
Greetz
Edit: I use the latest version of MySQL's C# connector

Problem passing ELMAH log id to Custom Error page in ASP.NET

I am using ELMAH to log unhandled exceptions in an ASP.NET Webforms application. Logging is working fine.
I want to pass the ELMAH error log id to a custom error page that will give the user the ability to email an administrator about the error. I have followed the advice from this answer. Here is my global.asax code:
void ErrorLog_Logged(object sender, ErrorLoggedEventArgs args)
{
Session[StateKeys.ElmahLogId] = args.Entry.Id;
// this doesn't work either:
// HttpContext.Current.Items[StateKeys.ElmahLogId] = args.Entry.Id;
}
But, on the Custom error page, the session variable reference and HttpContext.Current.Items are giving me a NullReference exception. How can I pass the ID to my custom error page?
This works for me:
void ErrorLog_Logged(object sender, ErrorLoggedEventArgs args)
{
if (args.Entry.Error.Exception is HandledElmahException)
return;
var config = WebConfigurationManager.OpenWebConfiguration("~");
var customErrorsSection = (CustomErrorsSection)config.GetSection("system.web/customErrors");
if (customErrorsSection != null)
{
switch (customErrorsSection.Mode)
{
case CustomErrorsMode.Off:
break;
case CustomErrorsMode.On:
FriendlyErrorTransfer(args.Entry.Id, customErrorsSection.DefaultRedirect);
break;
case CustomErrorsMode.RemoteOnly:
if (!HttpContext.Current.Request.IsLocal)
FriendlyErrorTransfer(args.Entry.Id, customErrorsSection.DefaultRedirect);
break;
default:
break;
}
}
}
void FriendlyErrorTransfer(string emlahId, string url)
{
Server.Transfer(String.Format("{0}?id={1}", url, Server.UrlEncode(emlahId)));
}
Unable to comment on Ronnie's solution. I had that in place for a while but it breaks the standard error flow process and causes ErrorLog_Logged to always transfer, even when calling
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
This is a problem if you still want to log an error from within a catch statement, for instance you have a workaround for an error but want to log the error to perform a proper fix, which can be pretty helpful on difficult to replicate issues.
I was able to correct this by using the following change:
//if (customErrorsSection != null)
if (customErrorsSection != null && this.Context.Error != null)
This respects the typical error handling properly, as the context.Error will be null in cases where you explicitely raise the exception in Elmah, but is not null when falling through default error handling (not via a catch or if caught and re-thrown). This causes Ronnie's solution to respond similar to the .Net error handling logic.

Categories