Enable support for FIDO2/U2F security keys (#541)

This commit is contained in:
pedro martelletto 2021-12-18 03:30:25 +01:00 committed by GitHub
parent 991465e079
commit 4cd1fd1dc0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 851 additions and 21 deletions

1
.gitignore vendored
View File

@ -46,6 +46,7 @@ tags
/config.h
/contrib/win32/openssh/LibreSSL
/contrib/win32/openssh/ZLib
/contrib/win32/openssh/libfido2
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.

View File

@ -0,0 +1,63 @@
param (
[string] $paths_target_file_path,
[string] $destDir,
[switch] $override
)
# Workaround that $PSScriptRoot is not support on ps version 2
If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path}
if([string]::IsNullOrEmpty($paths_target_file_path))
{
$paths_target_file_path = Join-Path $PSScriptRoot "paths.targets"
}
if([string]::IsNullOrEmpty($destDir))
{
$destDir = $PSScriptRoot
}
if($override)
{
Remove-Item (join-path $destDir "libfido2") -Recurse -Force -ErrorAction SilentlyContinue
}
elseif (Test-Path (Join-Path $destDir "libfido2") -PathType Container)
{
return
}
[xml] $buildConfig = Get-Content $paths_target_file_path
$version = $buildConfig.Project.PropertyGroup.fido2Version
Write-Host "Downloading libfido2 version:$version"
Write-Host "paths_target_file_path:$paths_target_file_path"
Write-Host "destDir:$destDir"
Write-Host "override:$override"
$zip_path = Join-Path $PSScriptRoot "libfido2.zip"
$release_url = "https://ambientworks.net/tmp/libfido2-1.10-b32020cc-win.zip"
Write-Host "release_url:$release_url"
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor `
[Net.SecurityProtocolType]::Tls11 -bor `
[Net.SecurityProtocolType]::Tls
Remove-Item $zip_path -Force -ErrorAction SilentlyContinue
Invoke-WebRequest -Uri $release_url -OutFile $zip_path -UseBasicParsing
if(-not (Test-Path $zip_path))
{
throw "failed to download libfido2 version:$version"
}
# XXX check pgp sig?
Expand-Archive -Path $zip_path -DestinationPath $destDir -Force -ErrorAction SilentlyContinue -ErrorVariable e
if($e -ne $null)
{
throw "Error when expand zip file. libfido2 version:$version"
}
Rename-Item -Path $destDir\libfido2-1.10-b32020cc-win -NewName libfido2
Remove-Item $zip_path -Force -ErrorAction SilentlyContinue
Write-Host "Succesfully downloaded libfido2 version:$version"

View File

@ -370,7 +370,7 @@ function Start-OpenSSHPackage
$buildDir = Join-Path $repositoryRoot ("bin\" + $folderName + "\" + $Configuration)
$payload = "sshd.exe", "ssh.exe", "ssh-agent.exe", "ssh-add.exe", "sftp.exe"
$payload += "sftp-server.exe", "scp.exe", "ssh-shellhost.exe", "ssh-keygen.exe", "ssh-keyscan.exe"
$payload += "sftp-server.exe", "scp.exe", "ssh-shellhost.exe", "ssh-keygen.exe", "ssh-keyscan.exe", "ssh-sk-helper.exe"
$payload += "sshd_config_default", "install-sshd.ps1", "uninstall-sshd.ps1"
$payload += "FixHostFilePermissions.ps1", "FixUserFilePermissions.ps1", "OpenSSHUtils.psm1", "OpenSSHUtils.psd1"
$payload += "openssh-events.man", "moduli", "LICENSE.txt"

View File

@ -10,3 +10,53 @@ OpenSSH-Lib-Path = The directory path of the location to which libra
LibreSSL-x86-Path = The directory path of LibreSSL statically compiled for x86 platform.
LibreSSL-x64-Path = The directory path of LibreSSL statically compiled for x64 platform.
Notes on FIDO2 support
----------------------
* How to build:
- Open Windows PowerShell.
- Build OpenSSH for Windows:
$ cd \path\to\openssh-portable\..
$ .\openssh-portable\contrib\win32\openssh\OpenSSH-build.ps1
* What has been tested:
* Using a Yubico Security Key.
- Create a new SSH key:
$ ssh-keygen.exe -t ecdsa-sk
* Save the key material in SSH's default paths without an associated passphrase.
- Add the SSH key to your GitHub account.
- Tell git to use our SSH build:
$ $Env:GIT_SSH = '\path\to\ssh.exe'
- Clone a repository using the SSH key for authentication:
$ git clone ssh://git@github.com/org/some-private-repo
* WSL2:
- Export GIT_SSH:
$ export GIT_SSH=/mnt/c/.../path/to/ssh.exe
- Optionally, alias ssh:
$ alias ssh=/mnt/c/.../path/to/ssh.exe
* Note: FIDO2 keys are supported by ssh-agent.
* What definitely doesn't work:
* ssh-keygen -O no-touch-required:
- there does not appear to be a way to toggle user presence in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS.
* ssh-keygen -K, ssh-add -K:
- these use Credential Management to reconstruct the SSH private key.

View File

@ -156,6 +156,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ssh-keyscan", "ssh-keyscan.
{0D02F0F0-013B-4EE3-906D-86517F3822C0} = {0D02F0F0-013B-4EE3-906D-86517F3822C0}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ssh-sk-helper", "ssh-sk-helper.vcxproj", "{7D0A75FC-F366-4B60-B72F-B37C3EA07CCB}"
ProjectSection(ProjectDependencies) = postProject
{05E1115F-8529-46D0-AAAF-52A404CE79A7} = {05E1115F-8529-46D0-AAAF-52A404CE79A7}
{8F9D3B74-8D33-448E-9762-26E8DCC6B2F4} = {8F9D3B74-8D33-448E-9762-26E8DCC6B2F4}
{DD483F7D-C553-4740-BC1A-903805AD0174} = {DD483F7D-C553-4740-BC1A-903805AD0174}
{0D02F0F0-013B-4EE3-906D-86517F3822C0} = {0D02F0F0-013B-4EE3-906D-86517F3822C0}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
@ -504,6 +512,22 @@ Global
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCA}.Release|x64.Build.0 = Release|x64
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCA}.Release|x86.ActiveCfg = Release|Win32
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCA}.Release|x86.Build.0 = Release|Win32
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCB}.Debug|ARM.ActiveCfg = Debug|ARM
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCB}.Debug|ARM.Build.0 = Debug|ARM
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCB}.Debug|ARM64.ActiveCfg = Debug|ARM64
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCB}.Debug|ARM64.Build.0 = Debug|ARM64
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCB}.Debug|x64.ActiveCfg = Debug|x64
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCB}.Debug|x64.Build.0 = Debug|x64
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCB}.Debug|x86.ActiveCfg = Debug|Win32
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCB}.Debug|x86.Build.0 = Debug|Win32
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCB}.Release|ARM.ActiveCfg = Release|ARM
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCB}.Release|ARM.Build.0 = Release|ARM
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCB}.Release|ARM64.ActiveCfg = Release|ARM64
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCB}.Release|ARM64.Build.0 = Release|ARM64
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCB}.Release|x64.ActiveCfg = Release|x64
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCB}.Release|x64.Build.0 = Release|x64
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCB}.Release|x86.ActiveCfg = Release|Win32
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCB}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -530,6 +554,7 @@ Global
{FC568FF0-60F2-4B2E-AF62-FD392EDBA1B9} = {A8096E32-E084-4FA0-AE01-A8D909EB2BB4}
{484A8CDE-B949-4BDA-B447-74685C8E032F} = {A8096E32-E084-4FA0-AE01-A8D909EB2BB4}
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCA} = {17322AAF-808F-4646-AD37-5B0EDDCB8F3E}
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCB} = {17322AAF-808F-4646-AD37-5B0EDDCB8F3E}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0AC224E8-C215-4270-954A-A2ACEE06DE58}

