mirror of
https://github.com/OPCFoundation/UA-.NETStandard.git
synced 2026-10-19 07:02:16 +08:00
d1883832e1
* merged security changes
* Tailor SecurityPolicyUri for format expected in s_securityPolicyUriToInfo
* Enhance security policy handling and key computation logic
* Merge SecurityEnhancements.
* Add support for SessionTransferToken. Removed obsolete SoftwareCertificate code.
* Fix NonceLength for None.
* Add support for RSA_DH, more fixes from IOP testings.
* Finish implementation of SecureChannelEnhancements.
* Rename EccUtils.cs to CryptoUtils.cs
* Address feedback from reviewers.
* Fix CoPilot flagged spelling errors.
* Rename EccUtils to CryptoUtils
* Update version from 1.5.378-preview to 1.5.378
* Fix unit tests.
* Allow SignatureData.Algorithm to be NULL or Empty.
* Fix issue with BrainPool_p256r1_ChaChaPoly
* Fix RSA_DH_AesGcm
* Fix OSC/padding by deriving HMAC keys, tightening symmetric size math, and correcting ECC_brainpoolP384r1/Basic128Rsa15 IV, signature, padding, and nonce parameters.
* Policies without asymmetric encryption (ECC) return the plaintext when encrypting user tokens; this prevents null payloads from causing BadIdentityTokenInvalid.
* Reserve outer CBC padding for avoiding SymetricEncryptAndSign->AddPadding to overwrite next fields (signature)
* Nonce stored as byte array in SessionConfiguration; Sesion snapshot restores ServerNonce and reconstructs ECC ephemeral key Nonce from bytes and policy
* Added _AesGcm and _ChaChaPoly variants to BuildSupportedSecurityPolicies() for all six ECC certificate types (nistP256, nistP384, brainpoolP256r1, brainpoolP384r1, curve25519, curve448) to SecurityConfiguration. Added Sign and SignAndEncrypt endpoints for the four ECC AesGcm/ChaChaPoly policy pairs (nistP256, nistP384, brainpoolP256r1, brainpoolP384r1) to ServerFixture.
* make ephemeralKeyPolicyUri nullable
* GenerateSecret also for NET7 and NET8
* Adjust Basic128Rsa15 policy properties for backword compatibility
* Exclude unsuported AEAD policies from .NET Framework client tests
* Addapt to new changes (still build fail)
* Addapt code to make it compile
* Fixed failing build on net48 (by ignoring potential null ref which is not reported on other newer targets)
* Preserve the certificate reference in Clone() so copied handlers can still sign
* Remove extra code and addapt to existing master configuration settings
* Filter *_AesGcm and *_ChaChaPoly security policies based on actual runtime support, so unsupported AEAD policies are not advertised or selected on older frameworks
* Expand ECC/RSA policy test coverage and keep Basic128Rsa15 nonce length backward-compatible
* Fix ReconnectSessionOnAlternateChannel _AES and _ChaCha policies
* Fixed IgnoreIfPolicyNotAdvertised so it now fetches endpoints on-demand (instead of relying on Endpoints being preloaded by earlier tests), which avoids false ignores when running tests directlyy
* Merge with commit 5e627f2ca1 from secure-channel-enhancements-2025-11 branch
* minor log mesatge formating
* Fix ClientLockoutTests
* Add ServerFixture policies upfront only if framework and runtime capability supports them
* A few cosmetic/config changes as review sugested
* Moved the session/security handling from StandardServer into a dedicated helper
* use X509IdentityTokenHandler from secure-channel-enhancements-2025-11
* Removed unused Opc.Ua.Types.UnitTests.csproj
* test(client): fix Basic128Rsa15 reconnect token-policy coverage
Advertise an explicit Basic128Rsa15 user token policy in the test fixture and tighten the reconnect test preconditions for non-advertised policies.
* test(client): fix session nonce persistence test helpers
Replace the generic reflection helpers in SessionTests with explicit client/server nonce accessors that match the actual field types.
Add a short Session comment to explain why client and server nonces currently use different representations.
* Merge branch 'master' into secure-channel-enhancements-2025-11-merge5
Merge with latest master and fix conflicts.
* Removed unused Opc.Ua.Types.UnitTests.csproj
* test(client): fix Basic128Rsa15 reconnect token-policy coverage
Advertise an explicit Basic128Rsa15 user token policy in the test fixture and tighten the reconnect test preconditions for non-advertised policies.
* test(client): fix session nonce persistence test helpers
Replace the generic reflection helpers in SessionTests with explicit client/server nonce accessors that match the actual field types.
Add a short Session comment to explain why client and server nonces currently use different representations.
* Build fixes
* Fix build
* update
* Minor updates
* Fix tests
* Add code to check all Endpoints.
* Update Design files to 1.05.7
* Run code fixers, add missing docs
* Fix build
* Revert removal of using
* Increase build timeout
---------
Co-authored-by: mrsuciu <Mircea-Adrian.Suciu@Softing.com>
Co-authored-by: Randy Armstrong <randy@sparhawksoftware.com>
160 lines
6.0 KiB
PowerShell
160 lines
6.0 KiB
PowerShell
# 1. Ensure directories exist
|
|
$certDir = "./bin/pki/trustedUser/certs"
|
|
$privateDir = "./bin/pki/trustedUser/private"
|
|
|
|
$curves = @(
|
|
'nistP256',
|
|
'nistP384',
|
|
'brainpoolP256r1',
|
|
'brainpoolP384r1'
|
|
)
|
|
|
|
foreach ($d in @($certDir, $privateDir)) {
|
|
if (-not (Test-Path $d)) {
|
|
New-Item -ItemType Directory -Path $d -Force | Out-Null
|
|
}
|
|
}
|
|
|
|
function New-CertificateWithAKI {
|
|
param(
|
|
[System.Security.Cryptography.X509Certificates.X509Certificate2] $SourceCert,
|
|
[string] $HashAlgorithmName = 'SHA256'
|
|
)
|
|
|
|
$hashAlg = [System.Security.Cryptography.HashAlgorithmName]::new($HashAlgorithmName)
|
|
|
|
# Determine key type and create CertificateRequest
|
|
$ecdsa = [System.Security.Cryptography.X509Certificates.ECDsaCertificateExtensions]::GetECDsaPrivateKey($SourceCert)
|
|
$rsa = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($SourceCert)
|
|
|
|
if ($ecdsa) {
|
|
$req = [System.Security.Cryptography.X509Certificates.CertificateRequest]::new(
|
|
$SourceCert.SubjectName, $ecdsa, $hashAlg)
|
|
}
|
|
elseif ($rsa) {
|
|
$req = [System.Security.Cryptography.X509Certificates.CertificateRequest]::new(
|
|
$SourceCert.SubjectName, $rsa, $hashAlg,
|
|
[System.Security.Cryptography.RSASignaturePadding]::Pkcs1)
|
|
}
|
|
else {
|
|
throw "Unsupported key type"
|
|
}
|
|
|
|
# Copy all extensions from source cert
|
|
foreach ($ext in $SourceCert.Extensions) {
|
|
$req.CertificateExtensions.Add($ext)
|
|
}
|
|
|
|
# Build Authority Key Identifier from Subject Key Identifier
|
|
$skiExt = $SourceCert.Extensions | Where-Object {
|
|
$_ -is [System.Security.Cryptography.X509Certificates.X509SubjectKeyIdentifierExtension]
|
|
}
|
|
|
|
if ($skiExt) {
|
|
$hex = $skiExt.SubjectKeyIdentifier
|
|
$keyIdBytes = [byte[]]::new($hex.Length / 2)
|
|
for ($i = 0; $i -lt $keyIdBytes.Length; $i++) {
|
|
$keyIdBytes[$i] = [System.Convert]::ToByte($hex.Substring($i * 2, 2), 16)
|
|
}
|
|
# AKI ASN.1: SEQUENCE { [0] IMPLICIT keyIdentifier }
|
|
# 30 <seqLen> 80 <keyIdLen> <keyIdBytes>
|
|
[byte[]] $akiInner = @(0x80, $keyIdBytes.Length) + $keyIdBytes
|
|
[byte[]] $akiValue = @(0x30, $akiInner.Length) + $akiInner
|
|
$akiOid = [System.Security.Cryptography.Oid]::new('2.5.29.35', 'Authority Key Identifier')
|
|
$akiExt = [System.Security.Cryptography.X509Certificates.X509Extension]::new(
|
|
$akiOid, $akiValue, $false)
|
|
$req.CertificateExtensions.Add($akiExt)
|
|
}
|
|
|
|
$notBefore = [DateTimeOffset]::UtcNow.AddMonths(-1)
|
|
$notAfter = [DateTimeOffset]::UtcNow.AddYears(1)
|
|
|
|
return $req.CreateSelfSigned($notBefore, $notAfter)
|
|
}
|
|
|
|
# 2. Create a self-signed ECC certificate (NIST P-256)
|
|
# $cert = New-SelfSignedCertificate `
|
|
# -Subject "CN=iama.tester@example.com" `
|
|
# -CertStoreLocation "Cert:\CurrentUser\My" `
|
|
# -KeyExportPolicy Exportable `
|
|
# -KeySpec Signature `
|
|
# -KeyAlgorithm ECDSA_nistP256 `
|
|
# -Curve 'CurveName' `
|
|
# -HashAlgorithm SHA256 `
|
|
# -NotAfter (Get-Date).AddYears(1)
|
|
|
|
foreach ($curve in $curves) {
|
|
|
|
Write-Host "Generating certificate for curve: $curve"
|
|
|
|
$signatureAlgorithm = if ($curve -match 'P384') { 'SHA384' } else { 'SHA256' }
|
|
|
|
# OIDs for the extensions
|
|
# 2.5.29.14 = Subject Key Identifier
|
|
# 2.5.29.35 = Authority Key Identifier
|
|
# 2.5.29.19 = Basic Constraints (Subject Type=End Entity or CA)
|
|
$name = 'CN=iama.tester@example.com,O=' + $curve;
|
|
|
|
$params = @{
|
|
Type = 'Custom'
|
|
Subject = $name
|
|
TextExtension = @(
|
|
'2.5.29.37={text}1.3.6.1.5.5.7.3.2', # Enhanced Key Usage (Client Auth)
|
|
'2.5.29.17={text}upn=iama.tester@example.com', # SAN
|
|
'2.5.29.19={text}ca=0' # Basic Constraints: Not a CA
|
|
)
|
|
KeyUsage = @('DigitalSignature', 'NonRepudiation') # Added KeyCertSign for self-signed logic
|
|
KeyAlgorithm = "ECDSA_$curve"
|
|
CurveExport = 'CurveName'
|
|
HashAlgorithm = $signatureAlgorithm
|
|
CertStoreLocation = 'Cert:\CurrentUser\My'
|
|
NotBefore = (Get-Date).AddMonths(-1)
|
|
NotAfter = (Get-Date).AddYears(1)
|
|
}
|
|
|
|
# 1. Create cert and rebuild with Authority Key Identifier
|
|
$tempCert = New-SelfSignedCertificate @params
|
|
$cert = New-CertificateWithAKI -SourceCert $tempCert -HashAlgorithmName $signatureAlgorithm
|
|
Remove-Item "Cert:\CurrentUser\My\$($tempCert.Thumbprint)" -Force
|
|
|
|
Write-Host "Certificate generated with Thumbprint: $($cert.Thumbprint)"
|
|
|
|
# 2. Export DER
|
|
$derPath = Join-Path $certDir "iama.tester.$curve.der"
|
|
[System.IO.File]::WriteAllBytes($derPath, $cert.RawData)
|
|
|
|
# 3. Export PFX with password
|
|
$pfxPath = Join-Path $privateDir "iama.tester.$curve.pfx"
|
|
$pfxBytes = $cert.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Pfx, 'password')
|
|
[System.IO.File]::WriteAllBytes($pfxPath, $pfxBytes)
|
|
|
|
Write-Host "Finished: $curve`n"
|
|
}
|
|
|
|
Write-Host "`n=== Generating RSA-2048 ==="
|
|
|
|
$rsaParams = @{
|
|
Type = 'Custom'
|
|
Subject = 'CN=iama.tester@example.com'
|
|
TextExtension = @(
|
|
'2.5.29.37={text}1.3.6.1.5.5.7.3.2'
|
|
'2.5.29.17={text}upn=iama.tester@example.com'
|
|
)
|
|
KeyUsage = @('DigitalSignature','DataEncipherment','NonRepudiation','KeyEncipherment', 'CertSign')
|
|
KeyAlgorithm = 'RSA'
|
|
KeyLength = 2048
|
|
CertStoreLocation = 'Cert:\CurrentUser\My'
|
|
NotBefore = (Get-Date).AddMonths(-1)
|
|
NotAfter = (Get-Date).AddYears(1)
|
|
}
|
|
|
|
$tempRsaCert = New-SelfSignedCertificate @rsaParams
|
|
$rsaCert = New-CertificateWithAKI -SourceCert $tempRsaCert -HashAlgorithmName 'SHA256'
|
|
Remove-Item "Cert:\CurrentUser\My\$($tempRsaCert.Thumbprint)" -Force
|
|
|
|
$derPath = Join-Path $certDir "iama.tester.rsa.der"
|
|
[System.IO.File]::WriteAllBytes($derPath, $rsaCert.RawData)
|
|
$pfxPath = Join-Path $privateDir "iama.tester.rsa.pfx"
|
|
$pfxBytes = $rsaCert.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Pfx, 'password')
|
|
[System.IO.File]::WriteAllBytes($pfxPath, $pfxBytes)
|