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

New esignature Release #63

Merged
merged 1 commit into from
Feb 5, 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
153 changes: 153 additions & 0 deletions Scripts/SecretServer/eSignature/Delinea.PoSH.Helpers/Utils.psm1
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
function Write-Log {
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[ValidateSet(0,1,2,3)]
[Int32]$ErrorLevel,
[Parameter(Mandatory,ValueFromPipeline)]
[string]$Message,
[Parameter(Mandatory,ValueFromPipeline)]
[string]$logApplicationHeader,
[Parameter(Mandatory,ValueFromPipeline)]
[int32]$LogLevel,
[Parameter(Mandatory=$false,ValueFromPipeline)]
[bool]$LogFileCheck=$false,
[Parameter(Mandatory=$false)]
[string]$LogFile=$null
)
# Evaluate Log Level based on global configuration
if ($ErrorLevel -le $LogLevel) {
# Format message
[string]$Timestamp = Get-Date -Format "yyyy-MM-ddThh:mm:sszzz"
switch ($ErrorLevel) {
"0" { [string]$MessageLevel = "INF0 " }
"1" { [string]$MessageLevel = "WARN " }
"2" { [string]$MessageLevel = "ERROR" }
"3" { [string]$MessageLevel = "DEBUG" }
}
# Write Log data
$MessageString = "{0}`t| {1}`t| {2}`t| {3}" -f $Timestamp, $MessageLevel, $logApplicationHeader, $Message
$MessageString | Out-File -FilePath $LogFile -Encoding utf8 -Append -ErrorAction SilentlyContinue
$Color = @{ 0 = 'Green'; 1 = 'Cyan'; 2 = 'Yellow'; 3 = 'Red'}
#Write-Host -ForegroundColor $Color[$ErrorLevel] -Object ( $DateTime + $Message)
}
if($LogFileCheck){
if($LogFile -eq $null -or $LogFile -eq ""){
throw "Logging check could not happen"
}
if (( Get-Item -Path $LogFile -ErrorAction SilentlyContinue ).Length -gt 25MB) {
Remove-Item -Path $LogFile -Force -ErrorAction SilentlyContinue
Write-Log -Errorlevel 2 -Message "Old logdata has been purged."
}
}

}
function CreatePsCredObj {
param (
[CmdletBinding()]
[Parameter(Mandatory)]
[string]$Password,
[Parameter(Mandatory)]
[string]$username
)
return New-Object System.Management.Automation.PSCredential ($username, (ConvertTo-SecureString -String $Password -AsPlainText -Force))
}
function CheckModuleExist{
param(
[string]$ModuleName
)
#plz forgive me for this is really ugly, but its needed for us
try {
try{Import-Module $ModuleName -ErrorAction Stop -Scope CurrentUser}catch{Install-Module $ModuleName -ErrorAction Stop -Scope CurrentUser -Force -WarningAction Stop}
}
catch {throw "Error trying to install the module, Exception: $($_), Message: $($_.Message)"}
}


function Set-RSASignatureFromPEMString {
param (
[Parameter(Mandatory=$true, HelpMessage="RSA String from client in tenant is needed.")]
[System.String]$RSAKey,
[Parameter(Mandatory=$true, HelpMessage="PEM or CERT.")]
[System.String]$Type
)
$pemContent = $RSAKey -replace '^-----[^-]+-----', '' -replace '-----[^-]+-----$', ''
$pemContent = $pemContent -replace '\n', '' -replace '\r', ''
$decodedBytes = [Convert]::FromBase64String($pemContent)
# possbily axe
if ($Type.ToUpper() -eq "CERT"){
try{
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 -ArgumentList ($decodedBytes, $null)
return $cert
}
catch {throw New-Object System.Exception "Creation of Signing Key failed. Exception Message: $($_.Exception.Message)."}
}
#
elseif ($Type.ToUpper() -eq "PEM"){
try {
$cngKey = [System.Security.Cryptography.CngKey]::Import($decodedBytes, [System.Security.Cryptography.CngKeyBlobFormat]::Pkcs8PrivateBlob)
return [System.Security.Cryptography.RSACng]::new($cngKey)
}
catch {throw New-Object System.Exception "Creation of Signing Key failed. Exception Message: $($_.Exception.Message)."}
}
#Space for other types
else{
throw New-Object System.Exception "Not a valid type to set RSA keys for. Thowing up here"
}
}