View File

@ -137,6 +137,19 @@
/* Enable for PKCS#11 support */
#define ENABLE_PKCS11 1
/* Enable for U2F/FIDO support */
#define ENABLE_SK
/* Enable for built-in U2F/FIDO support */
#define ENABLE_SK_INTERNAL
/* Define for discoverable credential support */
#define HAVE_FIDO_CRED_PROT
#define HAVE_FIDO_CRED_SET_PROT
#define HAVE_FIDO_DEV_SUPPORTS_CRED_PROT
#define HAVE_FIDO_DEV_GET_TOUCH_BEGIN
#define HAVE_FIDO_DEV_GET_TOUCH_STATUS
/* File names may not contain backslash characters */
/* #undef FILESYSTEM_NO_BACKSLASH */
@ -1715,4 +1728,4 @@
#define HAVE_LOCALTIME_R
#define HAVE_DECL_MEMMEM 0
#define WITH_ZLIB
#define _PATH_TTY "conin$"
#define _PATH_TTY "conin$"

View File

@ -187,6 +187,7 @@
</Link>
<PreBuildEvent>
<Command>powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)config.ps1" -Config_h_vs "$(SolutionDir)config.h.vs" -Config_h "$(OpenSSH-Src-Path)config.h" -VCIncludePath "$(VC_IncludePath)" -OutCRTHeader "$(OpenSSH-Src-Path)contrib\win32\win32compat\inc\crtheaders.h"
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetFIDO2.ps1
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetLibreSSL.ps1
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetZlib.ps1"</Command>
</PreBuildEvent>
@ -224,6 +225,7 @@ copy /Y "$(SolutionDir)openssh-events.man" "$(OutDir)"</Command>
</Link>
<PreBuildEvent>
<Command>powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)config.ps1" -Config_h_vs "$(SolutionDir)config.h.vs" -Config_h "$(OpenSSH-Src-Path)config.h" -VCIncludePath "$(VC_IncludePath)" -OutCRTHeader "$(OpenSSH-Src-Path)contrib\win32\win32compat\inc\crtheaders.h"
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetFIDO2.ps1
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetLibreSSL.ps1
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetZlib.ps1"</Command>
</PreBuildEvent>
@ -261,6 +263,7 @@ copy /Y "$(SolutionDir)openssh-events.man" "$(OutDir)"</Command>
</Link>
<PreBuildEvent>
<Command>powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)config.ps1" -Config_h_vs "$(SolutionDir)config.h.vs" -Config_h "$(OpenSSH-Src-Path)config.h" -VCIncludePath "$(VC_IncludePath)" -OutCRTHeader "$(OpenSSH-Src-Path)contrib\win32\win32compat\inc\crtheaders.h"
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetFIDO2.ps1
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetLibreSSL.ps1
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetZlib.ps1"</Command>
</PreBuildEvent>
@ -298,6 +301,7 @@ copy /Y "$(SolutionDir)openssh-events.man" "$(OutDir)"</Command>
</Link>
<PreBuildEvent>
<Command>powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)config.ps1" -Config_h_vs "$(SolutionDir)config.h.vs" -Config_h "$(OpenSSH-Src-Path)config.h" -VCIncludePath "$(VC_IncludePath)" -OutCRTHeader "$(OpenSSH-Src-Path)contrib\win32\win32compat\inc\crtheaders.h"
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetFIDO2.ps1
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetLibreSSL.ps1
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetZlib.ps1"</Command>
</PreBuildEvent>
@ -339,6 +343,7 @@ copy /Y "$(SolutionDir)openssh-events.man" "$(OutDir)"</Command>
</Link>
<PreBuildEvent>
<Command>powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)config.ps1" -Config_h_vs "$(SolutionDir)config.h.vs" -Config_h "$(OpenSSH-Src-Path)config.h" -VCIncludePath "$(VC_IncludePath)" -OutCRTHeader "$(OpenSSH-Src-Path)contrib\win32\win32compat\inc\crtheaders.h"
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetFIDO2.ps1
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetLibreSSL.ps1
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetZlib.ps1"</Command>
</PreBuildEvent>
@ -380,6 +385,7 @@ copy /Y "$(SolutionDir)openssh-events.man" "$(OutDir)"</Command>
</Link>
<PreBuildEvent>
<Command>powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)config.ps1" -Config_h_vs "$(SolutionDir)config.h.vs" -Config_h "$(OpenSSH-Src-Path)config.h" -VCIncludePath "$(VC_IncludePath)" -OutCRTHeader "$(OpenSSH-Src-Path)contrib\win32\win32compat\inc\crtheaders.h"
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetFIDO2.ps1
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetLibreSSL.ps1
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetZlib.ps1"</Command>
</PreBuildEvent>
@ -421,6 +427,7 @@ copy /Y "$(SolutionDir)openssh-events.man" "$(OutDir)"</Command>
</Link>
<PreBuildEvent>
<Command>powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)config.ps1" -Config_h_vs "$(SolutionDir)config.h.vs" -Config_h "$(OpenSSH-Src-Path)config.h" -VCIncludePath "$(VC_IncludePath)" -OutCRTHeader "$(OpenSSH-Src-Path)contrib\win32\win32compat\inc\crtheaders.h"
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetFIDO2.ps1
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetLibreSSL.ps1
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetZlib.ps1"</Command>
</PreBuildEvent>
@ -462,6 +469,7 @@ copy /Y "$(SolutionDir)openssh-events.man" "$(OutDir)"</Command>
</Link>
<PreBuildEvent>
<Command>powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)config.ps1" -Config_h_vs "$(SolutionDir)config.h.vs" -Config_h "$(OpenSSH-Src-Path)config.h" -VCIncludePath "$(VC_IncludePath)" -OutCRTHeader "$(OpenSSH-Src-Path)contrib\win32\win32compat\inc\crtheaders.h"
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetFIDO2.ps1
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetLibreSSL.ps1
powershell.exe -Executionpolicy Bypass -File "$(SolutionDir)GetZlib.ps1"</Command>
</PreBuildEvent>
@ -486,4 +494,4 @@ copy /Y "$(SolutionDir)openssh-events.man" "$(OutDir)"</Command>
<Target Name="BeforeClean">
<Delete Files="$(OpenSSH-Src-Path)contrib\win32\win32compat\inc\crtheaders.h" />
</Target>
</Project>
</Project>

