Using FindPrivateKey in WebApi - asp.net-web-api

I downloaded the source code for FindPrivateKey.exe.
I use this exe to find the filename and folder for a private key. I have to run this locally on the machine. I am looking for a way to get this information remotely using web api.
FindPrivateKey.exe works by itself as a console app.
But in my webapi code, it does not work (CryptAcquireCertificatePrivateKey returns false)
Is there an obvious reason for this? The web api site has AllowAnonymousAccess enabled, is that why?
I'm having trouble including the code snippet. Summarizing:
StoreName is "My"
StoreLocation is "Local Machine"
//the call below returns false and this is where I am stuck
if (CryptAcquireCertificatePrivateKey(cert.Handle,
acquireFlags, IntPtr.Zero, ref hProvider, ref _keyNumber, ref freeProvider))
{
...
}

I was able to get this to work by first impersonating a user with rights to the private key information. For anyone interested, google the DllImport code below for how to do this.
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int LogonUser(
string lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
public extern static int DuplicateToken(
IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);

Related

How do I open the "Open with" GUI from console command on Windows?

On Windows, if you right click a file in explorer, you get a context menu. One of the entries is Open With > Choose another program. Clicking this opens a GUI to choose a program to open the file. Is it possible to open this GUI from the command line?
There is a shell API for this purpose that can be used from PowerShell using P/Invoke. This is more reliable than the often suggested but undocumented "RunDll32.exe OpenAs_RunDLL" method (see this answer for details why it is bad).
Save this code as "openas.ps1":
param (
[Parameter(Mandatory)]
[String] $Path
)
$ErrorActionPreference = 'Stop'
Add-Type -TypeDefinition #'
using System;
using System.Runtime.InteropServices;
public class ShellOpenWith {
[DllImport("shell32.dll", EntryPoint = "SHOpenWithDialog", CharSet = CharSet.Unicode)]
private static extern int SHOpenWithDialog(IntPtr hWndParent, ref tagOPENASINFO oOAI);
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb773363(v=vs.85).aspx
private struct tagOPENASINFO
{
[MarshalAs(UnmanagedType.LPWStr)]
public string cszFile;
[MarshalAs(UnmanagedType.LPWStr)]
public string cszClass;
[MarshalAs(UnmanagedType.I4)]
public tagOPEN_AS_INFO_FLAGS oaifInFlags;
}
[Flags]
private enum tagOPEN_AS_INFO_FLAGS
{
OAIF_ALLOW_REGISTRATION = 0x00000001, // Show "Always" checkbox
OAIF_REGISTER_EXT = 0x00000002, // Perform registration when user hits OK
OAIF_EXEC = 0x00000004, // Exec file after registering
OAIF_FORCE_REGISTRATION = 0x00000008, // Force the checkbox to be registration
OAIF_HIDE_REGISTRATION = 0x00000020, // Vista+: Hide the "always use this file" checkbox
OAIF_URL_PROTOCOL = 0x00000040, // Vista+: cszFile is actually a URI scheme; show handlers for that scheme
OAIF_FILE_IS_URI = 0x00000080 // Win8+: The location pointed to by the pcszFile parameter is given as a URI
}
public static void DoOpenFileWith(string sFilename, IntPtr hwndParent = new IntPtr())
{
tagOPENASINFO oOAI = new tagOPENASINFO();
oOAI.cszFile = sFilename;
oOAI.cszClass = String.Empty;
oOAI.oaifInFlags = tagOPEN_AS_INFO_FLAGS.OAIF_ALLOW_REGISTRATION | tagOPEN_AS_INFO_FLAGS.OAIF_EXEC;
SHOpenWithDialog(hwndParent, ref oOAI);
}
}
'#
[ShellOpenWith]::DoOpenFileWith( $path )
Run this script from the commandline like this:
powershell.exe c:\openas.ps1 c:\file.txt

Unity Oracle connection DllNotFoundException: oci

So basically I was trying to access an Oracle database within unity and mono-develop. I copied the needed DLLs System.Data and System.Data.OracleClient
from under: C:\Program Files (x86)\Unity\Editor\Data\Mono\lib\mono\2.0
to the Project's Assets folder,
Here's my C# code:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.OracleClient;
public class OracleConn : MonoBehaviour
{
public string connectStr = "SomeConnectionString";
string TBName = "CZRK";
List<string> listOfID = new List<string>(); //ID
List<string> listOfName = new List<string>(); //NAME
private string content;
void Start()
{
OracleConnection conn = new OracleConnection(connectStr);
conn.Open(); //the line that causes error
}
}
then the error DllNotFoundException: oci pops out when executing conn.Open()
the full error log:
DllNotFoundException: oci
System.Data.OracleClient.Oci.OciCalls.OCIEnvCreate (System.IntPtr& envhpp, OciEnvironmentMode mode, IntPtr ctxp, IntPtr malocfp, IntPtr ralocfp, IntPtr mfreep, Int32 xtramem_sz, IntPtr usrmempp)
System.Data.OracleClient.Oci.OciEnvironmentHandle..ctor (OciEnvironmentMode mode)
System.Data.OracleClient.Oci.OciGlue.CreateConnection (OracleConnectionInfo conInfo)
System.Data.OracleClient.OracleConnectionPoolManager.CreateConnection (OracleConnectionInfo info)
System.Data.OracleClient.OracleConnectionPool.CreateConnection ()
System.Data.OracleClient.OracleConnectionPool.GetConnection ()
System.Data.OracleClient.OracleConnection.Open ()
(wrapper remoting-invoke-with-check) System.Data.OracleClient.OracleConnection:Open ()
OracleConn.Start () (at Assets/OracleConn.cs:25)
Besides, I also tried copy the DLL file oci.dll from oracleDB_11g into the assets folder, but problem remains, any ideas??
Got the same error on 5.5.0f3 also trying to hit 11g. My suspicion is the current set of drivers go up to 10g. Therefore I went 3rd party. I got https://www.devart.com/dotconnect/ working quickly. Note, I DO NOT work for them.

An exception of type 'System.IO.FileNotFoundException' occurred in PhoneApp2.DLL but was not handled in user code

When using SQLite for windows phone app, I am getting error in sqlite.cs:
path not for found
Here is the path, but when checked path could be found, I hardcoded the path and tried but it didn't work out.
string dbPath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "db.sqlite");
Here is the error
public static Result Open(string filename, out Sqlite3DatabaseHandle db, int flags, IntPtr zVfs)
{
return (Result)Sqlite3.sqlite3_open_v2(filename, out db, flags, "");
#else
return (Result)Sqlite3.sqlite3_open_v2(filename, out db, flags, null);
}
Here path db is coming null.

