The LandPhil be honest, be honorable, be kind, be compassionate, and work hard.

September 3, 2015

Firefox, Root Certificates, and you

Filed under: PowerShell — Tags: , , — phil @ 4:41 pm

If you’ve ever dealt with a certificate authority (CA), you may know most of this.  If this is your first foray into it, hold onto your butts.

Many enterprises stand up and run their own certificate authorities to 1) maintain control over certificate issuance, 2) maintain the security of the certificate chain, and 3) not have to pay a public certificate authority to issue certs.  Until recently, you could get certificates for private addresses (10.x.x.x or 192.168.x.x) or private names (my.domain.local) from public certificate authorities.  Now, they won’t issue a certificate unless they can actually verify that the name/address space belongs to you.  So, for many enterprises, the 3rd option above isn’t viable for namespaces behind their firewalls.

The easiest way to set up a CA, is to use Microsoft’s Certificate Authority role that is part of Windows Server.  A handy thing to remember here is that the CA infrastructure is NOT tied to the domain infrastructure.  So, even though it says it’s domain integrated, doesn’t mean you can’t issue certificates for spaces OUTSIDE of the named domain.  (Example: I installed it in my.domain.local, but I want to issue a certificate for notmine.newdomain.local.  I can, and it won’t be a problem.)  The domain integration is just an easy way to publish and distribute the important parts; namely the root certificate and the certificate revocation lists (CRLs).

Once you have your CA set up and domain integrated and your root CA is published, you’d be all set… if the only browsers in your organization are Internet Explorer or Chrome.  See, a web browser use a certificate store to keep all of the root certificates from all of the relevant public authorities.  It also will store any certificates that you want.  In the case of IE and Chrome, they use the OS integrated certificate store that is conveniently updated by Microsoft Update and Active Directory.  In the case of Firefox (and pretty much every other browser), the developers have decided NOT to trust the operating system store and has their own.  This, of course, means that you can’t rely on MS Update or Active Directory to update it with new root certificates.

Doing searching online, and you’ll find a few references on how to overcome this problem with visualbasic scripts and the “certutil.exe” utility that is part of Firefox.  I suggest you go check that out.  You will actually need to jump through the hoops to obtain the certutil.exe utility (specific for Firefox) in order to use the script I’ve included below.  The visualbasic script is fairly basic and has a few caveats and bugs that aren’t readily apparent, so I re-wrote the entire thing in PowerShell for the new generation.

I make no guarantees on it’s execution and with ALL code you download from the internet, it’s best to analyze and test it on your own prior to deployment.

## Import Certificates to Firefox
## Name: import_cert2firefox_public.ps1
## Author: Phillip Cheetham
## Date: 08/26/2015

## For GPO, add script to User Configuration \ Policies \ Windows Settings \ Scripts \ Logon
## Can configure as Powershell script, link to script path; will only work on Windows 7/2008 R2 or later
## Can configure as regular script:
##    Script Name: powershell.exe
##    Script Parameters: -noninteractive -command <script-path\script.ps1>

## Set variables from computer environment
$strTempDir = $env:TEMP
$strAppDataDir = $env:APPDATA
$strFirefoxProfilesDir = $strAppDataDir + "\Mozilla\Firefox\Profiles"

## Set Domain specific variables for installation
## Replace \\servername.domain.local\share\path with the network path to folder containing certutil.exe and certificate files
$strCertutilFolder = "\\servername.domain.local\share\path"
## Replace Local CA with name of local certificate authority.
$strLocalCertificateAuthorityName = "Local CA"
## Replace certificate.crt with the name of the certificate file
## If you need to deploy multiple certificate files, proceed to line 99
$StrCertificateFileName = "certificate.crt"
## Set appropriate trust for the certificate authority by editing "CT,c,C"
## Refer to for more information
$strTrustAttributes = "CT,c,C"