View File

@ -6,11 +6,17 @@
<OpenSSH-Lib-Path>$(SolutionDir)lib\</OpenSSH-Lib-Path>
<LibreSSLVersion>3.3.3.0</LibreSSLVersion>
<ZLibVersion>1.2.11</ZLibVersion>
<fido2Version>1.9.0</fido2Version>
<LibreSSL-Path>$(SolutionDir)\LibreSSL\sdk\</LibreSSL-Path>
<LibreSSL-x86-Path>$(SolutionDir)\LibreSSL\bin\desktop\x86\</LibreSSL-x86-Path>
<LibreSSL-x64-Path>$(SolutionDir)\LibreSSL\bin\desktop\x64\</LibreSSL-x64-Path>
<LibreSSL-arm64-Path>$(SolutionDir)\LibreSSL\bin\desktop\arm64\</LibreSSL-arm64-Path>
<LibreSSL-arm-Path>$(SolutionDir)\LibreSSL\bin\desktop\arm\</LibreSSL-arm-Path>
<fido2-Path>$(SolutionDir)\libfido2\</fido2-Path>
<fido2-x86-Path>$(SolutionDir)\libfido2\Win32\Release\v143\static\</fido2-x86-Path>
<fido2-x64-Path>$(SolutionDir)\libfido2\Win64\Release\v143\static\</fido2-x64-Path>
<fido2-arm64-Path>$(SolutionDir)\libfido2\ARM64\Release\v143\static\</fido2-arm64-Path>
<fido2-arm-Path>$(SolutionDir)\libfido2\ARM\Release\v143\static\</fido2-arm-Path>
<ZLib-Path>$(SolutionDir)\ZLib\sdk\</ZLib-Path>
<ZLib-x86-Path>$(SolutionDir)\ZLib\bin\x86\</ZLib-x86-Path>
<ZLib-x64-Path>$(SolutionDir)\ZLib\bin\x64\</ZLib-x64-Path>
@ -22,4 +28,4 @@
<AdditionalDependentLibs>bcrypt.lib;Userenv.lib;Crypt32.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Netapi32.lib;Rpcrt4.lib;ntdll.lib</AdditionalDependentLibs>
<MinimalCoreWin>false</MinimalCoreWin>
</PropertyGroup>
</Project>
</Project>

