[rst-commit] r185 - in /redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC): Redwax SignText (MFC)Dlg.cpp Redwax SignText (MFC)Dlg.h crypto.c crypto.h signtext.c signtext.h

rst-commit at redwax.eu rst-commit at redwax.eu
Tue Jul 9 23:36:05 CEST 2024


Author: minfrin at redwax.eu
Date: Tue Jul  9 23:36:04 2024
New Revision: 185

Log:
Add support for devices that capture the PIN externally.

Modified:
    redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/Redwax SignText (MFC)Dlg.cpp
    redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/Redwax SignText (MFC)Dlg.h
    redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/crypto.c
    redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/crypto.h
    redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/signtext.c
    redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/signtext.h

Modified: redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/Redwax SignText (MFC)Dlg.cpp
==============================================================================
--- redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/Redwax SignText (MFC)Dlg.cpp	(original)
+++ redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/Redwax SignText (MFC)Dlg.cpp	Tue Jul  9 23:36:04 2024
@@ -118,6 +118,7 @@
 
 BEGIN_MESSAGE_MAP(CRedwaxSignTextMFCDlg, CDialogEx)
 	ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, OnSelchangeTab1)
+	ON_NOTIFY(CBN_SELCHANGE, IDC_CERTIFICATEBOX, OnSelchangeCertBox)
 	ON_WM_SYSCOMMAND()
 	ON_WM_PAINT()
 	ON_WM_QUERYDRAGICON()
@@ -173,26 +174,6 @@
 	SetIcon(m_hIcon, TRUE);			// Set big icon
 	SetIcon(m_hIcon, FALSE);		// Set small icon
 
-	// TODO: Add extra initialization here
-
-//    std::shared_ptr<SignPage> upm_dlg1 = std::make_shared<SignPage>();
-//	std::shared_ptr<SignPage> upm_dlg2 = std::make_shared<SignPage>();
-
-//	VERIFY(upm_dlg1->Create(IDD_SIGN_PAGE, this));
-//	VERIFY(upm_dlg2->Create(IDD_SIGN_PAGE, this));
-
-//	m_dlg1.EnableDynamicLayout(TRUE);
-//	m_dlg2.EnableDynamicLayout(TRUE);
-
-//	CString text;
-//	upm_dlg1->GetWindowText(text);
-//	VERIFY(m_ctlTab.InsertItem(TCIF_TEXT, 0, text, 0, 0, 0, 0) == 0);
-//	std::vector<std::shared_ptr<SignPage>>::iterator it;//	it = m_dlgs.begin();
-//	m_dlgs.insert(m_dlgs.begin(), upm_dlg1);
-
-//	upm_dlg2->GetWindowText(text);
-//	VERIFY(m_ctlTab.InsertItem(TCIF_TEXT, 0, text, 0, 0, 0, 0) == 0);
-//	m_dlgs.insert(m_dlgs.begin(), upm_dlg2);
 
 	ResizeTab();
 	UpdateVisibleTab();
@@ -206,15 +187,17 @@
 
 	AfxBeginThread(HandleCryptoFunction, signtext);
 
-	/* store this dialog away so the timer can find it */
-//	SetProp(signtext->hwnd, L"signtext", signtext);
-
-//	SetTimer((UINT_PTR)signtext, 2000, CryptoTimer);
-
 	return TRUE;  // return TRUE  unless you set the focus to a control
 }
 
 void CRedwaxSignTextMFCDlg::OnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult)
+{
+	UpdateVisibleTab();
+
+	*pResult = 0;
+}
+
+void CRedwaxSignTextMFCDlg::OnSelchangeCertBox(NMHDR* pNMHDR, LRESULT* pResult)
 {
 	UpdateVisibleTab();
 
@@ -255,7 +238,45 @@
 				m_dlg->m_pinText.EnableWindow(FALSE);
 			}
 
