diff --git a/binaries/puttycac-0.77-installer.msi b/binaries/puttycac-0.77-installer.msi deleted file mode 100644 index 7ed45a7c..00000000 Binary files a/binaries/puttycac-0.77-installer.msi and /dev/null differ diff --git a/binaries/puttycac-0.77.zip b/binaries/puttycac-0.77.zip deleted file mode 100644 index 6617e4dc..00000000 Binary files a/binaries/puttycac-0.77.zip and /dev/null differ diff --git a/binaries/puttycac-0.77u1-installer.msi b/binaries/puttycac-0.77u1-installer.msi new file mode 100644 index 00000000..3d8e4203 Binary files /dev/null and b/binaries/puttycac-0.77u1-installer.msi differ diff --git a/binaries/puttycac-0.77u1.zip b/binaries/puttycac-0.77u1.zip new file mode 100644 index 00000000..23acdd5a Binary files /dev/null and b/binaries/puttycac-0.77u1.zip differ diff --git a/binaries/puttycac-64bit-0.77-installer.msi b/binaries/puttycac-64bit-0.77-installer.msi deleted file mode 100644 index 0c33ecb9..00000000 Binary files a/binaries/puttycac-64bit-0.77-installer.msi and /dev/null differ diff --git a/binaries/puttycac-64bit-0.77.zip b/binaries/puttycac-64bit-0.77.zip deleted file mode 100644 index c6ecc35e..00000000 Binary files a/binaries/puttycac-64bit-0.77.zip and /dev/null differ diff --git a/binaries/puttycac-64bit-0.77u1-installer.msi b/binaries/puttycac-64bit-0.77u1-installer.msi new file mode 100644 index 00000000..17bee8de Binary files /dev/null and b/binaries/puttycac-64bit-0.77u1-installer.msi differ diff --git a/binaries/puttycac-64bit-0.77u1.zip b/binaries/puttycac-64bit-0.77u1.zip new file mode 100644 index 00000000..44963643 Binary files /dev/null and b/binaries/puttycac-64bit-0.77u1.zip differ diff --git a/binaries/puttycac-hash.txt b/binaries/puttycac-hash.txt index 2da60114..3cca3853 100644 --- a/binaries/puttycac-hash.txt +++ b/binaries/puttycac-hash.txt @@ -1,81 +1,81 @@ Algorithm Hash Path --------- ---- ---- -SHA256 5ED68A803D4F920434CA94875452BDBDCFCBB19139A10C5FDA934F603FC01DC9 x64\pageant.exe -SHA256 0E33651140E5D0474BBD230669E7BD1B87D25769585C66D4D452F6DD9D0DA58E x64\plink.exe -SHA256 3E9402C059D43245942A316850954C512CE31BAB65309DEF6B9EDDE63F59D2E9 x64\pscp.exe -SHA256 16F704A938046058A10EA1A66926895FC8E60A154AD847D854B26AE3F8451D44 x64\psftp.exe -SHA256 9FC2CAF775374DA67A465C90816E4AD5563DF5BFCE62F4DD941D518425B9745C x64\pterm.exe -SHA256 511C56F314B21A6B1C4AF6E4FA6BAAD7B12737F65CA52C533C32E78EAA70B975 x64\putty.exe -SHA256 911C4ADD4E825CBB20FF4E5CFECE0E1D2FA506D1684D6E15455AB4835E5E92D8 x64\puttygen.exe -SHA256 79F71A0B0DC29ACBF7F05EFFA11D8BBB79EAF3D5A8A602CA56F5732C89C58F79 x64\puttyimp.exe -SHA256 91FBD43B6ADE371D47EB1927400DA533A1DCF79FD8C26FA0D052740DD443CE8D x64\puttytel.exe -SHA256 EF253D9AE5CE86BC52598E19B5807EFF356F0A3979FAD622E62E3406C3A7557A x86\pageant.exe -SHA256 D3CB8B2FC74E3A12CB220777E6DF7EA5766C7587B0FF00B9F16627ADD38C278F x86\plink.exe -SHA256 A1C4A607E3CB350B5C855911365AD7ACA85B2135AACF9FDDB44ADC09213DF204 x86\pscp.exe -SHA256 93947E6CF2E07CF3210ACC495C04F0E8B4B0E38B1B832B8664BC9B4AAE3F1C7D x86\psftp.exe -SHA256 4B346B7B94EB7A261724FF885855F5ED912334C5EF531829FEB32F04075BD942 x86\pterm.exe -SHA256 CA3CF7652E31A2BCF8D3858814740A8688D8FF49A426CF5AD95DDE316D8B1223 x86\putty.exe -SHA256 39451F7DD2DC7C8BAD5D6597CF251D3FBE8037E7B535B0A8BE4ADD9526145585 x86\puttygen.exe -SHA256 43D4E1AA70885EBA303ACF321005A62017A4DEBB01A3E5110CDA40A4866EBFFF x86\puttyimp.exe -SHA256 C2A6E5685787B979D23DD414E9D1B5480793988072E1EDB793EC81B26060D25D x86\puttytel.exe -SHA256 E334061768E4D6C425AB9E25EF0862B317E4B88E5C3936AA627C810C83BE17C1 puttycac-0.77-installer.msi -SHA256 5C4D7EA2E1081BE0CCC3A97EA6E6D3E450D1A206FE26A7C48524DA06B097552F puttycac-0.77.zip -SHA256 0F19075A9B2F2021921D339C6EF864AA2AF51AF4378D23307E280DEB8B89135D puttycac-64bit-0.77-installer.msi -SHA256 314C3EEBF6EAB6104DA5C182D62A2D7C9ABF915140CE7610B2D40D245E2CD6A4 puttycac-64bit-0.77.zip +SHA256 AF72C746573E7B9A578CA67752B9DB64B134975E6518E1B418FD29FDE7E821A6 x64\pageant.exe +SHA256 D26F6CC9A011C105A2AD211076B08E4D328DFFBEA7AD6348F27D31BFCC689CBC x64\plink.exe +SHA256 47F47D11B758724E4F7DB8DDEED124ED0A84A6B28EAE5B14F16BB37DF55C93C5 x64\pscp.exe +SHA256 87A0D312C78185FF9C16810AD2BB5C977D48161DF6964D422B691D27728EC2CA x64\psftp.exe +SHA256 672195E7C2BC27D77738315A77400835EEA16D881F3313583528B2FC4286C93F x64\pterm.exe +SHA256 0692203E48BA13691E1B82676C2D3A88999F3CD361651028962E1BAD1D91AC62 x64\putty.exe +SHA256 E74CA5BA12E3BF67291E55688482CDCF0010705B983F00B20EC7B4936CFD34EA x64\puttygen.exe +SHA256 832EF421CCAE9FB87EC625FD8C0D741E5C0C6361F8B1288F4E14C605C7E20E93 x64\puttyimp.exe +SHA256 0AF07B5F7308E3274B819BCDB5000E97BBCBB4080D6BB2AA59B5AF792D4366D5 x64\puttytel.exe +SHA256 B682547775310C0F2B7822B002AA188A4A9832529829FBC73556545A4268D12D x86\pageant.exe +SHA256 95C8ED20D0716C3F9D86EDA39285DD80C0D02BCCD35BCFE960F005E190B781B8 x86\plink.exe +SHA256 111A083425842D4382137C171BE8F467016E1474F02F08AF82BE962F379FBB19 x86\pscp.exe +SHA256 0E46485D36979E53FF3CE68BF4198F79136ED06FFEC835CFEEC9B1516183CAB2 x86\psftp.exe +SHA256 7CB543685D77CB71083951F7914CE01A1C38E89BE61DD3B482962B9D9D3D639E x86\pterm.exe +SHA256 0C600AD90109AB6CDA02E23B79183991C5AC4F36D53CE1447A66C3BAB45B6FC4 x86\putty.exe +SHA256 1662EDDCAA0B632DEEE57AC6AFB32021E894A82C907BDB0562053E4422AC479A x86\puttygen.exe +SHA256 6CD7A57D20BFC42C7AA8380619B811602E859D7F3532C604EFB3297973961641 x86\puttyimp.exe +SHA256 A0B668E708AAFD3BBD01B6E9CBD67EF14EDD76C094FB86CBCE4D65B623937B72 x86\puttytel.exe +SHA256 907F201234DE8906276B0EEB9A2CD8363FB64047F0607046D6C45EF12AED8F7E puttycac-0.77u1-installer.msi +SHA256 955BAA6141F34DFAAE158733BFC4F8F292D1E4326052F18C0A4B1569C96C12E6 puttycac-0.77u1.zip +SHA256 48076176FA7D09A0A7EB51D541B736A632FFE6A709A7DF388B95398F0D8284ED puttycac-64bit-0.77u1-installer.msi +SHA256 683409B131A5352BD8084A2B44AA180FBF367F35593120DC08CAC723640344D7 puttycac-64bit-0.77u1.zip Algorithm Hash Path --------- ---- ---- -SHA1 ED5232F86DB1F1A27D382034730F0A79A80BA209 x64\pageant.exe -SHA1 E4B517C74A10B8A9BDD990AA7DEF9DB7CBE131F7 x64\plink.exe -SHA1 6962D5EECA8F012C78EBF164A78ADECC71D2750E x64\pscp.exe -SHA1 30E5BA67493E134299B68B669EF0BC2F00B6D7AE x64\psftp.exe -SHA1 5C45D65AFE65AB57D56AFA79C89F57284EE09F2D x64\pterm.exe -SHA1 96DE1E301A8739C1F4009211F0027160BBF288BD x64\putty.exe -SHA1 13DD738E72E463FEBF60684D09D4BF9B5338D484 x64\puttygen.exe -SHA1 55B77A9A04C965AAD460F34AFE46BA231FF7B59D x64\puttyimp.exe -SHA1 5B31E6777F3CEC21130866DEFE35F98B095A2A51 x64\puttytel.exe -SHA1 D61BD4826EC40E4635BD868F5CECC2869CBB9789 x86\pageant.exe -SHA1 93712C208BB7E831C7986561867C9DA47DB00C46 x86\plink.exe -SHA1 054C8F1300D5EBB02406E9687D7D2C4D71E752CB x86\pscp.exe -SHA1 2C02CDF40105810E7349A92B70105327F9EEFDDE x86\psftp.exe -SHA1 66C756BAA3E677BFA5BDB1C5789493E5E3AB2C73 x86\pterm.exe -SHA1 776E356B5DDED8FB11BCCC0F2877B22505145166 x86\putty.exe -SHA1 1B23CBEB90F282048928571063966B3846B61A05 x86\puttygen.exe -SHA1 A54CB6BC7F743A60D511718FE653FE9F282BECC8 x86\puttyimp.exe -SHA1 C851B82956FB122622667B07A59919B4CBF4842B x86\puttytel.exe -SHA1 F9FF4D2AA267A32C67F2C3EB15F49C05DF991A86 puttycac-0.77-installer.msi -SHA1 BB5E6B74D609DD657BAB06186F3ED5810BEE671C puttycac-0.77.zip -SHA1 7A68DDCCDD6A8D30FC2A769EA47F7634D6D3BB40 puttycac-64bit-0.77-installer.msi -SHA1 A5F081F049A7F473D9018790164BBB50231E9872 puttycac-64bit-0.77.zip +SHA1 600E818F1A711670E356997B840821A85E5A2A18 x64\pageant.exe +SHA1 68A0EC3F56B2CDF75AD6A2B96AC9A5D6A2CD9870 x64\plink.exe +SHA1 1FEB739E706F984DB625D665B12D95CDDD97863A x64\pscp.exe +SHA1 B6EFCE85D9DE36C08D2B3D7E77CC06761A391EAB x64\psftp.exe +SHA1 FD4510756D197D18DE64F033DAC0A89A0862F20E x64\pterm.exe +SHA1 1E8D5E8AA06B2B8C8441DC3A89F7F44E467B01B9 x64\putty.exe +SHA1 891DDD65E3DB81502AD1BBA3304CC66551BAE882 x64\puttygen.exe +SHA1 345CD1197C3EFC91BBEBA25F250C2E67E51E1831 x64\puttyimp.exe +SHA1 AB5C73BF0BE37744D17D08FC77B47CB03294A291 x64\puttytel.exe +SHA1 F2541DF2B95C34A09F5D25F20A9DDB9D8CADDB93 x86\pageant.exe +SHA1 95C89D6A11687AEAB1812A01E416FD337491BC97 x86\plink.exe +SHA1 A5BF32C5C65722365EEB2E0BD36272932354C46B x86\pscp.exe +SHA1 6E4D4FD75B10104BDAAF2359DE7AFD2AD4134B77 x86\psftp.exe +SHA1 9D9D7F6F0B6B1290E922B2AC1C37F4A1C9399610 x86\pterm.exe +SHA1 95FC675D06CE39C5F075B74BFE019E37DE73D470 x86\putty.exe +SHA1 EE805873FF4B79E9714AF1CEBB3E01CC6D32980C x86\puttygen.exe +SHA1 411CDC7130EF21B90B9E43B9971FD0828A81D710 x86\puttyimp.exe +SHA1 2DFC68FC077C9CF753ADA785676FE08A853133BC x86\puttytel.exe +SHA1 D68A66646DAE9BBFF4159EAEB61FDF1B80CC6F9D puttycac-0.77u1-installer.msi +SHA1 73EEFADD3BBC7A8E61C941E4C436BD3427366189 puttycac-0.77u1.zip +SHA1 92101D24933BB5AE4AC056CA5AA0608E2D4A378B puttycac-64bit-0.77u1-installer.msi +SHA1 CEC82A50866A37A49C3FDE2E1149F7FA28916EAB puttycac-64bit-0.77u1.zip Algorithm Hash Path --------- ---- ---- -MD5 BD9AA0CEF8538E4660B58A6560BC3B11 x64\pageant.exe -MD5 C58AB3362172B9C9849AB3DD40C07122 x64\plink.exe -MD5 B5ACA78EBC4E708428AE7361BFE48FCF x64\pscp.exe -MD5 CA629AD2D8D0757351CF088FA1D01092 x64\psftp.exe -MD5 961E7E1A672DE4F4C964AA6BAC83C38D x64\pterm.exe -MD5 32ADD98D0E1A951A90A607C819B57D08 x64\putty.exe -MD5 0FCC46A6521DBEDAFC2F9CC4857DE048 x64\puttygen.exe -MD5 176E50EA37EFBB7AF50909CBD32BD5A2 x64\puttyimp.exe -MD5 DD456AEFAC3F115F01564F6EA2250511 x64\puttytel.exe -MD5 419BF7B46A973B94D52AB3FC4776D862 x86\pageant.exe -MD5 473E377FCCF4ABCC2136798B96DCD876 x86\plink.exe -MD5 1B433982928CAEA91C08C4649B462868 x86\pscp.exe -MD5 EAB48AE5743B6E35A936B116230B7A10 x86\psftp.exe -MD5 6B01C6D77F5808ADDACB1EF9EE0F8C84 x86\pterm.exe -MD5 A04DC1C3FF22611B6A3E1A7FB7D97083 x86\putty.exe -MD5 67B90B53FAE2B8E14A227E292066C706 x86\puttygen.exe -MD5 ED630F4D70B6B5A7CD964C28D43B653F x86\puttyimp.exe -MD5 5E246DE08870900A0255BC08A4C88337 x86\puttytel.exe -MD5 53077F59C66578BABBE54FB8054F2774 puttycac-0.77-installer.msi -MD5 EF08704BFC839363675F986AD1B13457 puttycac-0.77.zip -MD5 EB9B777047CB6C0E773EC20EA3A1D4FE puttycac-64bit-0.77-installer.msi -MD5 426432458D136DC182D3029FFEE4C03E puttycac-64bit-0.77.zip +MD5 BABB52BD7D0DB199AEE4306455C7AA5C x64\pageant.exe +MD5 D2CA8238B765CA8F13F728DB3355BC18 x64\plink.exe +MD5 405AB9624E6AF360E0731B0AA4D5FA47 x64\pscp.exe +MD5 A8576FCC8F3143A3676C75666E23DFBD x64\psftp.exe +MD5 F0FB74B35048528B52790FED63B14B17 x64\pterm.exe +MD5 5432125EAD11D3C76028C28E9DD5BB01 x64\putty.exe +MD5 5B1E67DD32EE91CD100E9EBEAC54384D x64\puttygen.exe +MD5 0E9F89F5F01D7DB27800C7D54F6BC7D9 x64\puttyimp.exe +MD5 ABAF6F8D8DBDD49CDC16224DC0EEF800 x64\puttytel.exe +MD5 E4395E95E28BB37E007EFA3BA1C7AA92 x86\pageant.exe +MD5 B509D0C6A2C96BBFBB83761A9D373050 x86\plink.exe +MD5 DF6E9057DC9B4FF7D93BF4BF3B889020 x86\pscp.exe +MD5 5483A44E490FE70AC35748CB47FE0F7D x86\psftp.exe +MD5 57ED820BE1620228666199E75D077768 x86\pterm.exe +MD5 50BC72FEE6052B46E2438FD0A2EF78BB x86\putty.exe +MD5 A12BA2C930789376E9C35704E3BB00C1 x86\puttygen.exe +MD5 E4542291C2744BDEBE144298319CCBF3 x86\puttyimp.exe +MD5 38CB111DD6B159C151C1A7CD10E1E5DF x86\puttytel.exe +MD5 EB602F84E2C2947E69985A6065F04335 puttycac-0.77u1-installer.msi +MD5 972AD706B7B9B502660B40C6F5974D7B puttycac-0.77u1.zip +MD5 5C06FEE3C683E132A7EC9284B3DE1AEC puttycac-64bit-0.77u1-installer.msi +MD5 687AB3DFECCBCF8D41D6238442F5FD77 puttycac-64bit-0.77u1.zip diff --git a/binaries/x64/pageant.exe b/binaries/x64/pageant.exe index 62bad9a2..466acda0 100644 Binary files a/binaries/x64/pageant.exe and b/binaries/x64/pageant.exe differ diff --git a/binaries/x64/plink.exe b/binaries/x64/plink.exe index 56ff2003..97343c52 100644 Binary files a/binaries/x64/plink.exe and b/binaries/x64/plink.exe differ diff --git a/binaries/x64/pscp.exe b/binaries/x64/pscp.exe index 0247eaea..198fc7be 100644 Binary files a/binaries/x64/pscp.exe and b/binaries/x64/pscp.exe differ diff --git a/binaries/x64/psftp.exe b/binaries/x64/psftp.exe index 0454731c..6efcf421 100644 Binary files a/binaries/x64/psftp.exe and b/binaries/x64/psftp.exe differ diff --git a/binaries/x64/pterm.exe b/binaries/x64/pterm.exe index 99fdb065..8aec9138 100644 Binary files a/binaries/x64/pterm.exe and b/binaries/x64/pterm.exe differ diff --git a/binaries/x64/putty.exe b/binaries/x64/putty.exe index 27892f39..99d0be20 100644 Binary files a/binaries/x64/putty.exe and b/binaries/x64/putty.exe differ diff --git a/binaries/x64/puttygen.exe b/binaries/x64/puttygen.exe index 8b21ee43..598d355f 100644 Binary files a/binaries/x64/puttygen.exe and b/binaries/x64/puttygen.exe differ diff --git a/binaries/x64/puttyimp.exe b/binaries/x64/puttyimp.exe index a80a81a6..907bf9a7 100644 Binary files a/binaries/x64/puttyimp.exe and b/binaries/x64/puttyimp.exe differ diff --git a/binaries/x64/puttytel.exe b/binaries/x64/puttytel.exe index be9f432b..92c40cc6 100644 Binary files a/binaries/x64/puttytel.exe and b/binaries/x64/puttytel.exe differ diff --git a/binaries/x86/pageant.exe b/binaries/x86/pageant.exe index 7137357e..eb663dbb 100644 Binary files a/binaries/x86/pageant.exe and b/binaries/x86/pageant.exe differ diff --git a/binaries/x86/plink.exe b/binaries/x86/plink.exe index 1123ecd5..aae9733f 100644 Binary files a/binaries/x86/plink.exe and b/binaries/x86/plink.exe differ diff --git a/binaries/x86/pscp.exe b/binaries/x86/pscp.exe index b496c6ce..cc2d4f43 100644 Binary files a/binaries/x86/pscp.exe and b/binaries/x86/pscp.exe differ diff --git a/binaries/x86/psftp.exe b/binaries/x86/psftp.exe index b39df930..3eacd250 100644 Binary files a/binaries/x86/psftp.exe and b/binaries/x86/psftp.exe differ diff --git a/binaries/x86/pterm.exe b/binaries/x86/pterm.exe index 51600d66..58ce4853 100644 Binary files a/binaries/x86/pterm.exe and b/binaries/x86/pterm.exe differ diff --git a/binaries/x86/putty.exe b/binaries/x86/putty.exe index 44369b5e..b79db0c6 100644 Binary files a/binaries/x86/putty.exe and b/binaries/x86/putty.exe differ diff --git a/binaries/x86/puttygen.exe b/binaries/x86/puttygen.exe index 0895a048..ec478fe6 100644 Binary files a/binaries/x86/puttygen.exe and b/binaries/x86/puttygen.exe differ diff --git a/binaries/x86/puttyimp.exe b/binaries/x86/puttyimp.exe index e5ff2d72..92477ee5 100644 Binary files a/binaries/x86/puttyimp.exe and b/binaries/x86/puttyimp.exe differ diff --git a/binaries/x86/puttytel.exe b/binaries/x86/puttytel.exe index 32173f0f..84678d5e 100644 Binary files a/binaries/x86/puttytel.exe and b/binaries/x86/puttytel.exe differ diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 0eb4cf1c..f5234a9b 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -1,8 +1,10 @@ cmake_minimum_required(VERSION 3.7) project(putty LANGUAGES C) +if(PUTTY_CAC) +enable_language(CXX) +endif() include(cmake/setup.cmake) - # Scan the docs directory first, so that when we start calling # installed_program(), we'll know if we have man pages available add_subdirectory(doc) diff --git a/code/cert/cert_capi.c b/code/cert/cert_capi.c index cfca9c76..ae044ca1 100644 --- a/code/cert/cert_capi.c +++ b/code/cert/cert_capi.c @@ -1,23 +1,24 @@ #ifdef PUTTY_CAC -#pragma comment(lib,"crypt32.lib") -#pragma comment(lib,"cryptui.lib") -#pragma comment(lib,"ncrypt.lib") - #include #include -#include #include +#include "ssh.h" + #include "cert_common.h" #define DEFINE_VARIABLES #include "cert_capi.h" #undef DEFINE_VARIABLES +#pragma comment(lib,"crypt32.lib") +#pragma comment(lib,"cryptui.lib") +#pragma comment(lib,"ncrypt.lib") + void cert_capi_load_cert(LPCSTR szCert, PCCERT_CONTEXT* ppCertCtx, HCERTSTORE* phStore) { - HCERTSTORE hStore = cert_capi_get_cert_store(NULL, NULL); + HCERTSTORE hStore = cert_capi_get_cert_store(NULL); if (hStore == NULL) { return; @@ -256,101 +257,12 @@ BYTE* cert_capi_sign(struct ssh2_userkey* userkey, LPCBYTE pDataToSign, int iDat return pSignedData; } -HCERTSTORE cert_capi_get_cert_store(LPCSTR* szHint, HWND hWnd) +HCERTSTORE cert_capi_get_cert_store() { - UNREFERENCED_PARAMETER(hWnd); - - // no library hint needed for fido - if (szHint != NULL) *szHint = NULL; - return CertOpenStore(CERT_STORE_PROV_SYSTEM_W, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, 0, CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_ENUM_ARCHIVED_FLAG, L"MY"); } -BOOL cert_capi_create_key(LPCSTR szAlgName, LPCSTR sSubjectName, BOOL bHardware) -{ - LPCWSTR szAlg = NULL; - DWORD iBits = 0; - if (false); - else if (strcmp(szAlgName, "rsa-1024") != 0) { iBits = 1024; szAlg = NCRYPT_RSA_ALGORITHM; } - else if (strcmp(szAlgName, "rsa-2048") != 0) { iBits = 2048; szAlg = NCRYPT_RSA_ALGORITHM; } - else if (strcmp(szAlgName, "rsa-3096") != 0) { iBits = 3096; szAlg = NCRYPT_RSA_ALGORITHM; } - else if (strcmp(szAlgName, "rsa-4096") != 0) { iBits = 4096; szAlg = NCRYPT_RSA_ALGORITHM; } - else if (strcmp(szAlgName, "ecdsa-sha2-nistp256") == 0) szAlg = NCRYPT_ECDSA_P256_ALGORITHM; - else if (strstr(szAlgName, "ecdsa-sha2-nistp384") == 0) szAlg = NCRYPT_ECDSA_P384_ALGORITHM; - else if (strcmp(szAlgName, "ecdsa-sha2-nistp512") == 0) szAlg = NCRYPT_ECDSA_P521_ALGORITHM; - else return false; - - // decorate the name for the cert - BYTE sNameBufferEncoded[1024] = { 0 }; - WCHAR sNameBufferWithCn[1024] = { 0 }; - CERT_NAME_BLOB tSubjectNameDecorated = { sizeof(sNameBufferEncoded), sNameBufferEncoded }; - if (swprintf_s(&sNameBufferWithCn[0], _countof(sNameBufferWithCn), L"CN=%S", sSubjectName) == -1 || - CertStrToNameW(X509_ASN_ENCODING, sNameBufferWithCn, 0, NULL, - tSubjectNameDecorated.pbData, &tSubjectNameDecorated.cbData, NULL) == 0) - { - return FALSE; - } - - // create crytographic key - BOOL bCertSuccess = FALSE; - NCRYPT_KEY_HANDLE hKey = (NCRYPT_KEY_HANDLE)NULL; - NCRYPT_PROV_HANDLE hProvider = (NCRYPT_PROV_HANDLE)NULL; - if (NCryptOpenStorageProvider(&hProvider, bHardware ? MS_SMART_CARD_KEY_STORAGE_PROVIDER : - MS_KEY_STORAGE_PROVIDER, 0) == ERROR_SUCCESS && - NCryptCreatePersistedKey(hProvider, &hKey, szAlg, - sNameBufferWithCn, AT_SIGNATURE, 0) == ERROR_SUCCESS && - (iBits == 0 || NCryptSetProperty(hKey, NCRYPT_LENGTH_PROPERTY, - (PBYTE)&iBits, sizeof(iBits), NCRYPT_PERSIST_FLAG) == ERROR_SUCCESS) && - NCryptFinalizeKey(hKey, 0) == ERROR_SUCCESS) - { - // give the certificate the client auth and smartcard logon attributes - LPSTR tKeyUsageSoftware[] = { szOID_PKIX_KP_CLIENT_AUTH }; - LPSTR tKeyUsageHardware[] = { szOID_KP_SMARTCARD_LOGON, szOID_PKIX_KP_CLIENT_AUTH }; - CERT_ENHKEY_USAGE tEnhancedKeyUsage = { - (bHardware) ? _countof(tKeyUsageHardware) : _countof(tKeyUsageSoftware), - (bHardware) ? tKeyUsageHardware : tKeyUsageSoftware - }; - - BYTE sKeyUsageEncoded[32]; - DWORD iKeyUsageEncodedSize = sizeof(sKeyUsageEncoded); - CryptEncodeObject(X509_ASN_ENCODING, X509_ENHANCED_KEY_USAGE, (LPVOID)&tEnhancedKeyUsage, &sKeyUsageEncoded[0], &iKeyUsageEncodedSize); - CERT_EXTENSION tExtension = { 0 }; - tExtension.pszObjId = szOID_ENHANCED_KEY_USAGE; - tExtension.Value.cbData = iKeyUsageEncodedSize; - tExtension.Value.pbData = &sKeyUsageEncoded[0]; - - // give the certificate a long lifetime - SYSTEMTIME tSystemTimeStart; - GetSystemTime(&tSystemTimeStart); - SYSTEMTIME tSystemTimeEnd = tSystemTimeStart; - tSystemTimeEnd.wYear += 100; - - // create tje certofocate - CERT_EXTENSIONS tExtensions = { 1, &tExtension }; - PCCERT_CONTEXT pContext = CertCreateSelfSignCertificate(hKey, &tSubjectNameDecorated, - 0, NULL, NULL, &tSystemTimeStart, &tSystemTimeEnd, &tExtensions); - if (pContext != NULL) - { - // open the cert store to save the cert - HCERTSTORE hCertStore = CertOpenSystemStoreW((HCRYPTPROV_LEGACY)NULL, L"MY"); - if (hCertStore != NULL) - { - // add the cert to the personal store - bCertSuccess = CertAddCertificateContextToStore(hCertStore, pContext, - CERT_STORE_ADD_REPLACE_EXISTING, NULL); - CertCloseStore(hCertStore, 0); - } - - CertFreeCertificateContext(pContext); - } - } - - if (hKey != (NCRYPT_HANDLE)NULL) NCryptFreeObject(hKey); - if (hProvider != (NCRYPT_HANDLE)NULL) NCryptFreeObject(hProvider); - return bCertSuccess; -} - BOOL cert_capi_delete_key(LPCSTR szCert) { // get a handle to the certificate diff --git a/code/cert/cert_capi.h b/code/cert/cert_capi.h index e515786e..dd5060e8 100644 --- a/code/cert/cert_capi.h +++ b/code/cert/cert_capi.h @@ -4,10 +4,9 @@ #include -// include ssh for types -#ifndef SSH_AGENT_SUCCESS -#include "ssh.h" -#endif +// forward declarations for shared structures +struct ssh2_userkey; +struct strbuf; // used to determine whether these variables are marked as extern // for external source files including these files @@ -15,13 +14,17 @@ #ifdef DEFINE_VARIABLES #define EXTERN #else +#ifdef __cplusplus +#define EXTERN EXTERN_C +#else #define EXTERN extern #endif +#endif // functions used by the common module EXTERN BOOL cert_capi_test_hash(LPCSTR szCert, DWORD iHashRequest); EXTERN BYTE * cert_capi_sign(struct ssh2_userkey * userkey, LPCBYTE pDataToSign, int iDataToSignLen, int * iSigLen, LPCSTR sHashAlgName); EXTERN void cert_capi_load_cert(LPCSTR szCert, PCCERT_CONTEXT* ppCertCtx, HCERTSTORE* phStore); -EXTERN HCERTSTORE cert_capi_get_cert_store(LPCSTR * szHint, HWND hWnd); +EXTERN HCERTSTORE cert_capi_get_cert_store(); #endif /* USE_CAPI */ diff --git a/code/cert/cert_capi_tools.cc b/code/cert/cert_capi_tools.cc new file mode 100644 index 00000000..ed3a7b9e --- /dev/null +++ b/code/cert/cert_capi_tools.cc @@ -0,0 +1,170 @@ +#ifdef PUTTY_CAC + +#include +#include +#include +#include + +#include + +#include "cert_common.h" +#include "cert_capi.h" + +#pragma comment(lib,"comsuppw.lib") +#include +CComPtr GetObjectId(_bstr_t sAlgName) +{ + CComPtr oAlgOid; + if (FAILED(CoCreateInstance(__uuidof(CObjectId), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&oAlgOid)))) exit(0); + oAlgOid->InitializeFromValue(sAlgName); + return oAlgOid; +} + +EXTERN_C LPSTR cert_capi_create_key(LPCSTR szAlgName, LPCSTR sSubjectName, BOOL bHardware) +{ + std::string sSubjectNameWithCn = std::string("CN=") + sSubjectName; + _bstr_t sProviderName = bHardware ? MS_SMART_CARD_KEY_STORAGE_PROVIDER : MS_KEY_STORAGE_PROVIDER; + _bstr_t sAlgOid; + + // determine bits and oid from passed strings + DWORD iBits = 0; + if (false); + else if (strcmp(szAlgName, "rsa-1024") == 0) { iBits = 1024; sAlgOid = szOID_RSA_RSA; } + else if (strcmp(szAlgName, "rsa-2048") == 0) { iBits = 2048; sAlgOid = szOID_RSA_RSA; } + else if (strcmp(szAlgName, "rsa-3072") == 0) { iBits = 3072; sAlgOid = szOID_RSA_RSA; } + else if (strcmp(szAlgName, "rsa-4096") == 0) { iBits = 4096; sAlgOid = szOID_RSA_RSA; } + else if (strcmp(szAlgName, "ecdsa-sha2-nistp256") == 0) { iBits = 256; sAlgOid = szOID_ECC_CURVE_P256; } + else if (strcmp(szAlgName, "ecdsa-sha2-nistp384") == 0) { iBits = 384; sAlgOid = szOID_ECC_CURVE_P384; } + else if (strcmp(szAlgName, "ecdsa-sha2-nistp521") == 0) { iBits = 521; sAlgOid = szOID_ECC_CURVE_P521; } + else return NULL; + + // initialize com + HRESULT iInit = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + if (iInit != S_OK && iInit != S_FALSE) return NULL; + + // create provider information structure + CComPtr oProviderInfo = nullptr; + if (FAILED(CoCreateInstance(__uuidof(CCspInformation), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&oProviderInfo))) || + FAILED(oProviderInfo->InitializeFromName(sProviderName))) + { + return NULL; + } + + // create string used for issuer and subject + CComPtr oName = nullptr; + if (FAILED(CoCreateInstance(__uuidof(CX500DistinguishedName), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&oName))) || + FAILED(oName->Encode(_bstr_t(sSubjectNameWithCn.c_str()), XCN_CERT_NAME_STR_NONE))) + { + return NULL; + } + + // initialize privatre key + CComPtr oPrivateKey = nullptr; + if (FAILED(CoCreateInstance(__uuidof(CX509PrivateKey), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&oPrivateKey))) || + FAILED(oPrivateKey->put_ProviderName(sProviderName)) || + FAILED(oPrivateKey->put_MachineContext(VARIANT_FALSE)) || + FAILED(oPrivateKey->put_Algorithm(GetObjectId(sAlgOid))) || + FAILED(oPrivateKey->put_Length(iBits)) || + FAILED(oPrivateKey->put_KeyProtection(XCN_NCRYPT_UI_NO_PROTECTION_FLAG)) || + FAILED(oPrivateKey->put_ExportPolicy(XCN_NCRYPT_ALLOW_EXPORT_NONE)) || + FAILED(oPrivateKey->Create())) + { + return NULL; + } + + // give the certificate a long lifetime + DOUBLE iNotBefore = 0, iNotAfter = 0; + SYSTEMTIME tSystemTimeStart; + GetSystemTime(&tSystemTimeStart); + SystemTimeToVariantTime(&tSystemTimeStart, &iNotBefore); + SYSTEMTIME tSystemTimeEnd = tSystemTimeStart; + tSystemTimeEnd.wYear += 10; + SystemTimeToVariantTime(&tSystemTimeEnd, &iNotAfter); + + // create certificate request + CComPtr oRequest = nullptr; + if (FAILED(CoCreateInstance(__uuidof(CX509CertificateRequestCertificate), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&oRequest))) || + FAILED(oRequest->InitializeFromPrivateKey(ContextUser, oPrivateKey, _bstr_t(L""))) || + FAILED(oRequest->put_Subject(oName)) || + FAILED(oRequest->put_Issuer(oName)) || + FAILED(oRequest->put_NotBefore(iNotBefore)) || + FAILED(oRequest->put_NotAfter(iNotAfter)) || + FAILED(oRequest->put_HashAlgorithm(GetObjectId(szOID_NIST_sha256)))) + { + return NULL; + } + + // create com structure for key usage + CComPtr oKeyUsage = nullptr; + if (FAILED(CoCreateInstance(__uuidof(CX509ExtensionKeyUsage), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&oKeyUsage))) || + FAILED(oKeyUsage->InitializeEncode(XCN_CERT_DIGITAL_SIGNATURE_KEY_USAGE))) + { + return NULL; + } + + // create list of oids for enhanced key usage + CComPtr oEnhancedKeyUsageOids = nullptr; + if (FAILED(CoCreateInstance(__uuidof(CObjectIds), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&oEnhancedKeyUsageOids))) || + FAILED(oEnhancedKeyUsageOids->Add(GetObjectId(szOID_PKIX_KP_CLIENT_AUTH))) || + (bHardware && FAILED(oEnhancedKeyUsageOids->Add(GetObjectId(szOID_KP_SMARTCARD_LOGON))))) + { + return NULL; + } + + // create com structure for enhanced key usage list + CComPtr oEnhancedKeyUsageList = nullptr; + if (FAILED(CoCreateInstance(__uuidof(CX509ExtensionEnhancedKeyUsage), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&oEnhancedKeyUsageList))) || + FAILED(oEnhancedKeyUsageList->InitializeEncode(oEnhancedKeyUsageOids))) + { + return NULL; + } + + // add key usage and enhanced key usage to extension list + CComPtr oExtensions = nullptr; + if (FAILED(oRequest->get_X509Extensions(&oExtensions)) || + FAILED(oExtensions->Add(oKeyUsage)) || + FAILED(oExtensions->Add(oEnhancedKeyUsageList)) || + FAILED(oRequest->Encode())) + { + return NULL; + } + + // create and submit self-signed enrollment request + CComPtr oEnrollment = nullptr; + BSTR sRequestString; + BSTR sInstralledCert; + if (FAILED(CoCreateInstance(__uuidof(CX509Enrollment), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&oEnrollment))) || + FAILED(oEnrollment->InitializeFromRequest(oRequest)) || + FAILED(oEnrollment->CreateRequest(XCN_CRYPT_STRING_BASE64, &sRequestString)) || + FAILED(oEnrollment->InstallResponse(AllowUntrustedCertificate, sRequestString, XCN_CRYPT_STRING_BASE64, _bstr_t(L""))) || + FAILED(oEnrollment->get_Certificate(XCN_CRYPT_STRING_BINARY, &sInstralledCert))) + { + return NULL; + } + SysFreeString(sRequestString); + + // fetch dummy context so we can lookup the thumbprint + PCCERT_CONTEXT tDummyCertContext = CertCreateCertificateContext( + X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + &((LPBYTE)sInstralledCert)[sizeof(UINT)], + SysStringByteLen(sInstralledCert)); + SysFreeString(sInstralledCert); + + // now use the public key to find the unified certificate in the cer store + LPSTR szThumbprint = NULL; + if (tDummyCertContext != NULL) + { + HCERTSTORE hCertStore = cert_capi_get_cert_store(); + PCCERT_CONTEXT tUnifiedCert = CertFindCertificateInStore(hCertStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + 0, CERT_FIND_PUBLIC_KEY, (PVOID)&tDummyCertContext->pCertInfo->SubjectPublicKeyInfo, NULL); + szThumbprint = cert_get_cert_thumbprint(IDEN_CAPI, tUnifiedCert, NULL); + CertCloseStore(hCertStore, 0); + if (tDummyCertContext != NULL) CertFreeCertificateContext(tUnifiedCert); + } + + // cleanup + if (tDummyCertContext != NULL) CertFreeCertificateContext(tDummyCertContext); + return szThumbprint; +} + +#endif // PUTTY_CAC \ No newline at end of file diff --git a/code/cert/cert_common.c b/code/cert/cert_common.c index 01b78bf9..498c9910 100644 --- a/code/cert/cert_common.c +++ b/code/cert/cert_common.c @@ -8,26 +8,23 @@ #include #include -#include "cert_pkcs.h" -#include "cert_capi.h" -#include "cert_fido.h" +#include "marshal.h" +#include "ssh.h" +#include "mpint.h" +#include "ecc.h" #define DEFINE_VARIABLES #include "cert_common.h" #undef DEFINE_VARIABLES +#include "cert_pkcs.h" +#include "cert_capi.h" +#include "cert_fido.h" + #ifndef PUTTY_REG_POS #define PUTTY_REG_POS "Software\\SimonTatham\\PuTTY" #endif -#ifndef SSH_AGENT_SUCCESS -#include "ssh.h" -#endif -#include "mpint.h" -#include "ecc.h" -#include "marshal.h" -#include "misc.h" - VOID cert_reverse_array(LPBYTE pb, DWORD cb) { for (DWORD i = 0, j = cb - 1; i < cb / 2; i++, j--) @@ -38,8 +35,11 @@ VOID cert_reverse_array(LPBYTE pb, DWORD cb) } } -LPSTR cert_get_cert_thumbprint(LPCSTR szIden, PCCERT_CONTEXT pCertContext, LPCSTR szHint) +LPSTR cert_get_cert_thumbprint(LPCSTR szIden, PCCERT_CONTEXT pCertContext) { + // sanity check + if (szIden == NULL || pCertContext == NULL) return FALSE; + BYTE pbThumbBinary[SHA1_BINARY_SIZE]; DWORD cbThumbBinary = SHA1_BINARY_SIZE; if (CertGetCertificateContextProperty(pCertContext, CERT_HASH_PROP_ID, pbThumbBinary, &cbThumbBinary) == FALSE) @@ -84,22 +84,22 @@ LPSTR cert_get_cert_thumbprint(LPCSTR szIden, PCCERT_CONTEXT pCertContext, LPCST return szThumb; } -LPSTR cert_prompt(LPCSTR szIden, HWND hWnd, BOOL bAutoSelect, LPCWSTR sCustomPrompt) +LPSTR cert_prompt(LPCSTR szIden, BOOL bAutoSelect, LPCWSTR sCustomPrompt) { HCERTSTORE hCertStore = NULL; LPCSTR szHint = NULL; if (cert_is_capipath(szIden)) { - hCertStore = cert_capi_get_cert_store(&szHint, hWnd); + hCertStore = cert_capi_get_cert_store(); } else if (cert_is_pkcspath(szIden)) { - hCertStore = cert_pkcs_get_cert_store(&szHint, hWnd); + hCertStore = cert_pkcs_get_cert_store(); } else if (cert_is_fidopath(szIden)) { - hCertStore = cert_fido_get_cert_store(&szHint, hWnd); + hCertStore = cert_fido_get_cert_store(); } // return if store could not be loaded @@ -132,7 +132,7 @@ LPSTR cert_prompt(LPCSTR szIden, HWND hWnd, BOOL bAutoSelect, LPCWSTR sCustomPro else { // display the certificate selection dialog - pCertContext = CryptUIDlgSelectCertificateFromStore(hMemoryStore, hWnd, + pCertContext = CryptUIDlgSelectCertificateFromStore(hMemoryStore, GetForegroundWindow(), L"PuTTY: Select Certificate Or Key", sCustomPrompt != NULL ? sCustomPrompt : ( L"Please select the certificate or key identifier that you would like " \ @@ -148,7 +148,7 @@ LPSTR cert_prompt(LPCSTR szIden, HWND hWnd, BOOL bAutoSelect, LPCWSTR sCustomPro DWORD cbThumbBinary = SHA1_BINARY_SIZE; if (CertGetCertificateContextProperty(pCertContext, CERT_HASH_PROP_ID, pbThumbBinary, &cbThumbBinary) == TRUE) { - szCert = cert_get_cert_thumbprint(IDEN_PREFIX(szIden), pCertContext, szHint); + szCert = cert_get_cert_thumbprint(IDEN_PREFIX(szIden), pCertContext); } // cleanup @@ -219,7 +219,7 @@ BOOL cert_confirm_signing(LPCSTR sFingerPrint, LPCSTR sComment) return (iResponse == IDYES); } -BOOL cert_sign(struct ssh2_userkey* userkey, LPCBYTE pDataToSign, int iDataToSignLen, int iAgentFlags, strbuf* pSignature) +BOOL cert_sign(struct ssh2_userkey* userkey, LPCBYTE pDataToSign, int iDataToSignLen, int iAgentFlags, struct strbuf * pSignature) { LPBYTE pRawSig = NULL; DWORD iCounter = 0; @@ -452,7 +452,7 @@ struct ssh2_userkey* cert_get_ssh_userkey(LPCSTR szCert, PCERT_CONTEXT pCertCont return pUserKey; } -struct ssh2_userkey* cert_load_key(LPCSTR szCert, HWND hWnd) +struct ssh2_userkey* cert_load_key(LPCSTR szCert) { // sanity check if (szCert == NULL) return NULL; @@ -462,7 +462,7 @@ struct ssh2_userkey* cert_load_key(LPCSTR szCert, HWND hWnd) BOOL bDynamicLookupAutoSelect = strcmp(IDEN_SPLIT(szCert), "**") == 0; if (bDynamicLookup || bDynamicLookupAutoSelect) { - szCert = cert_prompt(szCert, hWnd, bDynamicLookupAutoSelect, NULL); + szCert = cert_prompt(szCert, bDynamicLookupAutoSelect, NULL); if (szCert == NULL) return NULL; } @@ -500,7 +500,7 @@ LPSTR cert_key_string(LPCSTR szCert) // fetch the elements of the string LPSTR szKey = ssh2_pubkey_openssh_str(pUserKey); LPSTR szName = cert_subject_string(szCert); - LPSTR szHash = cert_get_cert_thumbprint(cert_iden(szCert), pCertContext, NULL); + LPSTR szHash = cert_get_cert_thumbprint(cert_iden(szCert), pCertContext); // append the ssh string, identifier:thumbprint, and certificate subject LPSTR szKeyWithComment = dupprintf("%s %s %s", szKey, szHash, szName); @@ -662,8 +662,8 @@ int cert_all_certs(LPSTR** pszCert) LPCSTR sStoreType[2] = { IDEN_CAPI, IDEN_FIDO }; HCERTSTORE hCertStore[2] = { - cert_capi_get_cert_store(NULL, NULL), - cert_fido_get_cert_store(NULL, NULL) + cert_capi_get_cert_store(NULL), + cert_fido_get_cert_store(NULL) }; // find certificates matching our criteria @@ -678,7 +678,7 @@ int cert_all_certs(LPSTR** pszCert) // count cert and [re]allocate the return string array *pszCert = snrealloc(*pszCert, iCertNum + 1, sizeof(LPSTR)); - (*pszCert)[iCertNum++] = cert_get_cert_thumbprint(sStoreType[iStore], pCertContext, NULL); + (*pszCert)[iCertNum++] = cert_get_cert_thumbprint(sStoreType[iStore], pCertContext); } // cleanup and return diff --git a/code/cert/cert_common.h b/code/cert/cert_common.h index ee7cef8e..e7a0ec42 100644 --- a/code/cert/cert_common.h +++ b/code/cert/cert_common.h @@ -4,10 +4,9 @@ #include -// include ssh for types -#ifndef SSH_AGENT_SUCCESS -#include "ssh.h" -#endif +// forward declarations for shared structures +struct ssh2_userkey; +struct strbuf; // used to determine whether these variables are marked as extern // for external source files including these files @@ -15,8 +14,12 @@ #ifdef DEFINE_VARIABLES #define EXTERN #else +#ifdef __cplusplus +#define EXTERN EXTERN_C +#else #define EXTERN extern #endif +#endif // functions used only by the capi and pkcs addon modules EXTERN VOID cert_reverse_array(LPBYTE pb, DWORD cb); @@ -37,21 +40,21 @@ EXTERN BOOL cert_cmdline_parse(LPCSTR sCommand); // functions used by putty code EXTERN LPSTR cert_key_string(LPCSTR szCert); EXTERN LPSTR cert_subject_string(LPCSTR szCert); -EXTERN LPSTR cert_prompt(LPCSTR szIden, HWND hWnd, BOOL bAutoSelect, LPCWSTR sCustomPrompt); +EXTERN LPSTR cert_prompt(LPCSTR szIden, BOOL bAutoSelect, LPCWSTR sCustomPrompt); EXTERN BOOL cert_test_hash(LPCSTR szCert, DWORD iHashRequest); EXTERN BOOL cert_confirm_signing(LPCSTR sFingerPrint, LPCSTR sComment); -EXTERN BOOL cert_sign(struct ssh2_userkey * userkey, LPCBYTE pDataToSign, int iDataToSignLen, int iAgentFlags, strbuf* pSignature); -EXTERN struct ssh2_userkey * cert_load_key(LPCSTR szCert, HWND hWnd); +EXTERN BOOL cert_sign(struct ssh2_userkey * userkey, LPCBYTE pDataToSign, int iDataToSignLen, int iAgentFlags, struct strbuf* pSignature); +EXTERN struct ssh2_userkey * cert_load_key(LPCSTR szCert); EXTERN VOID cert_display_cert(LPCSTR szCert, HWND hWnd); EXTERN int cert_all_certs(LPSTR ** pszCert); EXTERN VOID cert_convert_legacy(LPSTR szCert); EXTERN LPBYTE cert_get_hash(LPCSTR szAlgo, LPCBYTE pDataToHash, DWORD iDataToHashSize, DWORD * iHashedDataSize, BOOL bPrependDigest); -EXTERN BOOL cert_capi_create_key(LPCSTR szAlgName, LPCSTR sSubjectName, BOOL bHardware); EXTERN BOOL cert_capi_delete_key(LPCSTR szCert); EXTERN BOOL fido_create_key(LPCSTR szAlgName, LPCSTR szApplication, BOOL bResidentKey, BOOL bUserVerification); EXTERN BOOL fido_delete_key(LPCSTR szCert); EXTERN VOID fido_import_keys(); EXTERN VOID fido_clear_keys(); +EXTERN LPSTR cert_capi_create_key(LPCSTR szAlgName, LPCSTR sSubjectName, BOOL bHardware); // ed25519 oid; no native support in windows #ifndef szOID_ED25119 @@ -69,7 +72,7 @@ EXTERN VOID fido_clear_keys(); #define IDEN_FIDO_SIZE (strlen(IDEN_FIDO)) #define IDEN_SPLIT(p) (strchr(p,':') + 1) -#define IDEN_PREFIX(p) (cert_is_capipath(p) ? IDEN_CAPI : cert_is_pkcspath(p) ? IDEN_CAPI : IDEN_FIDO) +#define IDEN_PREFIX(p) (cert_is_capipath(p) ? IDEN_CAPI : cert_is_pkcspath(p) ? IDEN_PKCS : IDEN_FIDO) #define cert_is_capipath(p) (p != NULL && _strnicmp((LPSTR) p, IDEN_CAPI, IDEN_CAPI_SIZE) == 0) #define cert_is_pkcspath(p) (p != NULL && _strnicmp((LPSTR) p, IDEN_PKCS, IDEN_PKCS_SIZE) == 0) diff --git a/code/cert/cert_fido.c b/code/cert/cert_fido.c index 9e08a7f8..273d4bbe 100644 --- a/code/cert/cert_fido.c +++ b/code/cert/cert_fido.c @@ -7,6 +7,8 @@ #include #include +#include "ssh.h" + #define DEFINE_VARIABLES #include "cert_fido.h" #undef DEFINE_VARIABLES @@ -202,7 +204,7 @@ BYTE* cert_fido_sign(struct ssh2_userkey* userkey, LPCBYTE pDataToSign, int iDat tClientData.pbClientDataJSON = (PBYTE)pDataToSign; tClientData.pwszHashAlgId = sHashAlg; - // identify credential list(technically only required for non - resident keys) + // identify credential list (technically only required for non-resident keys) WEBAUTHN_CREDENTIAL tCredential = { WEBAUTHN_CREDENTIAL_CURRENT_VERSION }; tCredential.cbId = iCredIdBufferSize; tCredential.pwszCredentialType = WEBAUTHN_CREDENTIAL_TYPE_PUBLIC_KEY; @@ -380,13 +382,8 @@ void cert_fido_load_cert(LPCSTR szCert, PCCERT_CONTEXT* ppCertCtx, HCERTSTORE* p } -HCERTSTORE cert_fido_get_cert_store(LPCSTR* szHint, HWND hWnd) +HCERTSTORE cert_fido_get_cert_store() { - UNREFERENCED_PARAMETER(hWnd); - - // no library hint needed for fido - if (szHint != NULL) *szHint = NULL; - // open a memory-based cert store to store the certificate context i HCERTSTORE hStoreHandle = CertOpenStore(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); diff --git a/code/cert/cert_fido.h b/code/cert/cert_fido.h index 627140e1..a7988366 100644 --- a/code/cert/cert_fido.h +++ b/code/cert/cert_fido.h @@ -4,10 +4,9 @@ #include -// include ssh for types -#ifndef SSH_AGENT_SUCCESS -#include "ssh.h" -#endif +// forward declarations for shared structures +struct ssh2_userkey; +struct strbuf; // used to determine whether these variables are marked as extern // for external source files including these files @@ -22,6 +21,6 @@ EXTERN BOOL cert_fido_test_hash(LPCSTR szCert, DWORD iHashRequest); EXTERN BYTE* cert_fido_sign(struct ssh2_userkey* userkey, LPCBYTE pDataToSign, int iDataToSignLen, int* iSigLen, LPCSTR sHashAlgName, PDWORD iCounter, PBYTE iFlags); EXTERN void cert_fido_load_cert(LPCSTR szCert, PCCERT_CONTEXT* ppCertCtx, HCERTSTORE* phStore); -EXTERN HCERTSTORE cert_fido_get_cert_store(LPCSTR* szHint, HWND hWnd); +EXTERN HCERTSTORE cert_fido_get_cert_store(); #endif // PUTTY_CAC \ No newline at end of file diff --git a/code/cert/cert_pkcs.c b/code/cert/cert_pkcs.c index aba70f46..22b4af3f 100644 --- a/code/cert/cert_pkcs.c +++ b/code/cert/cert_pkcs.c @@ -8,16 +8,14 @@ #pragma comment(lib,"crypt32.lib") #pragma comment(lib,"credui.lib") -#include "cert_common.h" +#include "ssh.h" +#include "mpint.h" #define DEFINE_VARIABLES #include "cert_pkcs.h" #undef DEFINE_VARIABLES -#ifndef SSH_AGENT_SUCCESS -#include "ssh.h" -#endif -#include "mpint.h" +#include "cert_common.h" // required to be defined by pkcs headers #define CK_PTR * @@ -37,7 +35,7 @@ #pragma pack(pop, cryptoki) // functions used within the pkcs module -PCCERT_CONTEXT pkcs_get_cert_from_token(CK_FUNCTION_LIST_PTR FunctionList, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject); +PCCERT_CONTEXT pkcs_get_cert_from_token(CK_FUNCTION_LIST_PTR FunctionList, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, LPSTR szFile); CK_FUNCTION_LIST_PTR cert_pkcs_load_library(LPCSTR szLibrary); void * pkcs_get_attribute_value(CK_FUNCTION_LIST_PTR FunctionList, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_TYPE iAttribute, CK_ULONG_PTR iValueSize); @@ -325,9 +323,10 @@ void cert_pkcs_load_cert(LPCSTR szCert, PCCERT_CONTEXT* ppCertCtx, HCERTSTORE* p // lookup the cert in the token *phStore = NULL; - *ppCertCtx = pkcs_get_cert_from_token(pFunctionList, hSession, hObject); + *ppCertCtx = pkcs_get_cert_from_token(pFunctionList, hSession, hObject, szLibrary); // cleanup + pFunctionList->C_CloseSession(hSession); free(szThumb); } @@ -409,7 +408,7 @@ CK_FUNCTION_LIST_PTR cert_pkcs_load_library(LPCSTR szLibrary) return hItem->FunctionList; } -HCERTSTORE cert_pkcs_get_cert_store(LPCSTR * szHint, HWND hWnd) +HCERTSTORE cert_pkcs_get_cert_store() { static char szSysDir[MAX_PATH + 1] = "\0"; if (strlen(szSysDir) == 0 && GetSystemDirectory(szSysDir, _countof(szSysDir)) == 0) @@ -421,8 +420,8 @@ HCERTSTORE cert_pkcs_get_cert_store(LPCSTR * szHint, HWND hWnd) OPENFILENAME tFileNameInfo; ZeroMemory(&tFileNameInfo, sizeof(OPENFILENAME)); tFileNameInfo.lStructSize = sizeof(OPENFILENAME); - tFileNameInfo.hwndOwner = hWnd; - tFileNameInfo.lpstrFilter = "PKCS Library Files (*pkcs*.dll;*pks*.dll;*p11*.dll;gclib.dll)\0*pkcs*.dll;*pks*.dll;*p11*.dll;gclib.dll\0All Library Files (*.dll)\0*.dll\0\0"; + tFileNameInfo.hwndOwner = GetForegroundWindow(); + tFileNameInfo.lpstrFilter = "PKCS Library Files (*pkcs*.dll;*pks*.dll;*p11*.dll;*ykcs*.dll;gclib.dll)\0*pkcs*.dll;*pks*.dll;*p11*.dll;*ykcs*.dll;gclib.dll\0All Library Files (*.dll)\0*.dll\0\0"; tFileNameInfo.lpstrTitle = "Please Select PKCS #11 Library File"; tFileNameInfo.lpstrInitialDir = szSysDir; tFileNameInfo.Flags = OFN_FORCESHOWHIDDEN | OFN_FILEMUSTEXIST; @@ -485,7 +484,7 @@ HCERTSTORE cert_pkcs_get_cert_store(LPCSTR * szHint, HWND hWnd) for (CK_ULONG iCert = 0; iCert < iCertListSize; iCert++) { PCCERT_CONTEXT pCertContext = - pkcs_get_cert_from_token(pFunctionList, hSession, aCertList[iCert]); + pkcs_get_cert_from_token(pFunctionList, hSession, aCertList[iCert], tFileNameInfo.lpstrFile); // attributes to query from the certificate if (pCertContext == NULL) @@ -494,17 +493,6 @@ HCERTSTORE cert_pkcs_get_cert_store(LPCSTR * szHint, HWND hWnd) continue; } - // store the pkcs library as an attribute on the certificate - WCHAR sFileNameWide[MAX_PATH + 1]; - MultiByteToWideChar(CP_ACP, 0, szFile, -1, sFileNameWide, _countof(sFileNameWide)); - CRYPT_DATA_BLOB tFileName = { (wcslen(sFileNameWide) + 1) * sizeof(WCHAR), (PBYTE) sFileNameWide }; - if (CertSetCertificateContextProperty(pCertContext, CERT_PVK_FILE_PROP_ID, 0, &tFileName) != TRUE) - { - // error - CertFreeCertificateContext(pCertContext); - continue; - } - // add this certificate to our store CertAddCertificateContextToStore(hMemoryStore, pCertContext, CERT_STORE_ADD_ALWAYS, NULL); CertFreeCertificateContext(pCertContext); @@ -552,7 +540,7 @@ void * pkcs_get_attribute_value(CK_FUNCTION_LIST_PTR FunctionList, CK_SESSION_HA return aAttribute.pValue; } -PCCERT_CONTEXT pkcs_get_cert_from_token(CK_FUNCTION_LIST_PTR FunctionList, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) +PCCERT_CONTEXT pkcs_get_cert_from_token(CK_FUNCTION_LIST_PTR FunctionList, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, LPSTR szFile) { // query value from string CK_ULONG iValue = 0; @@ -569,6 +557,17 @@ PCCERT_CONTEXT pkcs_get_cert_from_token(CK_FUNCTION_LIST_PTR FunctionList, CK_SE PCCERT_CONTEXT pCertObject = CertCreateCertificateContext( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, pValue, iValue); + // store the pkcs library as an attribute on the certificate + WCHAR sFileNameWide[MAX_PATH + 1]; + MultiByteToWideChar(CP_ACP, 0, szFile, -1, sFileNameWide, _countof(sFileNameWide)); + CRYPT_DATA_BLOB tFileName = { (wcslen(sFileNameWide) + 1) * sizeof(WCHAR), (PBYTE)sFileNameWide }; + if (CertSetCertificateContextProperty(pCertObject, CERT_PVK_FILE_PROP_ID, 0, &tFileName) != TRUE) + { + // error + CertFreeCertificateContext(pCertObject); + pCertObject = NULL; + } + // cleanup and return free(pValue); return pCertObject; @@ -648,7 +647,7 @@ void pkcs_lookup_token_cert(LPCSTR szCert, CK_SESSION_HANDLE_PTR phSession, CK_O { // decode windows cert object from PCCERT_CONTEXT pCertContext = - pkcs_get_cert_from_token(pFunctionList, hSession, aCertList[iCert]); + pkcs_get_cert_from_token(pFunctionList, hSession, aCertList[iCert], szLibrary); // attributes to query from the certificate if (pCertContext == NULL) diff --git a/code/cert/cert_pkcs.h b/code/cert/cert_pkcs.h index e0289b65..2a4f95d0 100644 --- a/code/cert/cert_pkcs.h +++ b/code/cert/cert_pkcs.h @@ -4,10 +4,9 @@ #include -// include ssh for types -#ifndef SSH_AGENT_SUCCESS -#include "ssh.h" -#endif +// forward declarations for shared structures +struct ssh2_userkey; +struct strbuf; // used to determine whether these variables are marked as extern // for external source files including these files @@ -15,13 +14,17 @@ #ifdef DEFINE_VARIABLES #define EXTERN #else +#ifdef __cplusplus +#define EXTERN EXTERN_C +#else #define EXTERN extern #endif +#endif // functions used by the common module EXTERN BOOL cert_pkcs_test_hash(LPCSTR szCert, DWORD iHashRequest); EXTERN BYTE * cert_pkcs_sign(struct ssh2_userkey * userkey, LPCBYTE pDataToSign, int iDataToSignLen, int * iSigLen, LPCSTR sHashAlgName); EXTERN void cert_pkcs_load_cert(LPCSTR szCert, PCCERT_CONTEXT* ppCertCtx, HCERTSTORE* phStore); -EXTERN HCERTSTORE cert_pkcs_get_cert_store(LPCSTR * szHint, HWND hWnd); +EXTERN HCERTSTORE cert_pkcs_get_cert_store(); #endif // PUTTY_CAC \ No newline at end of file diff --git a/code/cmake/gitcommit.cmake b/code/cmake/gitcommit.cmake index 76f4c7f4..4326c01d 100644 --- a/code/cmake/gitcommit.cmake +++ b/code/cmake/gitcommit.cmake @@ -1,6 +1,6 @@ # Pure cmake script to write out cmake_commit.c and cmake_version.but -set(DEFAULT_COMMIT "61ab33efe48cfd1cea77e249e5598a89f3387fa3") +set(DEFAULT_COMMIT "See https://github.com/NoMoreFood/putty-cac") set(commit "${DEFAULT_COMMIT}") set(TOPLEVEL_SOURCE_DIR ${CMAKE_SOURCE_DIR}) diff --git a/code/cmake/platforms/windows.cmake b/code/cmake/platforms/windows.cmake index 7248ba43..162f1c34 100644 --- a/code/cmake/platforms/windows.cmake +++ b/code/cmake/platforms/windows.cmake @@ -177,14 +177,22 @@ function(installed_program target) "${target}${CMAKE_EXECUTABLE_SUFFIX}\n") endfunction() -# Conditionally add PuTTY-CAC functionality +# Conditionally add PuTTY-CAC compiler customizations if(PUTTY_CAC) add_compile_definitions(PUTTY_CAC) - string(REPLACE "/MD" "/MT" "CMAKE_C_FLAGS_RELEASE" "${CMAKE_C_FLAGS_RELEASE}") string(REPLACE "/Ob2" "/Ob1" "CMAKE_C_FLAGS_RELEASE" "${CMAKE_C_FLAGS_RELEASE}") - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Oi /Gy /GL") - set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /OPT:ICF /OPT:REF /LTCG /DELAYLOAD:webauthn.dll") - set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG") + string(REPLACE "/Ob2" "/Ob1" "CMAKE_CXX_FLAGS_RELEASE" "${CMAKE_CXX_FLAGS_RELEASE}") + string(REPLACE "/MD" "/MT" "CMAKE_C_FLAGS_RELEASE" "${CMAKE_C_FLAGS_RELEASE}") + string(REPLACE "/MD" "/MT" "CMAKE_CXX_FLAGS_RELEASE" "${CMAKE_CXX_FLAGS_RELEASE}") string(REPLACE "/MD" "/MT" "CMAKE_STATIC_LINKER_FLAGS_RELEASE" "${CMAKE_STATIC_LINKER_FLAGS_RELEASE}") string(REPLACE "/INCREMENTAL:NO" "" "CMAKE_STATIC_LINKER_FLAGS_RELEASE" "${CMAKE_STATIC_LINKER_FLAGS_RELEASE}") + string(REPLACE "/INCREMENTAL:NO" "" "CMAKE_EXE_LINKER_FLAGS_RELEASE" "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") + string(REPLACE "/INCREMENTAL:NO" "" "CMAKE_SHARED_LINKER_FLAGS_RELEASE" "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") + string(REPLACE "/DNDEBUG" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") + string(REPLACE "-DNDEBUG" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Oi /Gy /GL") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Oi /Gy /GL") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4244 /wd4267 /wd4018 /wd4146 /wd4293 /wd4090") + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /OPT:ICF /OPT:REF /LTCG /DELAYLOAD:webauthn.dll") + set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG") endif() \ No newline at end of file diff --git a/code/config.c b/code/config.c index 7909141c..5f5c6716 100644 --- a/code/config.c +++ b/code/config.c @@ -828,7 +828,7 @@ void cert_event_handler(union control* ctrl, dlgparam* dlg, void* data, int even // handle capi certificate set button press if (ctrl == certd->cert_set_capi_button && event == EVENT_ACTION) { - char* szCert = cert_prompt(IDEN_CAPI, NULL, FALSE, NULL); + char* szCert = cert_prompt(IDEN_CAPI, FALSE, NULL); if (szCert == NULL) return; conf_set_str(conf, CONF_cert_fingerprint, szCert); conf_set_bool(conf, CONF_cert_attempt_auth, 1); @@ -840,7 +840,7 @@ void cert_event_handler(union control* ctrl, dlgparam* dlg, void* data, int even // handle pkcs certificate set button press if (ctrl == certd->cert_set_pkcs_button && event == EVENT_ACTION) { - char* szCert = cert_prompt(IDEN_PKCS, NULL, FALSE, NULL); + char* szCert = cert_prompt(IDEN_PKCS, FALSE, NULL); if (szCert == NULL) return; conf_set_str(conf, CONF_cert_fingerprint, szCert); conf_set_bool(conf, CONF_cert_attempt_auth, 1); @@ -853,7 +853,7 @@ void cert_event_handler(union control* ctrl, dlgparam* dlg, void* data, int even // handle fido certificate set button press if (ctrl == certd->cert_set_fido_button && event == EVENT_ACTION) { - char* szCert = cert_prompt(IDEN_FIDO, NULL, FALSE, NULL); + char* szCert = cert_prompt(IDEN_FIDO, FALSE, NULL); if (szCert == NULL) return; conf_set_str(conf, CONF_cert_fingerprint, szCert); conf_set_bool(conf, CONF_cert_attempt_auth, 1); @@ -936,7 +936,7 @@ void fido_event_handler(union control* ctrl, dlgparam* dlg, void* data, int even { // alert user of success and ask about assignment if (MessageBoxW(NULL, L"FIDO key creation was successful and has been added to the FIDO cache. " \ - L"Do you want to assign the new key to the current session configuration?", + L"Do you want to assign the new key to the current session?", L"FIDO Key Creation Successful", MB_SYSTEMMODAL | MB_ICONQUESTION | MB_YESNO) == IDYES) { char* szCert = dupprintf("FIDO:%s", szAppId); @@ -956,7 +956,7 @@ void fido_event_handler(union control* ctrl, dlgparam* dlg, void* data, int even // handle fido key delete button press if (ctrl == fidod->fido_delete_key_button && event == EVENT_ACTION) { - char* szCert = cert_prompt(IDEN_FIDO, NULL, FALSE, + char* szCert = cert_prompt(IDEN_FIDO, FALSE, L"Select a FIDO key to remove. If this is a resident key, it will also " \ L"be deleted from the token."); if (szCert == NULL) return; @@ -1062,11 +1062,17 @@ void capi_event_handler(union control* ctrl, dlgparam* dlg, void* data, int even } // attempt to create certificate - if (cert_capi_create_key(szAlgId, szSubjectName, bHardwareToken)) + char* szCert = cert_capi_create_key(szAlgId, szSubjectName, bHardwareToken); + if (szCert != NULL) { - MessageBoxW(NULL, L"Certificate was successfully created. It should now be " \ - L"selectable in PuTTY if your filtering allows self-signed certificates.", - L"CAPI Certificate Creation Successful", MB_SYSTEMMODAL | MB_ICONINFORMATION); + if (MessageBoxW(NULL, L"Certificate was successfully created. " \ + L"Do you want to assign the new certificate to the current session?", + L"CAPI Certificate Creation Successful", MB_SYSTEMMODAL | MB_ICONQUESTION | MB_YESNO) == IDYES) + { + conf_set_str(conf, CONF_cert_fingerprint, szCert); + conf_set_bool(conf, CONF_cert_attempt_auth, 1); + } + sfree(szCert); } else { @@ -1083,7 +1089,7 @@ void capi_event_handler(union control* ctrl, dlgparam* dlg, void* data, int even // handle capi key delete button press if (ctrl == capid->capi_delete_key_button && event == EVENT_ACTION) { - char* szCert = cert_prompt(IDEN_CAPI, NULL, FALSE, + char* szCert = cert_prompt(IDEN_CAPI, FALSE, L"Select a CAPI key to remove. If this key on a smart card or token, " \ L"PuTTY will attempt to delete it from there as well."); if (szCert == NULL) return; diff --git a/code/pageant.c b/code/pageant.c index d70cf7e2..c555fba2 100644 --- a/code/pageant.c +++ b/code/pageant.c @@ -944,7 +944,8 @@ static PageantAsyncOp *pageant_make_op( char * search = dupprintf("%.*s", (int) t.len, t.ptr); if (cert_is_certpath(search)) { - key = cert_load_key(search, NULL); + ssh2_userkey * newkey = cert_load_key(search); + if (newkey == NULL) continue; else key = newkey; BinarySource_REWIND_TO(msg, ((char *) t.ptr - (char*) msg->data) - 4); sfree(search); break; diff --git a/code/sshpubk.c b/code/sshpubk.c index e13f8e2a..f1c3503d 100644 --- a/code/sshpubk.c +++ b/code/sshpubk.c @@ -1003,7 +1003,7 @@ ssh2_userkey *ppk_load_f(const Filename *filename, const char *passphrase, { #ifdef PUTTY_CAC if (cert_is_certpath(filename->path)) { - ssh2_userkey* ret = cert_load_key(filename->path, NULL); + ssh2_userkey* ret = cert_load_key(filename->path); if (ret == NULL) { *errorstr = "load key from certificate failed"; } @@ -1323,7 +1323,7 @@ bool ppk_loadpub_f(const Filename *filename, char **algorithm, BinarySink *bs, #ifdef PUTTY_CAC cert_convert_legacy(filename->path); if (cert_is_certpath(filename->path)) { - struct ssh2_userkey* userkey = cert_load_key(filename->path, NULL); + struct ssh2_userkey* userkey = cert_load_key(filename->path); if (userkey == NULL || userkey->key == NULL) { *errorstr = "load key from certificate failed"; return false; diff --git a/code/version.h b/code/version.h index 5f095caa..9b63082b 100644 --- a/code/version.h +++ b/code/version.h @@ -1,6 +1,6 @@ /* Generated by automated build script */ -#define RELEASE 0.77 -#define TEXTVER "Release 0.77" -#define SSHVER "-Release-0.77" -#define BINARY_VERSION 0,77,0,0 +#define RELEASE 0.77-1 +#define TEXTVER "Release 0.77-1" +#define SSHVER "-Release-0.77-1" +#define BINARY_VERSION 0,77,0,1 #define SOURCE_COMMIT "See https://github.com/NoMoreFood/putty-cac" diff --git a/code/windows/CMakeLists.txt b/code/windows/CMakeLists.txt index 01213bff..a12959fa 100644 --- a/code/windows/CMakeLists.txt +++ b/code/windows/CMakeLists.txt @@ -192,9 +192,10 @@ target_include_directories(testcrypt PUBLIC ../cert) target_include_directories(puttygen PUBLIC ../cert) add_sources_from_current_dir(crypto ../cert/cert_common.c -../cert/cert_pkcs.c ../cert/cert_capi.c -../cert/cert_fido.c) +../cert/cert_capi_tools.cc +../cert/cert_fido.c +../cert/cert_pkcs.c) add_executable(puttyimp puttyimp.c puttyimp.rc) diff --git a/code/windows/pageant.c b/code/windows/pageant.c index efbafc6c..68fcd82f 100644 --- a/code/windows/pageant.c +++ b/code/windows/pageant.c @@ -713,7 +713,7 @@ static INT_PTR CALLBACK KeyListProc(HWND hwnd, UINT msg, char * szCert = cert_prompt( (LOWORD(wParam) == IDC_KEYLIST_ADD_CAPI) ? IDEN_CAPI : (LOWORD(wParam) == IDC_KEYLIST_ADD_PKCS) ? IDEN_PKCS : - (LOWORD(wParam) == IDC_KEYLIST_ADD_FIDO) ? IDEN_FIDO : 0, hwnd, FALSE, NULL); + (LOWORD(wParam) == IDC_KEYLIST_ADD_FIDO) ? IDEN_FIDO : 0, FALSE, NULL); if (szCert == NULL) return 0; Filename *fn = filename_from_str(szCert); char *err = NULL; @@ -1400,7 +1400,7 @@ static LRESULT CALLBACK TrayWndProc(HWND hwnd, UINT message, char* szCert = cert_prompt( ((wParam & ~0xF) == IDM_ADDCAPI) ? IDEN_CAPI : ((wParam & ~0xF) == IDM_ADDPKCS) ? IDEN_PKCS : - ((wParam & ~0xF) == IDM_ADDFIDO) ? IDEN_FIDO : NULL, hwnd, FALSE, NULL); + ((wParam & ~0xF) == IDM_ADDFIDO) ? IDEN_FIDO : NULL, FALSE, NULL); if (szCert == NULL) break; Filename* fn = filename_from_str(szCert); char* err = NULL; diff --git a/packager/build.cmd b/packager/build.cmd index e9d87e7e..0da9e215 100644 --- a/packager/build.cmd +++ b/packager/build.cmd @@ -2,8 +2,8 @@ TITLE Building PuTTY-CAC :: version information -SET VER=0.77 -SET VERN=0.77.0.0 +SET VER=0.77u1 +SET VERN=0.77.0.1 :: setup environment variables based on location of this script SET INSTDIR=%~dp0 @@ -26,11 +26,11 @@ CALL "%VS%" CD /D "%INSTDIR%" RD /S /Q "%BLDDIR%" RD /S /Q "%BINDIR%" -CMAKE -S ..\code -A x64 -B %BLDDIR%\x64 -D PUTTY_CAC=1 +CMAKE -S ..\code -A x64 -B %BLDDIR%\x64 -D PUTTY_CAC=1 -D PUTTY_EMBEDDED_CHM_FILE=%BASEDIR%\doc\putty.chm CMAKE --build %BLDDIR%\x64 --parallel --config Release --target pageant plink pscp psftp pterm putty puttygen puttyimp puttytel MKDIR "%BINDIR%\x64" COPY /Y %BLDDIR%\x64\Release\*.exe "%BINDIR%\x64" -CMAKE -S ..\code -A Win32 -B %BLDDIR%\x86 -D PUTTY_CAC=1 +CMAKE -S ..\code -A Win32 -B %BLDDIR%\x86 -D PUTTY_CAC=1 -D PUTTY_EMBEDDED_CHM_FILE=%BASEDIR%\doc\putty.chm CMAKE --build %BLDDIR%\x86 --parallel --config Release --target pageant plink pscp psftp pterm putty puttygen puttyimp puttytel MKDIR "%BINDIR%\x86" COPY /Y %BLDDIR%\x86\Release\*.exe "%BINDIR%\x86" @@ -90,9 +90,9 @@ POPD :: output hash information SET HASHFILE=%BINDIR%\puttycac-hash.txt IF EXIST "%HASHFILE%" DEL /F "%HASHFILE%" -POWERSHELL -NoProfile -NonInteractive -NoLogo -Command "Get-ChildItem -Include @('*.msi','*.exe','*.zip') -Path '%BINDIR%' -Recurse | Get-FileHash -Algorithm SHA256 | Out-File -Append '%HASHFILE%' -Width 256" -POWERSHELL -NoProfile -NonInteractive -NoLogo -Command "Get-ChildItem -Include @('*.msi','*.exe','*.zip') -Path '%BINDIR%' -Recurse | Get-FileHash -Algorithm SHA1 | Out-File -Append '%HASHFILE%' -Width 256" -POWERSHELL -NoProfile -NonInteractive -NoLogo -Command "Get-ChildItem -Include @('*.msi','*.exe','*.zip') -Path '%BINDIR%' -Recurse | Get-FileHash -Algorithm MD5 | Out-File -Append '%HASHFILE%' -Width 256" -POWERSHELL -NoProfile -NonInteractive -NoLogo -Command "$Data = Get-Content '%HASHFILE%'; $Data.Replace((Get-Item -LiteralPath '%BINDIR%').FullName + '\','').Trim() | Set-Content '%HASHFILE%'" +%POWERSHELL% -Command "Get-ChildItem -Include @('*.msi','*.exe','*.zip') -Path '%BINDIR%' -Recurse | Get-FileHash -Algorithm SHA256 | Out-File -Append '%HASHFILE%' -Width 256" +%POWERSHELL% -Command "Get-ChildItem -Include @('*.msi','*.exe','*.zip') -Path '%BINDIR%' -Recurse | Get-FileHash -Algorithm SHA1 | Out-File -Append '%HASHFILE%' -Width 256" +%POWERSHELL% -NoProfile -NonInteractive -NoLogo -Command "Get-ChildItem -Include @('*.msi','*.exe','*.zip') -Path '%BINDIR%' -Recurse | Get-FileHash -Algorithm MD5 | Out-File -Append '%HASHFILE%' -Width 256" +%POWERSHELL% -NoProfile -NonInteractive -NoLogo -Command "$Data = Get-Content '%HASHFILE%'; $Data.Replace((Get-Item -LiteralPath '%BINDIR%').FullName + '\','').Trim() | Set-Content '%HASHFILE%'" PAUSE \ No newline at end of file diff --git a/packager/winget/NoMoreFood.PuTTY-CAC.installer.yaml b/packager/winget/NoMoreFood.PuTTY-CAC.installer.yaml index 2da531ba..8e03d427 100644 --- a/packager/winget/NoMoreFood.PuTTY-CAC.installer.yaml +++ b/packager/winget/NoMoreFood.PuTTY-CAC.installer.yaml @@ -1,5 +1,5 @@ PackageIdentifier: NoMoreFood.PuTTY-CAC -PackageVersion: 0.77.0.0 +PackageVersion: 0.77.0.1 Platform: - Windows.Desktop MinimumOSVersion: 10.0.0.0 @@ -14,17 +14,17 @@ Installers: Architecture: x64 InstallerType: msi Scope: machine - InstallerUrl: https://github.com/NoMoreFood/putty-cac/raw/0.77/binaries/puttycac-64bit-0.77-installer.msi - InstallerSha256: 0F19075A9B2F2021921D339C6EF864AA2AF51AF4378D23307E280DEB8B89135D + InstallerUrl: https://github.com/NoMoreFood/putty-cac/raw/0.77u1/binaries/puttycac-64bit-0.77u1-installer.msi + InstallerSha256: 48076176FA7D09A0A7EB51D541B736A632FFE6A709A7DF388B95398F0D8284ED UpgradeBehavior: install - ProductCode: '{25A8DBAF-1AEF-4FE3-A67E-BD7C2371287D}' + ProductCode: '{A8124469-BB62-4B6E-8BFF-44287B10E895}' - InstallerLocale: en-US Architecture: x86 InstallerType: msi Scope: machine - InstallerUrl: https://github.com/NoMoreFood/putty-cac/raw/0.77/binaries/puttycac-0.77-installer.msi - InstallerSha256: E334061768E4D6C425AB9E25EF0862B317E4B88E5C3936AA627C810C83BE17C1 + InstallerUrl: https://github.com/NoMoreFood/putty-cac/raw/0.77u1/binaries/puttycac-0.77u1-installer.msi + InstallerSha256: 907F201234DE8906276B0EEB9A2CD8363FB64047F0607046D6C45EF12AED8F7E UpgradeBehavior: install - ProductCode: '{BCC3136A-77A0-447C-A7C4-475170C92CE9}' + ProductCode: '{484F141E-A0FA-4916-9E21-4101B28915DE}' ManifestType: installer ManifestVersion: 1.1.0 \ No newline at end of file diff --git a/packager/winget/NoMoreFood.PuTTY-CAC.locale.en-US.yaml b/packager/winget/NoMoreFood.PuTTY-CAC.locale.en-US.yaml index a0db191a..9c5b097b 100644 --- a/packager/winget/NoMoreFood.PuTTY-CAC.locale.en-US.yaml +++ b/packager/winget/NoMoreFood.PuTTY-CAC.locale.en-US.yaml @@ -1,5 +1,5 @@ PackageIdentifier: NoMoreFood.PuTTY-CAC -PackageVersion: 0.77.0.0 +PackageVersion: 0.77.0.1 PackageLocale: en-US Publisher: Simon Tatham PublisherUrl: https://github.com/NoMoreFood diff --git a/packager/winget/NoMoreFood.PuTTY-CAC.yaml b/packager/winget/NoMoreFood.PuTTY-CAC.yaml index c42e2f9b..8d1834ec 100644 --- a/packager/winget/NoMoreFood.PuTTY-CAC.yaml +++ b/packager/winget/NoMoreFood.PuTTY-CAC.yaml @@ -1,5 +1,5 @@ PackageIdentifier: NoMoreFood.PuTTY-CAC -PackageVersion: 0.77.0.0 +PackageVersion: 0.77.0.1 DefaultLocale: en-US ManifestType: version ManifestVersion: 1.1.0 \ No newline at end of file diff --git a/tools/ExampleCertCreator.ps1 b/tools/ExampleCertCreator.ps1 index d71090d7..ccb6314f 100644 --- a/tools/ExampleCertCreator.ps1 +++ b/tools/ExampleCertCreator.ps1 @@ -23,7 +23,7 @@ ForEach ($KeyProvider in $KeyProviders.Keys) -FriendlyName "$KeyProviderAbbr RSA $KeyLength" -Subject "CN=$KeyProviderAbbr RSA $KeyLength" -ErrorAction SilentlyContinue } - If ($KeyProviderAbbr -notmatch 'CNG') { Continue } + If ($KeyProviderAbbr -ne 'CNG') { Continue } $AlgTypes = @('ECDSA_nistP256','ECDSA_nistP384','ECDSA_nistP521') ForEach ($AlgType in $AlgTypes) {