View File

@ -0,0 +1,409 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="paths.targets" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{7D0A75FC-F366-4B60-B72F-B37C3EA07CCB}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>sshskhelper</RootNamespace>
<WindowsTargetPlatformVersion>$(WindowsSDKVersion)</WindowsTargetPlatformVersion>
<ProjectName>ssh-sk-helper</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\$(TargetName)\</IntDir>
<IncludePath>$(fido2-Path)include;$(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\$(TargetName)\</IntDir>
<IncludePath>$(fido2-Path)include;$(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\$(TargetName)\</IntDir>
<IncludePath>$(fido2-Path)include;$(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\$(TargetName)\</IntDir>
<IncludePath>$(fido2-Path)include;$(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\$(TargetName)\</IntDir>
<IncludePath>$(fido2-Path)include;$(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\$(TargetName)\</IntDir>
<IncludePath>$(fido2-Path)include;$(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\$(TargetName)\</IntDir>
<IncludePath>$(fido2-Path)include;$(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\$(TargetName)\</IntDir>
<IncludePath>$(fido2-Path)include;$(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level1</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_WIN32_WINNT=0x600;WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir);$(LibreSSL-Path)include;$(ZLib-Path);$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<ControlFlowGuard>Guard</ControlFlowGuard>
<AdditionalOptions>/Gy %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>posix_compat.lib;libssh.lib;openbsd_compat.lib;zlib.lib;fido2.lib;cbor.lib;setupapi.lib;hid.lib;$(SSLLib)$(AdditionalDependentLibs);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-x86-Path);$(ZLib-x86-Path);$(fido2-x86-Path);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<EntryPointSymbol>wmainCRTStartup</EntryPointSymbol>
<AdditionalOptions>/debug /debugtype:cv,fixup /opt:ref /opt:icf /incremental:no /ignore:4099 /ignore:4098 %(AdditionalOptions)</AdditionalOptions>
</Link>
<Manifest>
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level1</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_WIN32_WINNT=0x600;WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir);$(LibreSSL-Path)include;$(ZLib-Path);$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<ControlFlowGuard>Guard</ControlFlowGuard>
<AdditionalOptions>/Gy %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>posix_compat.lib;libssh.lib;openbsd_compat.lib;zlib.lib;fido2.lib;cbor.lib;setupapi.lib;hid.lib;$(SSLLib)$(AdditionalDependentLibs);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-x64-Path);$(ZLib-x64-Path);$(fido2-x64-Path);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<EntryPointSymbol>wmainCRTStartup</EntryPointSymbol>
<AdditionalOptions>/debug /debugtype:cv,fixup /opt:ref /opt:icf /incremental:no /ignore:4099 /ignore:4098 %(AdditionalOptions)</AdditionalOptions>
</Link>
<Manifest>
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level1</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_WIN32_WINNT=0x600;WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir);$(LibreSSL-Path)include;$(ZLib-Path);$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<ControlFlowGuard>Guard</ControlFlowGuard>
<AdditionalOptions>/Gy %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>posix_compat.lib;libssh.lib;openbsd_compat.lib;zlib.lib;fido2.lib;cbor.lib;setupapi.lib;hid.lib;$(SSLLib)$(AdditionalDependentLibs);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-arm64-Path);$(ZLib-arm64-Path);$(fido2-arm64-Path);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<EntryPointSymbol>wmainCRTStartup</EntryPointSymbol>
<AdditionalOptions>/debug /debugtype:cv,fixup /opt:ref /opt:icf /incremental:no /ignore:4099 /ignore:4098 %(AdditionalOptions)</AdditionalOptions>
</Link>
<Manifest>
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level1</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_WIN32_WINNT=0x600;WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir);$(LibreSSL-Path)include;$(ZLib-Path);$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<ControlFlowGuard>Guard</ControlFlowGuard>
<AdditionalOptions>/Gy %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>posix_compat.lib;libssh.lib;openbsd_compat.lib;zlib.lib;fido2.lib;cbor.lib;setupapi.lib;hid.lib;$(SSLLib)$(AdditionalDependentLibs);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-arm-Path);$(ZLib-arm-Path);$(fido2-arm-Path);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<EntryPointSymbol>wmainCRTStartup</EntryPointSymbol>
<AdditionalOptions>/debug /debugtype:cv,fixup /opt:ref /opt:icf /incremental:no /ignore:4099 /ignore:4098 %(AdditionalOptions)</AdditionalOptions>
</Link>
<Manifest>
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level1</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_WIN32_WINNT=0x600;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir);$(LibreSSL-Path)include;$(ZLib-Path);$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ControlFlowGuard>Guard</ControlFlowGuard>
<AdditionalOptions>/Gy %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>posix_compat.lib;libssh.lib;openbsd_compat.lib;zlib.lib;fido2.lib;cbor.lib;setupapi.lib;hid.lib;$(SSLLib)$(AdditionalDependentLibs);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-x86-Path);$(ZLib-x86-Path);$(fido2-x86-Path);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<EntryPointSymbol>wmainCRTStartup</EntryPointSymbol>
<FullProgramDatabaseFile>true</FullProgramDatabaseFile>
<AdditionalOptions>/debug /debugtype:cv,fixup /opt:ref /opt:icf /incremental:no /ignore:4099 %(AdditionalOptions)</AdditionalOptions>
</Link>
<Manifest>
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level1</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_WIN32_WINNT=0x600;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir);$(LibreSSL-Path)include;$(ZLib-Path);$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WholeProgramOptimization>true</WholeProgramOptimization>
<ControlFlowGuard>Guard</ControlFlowGuard>
<AdditionalOptions>/Gy %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>posix_compat.lib;libssh.lib;openbsd_compat.lib;zlib.lib;fido2.lib;cbor.lib;setupapi.lib;hid.lib;$(SSLLib)$(AdditionalDependentLibs);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-x64-Path);$(ZLib-x64-Path);$(fido2-x64-Path);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<EntryPointSymbol>wmainCRTStartup</EntryPointSymbol>
<FullProgramDatabaseFile>true</FullProgramDatabaseFile>
<AdditionalOptions>/debug /debugtype:cv,fixup /opt:ref /opt:icf /incremental:no /ignore:4099 %(AdditionalOptions)</AdditionalOptions>
</Link>
<Manifest>
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<ClCompile>
<WarningLevel>Level1</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_WIN32_WINNT=0x600;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir);$(LibreSSL-Path)include;$(ZLib-Path);$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WholeProgramOptimization>true</WholeProgramOptimization>
<ControlFlowGuard>Guard</ControlFlowGuard>
<AdditionalOptions>/Gy %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>posix_compat.lib;libssh.lib;openbsd_compat.lib;zlib.lib;fido2.lib;cbor.lib;setupapi.lib;hid.lib;$(SSLLib)$(AdditionalDependentLibs);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-arm64-Path);$(ZLib-arm64-Path);$(fido2-arm64-Path);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<EntryPointSymbol>wmainCRTStartup</EntryPointSymbol>
<FullProgramDatabaseFile>true</FullProgramDatabaseFile>
<AdditionalOptions>/debug /debugtype:cv,fixup /opt:ref /opt:icf /incremental:no /ignore:4099 %(AdditionalOptions)</AdditionalOptions>
</Link>
<Manifest>
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<WarningLevel>Level1</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_WIN32_WINNT=0x600;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir);$(LibreSSL-Path)include;$(ZLib-Path);$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WholeProgramOptimization>true</WholeProgramOptimization>
<ControlFlowGuard>Guard</ControlFlowGuard>
<AdditionalOptions>/Gy %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>posix_compat.lib;libssh.lib;openbsd_compat.lib;zlib.lib;fido2.lib;cbor.lib;setupapi.lib;hid.lib;$(SSLLib)$(AdditionalDependentLibs);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-arm-Path);$(ZLib-arm-Path);$(fido2-arm-Path);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<EntryPointSymbol>wmainCRTStartup</EntryPointSymbol>
<FullProgramDatabaseFile>true</FullProgramDatabaseFile>
<AdditionalOptions>/debug /debugtype:cv,fixup /opt:ref /opt:icf /incremental:no /ignore:4099 %(AdditionalOptions)</AdditionalOptions>
</Link>
<Manifest>
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="$(OpenSSH-Src-Path)ssh-sk-helper.c" />
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c" />
<ClCompile Include="$(OpenSSH-Src-Path)ssh-sk.c" />
<ClCompile Include="$(OpenSSH-Src-Path)sk-usbhid.c">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OpenSSH-Src-Path)contrib\libfido2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="version.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -208,6 +208,7 @@ static int sign_blob(const struct sshkey *pubkey, u_char ** sig, size_t *siglen,
DWORD regdatalen = 0, keyblob_len = 0;
struct sshbuf* tmpbuf = NULL;
char *keyblob = NULL;
const char *sk_provider = NULL;
*sig = NULL;
*siglen = 0;
@ -230,8 +231,14 @@ static int sign_blob(const struct sshkey *pubkey, u_char ** sig, size_t *siglen,
else if (flags & SSH_AGENT_RSA_SHA2_512)
algo = "rsa-sha2-512";
if (sshkey_private_deserialize(tmpbuf, &prikey) != 0 ||
sshkey_sign(prikey, sig, siglen, blob, blen, algo, NULL, NULL, 0) != 0) {
if (sshkey_private_deserialize(tmpbuf, &prikey) != 0) {
debug("cannot deserialize key");
goto done;
}
if (sshkey_is_sk(prikey))
sk_provider = "internal";
if (sshkey_sign(prikey, sig, siglen, blob, blen, algo, sk_provider,
NULL, 0) != 0) {
debug("cannot sign using retrieved key");
goto done;
}
@ -472,4 +479,4 @@ int process_keyagent_request(struct sshbuf* request, struct sshbuf* response, st
}
}
#pragma warning(pop)
#pragma warning(pop)

View File

@ -136,8 +136,12 @@
/* Location of ssh-sk-helper to support keys in security keys */
#ifndef _PATH_SSH_SK_HELPER
#ifdef WINDOWS
#define _PATH_SSH_SK_HELPER "C:\\Windows\\System32\\OpenSSH\\ssh-sk-helper.exe"
#else
#define _PATH_SSH_SK_HELPER "/usr/libexec/ssh-sk-helper"
#endif
#endif
/* xauth for X11 forwarding */
#ifndef _PATH_XAUTH

View File

@ -686,7 +686,12 @@ sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len,
goto out;
}
*enroll_response = NULL;
#ifdef WINDOWS
/* Don't overwrite existing credentials on FIDO authenticators. */
arc4random_buf(user_id, sizeof(user_id));
#else
memset(user_id, 0, sizeof(user_id));
#endif
if (check_enroll_options(options, &device, user_id,
sizeof(user_id)) != 0)
goto out; /* error already logged */
@ -706,8 +711,15 @@ sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len,
}
if (device != NULL)
sk = sk_open(device);
else
else {
#ifdef WINDOWS
if ((sk = sk_open("windows://hello")) == NULL)
sk = sk_probe(NULL, NULL, 0);
#else
sk = sk_probe(NULL, NULL, 0);
#endif
}
if (sk == NULL) {
skdebug(__func__, "failed to find sk");
goto out;
@ -721,12 +733,31 @@ sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len,
skdebug(__func__, "fido_cred_set_type: %s", fido_strerr(r));
goto out;
}
if ((r = fido_cred_set_clientdata_hash(cred, challenge,
challenge_len)) != FIDO_OK) {
#ifndef WINDOWS
if (sha256_mem(challenge, challenge_len,
chall_hash, sizeof(chall_hash)) != 0) {
skdebug(__func__, "hash challenge failed");
goto out;
}
if ((r = fido_cred_set_clientdata_hash(cred, chall_hash,
sizeof(chall_hash))) != FIDO_OK) {
skdebug(__func__, "fido_cred_set_clientdata_hash: %s",
fido_strerr(r));
goto out;
}
#else
/*
* webauthn.dll (windows://hello in libfido2) requires the unhashed
* clientdata body, so we use fido_cred_set_clientdata() instead of
* fido_cred_set_clientdata_hash().
*/
if ((r = fido_cred_set_clientdata(cred, challenge,
challenge_len)) != FIDO_OK) {
skdebug(__func__, "fido_cred_set_clientdata: %s",
fido_strerr(r));
goto out;
}
#endif
if ((r = fido_cred_set_rk(cred, (flags & SSH_SK_RESIDENT_KEY) != 0 ?
FIDO_OPT_TRUE : FIDO_OPT_OMIT)) != FIDO_OK) {
skdebug(__func__, "fido_cred_set_rk: %s", fido_strerr(r));
@ -972,7 +1003,9 @@ sk_sign(uint32_t alg, const uint8_t *data, size_t datalen,
char *device = NULL;
struct sk_usbhid *sk = NULL;
struct sk_sign_response *response = NULL;
#ifndef WINDOWS
uint8_t message[32];
#endif
int ret = SSH_SK_ERR_GENERAL;
int r;
@ -985,17 +1018,33 @@ sk_sign(uint32_t alg, const uint8_t *data, size_t datalen,
*sign_response = NULL;
if (check_sign_load_resident_options(options, &device) != 0)
goto out; /* error already logged */
#ifndef WINDOWS
/* hash data to be signed before it goes to the security key */
/* This happens elsewhere on Windows; see note below. */
if ((r = sha256_mem(data, datalen, message, sizeof(message))) != 0) {
skdebug(__func__, "hash message failed");
goto out;
}
#endif
if (device != NULL)
sk = sk_open(device);
#ifdef WINDOWS
else {
if ((sk = sk_open("windows://hello")) == NULL) {
if (pin != NULL ||
(flags & SSH_SK_USER_VERIFICATION_REQD))
sk = sk_probe(NULL, NULL, 0);
else
sk = sk_probe(application, key_handle,
key_handle_len);
}
}
#else
else if (pin != NULL || (flags & SSH_SK_USER_VERIFICATION_REQD))
sk = sk_probe(NULL, NULL, 0);
else
sk = sk_probe(application, key_handle, key_handle_len);
#endif
if (sk == NULL) {
skdebug(__func__, "failed to find sk");
goto out;
@ -1004,12 +1053,26 @@ sk_sign(uint32_t alg, const uint8_t *data, size_t datalen,
skdebug(__func__, "fido_assert_new failed");
goto out;
}
#ifndef WINDOWS
if ((r = fido_assert_set_clientdata_hash(assert, message,
sizeof(message))) != FIDO_OK) {
skdebug(__func__, "fido_assert_set_clientdata_hash: %s",
fido_strerr(r));
goto out;
}
#else
/*
* webauthn.dll (windows://hello in libfido2) requires the unhashed
* clientdata body, so we use fido_assert_set_clientdata() instead of
* fido_assert_set_clientdata_hash().
*/
if ((r = fido_assert_set_clientdata(assert, data,
datalen)) != FIDO_OK) {
skdebug(__func__, "fido_assert_set_clientdata: %s",
fido_strerr(r));
goto out;
}
#endif
if ((r = fido_assert_set_rp(assert, application)) != FIDO_OK) {
skdebug(__func__, "fido_assert_set_rp: %s", fido_strerr(r));
goto out;
@ -1050,7 +1113,9 @@ sk_sign(uint32_t alg, const uint8_t *data, size_t datalen,
response = NULL;
ret = 0;
out:
#ifndef WINDOWS
explicit_bzero(message, sizeof(message));
#endif
free(device);
if (response != NULL) {
free(response->sig_r);

View File

@ -347,7 +347,7 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag,
}
ssh_free_identitylist(idlist);
}
#ifndef WINDOWS
if (sshkey_is_sk(private)) {
if (skprovider == NULL) {
fprintf(stderr, "Cannot load FIDO key %s "
@ -363,7 +363,10 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag,
/* Don't send provider constraint for other keys */
skprovider = NULL;
}
#else
if (!sshkey_is_sk(private))
skprovider = NULL;
#endif
if ((r = ssh_add_identity_constrained(agent_fd, private, comment,
lifetime, confirm, maxsign, skprovider)) == 0) {
ret = 0;
@ -796,7 +799,7 @@ main(int argc, char **argv)
goto done;
}
#ifdef ENABLE_SK_INTERNAL
#if !defined(WINDOWS) && defined(ENABLE_SK_INTERNAL)
if (skprovider == NULL)
skprovider = "internal";
#endif

View File

@ -1746,6 +1746,9 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
struct ssh_identitylist *agent_ids;
size_t j;
struct notifier_ctx *notifier = NULL;
#ifdef WINDOWS
int retried = 0;
#endif
#ifdef ENABLE_PKCS11
pkcs11_init(1);
@ -1781,12 +1784,14 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
} else {
/* CA key is assumed to be a private key on the filesystem */
ca = load_identity(tmp, NULL);
#ifndef WINDOWS
if (sshkey_is_sk(ca) &&
(ca->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) {
if ((pin = read_passphrase("Enter PIN for CA key: ",
RP_ALLOW_STDIN)) == NULL)
fatal_f("couldn't read PIN");
}
#endif
}
free(tmp);
@ -1848,6 +1853,9 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
&agent_fd)) != 0)
fatal_r(r, "Couldn't certify %s via agent", tmp);
} else {
#ifdef WINDOWS
retry:
#endif
if (sshkey_is_sk(ca) &&
(ca->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
notifier = notify_start(0,
@ -1857,6 +1865,17 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent,
r = sshkey_certify(public, ca, key_type_name,
sk_provider, pin);
notify_complete(notifier, "User presence confirmed");
#ifdef WINDOWS
if (r == SSH_ERR_KEY_WRONG_PASSPHRASE &&
pin == NULL && !retried && sshkey_is_sk(ca) &&
(ca->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) {
if ((pin = read_passphrase("Enter PIN for CA "
"key: ", RP_ALLOW_STDIN)) == NULL)
fatal_f("couldn't read PIN");
retried = 1;
goto retry;
}
#endif
if (r != 0)
fatal_r(r, "Couldn't certify key %s", tmp);
}
@ -2530,6 +2549,7 @@ sign_one(struct sshkey *signkey, const char *filename, int fd,
fprintf(stderr, "Signing file %s\n", filename);
}
if (signer == NULL && sshkey_is_sk(signkey)) {
#ifndef WINDOWS
if ((signkey->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) {
xasprintf(&prompt, "Enter PIN for %s key: ",
sshkey_type(signkey));
@ -2537,6 +2557,7 @@ sign_one(struct sshkey *signkey, const char *filename, int fd,
RP_ALLOW_STDIN)) == NULL)
fatal_f("couldn't read PIN");
}
#endif
if ((signkey->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
if ((fp = sshkey_fingerprint(signkey, fingerprint_hash,
SSH_FP_DEFAULT)) == NULL)
@ -3615,6 +3636,7 @@ main(int argc, char **argv)
}
if ((attest = sshbuf_new()) == NULL)
fatal("sshbuf_new failed");
#ifndef WINDOWS
if ((sk_flags &
(SSH_SK_USER_VERIFICATION_REQD|SSH_SK_RESIDENT_KEY))) {
passphrase = read_passphrase("Enter PIN for "
@ -3622,6 +3644,9 @@ main(int argc, char **argv)
} else {
passphrase = NULL;
}
#else
passphrase = NULL;
#endif
for (i = 0 ; ; i++) {
fflush(stdout);
r = sshsk_enroll(type, sk_provider, sk_device,

View File

@ -43,24 +43,85 @@
/* #define DEBUG_SK 1 */
#ifdef WINDOWS
static char module_path[PATH_MAX + 1];
static char *
find_helper_in_module_path(void)
{
wchar_t path[PATH_MAX + 1];
DWORD n;
char *ep;
memset(module_path, 0, sizeof(module_path));
memset(path, 0, sizeof(path));
if ((n = GetModuleFileNameW(NULL, path, PATH_MAX)) == 0 ||
n >= PATH_MAX) {
error_f("GetModuleFileNameW failed");
return NULL;
}
if (wcstombs_s(NULL, module_path, sizeof(module_path), path,
sizeof(module_path) - 1) != 0) {
error_f("wcstombs_s failed");
return NULL;
}
if ((ep = strrchr(module_path, '\\')) == NULL) {
error_f("couldn't locate trailing \\");
return NULL;
}
*(++ep) = '\0'; /* trim */
strlcat(module_path, "ssh-sk-helper.exe", sizeof(module_path) - 1);
return module_path;
}
static char *
find_helper(void)
{
char *helper;
char module_path[PATH_MAX + 1];
char *ep;
DWORD n;
if ((helper = getenv("SSH_SK_HELPER")) == NULL || strlen(helper) == 0) {
if ((helper = find_helper_in_module_path()) == NULL)
helper = _PATH_SSH_SK_HELPER;
}
if (!path_absolute(helper)) {
error_f("helper \"%s\" unusable: path not absolute", helper);
return NULL;
}
debug_f("using \"%s\" as helper", helper);
return helper;
}
#endif /* WINDOWS */
static int
start_helper(int *fdp, pid_t *pidp, void (**osigchldp)(int))
{
#ifndef ENABLE_SK
/* TODO - This is added temporarily to resolve build errors.
* The below logic has to be converted using posix_internal() APIs as windows doesn't support fork.
*/
return SSH_ERR_SYSTEM_ERROR;
#else
void (*osigchld)(int);
int oerrno, pair[2];
pid_t pid;
char *helper, *verbosity = NULL;
#ifdef WINDOWS
int r, actions_inited = 0;
char *av[3];
posix_spawn_file_actions_t actions;
#endif
*fdp = -1;
*pidp = 0;
*osigchldp = SIG_DFL;
#ifdef WINDOWS
r = SSH_ERR_SYSTEM_ERROR;
pair[0] = pair[1] = -1;
#endif
#ifdef WINDOWS
if ((helper = find_helper()) == NULL)
goto out;
#else
helper = getenv("SSH_SK_HELPER");
if (helper == NULL || strlen(helper) == 0)
helper = _PATH_SSH_SK_HELPER;
@ -70,6 +131,8 @@ start_helper(int *fdp, pid_t *pidp, void (**osigchldp)(int))
errno = oerrno;
return SSH_ERR_SYSTEM_ERROR;
}
#endif
#ifdef DEBUG_SK
verbosity = "-vvv";
#endif
@ -77,9 +140,39 @@ start_helper(int *fdp, pid_t *pidp, void (**osigchldp)(int))
/* Start helper */
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) {
error("socketpair: %s", strerror(errno));
#ifdef WINDOWS
goto out;
#else
return SSH_ERR_SYSTEM_ERROR;
#endif
}
osigchld = ssh_signal(SIGCHLD, SIG_DFL);
#ifdef WINDOWS
if (posix_spawn_file_actions_init(&actions) != 0) {
error_f("posix_spawn_file_actions_init failed");
goto out;
}
actions_inited = 1;
if (posix_spawn_file_actions_adddup2(&actions, pair[1],
STDIN_FILENO) != 0 ||
posix_spawn_file_actions_adddup2(&actions, pair[1],
STDOUT_FILENO) != 0) {
error_f("posix_spawn_file_actions_adddup2 failed");
goto out;
}
#endif
#ifdef WINDOWS
av[0] = helper;
av[1] = verbosity;
av[2] = NULL;
if (posix_spawnp((pid_t *)&pid, av[0], &actions, NULL, av, NULL) != 0) {
error_f("posix_spawnp failed");
goto out;
}
r = 0;
#else
if ((pid = fork()) == -1) {
oerrno = errno;
error("fork: %s", strerror(errno));
@ -105,12 +198,24 @@ start_helper(int *fdp, pid_t *pidp, void (**osigchldp)(int))
_exit(1);
}
close(pair[1]);
#endif
/* success */
debug3_f("started pid=%ld", (long)pid);
*fdp = pair[0];
*pidp = pid;
*osigchldp = osigchld;
#ifdef WINDOWS
pair[0] = -1;
out:
if (pair[0] != -1)
close(pair[0]);
if (pair[1] != -1)
close(pair[1]);
if (actions_inited)
posix_spawn_file_actions_destroy(&actions);
return r;
#else
return 0;
#endif
}

View File

@ -1281,8 +1281,21 @@ identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
}
sign_key = prv;
if (sshkey_is_sk(sign_key)) {
#ifdef WINDOWS
/*
* Don't prompt for FIDO2 PINs by default on Windows.
* The odds are we are communicating with webauthn.dll,
* which handles this internally. In the event we are
* talking directly to a FIDO2 device and a PIN is
* required, sshkey_sign() will return WRONG_PASSPHRASE
* and we will prompt for a PIN when we retry.
*/
if ((sign_key->sk_flags &
SSH_SK_USER_VERIFICATION_REQD) && 0) {
#else
if ((sign_key->sk_flags &
SSH_SK_USER_VERIFICATION_REQD)) {
#endif
retry_pin:
xasprintf(&prompt, "Enter PIN for %s key %s: ",
sshkey_type(sign_key), id->filename);

View File

@ -32,6 +32,9 @@
#include "sshsig.h"
#include "ssherr.h"
#include "sshkey.h"
#ifdef WINDOWS
#include "sk-api.h" /* XXX for SSH_SK_USER_VERIFICATION_REQD */
#endif
#include "match.h"
#include "digest.h"
@ -563,6 +566,10 @@ sshsig_sign_fd(struct sshkey *key, const char *hashalg,
{
struct sshbuf *b = NULL;
int r = SSH_ERR_INTERNAL_ERROR;
#ifdef WINDOWS
int retried = 0;
char *pin = NULL, *prompt = NULL;
#endif
if (hashalg == NULL)
hashalg = HASHALG_DEFAULT;
@ -572,12 +579,38 @@ sshsig_sign_fd(struct sshkey *key, const char *hashalg,
error_fr(r, "hash_file");
return r;
}
#ifdef WINDOWS
retry:
#endif
if ((r = sshsig_wrap_sign(key, hashalg, sk_provider, sk_pin, b,
sig_namespace, out, signer, signer_ctx)) != 0)
sig_namespace, out, signer, signer_ctx)) != 0) {
#ifdef WINDOWS
if (r == SSH_ERR_KEY_WRONG_PASSPHRASE && signer == NULL &&
sshkey_is_sk(key) && sk_pin == NULL && !retried &&
(key->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) {
xasprintf(&prompt, "Enter PIN for %s key: ",
sshkey_type(key));
if ((pin = read_passphrase(prompt,
RP_ALLOW_STDIN)) == NULL) {
debug_f("couldn't read PIN");
goto out;
}
sk_pin = pin;
retried = 1;
goto retry;
}
error_fr(r, "sshsig_wrap_sign");
#endif
goto out;
}
/* success */
r = 0;
out:
#ifdef WINDOWS
free(prompt);
if (pin != NULL)
freezero(pin, strlen(pin));
#endif
sshbuf_free(b);
return r;
}