-			m_dlg->m_pinText.SetCueBanner(L"Enter PIN", TRUE);
+			int currentCert = m_dlg->m_certificateBox.GetCurSel();
+
+			if (currentCert >= 0) {
+
+				SignTextCertificate* cert = (SignTextCertificate*)m_dlg->m_certificateBox.GetItemDataPtr(currentCert);
+
+				assert(cert);
+
+				switch (cert->secretType) {
+				case AlphaNumericPinType:
+					m_dlg->m_pinText.SetCueBanner(L"Enter PIN", TRUE);
+					m_dlg->m_pinText.SetReadOnly(FALSE);
+					break;
+				case ExternalPinType:
+					m_dlg->m_pinText.SetCueBanner(L"Enter PIN on pinpad", TRUE);
+					m_dlg->m_pinText.SetReadOnly(TRUE);
+					m_dlg->m_pinText.SetWindowText(_T(""));
+					break;
+				case ChallengeResponsePinType:
+					m_dlg->m_pinText.SetCueBanner(L"Challenge response PIN", TRUE);
+					m_dlg->m_pinText.SetReadOnly(FALSE);
+					break;
+				case EmptyPinType:
+					m_dlg->m_pinText.SetCueBanner(L"No PIN required", TRUE);
+					m_dlg->m_pinText.SetReadOnly(TRUE);
+					m_dlg->m_pinText.SetWindowText(_T(""));
+					break;
+				default:
+					m_dlg->m_pinText.SetCueBanner(L"", TRUE);
+					m_dlg->m_pinText.SetReadOnly(TRUE);
+					m_dlg->m_pinText.SetWindowText(_T(""));
+				}
+
+			}
+			else {
+				m_dlg->m_pinText.SetCueBanner(L"", TRUE);
+				m_dlg->m_pinText.SetReadOnly(TRUE);
+				m_dlg->m_pinText.SetWindowText(_T(""));
+			}
 
 			m_dlg->ShowWindow(SW_SHOW);
 		}
@@ -559,13 +580,6 @@
 
 	} while (next);
 
-
-	//	RECT rect;
-//	m_ctlTab.GetClientRect(&rect);
-//	m_ctlTab.AdjustRect(FALSE, &rect);
-//	dialogItem.dialog.SetWindowPos(&CWnd::wndBottom, 0, 0, rect.right, rect.bottom,
-//		SWP_NOMOVE);
-
 	m_ctlTab.SetCurSel(0);
 
 	ResizeTab();
@@ -777,6 +791,11 @@
 
 }
 
+void CRedwaxSignTextMFCDlg::OnIdok()
+{
+	/* ignore the ok button */
+}
+
 CRedwaxSignTextMFCDlg::~CRedwaxSignTextMFCDlg()
 {
 	WaitForSingleObject(hThread, INFINITE);
@@ -785,10 +804,3 @@
 	signtext_data_free(signtext);
 
 }
-
-
-
-void CRedwaxSignTextMFCDlg::OnIdok()
-{
-	/* ignore the ok button */
-}

Modified: redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/Redwax SignText (MFC)Dlg.h
==============================================================================
--- redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/Redwax SignText (MFC)Dlg.h	(original)
+++ redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/Redwax SignText (MFC)Dlg.h	Tue Jul  9 23:36:04 2024
@@ -70,6 +70,7 @@
 	// Generated message map functions
 	virtual BOOL OnInitDialog();
 	afx_msg void OnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult);
+	afx_msg void OnSelchangeCertBox(NMHDR* pNMHDR, LRESULT* pResult);
 	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
 	afx_msg void OnPaint();
 	afx_msg HCURSOR OnQueryDragIcon();

