Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 1.11.0 #113

Merged
merged 19 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ indent_size = 4
indent_style = space
tab_width = 4
guidelines = 100, 120
guidelines_style =
2.5px solid 40ff0000
guidelines_style = 2.5px solid 40ff0000

# New line preferences
end_of_line = crlf
Expand Down
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/2-bug-report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ body:
attributes:
label: Version
description: What version of our SDK are you using?
placeholder: 1.10.0
placeholder: 1.11.0
validations:
required: true
- type: input
id: version-firmare
attributes:
label: Version
description: What version of our firmware are you running?
placeholder: 5.4.3
placeholder: 5.7.0
validations:
required: true
- type: textarea
Expand Down
120 changes: 60 additions & 60 deletions .github/workflows/verify-code-style.yml
Original file line number Diff line number Diff line change
@@ -1,71 +1,71 @@
# Copyright 2021 Yubico AB
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# # Copyright 2021 Yubico AB
# #
# # Licensed under the Apache License, Version 2.0 (the "License");
# # you may not use this file except in compliance with the License.
# # You may obtain a copy of the License at
# #
# # http://www.apache.org/licenses/LICENSE-2.0
# #
# # Unless required by applicable law or agreed to in writing, software
# # distributed under the License is distributed on an "AS IS" BASIS,
# # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# # See the License for the specific language governing permissions and
# # limitations under the License.

name: Check code formatting
# name: Verify code style

on:
pull_request:
branches:
- 'main'
- 'develop**'
- 'release/**'
paths:
- '**.h'
- '**.c'
- '**.cs'
- '**.csproj'
- '**.sln'
- '.github/workflows/check-code-formatting.yml'
# on:
# pull_request:
# branches:
# - 'main'
# - 'develop**'
# - 'release/**'
# paths:
# - '**.h'
# - '**.c'
# - '**.cs'
# - '**.csproj'
# - '**.sln'
# - '.github/workflows/check-code-formatting.yml'

jobs:
verify-code-style:
name: "Verify code style"
runs-on: windows-latest
# jobs:
# verify-code-style:
# name: "Verify code style"
# runs-on: windows-latest

steps:
- uses: actions/checkout@v4
# steps:
# - uses: actions/checkout@v4

- uses: actions/setup-dotnet@v4
with:
global-json-file: global.json
# - uses: actions/setup-dotnet@v4
# with:
# global-json-file: global.json

- name: Add local NuGet repository
run: dotnet nuget add source --username ${{ github.actor }} --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/Yubico/index.json"
# - name: Add local NuGet repository
# run: dotnet nuget add source --username ${{ github.actor }} --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/Yubico/index.json"

- name: Build Yubico.NET.SDK.sln
run: dotnet build --nologo --verbosity normal Yubico.NET.SDK.sln
# #- name: Build Yubico.NET.SDK.sln
# # run: dotnet build --nologo --verbosity normal Yubico.NET.SDK.sln

- name: "Add DOTNET to path explicitly to address bug where it cannot be found"
shell: bash
run: |
DOTNET_PATH=$(which dotnet)
if [ -z "$DOTNET_PATH" ]; then
echo "dotnet not found via which, checking /usr/share/dotnet"
# Finding all executables named dotnet and picking the first one
DOTNET_PATH=$(find /usr/share/dotnet -type f -name "dotnet" -executable | head -n 1)
fi
# - name: "Add DOTNET to path explicitly to address bug where it cannot be found"
# shell: bash
# run: |
# DOTNET_PATH=$(which dotnet)
# if [ -z "$DOTNET_PATH" ]; then
# echo "dotnet not found via which, checking /usr/share/dotnet"
# # Finding all executables named dotnet and picking the first one
# DOTNET_PATH=$(find /usr/share/dotnet -type f -name "dotnet" -executable | head -n 1)
# fi

if [ -z "$DOTNET_PATH" ]; then
echo "dotnet executable not found."
exit 1
else
echo "Using dotnet at $DOTNET_PATH"
DOTNET_DIR=$(dirname $(readlink -f $DOTNET_PATH))
echo "$DOTNET_DIR" >> $GITHUB_PATH
echo "Added $DOTNET_DIR to GITHUB_PATH"
fi
# if [ -z "$DOTNET_PATH" ]; then
# echo "dotnet executable not found."
# exit 1
# else
# echo "Using dotnet at $DOTNET_PATH"
# DOTNET_DIR=$(dirname $(readlink -f $DOTNET_PATH))
# echo "$DOTNET_DIR" >> $GITHUB_PATH
# echo "Added $DOTNET_DIR to GITHUB_PATH"
# fi


