github.com/Venafi/vcert/v5@v5.10.2/pkg/playbook/util/capistore/embedded/install-cert.ps1 (about)

     1   <##################
     2  .DESCRIPTION
     3      install-cert adds or verifies an end-entity certificate is installed in the Personal CAPI store
     4  .PARAMETER certBytes
     5      The path of a PKCS#12 which contains the end-entity certificate and private key
     6  .PARAMETER friendlyName
     7      A text string that is used to identify the certificate when extracting it from the CAPI store
     8  .PARAMETER isNonExportable
     9      A boolean that controls whether or not the certificate should be exportable after it has been installed into the CAPI store
    10  .PARAMETER password
    11      The string password that was used to encrypt the private key
    12  .PARAMETER certStore
    13      The location to store the certificate in CAPI
    14  ##################>
    15  function install-cert {
    16      [CmdletBinding()]
    17      param (
    18          [Parameter(Mandatory)]
    19          [string] $friendlyName,
    20  
    21          [Parameter(Mandatory)]
    22          [string] $storeName,
    23  
    24          [Parameter(Mandatory)]
    25          [System.Security.Cryptography.X509Certificates.storeLocation] $storeLocation,
    26  
    27          [Parameter(Mandatory)]
    28          [bool] $isNonExportable,
    29  
    30          [Parameter(Mandatory)]
    31          [ValidateNotNullOrEmpty()]
    32          [string] $password,
    33  
    34          [Parameter(Mandatory)]
    35          [ValidateNotNullOrEmpty()]
    36          [ValidateScript( {
    37              if (Test-Path -Path $_) {
    38                  $true
    39              } else {
    40                  throw "unable to read PFX from '$($_)'"
    41              }
    42          })]
    43          [string] $certPath
    44      )
    45  
    46      # Make the keyset accessible only to user when installing in CurrentUser
    47      $keyset = if ($storeLocation -eq [System.Security.Cryptography.X509Certificates.StoreLocation]::CurrentUser) {'UserKeySet'} else {'MachineKeyset'}
    48      $exportable = if (-not $isNonExportable) { 'Exportable,' }
    49      
    50      $collection = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection
    51      $collection.Import($certPath, $password, "$($exportable)$($keyset),PersistKeySet")
    52  
    53      foreach ($cert in $collection.GetEnumerator())
    54      {
    55          # The storeName changes based on certificate type. Defaults to the specified store where the end-entity cert will go.
    56          #  use installToStore so not to reset the global $storeName variable
    57          $installToStore = $storeName
    58          
    59          $is_ca_cert = $false
    60          foreach ($ext in $cert.Extensions)
    61          {
    62              if ($ext.GetType().Name -eq "X509BasicConstraintsExtension")
    63              {
    64                  $is_ca_cert = $ext.CertificateAuthority
    65                  break
    66              }
    67          }
    68  
    69          if ($is_ca_cert)
    70          {
    71              # check to see if it is a root certificate
    72              if ($cert.Issuer -eq $cert.Subject)
    73              {
    74                  $installToStore = "Root"
    75                  if (Test-Path "Cert:\$($storeLocation)\$($installToStore)\$($cert.Thumbprint)")
    76                  {
    77                      continue  # already in the CAPI store
    78                  }
    79              }
    80              else # it is an intermediate certificate
    81              {
    82                  $installToStore = "CA"
    83                  if (Test-Path "Cert:\$($storeLocation)\$($installToStore)\$($cert.Thumbprint)")
    84                  {
    85                      continue  # already in the CAPI store
    86                  }
    87              }
    88          }
    89          else
    90          {
    91              if (!(Test-Path "Cert:\$($storeLocation)\$($installToStore)\$($cert.Thumbprint)"))
    92              {
    93                  $cert.FriendlyName = $friendlyName
    94              }
    95              else
    96              {
    97                  $existing = Get-Item "Cert:\$($storeLocation)\$($installToStore)\$($cert.Thumbprint)"
    98  
    99                  if ($existing.FriendlyName -ne $friendlyName)
   100                  {
   101                      throw "Certificate already installed but FriendlyName does not match - $($existing.FriendlyName)"
   102                  }
   103  
   104                  continue
   105              }
   106          }
   107  
   108          $capi = Get-Item "Cert:\$($storeLocation)\$($installToStore)"
   109          $capi.Open("ReadWrite")
   110          $capi.Add($cert)
   111          $capi.Close()
   112  
   113          # wait two seconds before checking to see the installation was successful
   114          Start-Sleep -s 2
   115  
   116          if (!(Test-Path "Cert:\$($storeLocation)\$($installToStore)\$($cert.Thumbprint)"))
   117          {
   118              if ($is_ca_cert) {
   119                  throw "Failed to install chain certificate on target system - $($cert.Subject)"
   120              }
   121              else
   122              {
   123                  throw "Could not install certificate on target system"
   124              }
   125          }
   126      }
   127  }