Modified: redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/crypto.c
==============================================================================
--- redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/crypto.c	(original)
+++ redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/crypto.c	Tue Jul  9 23:36:04 2024
@@ -118,24 +118,32 @@
 			case CERT_NCRYPT_KEY_SPEC:
 			{
 				NCRYPT_PROV_HANDLE prov = 0;
-				DWORD type = 0, size = sizeof(prov);
-				NCryptGetProperty(key, NCRYPT_PROVIDER_HANDLE_PROPERTY, (PBYTE) & prov, size, &size, 0);
+				DWORD type = 0, prov_size = sizeof(prov);
+				NCryptGetProperty(key, NCRYPT_PROVIDER_HANDLE_PROPERTY, (PBYTE) & prov, prov_size, &prov_size, 0);
 				if (prov)
 				{
-					size = sizeof(type);
-					NCryptGetProperty(prov, NCRYPT_IMPL_TYPE_PROPERTY, (PBYTE) & type, size, &size, 0);
+					prov_size = sizeof(type);
+					NCryptGetProperty(prov, NCRYPT_IMPL_TYPE_PROPERTY, (PBYTE) & type, prov_size, &prov_size, 0);
 					NCryptFreeObject(prov);
 				}
 
 				// NCRYPT_EXPORT_POLICY_PROPERTY
 				// NCRYPT_KEY_USAGE_PROPERTY
-				// NCRYPT_SCARD_PIN_INFO
+
+				SECRET_TYPE secretType = -1;
+				PIN_INFO pin_info;
+				DWORD pin_info_size = sizeof(PIN_INFO);
+				NCryptGetProperty(key, NCRYPT_SCARD_PIN_INFO, (PBYTE)&pin_info, pin_info_size, &pin_info_size, 0);
+				if (pin_info_size)
+				{
+					secretType = pin_info.PinType;
+				}
 
 				if (freeKey) {
 					NCryptFreeObject(key);
 				}
 
-				certificate = signtext_certificate_new(signtext, name, cert, spec, type, certificate);
+				certificate = signtext_certificate_new(signtext, name, cert, spec, type, secretType, certificate);
 
 				if (!certificates) {
 					certificates = certificate;
@@ -288,11 +296,6 @@
 
 	CertFreeCertificateContext(search);
 
-	/* no need for the cert any more, forget it */
-	signtext_certificate_unref(instance->certificate);
-
-	instance->certificate = NULL;
-
 	NCRYPT_HANDLE key;
 	DWORD dwKeySpec = 0;
 	if (!CryptAcquireCertificatePrivateKey(cert, CRYPT_ACQUIRE_CACHE_FLAG | CRYPT_ACQUIRE_COMPARE_KEY_FLAG | CRYPT_ACQUIRE_SILENT_FLAG | CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG, NULL, &key, &dwKeySpec, NULL))
@@ -303,27 +306,60 @@
 
 		PostMessage(instance->signtext->hwnd, WM_CRYPTO_NOTSIGNED, 0, 0);
 
+		/* no need for the cert any more, forget it */
+		signtext_certificate_unref(instance->certificate);
+
+		instance->certificate = NULL;
+
 		return;
 	}
 
-	if (NCryptSetProperty(key, NCRYPT_PIN_PROPERTY, (BYTE*)instance->pinBuffer, instance->pinLen, 0) != ERROR_SUCCESS)
-	{
-		instance->is_signing = FALSE;
-
-		CertCloseStore(sys, 0);
-
-		/* wrong pin fails here */
-		MessageBox(instance->signtext->hwnd, TEXT("The PIN was not accepted. Please enter it again carefully.\r\nEntering the PIN incorrectly multiple times will lock you out."), TEXT("Signing Error"), MB_OK);
-
-		PostMessage(instance->signtext->hwnd, WM_CRYPTO_NOTSIGNED, 0, 0);
-
-		return;
-	}
+	switch (instance->certificate->secretType) {
+	case AlphaNumericPinType:
+
+		if (NCryptSetProperty(key, NCRYPT_PIN_PROPERTY, (BYTE*)instance->pinBuffer, instance->pinLen, 0) != ERROR_SUCCESS)
+		{
+			instance->is_signing = FALSE;
+
+			CertCloseStore(sys, 0);
+
+			/* wrong pin fails here */
+			MessageBox(instance->signtext->hwnd, TEXT("The PIN was not accepted. Please enter it again carefully.\r\nEntering the PIN incorrectly multiple times will lock you out."), TEXT("Signing Error"), MB_OK);
+
+			PostMessage(instance->signtext->hwnd, WM_CRYPTO_NOTSIGNED, 0, 0);
+
+			/* no need for the cert any more, forget it */
+			signtext_certificate_unref(instance->certificate);
+
+			instance->certificate = NULL;
+
+			return;
+		}
+
+		break;
+	case ExternalPinType:
+		break;
+	case ChallengeResponsePinType:
+		break;
+	case EmptyPinType:
+		break;
+	default:
+		break;
+	}
+
+	/* no need for the cert any more, forget it */
+	signtext_certificate_unref(instance->certificate);
+
+	instance->certificate = NULL;
+
+	CCRYPT_OID_INFO* info;
+	info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, cert->pCertInfo->SignatureAlgorithm.pszObjId, 0);
 
 	CRYPT_ALGORITHM_IDENTIFIER hashAlgorithm;
 	memset(&hashAlgorithm, 0, sizeof(hashAlgorithm));
 #if 0
-	hashAlgorithm.pszObjId = szOID_RSA_SHA256RSA;
+//	hashAlgorithm.pszObjId = szOID_RSA_SHA256RSA;
+	hashAlgorithm.pszObjId = szOID_NIST_sha256;
 #else
 	hashAlgorithm.pszObjId = cert->pCertInfo->SignatureAlgorithm.pszObjId;
 #endif

Modified: redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/crypto.h
==============================================================================
--- redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/crypto.h	(original)
+++ redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/crypto.h	Tue Jul  9 23:36:04 2024
@@ -15,10 +15,10 @@
  */
 
 
-#include "signtext.h"
-
 #ifndef CRYPTO_H
 #define CRYPTO_H
+
+#include "signtext.h"
 
 #pragma comment(lib, "crypt32.lib")
 #pragma comment(lib, "ncrypt.lib")
@@ -45,6 +45,50 @@
 void
 crypto_sign(SignTextInstance* instance);
 
