Export root certificate using powershell - powershell

I am installing a client side certificate on a Windows 2012 server through Powershell.
Installing a client side certificate requires two steps:
Installing the certificate on the Personal Store ("my").
Installing the root certificate of that certificate in the Trusted
Root Certification Authority Store.
Step 1 is fairly easy.
However, step 2 is tricky. First, I do not know the length of the chain of the certificate. When doing it by-hand, you need to go to export each certificate in the chain until you reach the root (you can only export the first element of the chain). Then, you install the root certificate in the Trusted Store.
So, my question is: how do you get the root certificate of a certificate?
My idea would be to get the certificate chain and somehow process it until you get the root certificate. Any ideas on how this can be done?

GodEater's advice helped me, by looking at this page https://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates(v=vs.110).aspx I figured out how to do it:-
If you import your pkcs12 certificate into System.Security.Cryptography.X509Certificates.X509Certificate2Collection
When you take a look at the object both certificates are there, so simply looping through the object and adding each certificate to the correct store works:-
$fileName = "cert.p12";
$password = "Password"
$certRootStore = "localmachine";
$certStore = "Root";
$certStore2 = "My";
$X509Flags = "PersistKeySet,MachineKeySet";
$pfx = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection;
$pfx.Import($fileName, $Password, $X509Flags);
foreach ($cert in $pfx) {
if ($cert.Subject -match "CN=Your Cert Auth Name") {
$store = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store -ArgumentList $certStore,$certRootStore;
$store.Open("MaxAllowed");$store.Add($cert);
$store.Close | Out-Null
}
else {
$store = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store -ArgumentList $certStore2,$certRootStore;
$store.Open("MaxAllowed");
$store.Add($cert);
$store.Close | Out-Null
}
}

Related

Powershell - Enroll SSL cert On Behalf Of

I created Enrollment Agent Certificate, and through GUI i can install certificate for another user.
Now, i want to automate this procedure using Powershell.
On my local cert store Enrollment agent certificate is installed (Template name:Enrollment Agent) along with certificate i want to issue to other user (Template name:GP)
$PKCS10 = New-Object -ComObject X509Enrollment.CX509CertificateRequestPkcs10
# cert template name i want to issue to user
$PKCS10.InitializeFromTemplateName(0x1,"GP")
$PKCS10.Encode()
$pkcs7 = New-Object -ComObject X509enrollment.CX509CertificateRequestPkcs7
$pkcs7.InitializeFromInnerRequest($pkcs10)
$pkcs7.RequesterName = "domain\some.user"
$signer = New-Object -ComObject X509Enrollment.CSignerCertificate
# bellow is thumbprint of certificate i want to issue (GP)
$signer.Initialize(0,0,0xc,"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
$pkcs7.SignerCertificate = $signer
$Request = New-Object -ComObject X509Enrollment.CX509Enrollment
$Request.InitializeFromRequest($pkcs7)
$Request.Enroll()
Last line fail with error
CertEnroll::CX509Enrollment::Enroll: Error Verifying Request Signature
or Signing Certificate The certificate is not valid for the requested usage.
0x800b0110 (-2146762480 CERT_E_WRONG_USAGE)
Solved, had to specify Enrollment agent thumbprint

Importing certificate to certificate store with power shell script doesn't work but manually works

I am creating SSL certificate to bind to my website. I am using power shell script to automate my process from creation to importing the certificate to Certificate store. Once I bind the certificate to my website, my website does not work. but if I manually import the certificates to the certificate store and bind it to my website. I do no face any issues.
I am calling a script which adds root certificate to Trusted Root and client certificate to Personal store.
$pfx = new-object System.Security.Cryptography.X509Certificates.X509Certificate2
$rootCertImportPath = $runtimeDirPath + $rootCertName
$pfx.import($rootCertImportPath,$rootCAPass,"Exportable,PersistKeySet")
$store = new-object System.Security.Cryptography.X509Certificates.X509Store(
[System.Security.Cryptography.X509Certificates.StoreName]::Root,
"localmachine"
)
$store.open("MaxAllowed")
$store.add($pfx)
$store.close()
I am trying to import .cer file extension using $pfx.import call.
Do i need to pass additional arguments to the below mentioned function ?
$pfx.import($rootCertImportPath,$rootCAPass,"Exportable,PersistKeySet")
Please help me out!
You aren't importing the PFX, you are importing only public certificate without private key. So the correct call is:
$pfx.import($rootCertImportPath)
no other arguments are used.

Bypass Internet Explorer certificate warning

My Question is pretty straight forward.
Can I somehow bypass this warning in PowerShell?
Right now I'm loading the website with the InternetExplorer.Application ComObject, but I could switch to Invoke-Webrequest etc. if that's needed
EDIT: Additional information
This is just for a function I wrote to open ILO of our HP Servers via PowerShell. that's the function:
function Open-ILO {
param(
[Parameter(
Position = 0,
Mandatory = $true
)]
[string]$computer,
[switch]$show
)
$hash = #{
"Server1" = "http://10.0.0.49/"
"Server2" = "http://10.0.0.50/"
"Server3" = "http://10.0.0.56/"
}
$Wert = $hash.get_item($computer)
if (!$show.IsPresent)
{
$ie = new-object -com InternetExplorer.Application
$ie.Visible = $true
$ie.Navigate($Wert)
}
else { Write-Host $Wert }
}
The issue here isn't PowerShell it's Internet Explorer.
The ILO comes with a self-signed certificate which IE does not trust and so shows you the error. Self-signed certificates are not trusted as they are self-generated and require no verification from a certificate authority.
You can either generate a new cert for the ILO from an internal certificate authority to replace the self signed cert. If you are using Active Directory you will have a CA.
Or you can install the self-signed certificate so that IE trusts it.
Depending on your workplace security policy there might be security concerns with the second option, as your computer will trust content that is signed with that certificate. Most businesses will be ok with this but some with high security might not.

