Skip to content

Commit

Permalink
Enable support for FIDO2/U2F security keys (#541)
Browse files Browse the repository at this point in the history
  • Loading branch information
martelletto committed Dec 18, 2021
1 parent 991465e commit 4cd1fd1
Show file tree
Hide file tree
Showing 17 changed files with 851 additions and 21 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
63 changes: 63 additions & 0 deletions contrib/win32/openssh/GetFIDO2.ps1
Original file line number Diff line number Diff line change
@@ -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"
2 changes: 1 addition & 1 deletion contrib/win32/openssh/OpenSSHBuildHelper.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
50 changes: 50 additions & 0 deletions contrib/win32/openssh/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.
25 changes: 25 additions & 0 deletions contrib/win32/openssh/Win32-OpenSSH.sln
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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}
Expand Down
15 changes: 14 additions & 1 deletion contrib/win32/openssh/config.h.vs
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down Expand Up @@ -1715,4 +1728,4 @@
#define HAVE_LOCALTIME_R
#define HAVE_DECL_MEMMEM 0
#define WITH_ZLIB
#define _PATH_TTY "conin$"
#define _PATH_TTY "conin$"
10 changes: 9 additions & 1 deletion contrib/win32/openssh/config.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand All @@ -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>
8 changes: 7 additions & 1 deletion contrib/win32/openssh/paths.targets
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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>
Loading

0 comments on commit 4cd1fd1

Please sign in to comment.