- name: Check for correct formatting
run: dotnet format --verify-no-changes --no-restore -v d
# - name: Check for correct formatting
# run: dotnet format --verify-no-changes --no-restore -v d
2 changes: 1 addition & 1 deletion Yubico.NativeShims/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.13)
project(Yubico.NativeShims VERSION 1.10.1)
project(Yubico.NativeShims VERSION 1.11.0)
include(CheckCCompilerFlag)

if (APPLE OR UNIX)
Expand Down
2 changes: 1 addition & 1 deletion Yubico.NativeShims/vcpkg.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg/master/scripts/vcpkg.schema.json",
"name": "yubico-nativeshims",
"version": "1.10.0",
"version": "1.11.0",
"dependencies": [
"openssl"
]
Expand Down
56 changes: 56 additions & 0 deletions Yubico.YubiKey/docs/users-manual/getting-started/whats-new.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,62 @@ limitations under the License. -->
# What's new in the SDK?

Here you can find all of the updates and release notes for published versions of the SDK.

## 1.11.x Releases
### 1.11.0

Release date: June 28th, 2024

This release introduces significant enhancements and new features for the latest YubiKeys, including support for
firmware version 5.7, which allows for temporary disabling of NFC connectivity and checking PIN complexity status.
It also expands RSA key support in PIV to 3072 and 4096-bit keys, and includes improvements for YubiKey Bio and
Multi-Protocol Edition keys.
Additionally, there are optimizations in USB reclaim speed and adjustments to the touch sensor sensitivity and a few bug
fixes.
Several command classes have been deprecated due to changes in how device info is read by the SDK, and integration test
guardrails have been implemented for better security.