Connection to mainframe and Unix to get certificate information

I have a program that works good to get certificate information, but only for Windows boxes. I need it to work for UNIX and mainframe. I added the cert to the Windows trusted root cert auth and have the root cert there as well. I did not generate my own cert here as I didn't think it was needed.
It blows up on the last line where it does an auth, with the error
The remote certificate is invalid according to the validation procedure.
Any ideas what to check for?
$certpath = "C:\Certdir\Certificates\xxx.cer"
$cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::CreateFromCertFile($certPath)
[System.Security.Authentication.SslProtocols]$protocol = "TLS"
$certcol = New-Object System.Security.Cryptography.X509Certificates.X509CertificateCollection
$certcol.Add($cert)
$socket = New-Object Net.Sockets.TcpClient($computerName, $port)
$stream = $socket.GetStream()
$sslStream = New-Object System.Net.Security.SslStream $stream,$false
$sslStream.AuthenticateAsClient($computerName,$certcol,$protocol,$false)

Powershell Script to Install Certificate Into Active Directory Store

I'm trying to write a powershell script to install a certificate into the active directory certificate store,
Here are the steps to do this manually, any help would be greatly appreciated.
On a Windows 2008R2 domain controller,
Click Start -> Run
type MMC
click ok
Click File -> Add/Remove Snap-In
Select "Certificates" -> Add
Select "Service Account"
Click Next
Select "Local Computer"
Click Next
Select "Active Directory Domain Services"
Click Finish
Click Ok
I want the script to install the certificate into :
NTDS\Personal
I would post an image but I don't have enough "reputation" apparently, so I can only provide text instructions.
So basically what I've tried is, I've used this powershell function below to import a certificate into the Local Machine -> Personal Store, which is where most certificates go, and the code works.
But I need to install the certificate into the "NTDS\Personal" store on a domain controller, but the $certRootStore only accepts localmachine or CurrentUser, so I'm stuck : /
function Import-PfxCertificate
{
param
(
[String]$certPath,
[String]$certRootStore = "localmachine",
[String]$certStore = "My",
$pfxPass = $null
)
$pfx = new-object System.Security.Cryptography.X509Certificates.X509Certificate2
if ($pfxPass -eq $null)
{
$pfxPass = read-host "Password" -assecurestring
}
$pfx.import($certPath,$pfxPass,"Exportable,PersistKeySet")
$store = new-object System.Security.Cryptography.X509Certificates.X509Store($certStore,$certRootStore)
$store.open("MaxAllowed")
$store.add($pfx)
$store.close()
}
Import-PfxCertificate -certPath "d:\Certificate.pfx"
Regards Alex
Using a combination of what you already had above and the registry keys for the two certificate stores this works.
The only other thing is that I don't know how NTDS determines which certificate to use when there are multiple in the certificate store.
function Import-NTDSCertificate {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$PFXFile,
[Parameter(Mandatory)]
[string]$PFXPassword,
#Remove certificate from LocalMachine\Personal certificate store
[switch]$Cleanup
)
begin{
Write-Verbose -Message "Importing PFX file."
$PFXObject = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2
$PFXObject.Import($PFXFile,$PFXPassword,[System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)
$thumbprint = $PFXObject.Thumbprint
}
process{
Write-Verbose -Message "Importing certificate into LocalMachine\Personal"
$certificateStore = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store('My','LocalMachine')
$certificateStore.Open('MaxAllowed')
$certificateStore.Add($PFXObject)
$certificateStore.Close()
Write-Verbose -Message "Copying certificate from LocalMachine\Personal to NTDS\Personal"
$copyParameters = #{
'Path' = "HKLM:\Software\Microsoft\SystemCertificates\MY\Certificates\$thumbprint"
'Destination' = "HKLM:\SOFTWARE\Microsoft\Cryptography\Services\NTDS\SystemCertificates\My\Certificates\$thumbprint"
'Recurse' = $true
}
Copy-Item #copyParameters
}
end{
if ($Cleanup){
Write-Verbose -Message "Removing certificate from LocalMachine\Personal"
$removalParameters = #{
'Path' = "HKLM:\SOFTWARE\Microsoft\SystemCertificates\MY\Certificates\$thumbprint"
'Recurse' = $true
}
Remove-Item #removalParameters
}
}
}
Alright, first the bad news. The only managed certificate stores are LocalMachine and CurrentUser, as we have all seen in powershell.
Now, the not so bad news. We know that the 'physical' location store (physical is MS' word, not mine) exists in the registry on the ADDS server, HKLM\Software\Microsoft\Cryptography\Services\NTDS\SystemCertificates. This was dually verified by both
Using procmon while importing a certificate into the store using the mmc snap-in
Scavenging msdn for this nugget
The link in #2 shows that all physical stores for services are stored in the path mentioned above, substituting NTDS for . The real service name, not the display name.
However,
Because of the bad news. Trying to map it in powershell with that reg key as the root and -PSProvider Certificate will prove disappointing, it was the first thing I tried.
What one can try, is using the X509Store constructor that takes an IntPtr to a SystemStore, as described here. Yes, that invovles some unmanaged code, and mixing the two is something I do rarely, but this and googling for HCERTSTORE C# should get you there.
Even though this post is years old, it is still helpful and turns up in searches, so to address the question of "I don't know how NTDS determines which certificate to use when there are multiple in the certificate store", the answer is that you will get unreliable results when there are two or more valid certificates installed that meet the requested criteria so it is recommended to remove the old/unneeded certificate(s) and just leave the newest/best one for the server auth.