CryptUIWizDigitalSign failing when pwszTimestampURL specified

I am having issues when calling CryptUIWizDigitalSign to programatically sign an executable with our public code signing certificate, without showing any UI. The certificate is a Comodo code signing certificate.
It works fine when the timestamp URL parameter is set to null, but whenever I pass anything other than null in, the call fails (returns zero).
The problem is that without a timestamp, there is no countersignature, and so there are signature validity problems further down the line.
Environment is Windows 7 x64. There is a working standard internet connection. It appears from sniffing the network traffic that no attempt is made by CryptUIWizDigitalSign to contact the timestamp server.
I am calling this from .NET via a PInvoke, but I doubt that would make any difference.
Not a lot on the net about this function...
Dim cert As X509Certificate2 = New X509Certificate2("mycert.pfx", "password")
Dim pSigningCertContext As IntPtr = cert.Handle
Dim digitalSignInfo As CRYPTUI_WIZ_DIGITAL_SIGN_INFO
= New CRYPTUI_WIZ_DIGITAL_SIGN_INFO
digitalSignInfo.dwSize = Marshal.SizeOf(digitalSignInfo)
digitalSignInfo.dwSubjectChoice = CRYPTUI_WIZ_DIGITAL_SIGN_SUBJECT_FILE
digitalSignInfo.pwszFileName = "C:\temp\installer.exe"
digitalSignInfo.dwSigningCertChoice = CRYPTUI_WIZ_DIGITAL_SIGN_CERT
digitalSignInfo.pSigningCertContext = pSigningCertContext
digitalSignInfo.pwszTimestampURL = "http://timestamp.comodoca.com/authenticode"
digitalSignInfo.dwAdditionalCertChoice = 0
digitalSignInfo.pSignExtInfo = IntPtr.Zero
If (Not CryptUIWizDigitalSign(CRYPTUI_WIZ_NO_UI, IntPtr.Zero, vbNullString,
digitalSignInfo, pSignContext)) Then
Throw New Win32Exception(Marshal.GetLastWin32Error(),
"CryptUIWizDigitalSign")
End If
The CRYPTUI_WIZ_DIGITAL_SIGN_INFO type is defined as:
<StructLayout(LayoutKind.Sequential)> _
Public Structure CRYPTUI_WIZ_DIGITAL_SIGN_INFO
Public dwSize As Int32
Public dwSubjectChoice As Int32
<MarshalAs(UnmanagedType.LPWStr)> Public pwszFileName As String
Public dwSigningCertChoice As Int32
Public pSigningCertContext As IntPtr
Public pwszTimestampURL As String
Public dwAdditionalCertChoice As Int32
Public pSignExtInfo As IntPtr
End Structure
Public Const CRYPTUI_WIZ_DIGITAL_SIGN_SUBJECT_FILE As Int32 = 1
Public Const CRYPTUI_WIZ_DIGITAL_SIGN_CERT As Int32 = 1
Public Const CRYPTUI_WIZ_NO_UI As Int32 = 1
You've applied the MarshalAs attribute on pwszFileName but not pwszTimestampURL, is there any reason for this? They're described identically in the documentation for CRYPTUI_WIZ_DIGITAL_SIGN_INFO :
pwszFileName:
A pointer to a null-terminated Unicode string that contains the path and file name of the file to sign. This member is used if CRYPTUI_WIZ_DIGITAL_SIGN_SUBJECT_FILE is specified for the dwSubjectChoice member.
pwszTimestampURL:
A pointer to a null-terminated Unicode string that contains the URL for the time stamp.
Fixed - works only within a 32 bit process.