Features:
- Support for YubiKeys with the latest firmware (version 5.7):
- NFC connectivity can now be temporarily disabled with [SetIsNfcRestricted()](xref:Yubico.YubiKey.YubiKeyDevice.SetIsNfcRestricted%28System.Boolean%29) ([#91](https://github.com/Yubico/Yubico.NET.SDK/pull/91)).
- Additional property pages on the YubiKey are now read into [YubiKeyDeviceInfo](xref:Yubico.YubiKey.YubiKeyDeviceInfo) ([#92](https://github.com/Yubico/Yubico.NET.SDK/pull/92)).
- PIN complexity status can be checked with [IsPinComplexityEnabled](xref:Yubico.YubiKey.YubiKeyDevice.IsPinComplexityEnabled) ([#92](https://github.com/Yubico/Yubico.NET.SDK/pull/92)).
- PIN complexity specific error messages and exceptions ([#112](https://github.com/Yubico/Yubico.NET.SDK/pull/112)).
- The set of YubiKey applications that are capable of being put into FIPS mode can be retrieved with [FipsCapable](xref:Yubico.YubiKey.YubiKeyDevice.FipsCapable). The set of YubiKey applications that are in FIPS mode can be retrieved with [FipsApproved](xref:Yubico.YubiKey.YubiKeyDevice.FipsApproved) ([#92](https://github.com/Yubico/Yubico.NET.SDK/pull/92)).
- The part number for a key’s Secure Element processor, if available, can be retrieved with [PartNumber](xref:Yubico.YubiKey.YubiKeyDevice.PartNumber) ([#92](https://github.com/Yubico/Yubico.NET.SDK/pull/92)).
- The set of YubiKey applications that are blocked from being reset can be retrieved with [ResetBlocked](xref:Yubico.YubiKey.YubiKeyDevice.ResetBlocked) ([#92](https://github.com/Yubico/Yubico.NET.SDK/pull/92)).
- PIV: 3072 and 4096 RSA keys can now be generated and imported ([#100](https://github.com/Yubico/Yubico.NET.SDK/pull/100)).
- PIV: Keys can be moved between the different slots on the YubiKey. Any key except the **attestation key** can be moved from one slot to another ([#103](https://github.com/Yubico/Yubico.NET.SDK/pull/103)).
- Support for YubiKey Bio/Bio Multi-Protocol Edition keys:
- Get bio metadata ([#108](https://github.com/Yubico/Yubico.NET.SDK/pull/108))
- Added new verification policy enum values (PIN_OR_MATCH_ONCE, PIN_OR_MATCH_ALWAYS) ([#108](https://github.com/Yubico/Yubico.NET.SDK/pull/108))
- Bio user verification ([#108](https://github.com/Yubico/Yubico.NET.SDK/pull/108))
- Device Reset ([#110](https://github.com/Yubico/Yubico.NET.SDK/pull/110))
- The USB reclaim speed, which controls the time it takes to switch from one YubiKey application to another, has been reduced for compatible YubiKeys. To use the previous 3-second reclaim timeout for all keys, see [UseOldReclaimTimeoutBehavior](xref:Yubico.YubiKey.YubiKeyCompatSwitches.UseOldReclaimTimeoutBehavior) ([#93](https://github.com/Yubico/Yubico.NET.SDK/pull/93)).
- The sensitivity of the YubiKey’s capacitive touch sensor can now be temporarily adjusted with [SetTemporaryTouchThreshold](xref:Yubico.YubiKey.YubiKeyDevice.SetTemporaryTouchThreshold%28System.Int32%29) ([#95](https://github.com/Yubico/Yubico.NET.SDK/pull/95)).

Bug fixes:
- Update ManagementKeyAlgorithm on PIV Application reset ([#105](https://github.com/Yubico/Yubico.NET.SDK/pull/105)).
- Queue macOS input reports so that large responses aren't dropped ([#84](https://github.com/Yubico/Yubico.NET.SDK/pull/84)).
- Default back to old SCardConnect behavior. Reverts the change in behavior to open smart card handles exclusively. Instead now defaults back to shared like it was before, but allows for applications to toggle between the new and old behavior through the use of AppContext.SetSwitch ([#83](https://github.com/Yubico/Yubico.NET.SDK/pull/83)).

Miscellaneous:
- The way that YubiKey device info is read by the SDK has changed, and as a result, the following GetDeviceInfo command classes have been deprecated ([#91](https://github.com/Yubico/Yubico.NET.SDK/pull/91)):
- [Yubico.YubiKey.Management.Commands.GetDeviceInfoCommand](Yubico.YubiKey.Management.Commands.GetDeviceInfoCommand)
- [Yubico.YubiKey.Otp.Commands.GetDeviceInfoCommand](xref:Yubico.YubiKey.Otp.Commands.GetDeviceInfoCommand)
- [Yubico.YubiKey.U2f.Commands.GetDeviceInfoCommand](xref:Yubico.YubiKey.U2f.Commands.GetDeviceInfoCommand)
- [Yubico.YubiKey.Management.Commands.GetDeviceInfoResponse](xref:Yubico.YubiKey.Management.Commands.GetDeviceInfoResponse)
- [Yubico.YubiKey.Otp.Commands.GetDeviceInfoResponse](xref:Yubico.YubiKey.Otp.Commands.GetDeviceInfoResponse)
- [Yubico.YubiKey.U2f.Commands.GetDeviceInfoResponse](xref:Yubico.YubiKey.U2f.Commands.GetDeviceInfoResponse)
- The correct certificate OID friendly names are now used for ECDsaCng (nistP256) and ECDsaOpenSsl (ECDSA_P256) ([#78](https://github.com/Yubico/Yubico.NET.SDK/pull/78)).
- Integration test guardrails have been added to ensure tests are done only on specified keys. ([#100](https://github.com/Yubico/Yubico.NET.SDK/pull/100)).
- Fixed build issue when compiling `Yubico.NativeShims` on MacOS ([#109](https://github.com/Yubico/Yubico.NET.SDK/pull/109)).
- Run unit tests on all platforms in CI ([#80](https://github.com/Yubico/Yubico.NET.SDK/pull/80)).

Dependencies:
- Update xUnit and Microsoft.NET.Test.Sdk ([#94](https://github.com/Yubico/Yubico.NET.SDK/pull/94)).


## 1.10.x Releases

### 1.10.0
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
uid: UsersManualPinComplexityPolicy
---

<!-- Copyright 2024 Yubico AB

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->

# PIN Complexity policy

Since firmware 5.7, the YubiKey can enforce usage of non-trivial PINs in its applications, this feature has been named _PIN complexity policy_ and is derived from the current Revision 3 of SP 800-63 (specifically SP 800-63B-3) with additional consideration of Revision 4 of SP 800-63 (specifically SP 800-63B-4).

If PIN complexity has been enforced, the YubiKey will refuse to set or change values of following, if they violate the policy:
- PIV PIN and PUK
- FIDO2 PIN

That means that simple values such as `11111111`, `password` or `12345678` will be refused. The YubiKey can also be programmed during the pre-registration to refuse other specific values. More information can be found in our <a href="https://docs.yubico.com/hardware/yubikey/yk-tech-manual/5.7-firmware-specifics.html#pin-complexity">online documentation</a> for the firmware version 5.7 additions.

The SDK has support for getting information about the feature and also a way how to let the client know that an error is related to PIN complexity.

## Read current PIN complexity status
The PIN complexity enforcement status is part of the `IYubiKeyDeviceInfo` through `bool IsPinComplexityEnabled` property.

## Handle PIN complexity errors
The SDK can be used to create a variety of applications. If those support setting or changing PINs, they should handle the situation when a YubiKey refuses the user value because it is violating the PIN complexity.

The SDK communicates this by throwing specific Exceptions.

### PIV Session
In PIV session the exception thrown during PIN complexity violations is `SecurityException` with a specific message: `ExceptionMessages.PinComplexityViolation`.

If the application uses `KeyCollectors`, the violation is reported through `KeyEntryData.IsViolatingPinComplexity`.

The violations are reported for following operations:
- `PivSession.ChangePin()`
- `PivSession.ChangePuk()`
- `PivSession.ResetPin()`

### FIDO2 Session
In the FIDO2 application, `Fido2Exception` with `Status` of `CtapStatus.PinPolicyViolation` is thrown after a PIN complexity was violated. For `KeyCollectors`, `KeyEntryData.IsViolatingPinComplexity` will be set to `true` for these situations.

This applies to following `Fido2Session` operations:
- `Fido2Session.SetPin()`
- `Fido2Session.ChangePin()`

## Example code
You can find examples of code in the `PivSampleCode` and `Fido2SampleCode` examples as well in `PinComplexityTests` integration tests.
2 changes: 2 additions & 0 deletions Yubico.YubiKey/docs/users-manual/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
href: sdk-programming-guide/commands.md
- name: Device notifications
href: sdk-programming-guide/device-notifications.md
- name: PIN Complexity policy
href: sdk-programming-guide/pin-complexity-policy.md

- name: "Application: OTP"
homepage: application-otp/otp-overview.md
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ public virtual bool Fido2SampleKeyCollectorDelegate(KeyEntryData keyEntryData)
return false;
}

if (keyEntryData.IsViolatingPinComplexity)
{
SampleMenu.WriteMessage(MessageType.Special, 0, "The provided value violates PIN complexity.");

SampleMenu.WriteMessage(MessageType.Title, 0, "Try again? y/n");
char[] answer = SampleMenu.ReadResponse(out int _);
if (answer.Length == 0 || (answer[0] != 'y' && answer[0] != 'Y'))
{
return false;
}
}

if (keyEntryData.IsRetry)
{
SampleMenu.WriteMessage(MessageType.Title, 0, "A previous entry was incorrect, do you want to retry?");
Expand All @@ -49,7 +61,7 @@ public virtual bool Fido2SampleKeyCollectorDelegate(KeyEntryData keyEntryData)
string retryString =
((int)keyEntryData.RetriesRemaining).ToString("D", CultureInfo.InvariantCulture);
SampleMenu.WriteMessage(MessageType.Title, 0,
"(retries remainin until blocked: " + retryString + ")");
"(retries remaining until blocked: " + retryString + ")");
}

SampleMenu.WriteMessage(MessageType.Title, 0, "y/n");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,17 @@ public bool SampleKeyCollectorDelegate(KeyEntryData keyEntryData)
return false;
}

if (keyEntryData.IsRetry)
if (keyEntryData.IsViolatingPinComplexity &&
!GetUserInputOnPinComplexityViolation(keyEntryData))
{
if (!(keyEntryData.RetriesRemaining is null))
{
if (GetUserInputOnRetries(keyEntryData) == false)
{
return false;
}
}
return false;
}

if (keyEntryData.IsRetry &&
keyEntryData.RetriesRemaining.HasValue &&
!GetUserInputOnRetries(keyEntryData))
{
return false;
}

byte[] currentValue;
Expand Down Expand Up @@ -142,6 +144,20 @@ private bool GetUserInputOnRetries(KeyEntryData keyEntryData)
return response == 0;
}

private bool GetUserInputOnPinComplexityViolation(KeyEntryData keyEntryData)
{
SampleMenu.WriteMessage(MessageType.Special, 0, "The provided value violates PIN complexity.");

string title = "Try again?";
string[] menuItems = new string[]
{
"Yes, try again",
"No, cancel operation"
};
int response = _menuObject.RunMenu(title, menuItems);
return response == 0;
}

// Collect a value.
// The name describes what to collect.
// The defaultValueString is a string describing the default value and
Expand Down
Loading
Loading