"Certificate does not contain any CA certificate" error when I create a SSL profile on Azure Application Gateway - azure-web-app-service

Let me explain more about the scenario.
I have a web application that is hosted on an Azure App Service Plan.
I created two certificates "Root" and "Child" with the blow command:
Generate root cert:
$pwd = ConvertTo-SecureString -String "123" -Force -AsPlainText
$filepath = 'C:\Users\Desktop\certificates\'
$rootcert = New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -Subject "IdentityServerCN"-Provider "Microsoft Strong Cryptographic Provider"-HashAlgorithm "SHA512"-NotAfter (Get-Date).AddYears(5) -KeyUsageProperty All -KeyUsage CertSign, CRLSign, DigitalSignature
Export-PfxCertificate -cert ('Cert:\LocalMachine\My\' + $rootcert.thumbprint) -FilePath ($filepath+'IdentityServerCertificate.pfx')  -Password $pwd
 
Generate child cert:
$pwd = ConvertTo-SecureString -String "123" -Force -AsPlainText
$scope = "app"
$env = "develoepr"
$filepath = 'C:\Users\Desktop\certificates\test\'
$certname = $scope + "_"+ $env
$childcert = New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -Subject "IdentityServerCN"-Provider "Microsoft Strong Cryptographic Provider"-HashAlgorithm "SHA512"-NotAfter (Get-Date).AddYears(5) -Signer $rootcert  -FriendlyName $certname
Export-PfxCertificate -cert ('Cert:\LocalMachine\My\' + $childcert.thumbprint) -FilePath ($filepath + $certname+'.pfx') -Password $pwd
When I directly open the web app URL https://app-test-platform.azurewebsites.net/index.html the application request a certificate. I selecet the child certificate and then the application opened.
Now, I want to move this app behind the Azure Application Gateway and I configure all settings (backend, listeners and etc). Based on this document for this solution I need SSL Profile. First of all, I need to export the trusted CA certificate chain (this document). I have done all steps and when I back to Application Gateway and created an SSL profile I received this error when I want to upload *.cer files.
Failed to save configuration changes to application gateway 'XXXX'. Error: TrustedClientCertificate XXXX/providers/Microsoft.Network/applicationGateways/XXXX/trustedClientCertificates/XXX'>XXXX/XXX does not contain any CA certificate. A CA certificate contains the basic constraint extension with the subject type as CA.

You can use the below powershell command to create the root and leaf certificates for mutual authentication.
Root:
$cert = New-SelfSignedCertificate -Type Custom -KeySpec Signature -Subject "CN=MutualAuthRoot" -KeyExportPolicy Exportable -HashAlgorithm sha256 -KeyLength 2048 -TextExtension #("2.5.29.19={text}CA=true") -CertStoreLocation "Cert:\CurrentUser\My" -KeyUsageProperty Sign -KeyUsage CertSign
Client:
New-SelfSignedCertificate -Type Custom -DnsName MutualAuthLeaf -KeySpec Signature -Subject "CN=MutualAuthLeaf" -KeyExportPolicy Exportable -HashAlgorithm sha256 -KeyLength 2048 -CertStoreLocation "Cert:\CurrentUser\My" -Signer $cert -TextExtension #("2.5.29.37={text}1.3.6.1.5.5.7.3.2")

Related

Connect-Exchange CertificatePath in Azure Function

I'm trying to understand how to add the parameter -CertificateFilePath in a Powershell Azure Function. Locally you just add the location of the path *c:\locationpath*.
But when used in a Azure Function, I'm not sure how to add the file path from a Function App that has the cert already in TLS/SSL settings where I've uploaded the certificate.
A common way I've seen to do is:
Connect-ExchangeOnline -AppID $AppId -CertificateThumbprint $Thumbprint -Organization company.com
But that usually has a pop up that ask for an account to select which is why it might be failing in the Function. Also I'm trying to use a certificate.
Another way I've seen is using the AZ Vault, which I didn't want to use if my certificates are already in an app registration and in the Function itself in TLS/SSL Settings.
I just want to be able to query Exchange without user credentials with a service I've created. Thank you.
As venkateshdodda-mt Suggested try the below steps
1 Generate Certificate and Service Principal
By credential
By CertificateThumbprint & ApplicationId
By AadAccessToken & AccountId
# Login to Azure AD PowerShell With Admin Account
Connect-AzureAD
# Create the self signed cert
$currentDate = Get-Date
$endDate = $currentDate.AddYears(1)
$notAfter = $endDate.AddYears(1)
$pwd = "YOUR_PASSWORD"
$thumb = (New-SelfSignedCertificate -CertStoreLocation cert:\localmachine\my -DnsName YOUR_DNS -KeyExportPolicy Exportable -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" -NotAfter $notAfter).Thumbprint
$pwd = ConvertTo-SecureString -String $pwd -Force -AsPlainText
Export-PfxCertificate -cert "cert:\localmachine\my\$thumb" -FilePath YOUR_PFX_PATH.pfx -Password $pwd
# Load the certificate
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate("YOUR_PFX_PATH.pfx", $pwd)
$keyValue = [System.Convert]::ToBase64String($cert.GetRawCertData())
# Create the Azure Active Directory Application
$application = New-AzureADApplication -DisplayName "YOUR_APP_NAME" -IdentifierUris "https://YOUR_APP_NAME"
New-AzureADApplicationKeyCredential -ObjectId $application.ObjectId -CustomKeyIdentifier "YOUR_PASSWORD" -StartDate $currentDate -EndDate $endDate -Type AsymmetricX509Cert -Usage Verify -Value $keyValue
# Create the Service Principal and connect it to the Application
$sp = New-AzureADServicePrincipal -AppId $application.AppId
# Give the Service Principal Reader access to the current tenant (Get-AzureADDirectoryRole)
Add-AzureADDirectoryRoleMember -ObjectId 72f988bf-86f1-41af-91ab-2d7cd011db47 -RefObjectId $sp.ObjectId
# Get Tenant Detail
$tenant = Get-AzureADTenantDetail
# Now you can login to Azure PowerShell with your Service Principal and Certificate
Connect-AzureAD -TenantId $tenant.ObjectId -ApplicationId $sp.AppId -CertificateThumbprint $thumb
# Output TenantId, AppId and Thumbprint to use in azure function's script
Write-Host "TenantId: "$tenant.ObjectId
Write-Host "AppId: "$sp.AppId
Write-Host "Thumbprint: "$thumb
2 Configure Azure Function to Use Certificate
3 Copy AzureAD PowerShell Module to Azure Function
4 Write PowerShell Script from Azure Function to Connect to Azure AD
for further information check Azure functions check with powershell

X.509 certificate in trusted store for ubuntu - Powershell Microsoft graph

Main goal
I am trying to find a way to add licenses to a user using ubuntu linux; either by powershell or any other programmable method. My last resort is to use selenium with python.
Actual problem
I am trying to use Connect-MgGraph cmdlet with a certificate for unattended scripts. The information on this is here: https://learn.microsoft.com/en-us/graph/powershell/app-only?tabs=azure-portal
I already have app registered with exchange and admin access. I also already have a cert. I used it before when connecting to exchange online powershell.
When I try to run: Connect-MgGraph -ClientID $ApplicationId -TenantId $TenantId -CertificateName $Certificate
It Gives me an error: certificate was not found or has expired.
Here us what I tried:
I first tried using the certpath as a variable and then passing that - failed
$CertificateFilePath = "/home/tech/scripts/powershell_scripts/exchangecert/msexchange.pfx"
##other stuff
Connect-MgGraph -ClientID $ApplicationId -TenantId $TenantId -CertificateName $CertificateFilePath
### FAILED RESULT
Connect-MgGraph: /home/tech/scripts/powershell_scripts/exchangecert/msexchange.cer certificate was not found or has expired.
I tried using this bit of commands that I found from here:https://github.com/Azure/azure-powershell/issues/8675
$StoreName = [System.Security.Cryptography.X509Certificates.StoreName]::My
$StoreLocation = [System.Security.Cryptography.X509Certificates.StoreLocation]::CurrentUser
$Store = [System.Security.Cryptography.X509Certificates.X509Store]::new($StoreName, $StoreLocation)
$Flag = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable
$Certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new("/home/tech/scripts/powershell_scripts/exchangecert/msexchange.cer","apassword",$Flag)
$Store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
$Store.Add($Certificate)
$Store.Close()
### FAILED RESULT
Connect-MgGraph: [Subject]
CN=adomain.com
[Issuer]
CN=adomain.com
[Serial Number]
aserialnumber
[Not Before]
5/30/2021 2:51:16 PM
[Not After]
5/30/2022 3:01:17 PM
[Thumbprint]
athumbprint
certificate was not found or has expired.
Everything I have tried so far is failing. I know this would work on windows but I would really like to authenticate unattended on ubuntu.
Thanks everyone.
-CertificateName should be the subject name of the cert, not the path to the cert. But, you should probably try using the thumbprint instead. I think you're missing some more code for installing the cert. Try something like this, substituting your details in the beginning to generate the correct PFX. (i.e. Make sure key.pem and cert.pem exist in /etc/ssl/private/)
$CertPath = '/etc/ssl/private/'
$CertKey = $CertPath + 'key.pem'
$CertPublic = $CertPath + 'cert.pem'
$CertMerge = $CertPath + 'merged.pfx'
$CertPass = 'somepassword'
$CertExpire = 365
$CertName = 'somecertname')
# Generate new certificate and convert it to pfx format
openssl req -newkey rsa:2048 -new -nodes -x509 -days $CertExpire -keyout $CertKey -out $CertPublic -subj "/C=LV/ST=Some-State/L=LV/O=$CertName/OU=IT"
openssl pkcs12 -in $CertPublic -inkey $CertKey -export -out $CertMerge -passout pass:$CertPass
At this point, you should check to make sure merged.pfx got created. Then continue:
# Store certificate in certificate store
$StoreName = [System.Security.Cryptography.X509Certificates.StoreName]::My
$StoreLocation = [System.Security.Cryptography.X509Certificates.StoreLocation]::CurrentUser
$Store = [System.Security.Cryptography.X509Certificates.X509Store]::new($StoreName, $StoreLocation)
$Flag = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable
$Certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($CertMerge, $CertPass, $Flag)
$Store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
$Store.Add($Certificate)
$Store.Close()
# Get cert thumbprint
$CertValue = [Convert]::ToBase64String($Certificate.GetRawCertData())
$Thumbprint = $Certificate.Thumbprint
Then use $Thumbprint to log in:
Connect-MgGraph -ClientID $ApplicationId -TenantId $TenantId -CertificateThumbprint "YOUR_CERT_THUMBPRINT"

Azure Portal Application in AD says certificate is expired even after I have updated it

My AD application certificate expired and I have put a new one in and deleted all the old expired ones, however when I go to the application it still shows it as expired
You could follow the steps below to create a new certificate credential for your AD App.
1.Run the PowerShell command in local, change the -FilePath to what you want.
$cert=New-SelfSignedCertificate -Subject "CN=TodoListDaemonWithCert" -CertStoreLocation "Cert:\CurrentUser\My" -KeyExportPolicy Exportable -KeySpec Signature
Export-Certificate -Cert $cert -FilePath C:\Users\joyw\Desktop\user1234.cer
2.Navigate to the Azure Active Directory in the portal -> your AD App -> Certificates & secrets -> Upload certificate.
Or if you don't want to upload the certificate manually, you could use the powrshell script as below, after running the script, refresh the portal, you will find it works fine. Make sure you install the Az module.
Connect-AzAccount
$cert=New-SelfSignedCertificate -Subject "CN=TodoListDaemonWithCert" -CertStoreLocation "Cert:\CurrentUser\My" -KeyExportPolicy Exportable -KeySpec Signature
$binCert = $cert.GetRawCertData()
$credValue = [System.Convert]::ToBase64String($binCert)
New-AzADAppCredential -ApplicationId <application-id of the AD App> -CertValue $credValue -StartDate $cert.NotBefore -EndDate $cert.NotAfter

Specify specific certificate when encrypting web.config connection string section

Is there any possibility of encrypt sections in web.config with a specific certificate (not de default one), so I can read the same web.config in different machines?
Or... encrypt sections so two servers can decrypt automatically?
Both machines are Windows Server 2019
Thanks a lot.
According to your descritpion, I suggest you could try to follow below steps to encrypt the web.config and decrypt the web.config by using certificate.
1.Create a certificate to encrypt the config file.
$cert = New-SelfSignedCertificate -Type DocumentEncryptionCert -Subject "CN=DevConfig" -KeyExportPolicy Exportable -KeySpec KeyExchange
Export-Certificate -Cert $cert -FilePath ".\DevConfig.cer"
$mypwd = ConvertTo-SecureString -String "1234" -Force -AsPlainText
Export-PfxCertificate -Cert $cert -FilePath ".\DevConfig.pfx" -Password $mypwd
$cert
2.Improt the encypt certificate:
Import-Certificate -Filepath ".\DevConfig.cer" -CertStoreLocation cert:\LocalMachine\My
3.Imprort the decrypt certificate:
$mypwd = ConvertTo-SecureString -String "1234" -Force -AsPlainText
Import-PfxCertificate -FilePath ".\DevConfig.pfx" -CertStoreLocation Cert:\LocalMachine\My -Password $mypwd
4.Install the WebConfigEncrypter NuGet package.
Install-Package WebConfigEncrypter -Version 1.1.0
5.Add below config into web.config file. Notice: you should find the thumbprint from the generated certificate file like below:
<configProtectedData>
<providers>
<add name="Pkcs12Provider" thumbprint="91cb0b7c611e54f6bfd43c4d8d178b542bc6557e" type="WebConfigEncrypter.Pkcs12ProtectedConfigurationProvider, WebConfigEncrypter" storeLocation="LocalMachine"/>
</providers>
</configProtectedData>
6.Run below command in the web.config file fodler:
aspnet_regiis -pef "connectionStrings" "." -prov "Pkcs12Provider"
7.You will find your web.config is encrypted, but if you improt the decrypt certificatie in the remote server, you will find your application work well.

Import-AzKeyVaultCertificate cmdlet results in: Key not valid for user in specified state

I'm trying to import a .pfx certificate to an Azure keyvault but am having some issues.
Import-AzKeyVaultCertificate -VaultName "SecHash03" -Name "CodeSigning" -FilePath "\path\to\my\cert.pfx"
Results in:
Import-AzKeyVaultCertificate : Key not valid for use in specified state.
At line:1 char:1
+ Import-AzKeyVaultCertificate -VaultName SecHash03 -Name " ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Import-AzKeyVaultCertificate], CryptographicException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.KeyVault.ImportAzureKeyVaultCertificate
I'm requesting this cert from an Enterprise CA using certreq from a machine in the same domain as the CA. There is no password required to import the cert. Plan was to then upload that cert to the aforementioned Azure keyvault.
I tried using the Azure portal to import this cert and that works fine; import and usage both works well. So this is not an issue with Roles as suggested in another similar Stackoverflow answer (Importing certificate to Azure Key Vault: Key not valid for use in specified state).
Please advice!
As far as I know, when you import a pre-existing .pfx file cert to Azure key vault, you need to provide a password which is used for protecting the cert as you need to export the cert within the Private Key and include all certificates in the certificate path if possible. For example,
# Export the cert to a PFX with password
$password = ConvertTo-SecureString "Password!" -AsPlainText -Force
Export-PfxCertificate -Cert "cert:\CurrentUser\My\$($cert.Thumbprint)" -FilePath C:\temp\cert2.pfx -Password $password
# Upload to Key Vault
Import-AzureKeyVaultCertificate -VaultName noel-temp -Name cert2 -FilePath C:\temp\cert2.pfx -Password $password
Alternatively,
If you use a supported CA, you can even configure Key Vault to enroll
for certificates on your behalf. No leaking of keys! For simplicity,
the policy in these examples will be set to generate self-signed certs
from Key Vault.
# Have Key Vault create the certificate with a simple policy
$policy = New-AzureKeyVaultCertificatePolicy -SubjectName "CN=mycluster.southcentralus.cloudapp.azure.com" -IssuerName Self -ValidityInMonths 12
Add-AzureKeyVaultCertificate -VaultName noel-temp -Name cert1 -CertificatePolicy $policy
# Download the secret (private key information) associated with the cert
$secret = Get-AzureKeyVaultSecret -VaultName noel-temp -Name cert1
$secretBytes = [System.Convert]::FromBase64String($secret.SecretValueText)
[System.IO.File]::WriteAllBytes("C:\temp\cert1.pfx", $secretBytes)
# Import the certificate to CurrentUser\My
Import-PfxCertificate -FilePath C:\temp\cert1.pfx -CertStoreLocation cert:\CurrentUser\My -Exportable
You could get more details from these two links:
Importing Certificates to Key Vault
Manage certificates via Azure Key Vault

Resources