+/* From cardmod.h */
+
+typedef     DWORD                       PIN_SET, * PPIN_SET;
+
+typedef enum
+{
+    AuthenticationPin,                  // Authentication PIN
+    DigitalSignaturePin,                // Digital Signature PIN
+    EncryptionPin,                      // Encryption PIN
+    NonRepudiationPin,                  // Non Repudiation PIN
+    AdministratorPin,                   // Administrator PIN
+    PrimaryCardPin,                     // Primary Card PIN
+    UnblockOnlyPin,                     // Unblock only PIN (PUK)
+} SECRET_PURPOSE;
+
+typedef enum
+{
+    PinCacheNormal = 0,
+    PinCacheTimed,
+    PinCacheNone,
+    PinCacheAlwaysPrompt
+} PIN_CACHE_POLICY_TYPE;
+
+typedef struct _PIN_CACHE_POLICY
+{
+    DWORD                                 dwVersion;
+    PIN_CACHE_POLICY_TYPE                 PinCachePolicyType;
+    DWORD                                 dwPinCachePolicyInfo;
+} PIN_CACHE_POLICY, * PPIN_CACHE_POLICY;
+
+typedef struct _PIN_INFO
+{
+    DWORD                                 dwVersion;
+    SECRET_TYPE                           PinType;
+    SECRET_PURPOSE                        PinPurpose;
+    PIN_SET                               dwChangePermission;
+    PIN_SET                               dwUnblockPermission;
+    PIN_CACHE_POLICY                      PinCachePolicy;
+    DWORD                                 dwFlags;
+} PIN_INFO, * PPIN_INFO;
+
+#if 0
+#endif
+
 #ifdef __cplusplus
 }
 #endif

Modified: redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/signtext.c
==============================================================================
--- redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/signtext.c	(original)
+++ redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/signtext.c	Tue Jul  9 23:36:04 2024
@@ -72,7 +72,7 @@
     free(data);
 }
 
-SignTextCertificate* signtext_certificate_new(SignTextData* signtext, LPWSTR name, PCCERT_CONTEXT cert, DWORD spec, DWORD type, SignTextCertificate *prev)
+SignTextCertificate* signtext_certificate_new(SignTextData* signtext, LPWSTR name, PCCERT_CONTEXT cert, DWORD spec, DWORD type, SECRET_TYPE secretType, SignTextCertificate *prev)
 {
     SignTextCertificate* certificate = calloc(sizeof(SignTextCertificate), 1);
 
@@ -83,6 +83,7 @@
     certificate->cbCertEncoded = cert->cbCertEncoded;
     certificate->spec = spec;
     certificate->type = type;
+    certificate->secretType = secretType;
 
     certificate->ref = 1;
 

Modified: redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/signtext.h
==============================================================================
--- redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/signtext.h	(original)
+++ redwax-signtext-windows/trunk/Redwax SignText/Redwax SignText (MFC)/signtext.h	Tue Jul  9 23:36:04 2024
@@ -44,6 +44,15 @@
 #define WM_CRYPTO_SIGNED WM_APP+103
 #define WM_CRYPTO_NOTSIGNED WM_APP+104
 
+/* From cardmod.h */
+
+typedef enum
+{
+    AlphaNumericPinType = 0,            // Regular PIN
+    ExternalPinType,                    // Biometric PIN
+    ChallengeResponsePinType,           // Challenge/Response PIN
+    EmptyPinType                        // No PIN
+} SECRET_TYPE;
 
 typedef struct SignTextData {
 	HWND hwnd;
@@ -65,6 +74,7 @@
 	DWORD cbCertEncoded;
 	DWORD spec;
 	DWORD type;
+	SECRET_TYPE secretType;
 	SignTextCertificate* next;
 	int ref;
 };
@@ -109,7 +119,7 @@
 SignTextInstance* signtext_instance_new(SignTextData* signtext, int id, const char* uuid, const char* uri);
 void signtext_instance_free(SignTextInstance* instance);
 
-SignTextCertificate* signtext_certificate_new(SignTextData* signtext, LPWSTR name, PCCERT_CONTEXT cert, DWORD spec, DWORD type, SignTextCertificate* prev);
+SignTextCertificate* signtext_certificate_new(SignTextData* signtext, LPWSTR name, PCCERT_CONTEXT cert, DWORD spec, DWORD type, SECRET_TYPE secretType, SignTextCertificate* prev);
 SignTextCertificate* signtext_certificate_ref(SignTextCertificate* cert);
 SignTextCertificate* signtext_certificate_unref(SignTextCertificate* cert);
 



More information about the rst-commit mailing list