## Do not edit below this line
function IsInstalled

    if (($env:PROCESSOR_ARCHITECTURE -eq "AMD64") -or ($env:PROCESSOR_ARCHITECTURE -eq "IA64")) {
        $os64bit = $true
    } else { $os64bit = $false }

    if ($os64bit -eq $true) {
        if (Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object { $_.DisplayName -match $ProgramName }) {
        else {
    else {
        if (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object { $_.DisplayName -match $ProgramName }) {
        else {

if (IsInstalled("Firefox")) {
    if ((Test-Path -Path ($strTempDir + "\FirefoxTools")) -eq $true) {
        # Directory exists, ideally remove directory first to assure published files/certs are current
        Remove-Item -Path ($strTempDir + "\FirefoxTools") -Force -Recurse -ErrorAction SilentlyContinue #attempt to remove before overwriting
        if (New-Item -ItemType Directory ($strTempDir + "\FirefoxTools") -Force) { #if delete fails, force directory overwrite
            Copy-Item ($strCertutilFolder + "\*") ($strTempDir + "\FirefoxTools") -Force #in any case, force file overwrite
        else {
            exit #terminate script execution if directory creation fails
    else {
        # Directory does not exist
        if (New-Item -ItemType Directory ($strTempDir + "\FirefoxTools") -Force) {
            Copy-Item ($strCertutilFolder + "\*") ($strTempDir + "\FirefoxTools") -Force
        else {
            exit #terminate script execution if directory creation fails
    #insert certificates
    $arrFirefoxProfileList = Get-ChildItem $strFirefoxProfilesDir
    foreach ($profile in $arrFirefoxProfileList) {
        ## Backup certdb file
        Copy-Item ($profileDir + "\cert8.db") ($profileDir + "\cert8.db.old") -Force -ErrorAction SilentlyContinue

        ## Execute certificate insertion
        ## Build command line, one section at a time because Invoke-Expression will not process as single line
        ## and '&' command interpreter will not process as single variable
        $execCmd = $strTempDir + "\FirefoxTools\certutil.exe"
        $execCAName = "`'$strLocalCertificateAuthorityName`'" #needs to be encapsulated in single quotes
        $execRootFile = $strTempDir + "\FirefoxTools\" + $strCertificateFileName
        $execAttribs = "`"$strTrustAttributes`"" #needs to be encapsulated in double quotes - VERY IMPORTANT
        $execProfile = $profile.FullName
        & $execCmd -A -n $execCAName -i $execRootFile -t $execAttribs -d $execProfile

        ## To include multiple certificate files, uncomment and copy the lines below as necessary
        ## $strLocalCertificateAuthorityName = "Local CA" #<- Update this line
        ## $execCAName = "`'$strLocalCertificateAuthorityName`'"
        ## $strCertificateFileName = "certificate.crt" #<- Update this line
        ## & $execCmd -A -n $execCAName -i $execRootFile -t $execAttribs -d $execProfile
    Remove-Item -Path ($strTempDir + "\FirefoxTools") -Force -Recurse -ErrorAction SilentlyContinue #remove temp directory


February 28, 2011

SharePoint: The State Service

Filed under: PowerShell,SharePoint — phil @ 8:13 am

Normally, one wouldn’t be writing this blog post. Normally, one wouldn’t be looking for the information contained in this blog post either. See, usually when you do the installation of SharePoint, you run the Configuration Wizard and the end and tell it to set up all of the basic services. We didn’t do it that way.

In fact, we manually set up all of our service applications so that we had complete control over what application pools they were assigned to, what they were named, and what database (if any) was created to support them. This worked splendidly for all of the service applications that have a constructor accessible via the Central Administration interface. As you may have already surmised by the content of this article thus far, the State Service does not. The only way to created a State Service application (and associated proxy) is to either create it using the configuration wizard, or create it via PowerShell.

Using the configuration wizard will create the service and create the application proxy and create the application database using the farm SQL server. This is perfect if you don’t really care what things are named or where they are stored. I don’t like to do things that way.

When you use PowerShell, you have control over the name of the service application, the name of the application proxy and the name and location of the database file. Below is the code to create the State Service application.

$serviceApp = New-SPStateServiceApplication -Name "State Service"
New-SPStateServiceDatabase -Name "StateServiceDatabase" `
-ServiceApplication $serviceApp
New-SPStateServiceApplicationProxy -Name "State Service" `
-ServiceApplication $serviceApp -DefaultProxyGroup

The following site contains this information as well as the instructions on how to do this using Central Administration and the farm configuration wizard.

December 21, 2010

PowerShell: Why can’t I sign scripts

Filed under: PowerShell — phil @ 7:48 am

This was an entertaining problem and I have to share.  First off, most people just disable script signing in PowerShell.  It’s just the way of the world.  Since I’m the one “in charge” for this project, I decided that I don’t want to disable script signing.  The first question I had for our AD folks was whether or not we were running a CA and if I could get permission for a code-signing certificate.  After a few back and forths it was determined that we do not have a CA (at least not one in the domain), so I decided I’d just sign them locally.  There are many resources out there for doing this, so I won’t reiterate here.  Suffice to say, you need to install the .NET Framework SDK and run makecert to first create a CA on your machine and then to issue yourself a certificate.

So, I’d gotten to that point, I had a certificate, I had a script, I was ready to go.  So I ran:

Set-AuthenticodeSignature test.ps1 @(Get-ChildItem cert:\CurrentUser\My -codesigning)[0]

…and received an unknown error.  I poked around and found that a lot of people had this problem.  It turns out that when you save a script file using the new PowerShell 2.0 ISE, it saves it encoded as UCS-2 Big Endian.  The code-signing engine only recognizes UTF-8.  In order to get around this, you must open your script file in notepad and re-save it so that it’s encoded in UTF-8.  (Or in my case, I opened it in NotePad++ and changed the encoding.)  Good job, Microsoft.

Powered by WordPress