# Fix this so that it passes custom standard and non standard claims like the C# project
function Get-JWT {
param (
[Parameter(Mandatory=$false, HelpMessage="Kid of app.")]
[System.String]$Kid=$null,
[Parameter(Mandatory=$true, HelpMessage="targeted audience of the token.")]
[System.String]$aud,
[Parameter(Mandatory=$true, HelpMessage="Subject of the token.")]
[System.String]$sub,
[Parameter(Mandatory=$true, HelpMessage="Issuer of the token.")]
[System.String]$iss,
[Parameter(Mandatory=$false, HelpMessage="Algorithm; ie: RS256 (most common).")]
[System.String]$alg="RS256",
[Parameter(Mandatory=$false, HelpMessage="Algorithm; ie: RS256 (most common).")]
[System.String]$scope=$null,
[Parameter(Mandatory=$true, HelpMessage="privatekey text")]
[System.String]$privkey
)
$header = @{
"alg" = $alg
"typ" = "JWT"
}
if ($null -ne $Kid -and $Kid -ne ""){$header.kid = $kid}
$payload = @{
"aud" = $aud
"iss"= $iss
"sub" = $sub
"iat" = [math]::Round((Get-Date -UFormat %s))
"exp" = [Math]::Floor((Get-Date).ToUniversalTime().AddHours(1).Subtract((Get-Date "1970-01-01")).TotalSeconds)# Token expires in 1 hour
"jti" = [Guid]::NewGuid().ToString()
}
if ($null -ne $scope -and $scope -ne ""){$payload.scope = $scope}
$encodedPayload = ([Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes(($payload | ConvertTo-Json -Compress))).
Trim()).
Replace('+', '-').
Replace('/', '_').
TrimEnd('=').
Trim()
$encodedHeader = ([Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes(($header | ConvertTo-Json -Compress))).
Trim()).
Replace('+', '-').
Replace('/', '_').
TrimEnd('=').
Trim()
$encodedToken = "$encodedHeader.$encodedPayload"
$dataToSign = [System.Text.Encoding]::UTF8.GetBytes($encodedToken)
try{
$rsaSignature = $(Set-RSASignatureFromPEMString -RSAKey $privkey -Type "PEM").SignData($dataToSign, [System.Security.Cryptography.HashAlgorithmName]::SHA256, [System.Security.Cryptography.RSASignaturePadding]::Pkcs1)
$encodedSignature = [Convert]::ToBase64String($rsaSignature)
}
catch {throw New-Object System.Exception "Signing of JWT failed. Exception Message: $($_.Exception.Message)."}
$encodedSignature = $encodedSignature.Replace('+', '-').Replace('/', '_').TrimEnd('=')
$jwt = "$encodedHeader.$encodedPayload.$encodedSignature"
return [System.String]$jwt
}
43 changes: 43 additions & 0 deletions Scripts/SecretServer/eSignature/Delinea.PoSH.Helpers/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
v# Installation Steps of the PoSH Utils Delinea Helper Module

1. Open PowerShell with administrative privileges as this will be installed on the root drive in Windows under the Program Files folder.

2. Navigate to the root directory of your PowerShell module project.

3. Use the `Copy-Item` cmdlet to copy the module folder to the desired directory. The file: `.\Delinea.PoSH.Helpers\Utils.psm1` Needs to be in the directory: `$env:ProgramFiles\Thycotic Software Ltd\Distributed Engine\Delinea.PoSH.Helpers\`

```powershell
Copy-Item -Path ".\Delinea.PoSH.Helpers\Utils.psm1" -Destination "$env:ProgramFiles\Thycotic Software Ltd\Distributed Engine\Delinea.PoSH.Helpers\" -Recurse -Force

## If the Error Occurs:

```powershell
Copy-Item : Could not find a part of the path 'C:\Program Files\Thycotic Software Ltd\Distributed Engine\Delinea.PoSH.Helpers\'
```

## The Issue is Caused Because the Path Does Not Exist, Run This Command in an Admin Powershell Terminal:

```powershell
if (-not (Test-Path -Path "$env:ProgramFiles\Thycotic Software Ltd\Distributed Engine\Delinea.PoSH.Helpers" -PathType Container)) {
New-Item -Path "$env:ProgramFiles\Thycotic Software Ltd\Distributed Engine\Delinea.PoSH.Helpers" -ItemType Directory
}
```

## The Output Will Show successful:

```powershell
Directory: C:\Program Files\Thycotic Software Ltd\Distributed Engine


Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 1/30/2024 2:59 PM Delinea.PoSH.Helpers
```

## Then Run the Command Again and it Will Copy Over.

- Check it by Running:

```powershell
Get-Content "$env:ProgramFiles\Thycotic Software Ltd\Distributed Engine\Delinea.PoSH.Helpers\"
```
Loading
Loading