Windows GUID or Application List

I was wondering if it is possible to retreive from Windows a list of the applications installed INCLUDING their GUID and Upgrade GUID. I am having problems getting my upgrade to work for one of my programs, and need to check these values for the old version of the program. Thanks for the help!
You can use MSI api functions to enumerate all installed products and to query their properties. If you replace MsiGetProductInfo with MsiGetProductInfoEx you will be able to query additional information such as the installation context or user SID associated for an installation.
However, this does not allow you to enumerate the UpgradeCode. As far as I know MSI doesn't keep a record associating a ProductCode with an UpgradeCode; only the reverse mapping is available and you can enumerate the products related to an UpgradeCode using the MsiEnumRelatedProducts function.
Below you will find sample code which enumerates the installed or advertised products and their ProductCode using C#:
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
class Program
{
[DllImport("msi.dll", CharSet = CharSet.Unicode)]
static extern Int32 MsiGetProductInfo(string product, string property,
[Out] StringBuilder valueBuf, ref Int32 len);
[DllImport("msi.dll", SetLastError = true)]
static extern int MsiEnumProducts(int iProductIndex,
StringBuilder lpProductBuf);
static void Main(string[] args)
{
StringBuilder sbProductCode = new StringBuilder(39);
int iIdx = 0;
while (MsiEnumProducts(iIdx++, sbProductCode) == 0)
{
Int32 productNameLen = 512;
StringBuilder sbProductName = new StringBuilder(productNameLen);
MsiGetProductInfo(sbProductCode.ToString(),
"ProductName", sbProductName, ref productNameLen);
Console.WriteLine("Product: {0}\t{1}", sbProductName, sbProductCode);
}
}
}
Update
If you still have the MSI installer of the previous version you can simply open the file using Orca and search for the UpgradeCode.

Resources