<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Mike Melone's Blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/option_explicit/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/option_explicit/feed.xml</link>
    <description>A deep-dive on PKI, information security, and the Windows platform</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:47:24 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>The PowerShell Yes-man</title>
      <link>https://docs.microsoft.com/archive/blogs/option_explicit/the-powershell-yes-man</link>
      <pubDate>Fri, 05 May 2017 14:21:28 GMT</pubDate>
      <dc:creator><![CDATA[Michael Melone]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/option_explicit/?p=225</guid>
      <description><![CDATA[Every sysadmin encounters those command-line applications that require the user to enter 'y'...]]></description>
      <content:encoded><![CDATA[Every sysadmin encounters those command-line applications that require the user to enter 'y' repeatedly to accept prompts.  This is time-consuming and capitalizes all of your time until the task is finished.

The good news?  PowerShell has a way to automate those infinite y's, or whatever your prompt may require!  Here's a sample snippet that we will take apart:

<hr />

<blockquote>$psiApp = New-Object System.Diagnostics.ProcessStartInfo
$psiApp.FileName = "YourApp.exe"
$psiApp.UseShellExecute = $false
$psiApp.RedirectStandardInput = $true
<div>$prcApp = [System.Diagnostics.Process]::Start($psiApp)</div>
<div></div>
<div>While (!$prcApp.HasExited) {
$prcApp.StandardInput.WriteLine("y")</div>
<div>      Start-Sleep -Milliseconds 500
}</div></blockquote>
<div>

<hr />

In this script, we start by creating a new instance of System.Diagnostics.ProcessStartInfo (<a href="https://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo(v=vs.110).aspx">MSDN</a>).  ProcessStartInfo is a .Net object used when you want to create a new process using some custom parameters.  The properties we configure on this object are:</div>
<ul>
 	<li>FileName: The path to the file you wish to create the process from</li>
 	<li>UseShellExecute: This determines whether the file is launched using shell execute (think start.exe) or not.  Using shell execute means that the FileName can specify non-executable files with file associations (for example, a .docx document would launch Microsoft Word and open the document).  With ShellExecute disabled, the file in FileName must be executable.</li>
 	<li>RedirectStandardInput: This property enables us to programmatically write text directly to the STDIN pipe to the process.  We will use this to send in our series of Y's.</li>
</ul>
Once the ProcessStartInfo object is configured, we call the Start method (<a href="https://msdn.microsoft.com/en-us/library/0w4h05yb(v=vs.110).aspx">MSDN</a>) of System.Diagnostics.Process (<a href="https://msdn.microsoft.com/en-us/library/system.diagnostics.process(v=vs.110).aspx">MSDN</a>).  This creates a process using our previously configured ProcessStartInfo object, thus launching your application.

The last section is a Do-While loop that watches the HasExited property (<a href="https://msdn.microsoft.com/en-us/library/system.diagnostics.process.hasexited(v=vs.110).aspx">MSDN</a>) of the Process we just created.  This property will remain False until the program closes, at which time there is no reason to continue attempting to send Y's to it.

Within this loop we have two PowerShell commands.  The first one calls the WriteLine() (<a href="https://msdn.microsoft.com/en-us/library/7ack4zyt(v=vs.110).aspx">MSDN</a>) method of the StandardInput property (<a href="https://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardinput(v=vs.110).aspx">MSDN</a>) our process.  According to MSDN. the StandardInput property is a System.IO.StreamWriter object (<a href="https://msdn.microsoft.com/en-us/library/system.io.streamwriter(v=vs.110).aspx">MSDN</a>).  A StreamWriter is a .Net object that allows us to write characters to the stream, in this case the StandardInput property of our process, or STDIN.  Calling WriteLine("y") on this stream will send a "y" into the input for the process.

Last, we implement a 500 ms delay so that we don't totally inundate the application with endless Y's :).]]></content:encoded>
    </item>
    <item>
      <title>PSExec for PowerShell</title>
      <link>https://docs.microsoft.com/archive/blogs/option_explicit/psexec-for-powershell</link>
      <pubDate>Tue, 04 Dec 2012 20:39:00 GMT</pubDate>
      <dc:creator><![CDATA[Michael Melone]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/option_explicit/2012/12/04/psexec-for-powershell/</guid>
      <description><![CDATA[Today I ran into some issues calling PSExec.exe...]]></description>
      <content:encoded><![CDATA[<p>Today I ran into some issues calling PSExec.exe (<a href="http://technet.microsoft.com/en-us/sysinternals/bb897553">http://technet.microsoft.com/en-us/sysinternals/bb897553</a>&nbsp;) from PowerShell and realized that there is no native cmdlet to&nbsp;execute an application&nbsp;on a remote&nbsp;computer natively in PowerShell.&nbsp; After spending some time&nbsp;associated with encoding (psexec.exe expects UTF8, however PowerShell is sending Unicode) I decided to create a PowerShell&nbsp;script that could accomplish many of the tasks that PSExec&nbsp;could without needing a PSSession (to support down-level clients).&nbsp;&nbsp;Let me know what you think of Start-RemoteProcess:</p>
<p><span style="font-family: courier new,courier;">#******************************************************************************</span><br /><span style="font-family: courier new,courier;">#* &lt;Function Start-RemoteProcess&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#* This function uses WMI to start a process on a remote computer.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#* Input:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp; [string] $Path - path to the file to execute&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp; [string] $Computer - computer to create the process on&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $Window {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Hidden" - hide the process window&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Normal" - activate and display the window (default)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Minimized" - minimize the window&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Maximized" - maximize the window&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp; [string] $StartPath - the starting path for the application&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp; [string] $Title - set the title of the window&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp; [switch] $Priority {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Realtime" - set the process priority to realtime&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "High" - set the process priority to high&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "AboveNormal" - set the process priority to above normal&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Normal" - set the process priority to normal (default)&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "BelowNormal" - set the process priority to below normal&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Idle" - set the process priority to idle&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp; [int]&nbsp;&nbsp;&nbsp; $X - set the x position of the window&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp; [int]&nbsp;&nbsp;&nbsp; $XSize - set the width of the window&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp; [int]&nbsp;&nbsp;&nbsp; $Y - set the y position of the window&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp; [int]&nbsp;&nbsp;&nbsp; $YSize - set the height of the window&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp; [PSCredential] $Credential - Credentials to connect to the computer&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp; [switch] $Elevate - Elevate the process in UAC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#* Output:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#*&nbsp;&nbsp;&nbsp;&nbsp; [wmiobject]"Win32_Process" - the process that was created&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;">#******************************************************************************</span><br /><span style="font-family: courier new,courier;">function Start-RemoteProcess {</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; param(</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Mandatory=$True,</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ValueFromPipeline=$True,</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HelpMessage='The process to start on the computer')]</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [string] $Path,</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HelpMessage='The computer to start the process on')]</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [string] $Computer = ".",</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HelpMessage='The starting working path for the application')]</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [string] $StartPath = "c:\windows\system32\",</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ValidateSet("Hidden", "Normal", "Minimized", "Maximized",</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IgnoreCase= $True)]</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HelpMessage='What state to start the program window')]</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $Window = "Normal",</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HelpMessage='The title to assign to the window')]</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [string] $Title,</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ValidateSet("RealTime", "High", "AboveNormal", "Normal", </span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "BelowNormal","Idle", IgnoreCase=$True)]</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HelpMessage='What priority to assign the new process')]</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $Priority = "Normal",</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HelpMessage='The starting X position of the window')]</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [int] $X,</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HelpMessage='The width of the window')]</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [int] $XSize,</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HelpMessage='The starting Y position of the window')]</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [int] $Y,</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HelpMessage='The starting height of the window')]</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [int] $YSize,</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HelpMessage='Credentials to connect to the remote computer')]</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [PSCredential] $Credential,</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Parameter(</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HelpMessage='Elevate the process in User Account Control')]</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [switch] $Elevate = $False</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; )</span><br />&nbsp;&nbsp;&nbsp; <br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; #Create a new instance of W32_ProcessStartup</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; $wmiProcessStartup = [wmiclass]"Win32_ProcessStartup"</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; #Set the window state for the process</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; switch($Window) {</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Hidden" {$wmiProcessStartup.Properties['ShowWindow'].Value = 0}</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Minimized" {$wmiProcessStartup.Properties['ShowWindow'].Value = 2}</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Maximized" {$wmiProcessStartup.Properties['ShowWindow'].Value = 3}</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; }</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; #Set the window title if specified</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; if ($Title -ne $Null) {$wmiProcessStartup.Properties['Title'].Value = $Title}</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; #Set the process priority, if specified</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; switch($Priority){</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "RealTime" {$wmiProcessStartup.Properties['PriorityClass'].Value = 256}</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "High" {$wmiProcessStartup.Properties['PriorityClass'].Value = 128}</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "AboveNormal" {$wmiProcessStartup.Properties['PriorityClass'].Value = 32768}</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "BelowNormal" {$wmiProcessStartup.Properties['PriorityClass'].Value = 16384}</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Idle" {$wmiProcessStartup.Properties['PriorityClass'].Value = 64}</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; }</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; #Set the window X position if specified</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; If ($X -ne $Null) {$wmiProcessStartup.Properties['X'].Value = $X}</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; #Set the window Y position if specified</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; If ($Y -ne $Null) {$wmiProcessStartup.Properties['Y'].Value = $Y}</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; #Set the window width if specified</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; If ($XSize -ne $Null) {$wmiProcessStartup.Properties['XSize'].Value = $XSize}</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; #Set the window height if specified</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; If ($YSize -ne $Null) {$wmiProcessStartup.Properties['YSize'].Value = $YSize}</span></p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; if ($Credential -eq $Null) {</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #Credentials were not specified</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If ($Elevate) {</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #Elevation was requested</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return Invoke-WmiMethod -ComputerName $Computer -Class "Win32_Process" -Name Create -EnableAllPrivileges -ArgumentList $Path, $StartPath, $wmiProcessStartup</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #Elevation was not requested</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return Invoke-WmiMethod -ComputerName $Computer -Class "Win32_Process" -Name Create -ArgumentList $Path, $StartPath, $wmiProcessStartup</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; } else {</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #Credentials were specified</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If ($Elevate) {</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #Elevation was requested</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return Invoke-WmiMethod -ComputerName $Computer -Class "Win32_Process" -Name Create -EnableAllPrivileges -ArgumentList $Path, $StartPath, $wmiProcessStartup -Credential $Credential</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #Elevation was not requested</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return Invoke-WmiMethod -ComputerName $Computer -Class "Win32_Process" -Name Create -ArgumentList $Path, $StartPath, $wmiProcessStartup -Credential $Credential</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br /><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; }</span><br /><span style="font-family: courier new,courier;">}</span></p>
<p><span style="font-family: courier new,courier;"><span style="font-family: courier new,courier;">#******************************************************************************</span><br /><span style="font-family: courier new,courier;">#* &lt;/Function Start-RemoteProcess&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span><br /><span style="font-family: courier new,courier;"><span style="font-family: courier new,courier;">#******************************************************************************</span></span></span></p>]]></content:encoded>
    </item>
    <item>
      <title>Validating a Certificate</title>
      <link>https://docs.microsoft.com/archive/blogs/option_explicit/validating-a-certificate</link>
      <pubDate>Thu, 19 Apr 2012 07:28:00 GMT</pubDate>
      <dc:creator><![CDATA[Michael Melone]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/option_explicit/2012/04/19/validating-a-certificate/</guid>
      <description><![CDATA[Certificate validation is implemented differently based on the application validating the...]]></description>
      <content:encoded><![CDATA[<p>Certificate validation is implemented differently based on the application validating the certificate, the type of identity being validated (i.e. validating a certificate from a web server will differ from validating a signed e-mail), and configuration of the Windows computer performing the validation.&nbsp; In general, three main areas of a certificate are checked during validation:</p>
<ul>
<li>Does one of the asserted identification attributes match the identity of the principal supplying the certificate?</li>
<li>Is the certificate being used in an authorized capacity?</li>
<li>Does the certificate chain to a certificate listed in the "Trusted Root Certification Authorities" certificate store?</li>
<li>Is the certificate revoked?</li>
</ul>
<h1>Validating the Identity of the Certificate Owner</h1>
<p>In&nbsp;many cases, certificates are designed to provide identification of the computer or person holding the corresponding private key.&nbsp; For example, when a user provides their Windows Live credentials to log on to a website the computer will validate that the certificate being used by the web server is authorized for&nbsp;the URL the user is accessing.&nbsp; Another example of this is when you receive a digitally signed e-mail; the e-mail signature is only valid if the sender's e-mail matches the e-mail address listed on the certificate (under RFC822 Name).</p>
<p>In the initial two versions of the X.509 standard the only way to assert an identity was to use the "Subject" field of the certificate.&nbsp; This field contains the X.500 address (also referred to as the LDAP distinguished name) of the object whose identity is being asserted.&nbsp; As mentioned in my previous blog entry on the X.509 certificate, this is a throw back to the roots and original intent for PKI: directory services.&nbsp; Later, when version 3 of the X.509 standard was passed, the "Subject Alternative Name" (sometimes referred to as a "SAN" field) was added allowing the issuer additional flexibility in specifying the identity of the authenticating entity.&nbsp; Out-of-the-box this provided options to identify the certificate owner in any of the following ways (ref: <a href="http://publib.boulder.ibm.com/infocenter/domhelp/v8r0/index.jsp?topic=%2Fcom.ibm.help.domino.admin.doc%2FDOC%2FH_KEY_USAGE_EXTENSIONS_FOR_INTERNET_CERTIFICATES_1521_OVER.html">http://publib.boulder.ibm.com/infocenter/domhelp/v8r0/index.jsp?topic=%2Fcom.ibm.help.domino.admin.doc%2FDOC%2FH_KEY_USAGE_EXTENSIONS_FOR_INTERNET_CERTIFICATES_1521_OVER.html)</a>:</p>
<ul>
<li><strong>RFC 822 Name</strong><br />Another name for rfc822Name is the subject's e-mail address</li>
<li><strong>DNS Name</strong><br />A DNS name meeting specifications outlined in RFC 1034 (<a href="http://www.ietf.org/rfc/rfc1034.txt">http://www.ietf.org/rfc/rfc1034.txt</a>)</li>
<li><strong>X.400 Address</strong><br />The X.400&nbsp;standard governs message handling and look similar to the X.500 directory services standard, however addressing elements such as the country name, organization name, given name, surname, initials, etc.)</li>
<li><strong>Directory Name</strong><br />This is the distinguished name of the subject</li>
<li><strong>Electronic Data Identifier (EDI)&nbsp;Party Name</strong><br />The ediPartyName attribute allows the certificate to specify an alternative authority (referred to as a nameAssigner) that has assigned a name to the subject.&nbsp; An example of where this might be of use is in federation whereby another directory service is asserting the name of a certified entity.</li>
<li><strong>Uniform Resource Identifier (URI)</strong><br />This field contains a uniform resource identifier, or URI, conforming to RFC 3986 (<a href="http://www.ietf.org/rfc/rfc3986.txt">http://www.ietf.org/rfc/rfc3986.txt</a>).&nbsp; URIs usually look similar to a uniform resource locator (URL), however they are used to provide a hierarchical association of an attribute.&nbsp; URIs are commonly used in XML to uniquely identify a&nbsp;schema and are commonly confused with URLs due to their similarity, however a URI does not need to be a reachable networked location.</li>
<li><strong>IP Address</strong><br />IP address of the certified entity</li>
<li><strong>Registered ID</strong><br />An object identifier (OID) that can be used to identify the certified entity</li>
<li><strong>Other Name</strong><br />Yet another reference to extend the naming capability, use of this allows specification of anything available in the OTHER-NAME information object class</li>
</ul>
<h1>Certificate (Key) Usage Validation</h1>
<p>In addition to&nbsp;validating the identity of the certificate holder an application may validate the purpose that the certificate is authorized for to ensure it is valid for its current use.&nbsp; This validation is what prevents any non-CA certificate from acting as a certification authority and issuing certificates.&nbsp; Key usage&nbsp;can be&nbsp;specified in either the "Key Usage"&nbsp; or "Extended Key Usage" attribute based on the validation requirements of the application.</p>
<p>The "Key Usage" field offers generic purpose validation based on the way an asymmetric key pair may be used as part of a PKI.&nbsp; This is a multivariate field that may consist of&nbsp;zero or more of the following uses:</p>
<ul>
<li><strong>DigitalSignature</strong><br />The public key may be used&nbsp;to verify digital signatures for integrity purposes</li>
<li><strong>Non-Repudiation (later named contentCommitment)</strong><br />The public key may be used to verify digital signatures to prevent false denial of an action (i.e. to identify falsehood in a claim that an action did not occur).&nbsp; The key difference between this use and the "Digital Signature" use is the validation of other signed elements (ex: time or other identifying elements that may not be listed in the certificate).&nbsp; An example of this would be using S\MIME to digitally sign an e-mail</li>
<li><strong>Key Encipherment</strong><br />The public key may be used to&nbsp;encrypt keys or other security information.&nbsp; An example of this would be SSL session key negotiation where the public key on the certificate from a Web server is used to encrypt a symmetric key to be shared to establish a secure channel between a computer and the server (the symmetric key is encrypted with the public key which can then only be decrypted by&nbsp;the matching private key held by the server)</li>
<li><strong>Data Encipherment</strong><br />The public key may be used to encrypt information that does not fall into the category of keys or security information.</li>
<li><strong>Key Agreement</strong><br />The public key may be used to negotiate a key without encrypting the key itself.&nbsp; An example of this would be if a series of keys were pre-populated and the application encrypted information to allow the distant end to choose which key to use.</li>
<li><strong>Certificate Signing (keyCertSign)</strong><br />The public key may be used to validate certificate signatures (only valid on CA certificates)</li>
<li><strong>CRLSigning</strong><br />The public key may be used to verify a CA&rsquo;s signature on a certificate revocation list (CRL)</li>
<li><strong>Encipher Only</strong><br />The public key may only be used to encrypt data to be sent to&nbsp;another system.&nbsp; This key usage is only valid when the Key Agreement usage is set.</li>
<li><strong>Decipher Only</strong><br />The public key may only be used to decrypt data sent from another system.&nbsp; This key usage is only valid when the Key Agreement usage is set.</li>
</ul>
<p>In some cases these basic key usages may not be enough to identify a very specific or important use of the public key.&nbsp; To address this need, the X.509 standard provides an additional field called Extended Key Usage (EKU).&nbsp; Values for the EKU field are defined in a number of different RFCs.&nbsp; Some examples of extended key usages include:</p>
<ul>
<li>Smart card logon</li>
<li>OCSP signing certificates</li>
<li>E-mail digital signature</li>
<li>Certificate Revocation List (CRL) signing</li>
<li>Time stamping</li>
<li>Code signing</li>
<li>Transport Layer Security (TLS) clients or servers</li>
</ul>
<h1>Certificate Chaining and Trust Validation</h1>
<p>Another&nbsp;important&nbsp;part of validating a certificate is ensuring that it chains to a trusted root CA.&nbsp; As discussed in my post on the X.509 certificate, any version 3 certificate signed by a certification authority should have at least one entry under the&nbsp;"Authority Information Access" pointing clients towards a location where they can obtain the certificate of the signing CA to validate the relationship.&nbsp; This path&nbsp;should be available to all clients that may need to validate certificates issued by or chaining to the CA.&nbsp; This concept is important to note when renewing the key pair on a CA since this is commonly done at around 50% of the CA's validity period meaning that certificates will need to access this path after key renewal occurs.&nbsp; When a key pair is renewed on a CA the new certificate should not use the same path as the original certificate unless the private key for the CA and the authority key identifier (AKI)&nbsp;are not changed as part of the renewal.</p>
<h2>Authority Key Identifier \ Subject Key Identifier Matching</h2>
<p>Validity&nbsp;of a certificate chain is confirmed by retrieving the issuer's certificate (by default from the certificate's AIA path) and comparing the issuing certificate's subject key identifier (SKI) entry with the issued certificate's AKI entry.&nbsp; As discussed in part 2 of this series, the SKI is populated with one of three values: the serial number of the certificate, a unique ID assigned by the signing CA, or any manner of identification listed as part of the GeneralName data type.&nbsp; When a CA issues a certificate the signing certificate's SKI is imprinted as the issued certificate's AKI prior to being signed thus asserting the relationship.</p>
<h2>Retrieving the Signing Certificate</h2>
<p>To validate a certificate chain, the&nbsp;validating client must have access to every certificate up to and including the root CA.&nbsp;&nbsp;By default,&nbsp;the client will try to&nbsp;use the certificate's AIA path&nbsp;unless the issuer's certificate is published to the client's intermediate certification authorities (SubCA) store.&nbsp; Windows and Active Directory provide a number of ways to publish these certificates which will be&nbsp;discussed below.</p>
<h3>The Authority Information Access Field</h3>
<p>Once a certificate is issued the AIA path cannot be changed without reissue, therefore the location used to publish these certificates must be thoroughly thought out.&nbsp; The AIA field allows for either HTTP or LDAP paths to provide flexibility in publishing locations.&nbsp; By default, an Active Directory Certificate Services (ADCS) enterprise CA will publish its certificate to the Active Directory configuration partition&nbsp;which is automatically replicated to all domain controllers in the forest.&nbsp; This provides site awareness and resiliency, however this path is best suited for internal use only since its path is likely inaccessible to external clients and can reveal information about your forest.</p>
<p>The alternative is to present the AIA path using HTTP, a more common and Internet-friendly means of distribution.&nbsp; When using HTTP ensure that the web servers publishing the AIA path are highly available and scalable to handle requests from every client that may need to validate a certificate issued by the CA.</p>
<p>&nbsp;</p>
<p>Some important considerations when deciding on the number and location of AIA paths include:</p>
<ul>
<li><strong>Ensure the path is accessible to all clients in all reasonable situations</strong><br />Lack of a signing certificate will break the validating client's ability to chain to a trusted root CA and therefore will likely result in failed validation</li>
<li><strong>Be cautious about exposing internal configurations</strong><br />Although LDAP is a great&nbsp;option for providing availability and&nbsp;distribution, understand that listing an Active Directory path as the&nbsp;AIA path for a certificate will result in that path&nbsp;being hard-coded into every certificate signed by a&nbsp;CA</li>
<li><strong>Order AIA paths based on&nbsp;accessibility to validating&nbsp;clients</strong><br />Clients will&nbsp;try AIA paths in order, therefore it is ideal to list these paths in the order that provides the fastest access to clients</li>
</ul>
<h3>The Intermediate Certification Authorities Store</h3>
<p>To reduce the number of connections to an AIA publishing point and increase resiliency of certificate validation it is sometimes ideal to install CA certificates to the Intermediate Certification Authorities (SubCA) store of validating clients.&nbsp; Use of the SubCA store ensures that certificate validation continues without error when the AIA path written to the certificate becomes inaccessible.&nbsp; As a side benefit, certificates published to clients provide additional configuration options to include configuration of cross-signing certificates, OCSP server address, extended validation options, and purpose limitation through the certificates snap-in or through Group Policy.</p>
<h2>The Trusted Root Certification Authorities Store</h2>
<p>&nbsp;Since root CAs do not have an issuer their certificate will not have all of the information available used to validate other types of certificates (i.e. issuer, AKI, CDP, AIA).&nbsp; Because of this, to establish trust with a root CA it must be installed in the trusted root certification authorities container (RootCA).&nbsp; For a certificate to be considered valid the last CA in the chain must be installed in this container.&nbsp; Like the SubCA store, the RootCA store can be populated locally, through Group Policy, or through Active Directory configuration.</p>
<h1>Checking for Certificate Revocation</h1>
<p>Issues with revocation checking services is probably one of&nbsp;the most common causes of PKI failure.&nbsp; Since PKI is a security service many authentication&nbsp;applications will treat a lack of valid revocation information the same as if the certificate were revoked.&nbsp; Since certificates are commonly issued for multiple years, the risk of compromise is significantly higher than a Kerberos ticket (5 minutes)&nbsp;or even a ticket granting ticket&nbsp;(10 hours).&nbsp; As such, it is important to provide reliable revocation services for these credentials.&nbsp; Since these revocation methods were covered thoroughly in a previous blog entry, this post will focus solely on client interactions with respect to revocation checking.</p>
<p>A few things to consider when designing revocation services:</p>
<ul>
<li><strong>A client will accept the first valid response from a revocation provider<br /></strong>It is ideal to order revocation providers based on locality and service performance.&nbsp; Also, an expired Certificate Revocation List (CRL) counts as a valid response and commonly results in the certificate being treated as revoked.</li>
<li><strong>OCSP is significantly faster and more efficient than CRL checking</strong><br />Whenever possible, leverage OCSP services rather than CRL for PKI deployments of scale.</li>
<li><strong>Provide a valid CRL publishing location even if you are running Windows Vista+<br /></strong>Not every application supports OCSP and the revocation check is not always performed by Windows (i.e Java applications).&nbsp; Also, Windows XP and prior operating systems do not support OCSP.&nbsp; Because of this, it is important to provide a&nbsp;CRL download point to support these situations.</li>
</ul>
<h2>Online Certificate Status Protocol (OCSP)</h2>
<p>Since Windows Vista and Certificate API: Next Generation (CAPI-NG), Online Certificate Status Protocol (OCSP) has been the preferred method to determine the revocation status&nbsp;when available.&nbsp; In addition to supporting OCSP addresses listed in the certificate's AIA, Windows Vista and later also provide the ability to specify alternate OCSP servers through Group Policy or the certificates MMC snap-in.&nbsp; When configured, these addresses are attempted in order prior to trying any addresses listed in the certificate and can be use to provide&nbsp;locality-based services and additional redundancy.&nbsp; On the same tab with the OCSP responders is the option to disable CRL checking altogether; this is not recommended as it may result in denial of service should OCSP services be unavailable.&nbsp; If OCSP addresses are not configured, Windows&nbsp;will try the OCSP address listed in the certificate's AIA field if one exists.</p>
<h2>Certificate Revocation Lists (CRL)</h2>
<p>In the event that OCSP services are not available, if a non-OCSP aware software package is validating revocation status,&nbsp;or Windows XP or prior is in use,&nbsp;revocation &nbsp;the operating system will begin trying paths listed in the CDP field of the certificate in the order&nbsp;provided&nbsp;from top to bottom.&nbsp;&nbsp;The order of&nbsp;CRL distribution points&nbsp;is an important consideration when configuring a CA because clients may experience performance issues or denial of service due to inaccessible CDP paths.&nbsp; In addition, be cautious when using internal addresses on publically available certificates as it may expose internal design information.</p>
<p>A major concern when&nbsp;using CRLs&nbsp;pertains to their potential size.&nbsp; When large amounts of certificate revocations occur on a CA a CRL can grow very large if not partitioned and may result in clients experiencing timeouts when reading these large files.&nbsp; Additionally, a larger CRL will take more resources to validate a certificate.&nbsp; Please note the upcoming section on URL retrieval timeouts when considering the design of your revocation strategy.</p>
<p>Another important consideration when designing a CRL revocation check strategy is&nbsp;ensuring the freshness of the published CRL.&nbsp; In some applications (such as smart card logon), inability to retrieve a valid CRL causes the certificate to be treated as if it were revoked.</p>
<h1>Final Notes&nbsp;</h1>
<h2>URL Retrieval Timeouts</h2>
<p>An important note when considering&nbsp;AIA&nbsp;and CDP paths&nbsp;is the client's URL retrieval timeout limits.&nbsp; In Windows XP (and I am assuming this hasn't changed) clients are allowed a 15 second period to download the certificate from an AIA path or a CRL from a CDP.&nbsp; Within these 15 seconds, the first 10 seconds are allotted to the first path with every subsequent path being allowed 50% of the remaining time&nbsp;of its predecessor (ref: <a href="http://social.technet.microsoft.com/wiki/contents/articles/4954.windows-xp-certificate-status-and-revocation-checking.aspx#CRL_Retrieval_Timeout_Thresholds">http://social.technet.microsoft.com/wiki/contents/articles/4954.windows-xp-certificate-status-and-revocation-checking.aspx#CRL_Retrieval_Timeout_Thresholds)</a>.&nbsp; This means that if a client may take more than 10 seconds to download the content they will be unable to perform the revocation check on any path.</p>
<p>For internal clients with large CRLs or slow links this setting is manageable through registry modification:</p>
<ul>
<li><strong>URL Retrieval Timeout<br /></strong>Registry Location: HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CertDllCreateCertificateChainEngine\Config&nbsp;<br />Type: REG_DWORD<br />Name: ChainUrlRetrievalTimeoutMilliseconds<br />Default: Not set, effective setting is 15000 (15 seconds)<br />Range: 1 - 65535<br />Purpose: Configures the total amount of time (in milliseconds) that a client will allot for retrieving a single certificate's AIA or CDP path</li>
<li><strong>Aggregate URL Retrieval Timeout</strong><br />Registry Location: HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CertDllCreateCertificateChainEngine\Config<br />Type: REG_DWORD<br />Name: ChainRevAccumulativeUrlRetrievalTimeoutMilliseconds<br />Default: Not set, effective setting is 20000 (20 seconds)<br />Range: 1-65535<br />Purpose: Defines the maximum amount of time allotted to all URL downloads of a type.</li>
<li><strong>Maximum AIA URL Count<br /></strong>Registry Location: HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CertDllCreateCertificateChainEngine\Config<br />Type: REG_DWORD<br />Name: MaxAIAUrlCountInCert<br />Default: Not set, effective setting is 5<br />Range: 1-65535<br />Purpose: Defines the maximum number of AIA paths retrieved when validating a certificate chain</li>
</ul>
<h2>Custom CAPI Revocation Providers</h2>
<p>This entry covers the way that Windows performs certificate validation, however some environments use custom revocation providers which may modify this behavior.&nbsp; If this software is in use, please refer to their documentation for information on the certificate validation process.</p>]]></content:encoded>
    </item>
    <item>
      <title>The PKI Revocation Infrastructure</title>
      <link>https://docs.microsoft.com/archive/blogs/option_explicit/the-pki-revocation-infrastructure</link>
      <pubDate>Thu, 12 Apr 2012 15:56:00 GMT</pubDate>
      <dc:creator><![CDATA[Michael Melone]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/option_explicit/2012/04/12/the-pki-revocation-infrastructure/</guid>
      <description><![CDATA[One of the benefits of leveraging PKI is the ability to revoke a certificate.&nbsp; PKI is a loosely...]]></description>
      <content:encoded><![CDATA[<p>One of the benefits of leveraging PKI is the ability to revoke a certificate.&nbsp; PKI is a loosely coupled system that outsources trust to organizations in charge of asserting identities of otherwise unknown systems.&nbsp; At times, these external entities may become compromised thus requiring revocation of their provided certificate.&nbsp; Unfortunately, this feature also tends to be the one most likely to cause an outage in PKI. &nbsp;A lack of valid revocation information in many cases marks the certificate as revoked.&nbsp; That said it is important to ensure availability of all revocation information locations provided on the certificate as well as any revocation sources explicitly specified elsewhere on the operating system or application validating the certificate.</p>
<p>Certificate revocation information is available in various forms; I will cover these in an evolutionary manner starting with the Certificate Revocation List (CRL).</p>
<h1>Certificate Revocation List (CRL)</h1>
<p>The CRL, originally defined in RFC 1422, is a flat file containing the serial numbers of certificates revoked by the signing certificate authority (CA).&nbsp; Two versions of the CRL format exist; however, version 1 is unlikely to be found today.</p>
<h2>CRL version 1</h2>
<p>Originally defined in the 1988 ITU standard for PKI (section 10.2.6), version 1 of the CRL format was suitable for directory services use only.&nbsp; In its initial version, the CRL was expected to exist in a predictable location in directory services and provided two multivariate values: certificateRevocationList and authorityRevocationList.</p>
<ul>
<li><strong>Certificate Revocation List</strong><br />An array of certificate serial numbers corresponding to certificates revoked by a certificate authority.&nbsp; Each entry is formatted as follows:</li>
<ul>
<li><strong>Signature</strong><br />A digital signature to prevent unauthorized tamper of the CR</li>
<li><strong>Issuer</strong><br />The name of the CRL issue</li>
<li><strong>Last Update</strong><br />The UTC time of the CRL update</li>
<li><strong>Revoked Certificates<br /></strong>A signed certificate revocation entry containing the certificate issuer, serial number, and revocation date</li>
</ul>
<li><strong>Authority Revocation List<br /></strong>Though rarely implemented, the Authority Revocation List (ARL) provides a revocation mechanism for trusted certificate authorities.&nbsp; This functionality is effectively replaced through adding compromised root CAs to the untrusted certificate authorities container in Windows.</li>
</ul>
<p>This simple format was modified in 1993 prior to being formally implemented in RFC 1422 along with the first version of the X.509 certificate (<a href="http://tools.ietf.org/html/rfc1422">http://tools.ietf.org/html/rfc1422</a>, section 3.5).</p>
<h2>CRL version 2</h2>
<p>As the possibilities associated with PKI were realized, it became apparent that version 1 of the CRL was insufficient for the wide array of purposes it could serve.&nbsp; In response, CRL version 2 was developed and published along with the new X.509 v3 certificate standard in RFC 2459 (<a href="http://tools.ietf.org/html/rfc2459">http://tools.ietf.org/html/rfc2459</a>, section 5).&nbsp; The format added the following fields:</p>
<ul>
<li><strong>Version</strong><br />This field is used to denote format used for the CRL</li>
<li><strong>Revoked Certificates {crlEntryExtension}</strong><br />The optional crlEntryExtension attribute was added to the revokedCertificates type to allow the CA to note reason codes and revocation dates associated with certificate revocation entries.&nbsp; This class contains the following fields:
<ul>
<li><strong>Reason Code<br /></strong>The reason code is an integer value noting the reason why the certificate was revoked</li>
<li><strong>Hold Instruction Code<br /></strong>This feature shows that a CA is now able to place a certificate on hold, a state whereby the certificate is to be treated as revoked, however not necessarily permanent.&nbsp; One interesting feature of this field is the ability to have the validating entity contact the issuer if the certificate is encountered.</li>
<li><strong>Invalidity Date<br /></strong>This is the date that the certificate was deemed invalid</li>
<li><strong>Certificate Issuer<br /></strong>This is a very important field noting the issuer of the revoked certificate by its subject.&nbsp; If this field is empty it is assumed that the revoking entity was the same as the CRL issuer.</li>
</ul>
</li>
<li><strong>CRL Extensions<br /></strong>Version 2 of the CRL format was improved much in the same way as version 3 of the X.509 certificate.&nbsp; This field holds values defined as extensions in RFC 5280, the same RFC used to define certificate extensions.&nbsp; A discussion of some of the extensions available for use is available in part 2 of the PKI series.&nbsp; Extensions designed specifically for use with CRLs are discussed below.</li>
</ul>
<h2>CRL Extensions</h2>
<p>Version 2 of the CRL added a few extensions specifically designed for improving validation capabilities.&nbsp; Some of these extensions include the following:</p>
<ul>
<li><strong>Authority Key Identifier</strong><br />Like the X.509 certificate, the authority key identifier is a string value used to uniquely identify the key pair used to sign the CRL.&nbsp; This value is most commonly populated with a hash of the public key.</li>
<li><strong>Issuer Alternative Name</strong><br />A CA administrator can use the issuer alternative name to specify identities other than the subject that the signing CA may be known by.&nbsp; Essentially, this is the same as the X.509 subject alternative name field except applying to the issuer rather than the certified asset.</li>
<li><strong>CRL Number</strong><br />CRL number is a serial number associated with the current CRL.&nbsp; This number should be sequential and incremented by one with every new CRL published.</li>
<li><strong>Delta CRL Indicator<br /></strong>The delta CRL is a differential revocation list designed to improve performance of revocation checking, especially in the instance of large or fast-growing revocation lists.&nbsp; This functionality is discussed below.</li>
<li><strong>Issuing Distribution Point</strong><br />This field identifies where the CRL is published for consumption and should match the CRL distribution point (CDP) field of the associated certificate.&nbsp; This path must be either HTTP or LDAP.</li>
</ul>
<h2>Delta CRL</h2>
<p>Version 2 of the CRL improved revocation checking through implementing the concept of a delta CRL.&nbsp; Bandwidth can become an issue when revocation lists change frequently or grow lengthy with revoked certificates.&nbsp; To address this concern the standard created the ability to use delta CRLs; differential revocation lists published on a more regular basis than the CRL.</p>
<p>Without delta CRLs, a client must download potentially large revocation lists (100 MB is possible) every time the CRL expires.&nbsp; This causes the CA administrator to need to choose between bandwidth and timely revocation information (clients will not need to obtain a new CRL until the old one expires, therefore it may take weeks before the revoked credential is treated as such by clients).</p>
<p>The delta CRL was designed to alleviate these concerns by providing a smaller differential CRL containing all certificates revoked since the publishing of the main CRL that could be published more regularly and required less bandwidth to download.</p>
<p>An important note regarding the use of delta CRLs is that a valid copy of both the main CRL and the delta CRL must be available to perform a successful revocation check.&nbsp; Because of this, an empty delta CRL must be published whenever a new CRL is published.&nbsp; By default, in a Windows CA the delta CRL is published with the same name as the CRL with a &ldquo;+&rdquo; appended.</p>
<h1>Online Certificate Status Protocol (OCSP)</h1>
<p>Despite improvements realized from the use of delta CRLs, the revocation process was still bandwidth and resource intensive.&nbsp; Clients wishing to validate the revocation status of a certificate needed to download one or two files (CRL and an optional delta CRL), load these potentially large files into memory, perform a signature and trust verification, and finally search them for a serial number.&nbsp; Though this may not sound terribly resource intensive consider a situation such as smart card login for a domain controller.&nbsp; Due to the security implications associated with domain authentication, revocation information is sought at every authentication attempt.&nbsp; If multiple CAs provide user certificates for logon purposes each will have their own CRLs and delta CRLs.&nbsp; This scenario compounded with the morning logon rush and large (50+ MB) revocation lists and performance will quickly degrade.</p>
<p>In 1999, Entrust&rsquo;s RFC for OCSP (<a href="http://www.ietf.org/rfc/rfc2560.txt"><span style="color: #0000ff; font-family: Calibri; font-size: small;">http://www.ietf.org/rfc/rfc2560.txt</span></a>) was published in an effort to solve all of these issues.&nbsp; The vehicle used to perform revocation checks using OCSP is defined loosely (no transport mechanism is mandated per RFC), however almost all implementations of OCSP use HTTP or HTTPS.</p>
<h2>OCSP Request</h2>
<p>An OCSP request is formatted using ASN.1 syntax with DER encoding in alignment with the formatting of most other PKI communication.&nbsp; The basic format of the OCSP request is as follows:</p>
<ul>
<li><strong>Version</strong><br />The version of the OCSP protocol used</li>
<li><strong>Requestor Name</strong><br />An optional string value representing the identity of the requestor</li>
<li><strong>Request List</strong><br />A multivariate attribute containing one or more certificates to validate.&nbsp; This is an important improvement that allows a single request to validate multiple certificates.&nbsp; Individual requests are sent using a hash of the issuer name, a hash of the issuer&rsquo;s public key, and the serial number of the certificate to be validated.</li>
</ul>
<p>Optionally, the entire request can be digitally signed to prove the identity of the owner as well as the integrity of the message (without this, it is possible to use a man-in-the-middle attack to modify the request in-transit and change the certificates being validated thus damaging the integrity of the system).</p>
<h2>OCSP Response</h2>
<p>Once the OCSP responder has accepted the request, it searches the revocation information it has stored and generates an individual response for each revocation request returned as an array of responses.&nbsp; In addition to these responses, the responder has the ability to provide response status codes.&nbsp; Per RFC 2560 the approved response codes are:</p>
<ul>
<li>(0) Successful</li>
<li>(1) Malformed Request</li>
<li>(2) Internal Error</li>
<li>(3) Try Later</li>
<li>(5) Signature is Required (and wasn&rsquo;t provided as part of the request)</li>
<li>(6) Unauthorized</li>
</ul>
<p>Each certificate revocation request entry is provided an individual response (for example, if four certificates were sent for validation the response will contain four OCSP response entries).&nbsp; Each individual entry is digitally signed and is listed as either good, revoked, or unknown along with the last and next update of revocation information.&nbsp; If the certificate is revoked, the revocation time is provided along with (optionally) the reason for revocation.</p>
<h2>OCSP Responder Certificates</h2>
<p>Right about now I&rsquo;m sure some of the security geeks out there are thinking of all of the scenarios that could result from obtaining a trusted certificate for OCSP purposes.&nbsp; To address the potential issue whereby an attacker could trick a victim into trusting revocation information through using an OCSP responder certificate from a well-known trusted certification authority the standard mandates that the OCSP responder certificate must have been issued from the CA it is answering on behalf of (RFC 2560 section 4.2.2.2).&nbsp; This is important from an implementation perspective as it means one cannot just stand up an OCSP responder and feed it CRLs from CAs they do not own.&nbsp; For organizations with heavy revocation checks against organizationally external CAs this likely means reliance on WAN links for activities that require positive revocation responses (i.e. smart card logon).&nbsp; To solve this issue, some OCSP responder vendors have developed systems whereby OCSP responses are pre-signed and downloaded to on-site OCSP responder instances thereby alleviating reliance on the WAN.&nbsp; In addition, Microsoft provides an option on Windows 7 \ Windows Server 2008 R2 and later clients to allow the OCSP responder to use any trusted OCSP responder certificate for a CA.</p>
<p>Now a chicken-and-the-egg issue arises: if the OCSP responder certificate is issued by the CA and also responds on behalf of the CA how do we obtain revocation information for that certificate?&nbsp; The answer here: we don&rsquo;t.&nbsp; This means that the compromise of an OCSP responder certificate is a critical security breach.&nbsp; To address this issue, OCSP responder certificates should be issued with a very short lifespan.&nbsp; By default, the Active Directory certificate template used for OCSP specifies a validity period of&nbsp;two weeks.</p>
<h2>Nonce</h2>
<p>One question that tends to arise when customers&nbsp; configure OCSP is an option called &ldquo;include nonce&rdquo;.&nbsp; According to RFC 2560 &ldquo;The nonce cryptographically binds a request and a response to prevent replay attacks&rdquo;; an abstract term that leads most to only becoming more confused, enabling nonce, then potentially experiencing revocation outages.&nbsp; The nonce extension prevents the OCSP responder from using a cached revocation response.</p>
<p>Using the nonce extension forces an administrator to decide that the integrity of the revocation response is so important that it is worth risking the availability thereof.&nbsp; Using this option prevents use of the previously-mentioned OCSP response caching systems, will increase the CPU utilization on the OCSP responder, and increase the time it takes to receive a revocation response.&nbsp;</p>
<p>If the nonce extension is configured and the OCSP responder is unable (either through configuration or lack of an OCSP responder certificate) to provide this capability it will reject the request with an &ldquo;unauthorized&rdquo; error.</p>
<h2>Locating an OCSP Responder</h2>
<p>OCSP responder addresses can be stamped as part of the certificate&rsquo;s properties; however, they are not where most would expect to find it.&nbsp; If a CA has an OCSP responder available, it can stamp the address of the OCSP responder in the Authority Information Access extension (not the CRL Distribution Point).</p>
<p>In some cases, organizations may add an OCSP responder after implementing PKI or offer an on-site OCSP responder to improve performance and decrease WAN utilization.&nbsp; For these situations, Microsoft provides the option to configure OCSP addresses through group policy (Windows Vista or later).&nbsp; OCSP responder information is configured on a per-CA basis in the certificate store, whether in Group Policy or locally.&nbsp; For detailed information on how to configure an OCSP responder with Group Policy please refer to <a href="http://technet.microsoft.com/en-us/library/ee619786(v=WS.10).aspx">http://technet.microsoft.com/en-us/library/ee619786(v=WS.10).aspx</a>.</p>
<p>Last, if your organization has down-level (Windows XP \Server 2003 R2 or prior) you may need to rely on a third-party OCSP responder client to provide this functionality.</p>]]></content:encoded>
    </item>
    <item>
      <title>Establishing the PKI Relationship</title>
      <link>https://docs.microsoft.com/archive/blogs/option_explicit/establishing-the-pki-relationship</link>
      <pubDate>Thu, 12 Apr 2012 12:53:00 GMT</pubDate>
      <dc:creator><![CDATA[Michael Melone]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/option_explicit/2012/04/12/establishing-the-pki-relationship/</guid>
      <description><![CDATA[An important rule in PKI is that the private key can never leave the asset being certified without...]]></description>
      <content:encoded><![CDATA[<p>An important rule in PKI is that the private key can <span style="text-decoration: underline;">never</span> leave the asset being certified without being protected (and it is best practice that the private key never leaves the asset if possible).&nbsp;&nbsp;If the private key leaves the certified asset at any time without sufficient protection the key is subject to compromise thus reducing the integrity of the system and the certified asset.&nbsp; That said,&nbsp;the key pair can only be generated on the asset being certified (a common misconception is that the certification authority (CA) generates the key pair, however this would imply that the CA, a service that is commonly external to the certified asset, could easily impersonate anything it certifies).&nbsp; This key pair is generated using a cryptographic service provider (CSP), a Dynamic Link Library (DLL) containing functions required to generate and use an asymmetric key pair.&nbsp; Windows provides a number of&nbsp; CSPs as part of the operating system installation, however also provides a framework for custom CSP development (<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa380245(v=vs.85).aspx">http://msdn.microsoft.com/en-us/library/windows/desktop/aa380245(v=vs.85).aspx</a>).&nbsp; Custom CSPs are rarely used outside of hardware security modules (HSM), a more advanced topic to be covered later.</p>
<p>In most cases key pair generation occurs as part of a certificate request process (without a certificate request the asset can only be self-signed and thus will not be trusted by external entities by default).&nbsp; As part of the certificate request the requesting user or computer will specify a series of attributes it would like to appear on the certificate.&nbsp; These attributes can be changed by the certification authority prior to issuance of the certificate (depending on the CA software being&nbsp;used) based on the template, issuance policies, etc.&nbsp; All of this information is then digitally signed by the new private key to prove ownership and packaged into a ASN.1 DER-encoded certificate request following either&nbsp;Public Key Cryptography Standard (PKCS) #10 (<a href="http://www.rsa.com/rsalabs/node.asp?id=2132">http://www.rsa.com/rsalabs/node.asp?id=2132</a>) a.k.a. RFC 2986 (<a href="http://tools.ietf.org/html/rfc2986">http://tools.ietf.org/html/rfc2986</a>) or Certificate Management Messages over CMS (CMC) request (<a href="http://www.ietf.org/rfc/rfc2797.txt">http://www.ietf.org/rfc/rfc2797.txt</a>).</p>
<p>Once the request is generated it can be transmitted safely to the certification authority in a number of manners based on the system used and its available capabilities ranging from a completely manual submission to a completely automated enrollment when using Windows Server 2003 or later CA's and domain membership (this topic will be covered in a later post).&nbsp; Regardless of how the request is transmitted to the CA it will result in a pending certificate request requiring some form of authentication and authorization (which may be automated) and is not governed by the X.509 standard.&nbsp; In many cases certificates are issued based on templates, a capability defined in RFC 4212 (<a href="http://www.ietf.org/rfc/rfc4212.txt">http://www.ietf.org/rfc/rfc4212.txt</a>).&nbsp; These templates enable standardization of the format used for a given certificate and, in the case of Microsoft Windows CAs, can be used to determine issuance policies.</p>
<p>At this time, the administrators operating the CA have the ability to review and optionally modify (based on the CA platform used) the request to fit policy.&nbsp; Once the organization operating the CA has sufficiently determined the authenticity of the request and its authorization the CA administrator can approve the request which will cause the CA to convert the request into an X.509 certificate.&nbsp; At this time the certificate will contain the public key, a validity period determined by the CA, the location(s) where clients can access the CA's public key (called the Authority Information Access, or AIA), location(s) where revocation information will be published (called the Certificate Revocation List (CRL) Distribution Point, or CDP), a hash of the CA's private key (called the Authority Key Identifier), as well as a number of other parameters that can be optionally configured on the CA (for more information on this please see the previous post in this series, <a href="http://blogs.technet.com/b/option_explicit/archive/2012/04/09/pki-series-part-2-certificates-and-the-x.509-standard.aspx">http://blogs.technet.com/b/option_explicit/archive/2012/04/09/pki-series-part-2-certificates-and-the-x.509-standard.aspx</a>).&nbsp; The authenticity is then established when the CA uses its private key to digitally sign this information thus preventing unauthorized modification.</p>
<h1>Using a Microsoft Certification Authority</h1>
<p>Microsoft provides many benefits when using the Active Directory Certificate Services (ADCS) certification authority role, especially when configured as an enterprise certification authority.&nbsp; For the purposes of this post we will limit the discussion of these benefits to only those facilitating enrollment and will not cover topics such as certificate management, template management, or other CA-centric tasks (these will be covered in&nbsp;a later post).</p>
<p>Organizations leveraging an ADCS enterprise CA are able to use features such as certificate auto-enrollment (or for Windows 2000 workstations Automatic Certificate Request) to simplify the process of certificate issuance.&nbsp; These features allow users&nbsp;and computers to leverage their Active Directory credentials to request certificates from an enterprise CA.</p>
<h2>Automatic Certificate Request Settings (ACRS)</h2>
<p>Automatic Certificate Request Settings (ACRS) was developed as a means to&nbsp;automatically issue&nbsp;computer certificates on computers running Windows 2000 or later.&nbsp; This feature enables these computers to automatically enroll themselves for a computer certificate from a specified enterprise CA.</p>
<p>ACRS is configured through computer group policy and will only appear when editing a domain policy (these settings will not be displayed if you are editing your local computer policy) and are at the following location: "Computer Configuration\Policies\Windows Settings\Security Settings\Public Key Policies\Automatic Certificate Request".&nbsp; Certificates used for ACRS must be based on an Active Directory certificate template which is assignable to computer objects (this method cannot be used to enroll user certificates) and can only be based on a v1 template (listed as a "Windows 2000" template in Windows Server 2008 R2 and prior or as schema version 1 on Windows Server 8 beta).</p>
<h2>Certificate Auto-Enrollment</h2>
<p>Auto-enrollment is an evolution of ACRS that began shipping with Windows 2003.&nbsp; Auto-enrollment provides both&nbsp;users and computers&nbsp;the ability to participate in automatic certificate enrollment.&nbsp; Client computers participating in auto-enrollment must use at least&nbsp;Windows 2003 or Windows XP and require an enterprise CA running one of the following operating systems:</p>
<ul>
<li>Windows 2003 Enterprise or Datacenter</li>
<li>Windows 2003 R2 Enterprise or Datacenter</li>
<li>Windows 2008 Enterprise or Datacenter</li>
<li>Windows 2008 R2 Standard, Enterprise, or Datacenter</li>
</ul>
<p>To use auto-enrollment the user or computer must be allowed both enroll and autoenroll permissions on the Active Directory certificate template.&nbsp; In addition, the enrolling user or computer must be configured to use auto-enrollment through group policy (note: computer configuration only applies to the computer's automatic enrollment ability and the user's configuration only applies to the user's automaitc enrollment; one does not configure both).</p>
<p>Auto-enrollment requires a certificate template version of at least 2 (listed as "Windows 2003" in Windows 2008&nbsp;R2 and prior, schema version 2 in Windows Server 8 beta); the autoenroll permission isn't even available on v1 templates.</p>
<h2>ADCS Web Enrollment</h2>
<p>Microsoft provides Web enrollment as a role feature for ADCS to simplify user certificate enrollment processes (in previous versions users were allowed to enroll certificates on behalf of computers, however this is no longer available).&nbsp; In its current version (Windows Server 2008+) Web enrollment allows users to request certificates based on v1 and v2 certificate templates and, based upon issuance policies assigned to those templates, can automatically issue certificates based on provided domain authentication.</p>
<h2>Certificate Enrollment Web Services (CES) \ Certificate Enrollment Policy Web Services (CEP)</h2>
<p>A new feature introduced with Windows Server 2008 R2 is the ability to manage certificate enrollment using Web services using a combination of the Certificate Enrollment Web Services (CES) and Certificate Enrollment Policy Web Services (CEP) role features (under the ADCS role).&nbsp; These Web services enable administrators to configure client computers to manage certificates without RPC access to the certification authority (a major manageability improvement when dealing with firewalls).&nbsp; Use of this feature requires at least Windows Vista or Windows Server 2008 certificate clients.</p>
<h2>Microsoft Simple Certificate Enrollment Protocol (MSCEP) \ Microsoft Network Device Enrollment Services (NDES)</h2>
<p>In order to support Cisco System's Simple Certificate Enrollment Protocol (SCEP) (<a href="http://www.cisco.com/warp/public/cc/pd/sqsw/tech/scep_wp.htm">http://www.cisco.com/warp/public/cc/pd/sqsw/tech/scep_wp.htm</a>)&nbsp;Microsoft provides two different solutions based on what version of Windows is running on the server performing certificate enrollment; &nbsp;Microsoft Simple Certificate Enrollment Protocol (MSCEP) in Windows Server 2003 (<a href="http://www.microsoft.com/download/en/details.aspx?displaylang=en&amp;id=2178">http://www.microsoft.com/download/en/details.aspx?displaylang=en&amp;id=2178</a>)&nbsp;and Network Device Enrollment Services (NDES) role service in Windows Server 2008 (<a href="http://technet.microsoft.com/en-us/library/ff955645(v=ws.10).aspx">http://technet.microsoft.com/en-us/library/ff955645(v=ws.10).aspx</a>).</p>
<p>Many new devices are requiring certificates to authenticate to corporate resources in order to obtain access to resources such as wireless networks.&nbsp; Some of these devices have chosen to leverage the SCEP protocol to request their certificate due to its inherent simplicity.&nbsp; SCEP is essentially a simple Web service that can provide a device a certificate in as few as&nbsp;four exchanges (client requests SCEP server's certificate, SCEP server sends certificate, client requests certificate from SCEP server, server provides certificate) when authentication is not used; Even when the SCEP server requires authentication only a few additional packets are required to complete the transaction.</p>
<h1>How to Perform a Certificate Request using&nbsp;the Windows&nbsp;GUI \ CLI</h1>
<p>Microsoft Windows offers a number of ways to generate a certificate request.&nbsp; In addition to the following methods, many applications (such as IIS and Exchange) provide interfaces to request certificates from the operating system to simplify the process and to ensure that all required attributes and OIDs are resident in the request.&nbsp; To simplify this post, we will cover three of the most common ways to generate certificates; the MMC snap-in, certreq.exe, and Internet Information Services (IIS).</p>
<h2>Request a Certificate using the Certificates MMC Snap-In with an Enrollment Policy</h2>
<p>If your environment is configured with an enterprise certification authority (or if you are requesting a certificate using Certificat Enrollment Web Service (CES) feature of Windows 2008 R2) you may have the ability to leverage the enrollment policy to handle your certificate request.&nbsp; Enrollment policies are essentially instructions for how your computer can request certificates from an enterprise certification authority.</p>
<ol>
<li>Open the&nbsp;Microsoft Management Console (MMC).</li>
<li>Click the File drop-down menu and select "Add / Remove Snap-in...".</li>
<li>Double-click the "Certificates" snap-in and select the principal you want to request a certificate for (the current user, a service account, or the computer's account) and click the "Next &gt;" or&nbsp;"Finish" button.</li>
<ol>
<li>If you selected service account or computer account choose the&nbsp;user you are requesting a certificate for (you cannot perform any private key management requests for&nbsp;remote computers) and click the "Finish" button.</li>
</ol>
<li>Click the "OK" button on the "Add or Remove Snap-ins" dialogue.</li>
<li>Expand the newly-added "Certificates" snap-in.</li>
<li>Right-click the "Personal" store (it will appear as a folder), select "All Tasks &gt;", then "Request New Certificate...".</li>
<li>Click the "Next &gt;" button on the "Before You Begin" dialogue.</li>
<li>If you are requesting a certificate based on a published template choose the appropriate enrollment policy and click the "Next" button.&nbsp; If you need to perform a custom request (i.e. a request where you will need to specify a different enrollment policy than is configured) you can click the "Add New" option under "Custom Request" and specify the enrollment policy server's information.</li>
<li>Choose the template for the certificate you wish to request and click "Enroll".&nbsp; Note that this screen will only display certificate types that you are allowed to enroll for; selecting the "show all templates" option will display all available templates.</li>
<ol>
<li>Some certificates will require additional information prior to requesting them.&nbsp; These can be identified by the caution symbol beneath the template and to the left of to the link to provide the additional information.</li>
</ol>
<li>Based on the configuration of the certificate template the certificate will either be automatically issued to you or be submitted for authorization by a CA manager.&nbsp; The certificate will be automatically downloaded and installed once the request is complete if using the Active Directory enrollment policy.&nbsp; If the certificate was requested using CES from an external organization the certificate can also be installed manually by importing it into the certified entity's personal store.</li>
</ol>
<h2>Request a Certificate using the Certificates MMC Snap-In without an Enrollment Policy (called an offline request)</h2>
<p>If you are working with a stand-alone or external certification authority you may need to process your request through submission of a PKCS #10 or CMC request.</p>
<ol>
<li>Open the Microsoft Management Console (MMC).</li>
<li>Click the File drop-down menu and select "Add / Remove Snap-in...".</li>
<li>Double-click the "Certificates" snap-in and select the principal you want to request a certificate for (the current user, a service account, or the computer's account) and click the "Next &gt;" or "Finish" button.</li>
<ol>
<li>If you selected service account or computer account choose the user you are requesting a certificate for (you cannot perform any private key management requests for remote computers) and click the "Finish" button.</li>
</ol>
<li>Click the "OK" button on the "Add or Remove Snap-ins" dialogue.</li>
<li>Expand the newly-added "Certificates" snap-in.</li>
<li>Right-click the "Personal" store (it will appear as a folder), select "All Tasks &gt;", then "Advanced Operations &gt;", then "Create Custom Request...".</li>
<li>Select "Proceed without enrollment policy" under the "Custom Request" header and click the "Next" button.</li>
<li>Choose the template (CNG (not supported on all applications as of this writing) or Legacy Key)&nbsp;from the drop-down menu and the&nbsp;request format&nbsp;(CMC or PKCS #10) and click the "Next" button.</li>
<li>Click the arrow next to "Details"&nbsp;under the "Custom Request" header and click the "Properties" button.</li>
<li>Fill out the certificate properties for the associated request (an explanation of these properties are available in the previous post).&nbsp; Once complete click the "OK" button.</li>
<li>Click the "Next" button on the "Certificate Information" window.</li>
<li>Choose where you would like to save the resulting request file and the format to save it in and click the "Finish" button.</li>
<li>Provide this file to the certification authority to submit the request (software implementations may vary).</li>
<li>Once the certificate request is approved, the resulting certificate file can be imported into the requesting entity's personal store to join the certificate with its associated private key.</li>
</ol>
<h2>Using certreq.exe</h2>
<p>&nbsp;For those fond of command line interfaces and .inf files Microsoft has provided certreq.exe.&nbsp; Using certreq.exe is simple, however the associated .inf file can be complex.&nbsp; Formatting required for the .inf file can be found at the following location: <a href="http://technet.microsoft.com/en-us/library/cc736326(v=WS.10).aspx">http://technet.microsoft.com/en-us/library/cc736326(v=WS.10).aspx</a>.&nbsp;</p>
<h4>certreq.exe -new</h4>
<p>Generating a new certificate request can be done&nbsp;by&nbsp;running the&nbsp;"certreq.exe -new {requestFileOutputPath}" command and either specifying the requested attributes as switches or providing an .inf file with all of the requested attributes for the new certificate.</p>
<h4>certreq.exe -submit</h4>
<p>Once&nbsp;a request has been generated it can be easily sent to a CA configured by an enrollment policy using the "certreq.exe -submit {requestFilePath}" switch.</p>
<h4>certreq.exe -retrieve</h4>
<p>If a certificate has been approved by an enterprise CA it can be retrieved using "certreq.exe -retrieve {requestID}".&nbsp; This command will retrieve the signed certificate from the CA and allow you to save it to your system.</p>
<h4>certreq.exe -accept</h4>
<p>To complete a request using certreq.exe you can use the "certreq.exe -accept" switch to install the new certificate and associate it with the private key.&nbsp;</p>
<h2>Using Internet Information Services (IIS)</h2>
<p>&nbsp;A common way to request secure sockets layer (SSL) certificates is through the built-in interfaces provided in IIS.&nbsp; The following are steps required to perform the certificate request (source: <a href="http://technet.microsoft.com/en-us/library/cc732906(v=WS.10).aspx">http://technet.microsoft.com/en-us/library/cc732906(v=WS.10).aspx</a>)</p>
<ol>
<li>Open IIS Manager and navigate to the level you want to manage. For information about opening IIS Manager, see <a href="http://technet.microsoft.com/en-us/library/cc770472(v=ws.10).aspx">Open IIS Manager (IIS 7)</a>. For information about navigating to locations in the UI, see <a href="http://technet.microsoft.com/en-us/library/cc732920(v=ws.10).aspx">Navigation in IIS Manager (IIS 7)</a>.</li>
<li>In Features View, double-click Server Certificates.</li>
<li>In the Actions pane, click Create Certificate Request.</li>
<li>On the Distinguished Name Properties page of the Request Certificate Wizard, type the following information, and then click Next.</li>
<ol>
<li>In the Common name text box, type a name for the certificate.</li>
<li>In the Organization text box, type the name of the organization in which the certificate will be used.</li>
<li>In the Organizational unit text box, type the name of the organizational unit in the organization in which the certificate will be used.</li>
<li>In the City/locality text box, type the unabbreviated name of the city or locality where your organization or organizational unit is located.</li>
<li>In the State/province text box, type the unabbreviated name of the state or province where your organization or organizational unit is located.</li>
<li>In the Country/region text box, type the name of the country or region where your organization or organizational unit is located.</li>
</ol>
<li>On the Cryptographic Service Provider Properties page, select either Microsoft RSA SChannel Cryptographic Provider or Microsoft DH SChannel Cryptographic Provider from the Cryptographic service provider drop-down list. By default, IIS&nbsp;7 uses the Microsoft RSA SChannel Cryptographic Provider.</li>
<li>In the Bit length drop-down list, select a bit length that can be used by the provider. By default, the RSA SChannel provider uses a bit length of 1024. The DH SChannel provider uses a bit length of 512. A longer bit length is more secure, but it can affect performance.</li>
<li>Click Next.</li>
<li>On the File Name page, type a file name in the Specify a file name for the certificate request text box, or click the browse button (&hellip;) to locate a file, and then click Finish.</li>
<li>Send the certificate request to a public CA.&nbsp;</li>
</ol>
<h1>How to Perform a Certificate Request using a Script</h1>
<p>For all of the systems administrators wishing to automate this effort somewhat I will provide two script examples on how to request an X.509 certificate, one in VBScript and the other a custom PowerShell cmdlet that I created.&nbsp; Before getting into the code I will take a moment to cover the object used&nbsp;in requesting certificates, CEnroll (<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa376007(v=vs.85).aspx">http://msdn.microsoft.com/en-us/library/windows/desktop/aa376007(v=vs.85).aspx</a>).</p>
<h2>How to Establish the Relationship Programmatically</h2>
<p>Now, for my code monkey readers some sample code thanks to MSDN.&nbsp; In addition, I will provide a non-developer translation for the sysadmins interested in how things work behind the scenes.&nbsp;</p>
<h2>Generating and Submitting a Certificate Request in C++</h2>
<p>The following source code was copied from&nbsp;the following&nbsp;MSDN&nbsp;post&nbsp;&nbsp;(<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa387670(v=vs.85).aspx">http://msdn.microsoft.com/en-us/library/windows/desktop/aa387670(v=vs.85).aspx</a>).&nbsp; Please note that this code uses Windows XP \ Server 2003 R2 and prior methods.</p>
<table border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td valign="top" colspan="2">
<p align="center"><span>Certificate Request in C++ (and function translation)</span></p>
</td>
</tr>
<tr>
<td width="500" valign="top">
<p align="center"><strong>Source Code</strong></p>
</td>
<td valign="top">
<p align="center"><strong>Non-Developer Translation</strong></p>
</td>
</tr>
<tr>
<td valign="top">
<p>// Copyright (C) Microsoft.&nbsp; All rights reserved</p>
<p>// Example for Certificate Enrollment Control</p>
<p>// used with ICertRequest in C++</p>
<p>//</p>
</td>
<td width="450" valign="top">
<p>Standard copyright information</p>
</td>
</tr>
<tr>
<td valign="top">
<p>#include &lt;stdio.h&gt;</p>
<p>#include &lt;Certsrv.h&gt; // for ICertRequest object</p>
<p>#include &lt;xenroll.h&gt;</p>
<p>#include &lt;windows.h&gt;</p>
</td>
<td width="450" valign="top">
<p>Include all of the&nbsp;necessary DLL's to perform the certificate request.&nbsp; For those unfamiliar with C++, these .h files are called header files and contain all of the publicly accessible functions in a DLL and the inputs required for them.</p>
</td>
</tr>
<tr>
<td valign="top">
<p>HRESULT __cdecl main()</p>
<p>{</p>
</td>
<td width="450" valign="top">
<p>This is the beginning of the main function which returns a hexadecimal result code</p>
</td>
</tr>
<tr>
<td valign="top">
<p>&nbsp;&nbsp;&nbsp; // Pointer to interface objects.</p>
<p>&nbsp;&nbsp;&nbsp; ICEnroll4 * pEnroll = NULL;</p>
<p>&nbsp;&nbsp;&nbsp; ICertRequest2 * pRequest = NULL;</p>
</td>
<td width="450" valign="top">
<p>Here we are defining memory locations where we will place memory pointers for the software interfaces we will use to request the certificate.<br /><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa382488(v=vs.85).aspx">ICEnroll4</a> &ndash; an interface for enrolling a certificate request (deprecated in Vista \ 2008)<br /><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa385041(v=vs.85).aspx">ICertRequest2</a> an interface for requesting a certificate</p>
</td>
</tr>
<tr>
<td valign="top">
<p>&nbsp;&nbsp;&nbsp; // BSTR variables.</p>
<p>&nbsp;&nbsp;&nbsp; BSTR&nbsp;&nbsp;&nbsp; bstrDN = NULL;</p>
<p>&nbsp;&nbsp;&nbsp; BSTR&nbsp;&nbsp;&nbsp; bstrOID = NULL;</p>
<p>&nbsp;&nbsp;&nbsp; BSTR&nbsp;&nbsp;&nbsp; bstrCertAuth = NULL;</p>
<p>&nbsp;&nbsp;&nbsp; BSTR&nbsp;&nbsp;&nbsp; bstrReq = NULL;</p>
<p>&nbsp;&nbsp;&nbsp; BSTR&nbsp;&nbsp;&nbsp; bstrAttrib = NULL;</p>
</td>
<td width="450" valign="top">
<p>Now we are defining the variable inputs we will use later such as:<br /> - The distinguished name of the certificate (the subject)<br /> - OIDs for the certificate (how it can be used)<br /> - A configuration string for the CA it will be submitted to<br /> - A string location to hold the resulting PKCS #10 request<br /> - A string to hold any attributes the certificate will need</p>
</td>
</tr>
<tr>
<td valign="top">
<p>&nbsp;&nbsp;&nbsp; // Request disposition variable.</p>
<p>&nbsp;&nbsp;&nbsp; long&nbsp;&nbsp;&nbsp; nDisp;</p>
</td>
<td width="450" valign="top">
<p>&hellip;and a location to hold the result code from the request submission attempt</p>
</td>
</tr>
<tr>
<td valign="top">
<p>&nbsp;&nbsp;&nbsp; // Variable for return value.</p>
<p>&nbsp;&nbsp;&nbsp; HRESULT&nbsp;&nbsp;&nbsp; hr;</p>
</td>
<td width="450" valign="top">
<p>...and finally, a variable to hold result codes in case we encounter any issues.</p>
</td>
</tr>
<tr>
<td valign="top">
<p>&nbsp;&nbsp;&nbsp; // Initialize COM.</p>
<p>&nbsp;&nbsp;&nbsp; hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );</p>
<p></p>
<p>&nbsp;&nbsp;&nbsp; // Check status.</p>
<p>&nbsp;&nbsp;&nbsp; if ( FAILED( hr ) )</p>
<p>&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Failed CoInitializeEx - [%x]\n", hr);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error;</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
</td>
<td width="450" valign="top">
<p>Now that all of the variables and interface pointers are defined, we try to initialize the COM interface.<br /><a href="http://blogs.technet.com/tiny_mce/plugins/paste/CoCreateInstanceEx()">CoCreateInstanceEx()</a></p>
</td>
</tr>
<tr>
<td valign="top">
<p>&nbsp;&nbsp;&nbsp; // Create an instance of the Certificate Enrollment object.</p>
<p>&nbsp;&nbsp;&nbsp; hr = CoCreateInstance( CLSID_CEnroll,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NULL,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CLSCTX_INPROC_SERVER,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IID_ICEnroll4,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (void **)&amp;pEnroll);</p>
<p>&nbsp;&nbsp;&nbsp; // Check status.</p>
<p>&nbsp;&nbsp;&nbsp; if ( FAILED( hr ) )</p>
<p>&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Failed CoCreateInstance - pEnroll [%x]\n", hr);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error;</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
</td>
<td width="450" valign="top">
<p>Since the COM interface call was successful we use COM to create a new instance of the ICEnroll4 interface at the location we allocated<br /><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms686615(v=vs.85).aspx">CoCreateInstance()</a></p>
</td>
</tr>
<tr>
<td valign="top">
<p>&nbsp;&nbsp;&nbsp; // Create an instance of the Certificate Request object.</p>
<p>&nbsp;&nbsp;&nbsp; hr = CoCreateInstance( CLSID_CCertRequest,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NULL,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CLSCTX_INPROC_SERVER,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IID_ICertRequest2,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (void **)&amp;pRequest);</p>
<p>&nbsp;&nbsp;&nbsp; // Check status.</p>
<p>&nbsp;&nbsp;&nbsp; if ( FAILED( hr ) )</p>
<p>&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Failed CoCreateInstance - pRequest [%x]\n", hr);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error;</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
</td>
<td width="450" valign="top">
<p>Now we create an instance of the certificate request object and place it into the ICertRequest2 location we allocated before.</p>
</td>
</tr>
<tr>
<td valign="top">
<p>&nbsp;&nbsp;&nbsp; // Create the data for the request.</p>
<p>&nbsp;&nbsp;&nbsp; // A user interface or database retrieval could</p>
<p>&nbsp;&nbsp;&nbsp; // be used instead of this sample's hard-coded text.</p>
<p>&nbsp;&nbsp;&nbsp; bstrDN = SysAllocString(L"CN=UserName"&nbsp;&nbsp;&nbsp; // Common Name</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; L",OU=UserUnit"&nbsp;&nbsp; // Org Unit</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; L",O=UserOrg"&nbsp;&nbsp;&nbsp;&nbsp; // Org</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; L",L=UserCity"&nbsp;&nbsp;&nbsp; // Locality</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; L",S=WA"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // State</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; L",C=US");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Country/Region</p>
<p>&nbsp;&nbsp;&nbsp; if (NULL == bstrDN)</p>
<p>&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Failed SysAllocString\n");</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error;</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
</td>
<td width="450" valign="top">
<p>Now that we have the memory structures successfully populated with an instance of the interfaces we start building our variables that we will use to perform the request.&nbsp; Here we are building the distinguished name (a.k.a. subject) of our certificate.&nbsp; The resulting subject should be &ldquo;CN=UserName,OU=UserUnit,O=UserOrg,L=UserCity,S=WA,C=US&rdquo;.&nbsp; Why use LDAP format?&nbsp; The X.509 standard was built as part of the X.500 series of directory services standards when it was created.&nbsp; You may recognize X.500 as a directory services location address; this standard also defined DAP which evolved into LDAP, thus the naming format.</p>
</td>
</tr>
<tr>
<td valign="top">
<p>&nbsp;&nbsp;&nbsp; // Allocate the BSTR representing the certification authority.</p>
<p>&nbsp;&nbsp;&nbsp; // Note the use of '\\' to produce a single '\' in C++.</p>
<p>&nbsp;&nbsp;&nbsp; bstrCertAuth = SysAllocString(L"Server\\CertAuth");</p>
<p>&nbsp;&nbsp;&nbsp; if (NULL == bstrCertAuth)</p>
<p>&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Failed SysAllocString\n");</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error;</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
</td>
<td width="450" valign="top">
<p>We now set the name of the certification authority we will submit the request to.&nbsp; In this case it will be &ldquo;Server\CertAuth&rdquo;, though requests developed on Windows 7 \ Server 2008 R2 can use a HTTPS location (this is due to the availability of Certificate Enrollment Web Services in Server 2008 R2 (ref: <a href="http://blogs.technet.com/b/askds/archive/2010/02/01/certificate-enrollment-web-services.aspx">http://blogs.technet.com/b/askds/archive/2010/02/01/certificate-enrollment-web-services.aspx</a>))</p>
</td>
</tr>
<tr>
<td valign="top">
<p>&nbsp;&nbsp;&nbsp; // Allocate the BSTR for the certificate usage.</p>
<p>&nbsp;&nbsp;&nbsp; bstrOID = SysAllocString(L"1.3.6.1.4.1.311.2.1.21");</p>
<p>&nbsp;&nbsp;&nbsp; if (NULL == bstrOID)</p>
<p>&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Failed SysAllocString\n");</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error;</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
</td>
<td width="450" valign="top">
<p>In this section we define the object identifiers (OID) that define the requested use of the certificate we want.&nbsp; In this case it is &ldquo;1.3.6.1.4.1.311.2.1.21&rdquo; which is &ldquo;SPC_INDIVIDUAL_SP_KEY_PURPOSE_OBJID&rdquo;.&nbsp; Translation: Authenticode Software Publishing&nbsp; (ref: <a href="http://support.microsoft.com/kb/287547">http://support.microsoft.com/kb/287547</a>)</p>
</td>
</tr>
<tr>
<td valign="top">
<p>&nbsp;&nbsp;&nbsp; // Allocate the BSTR for the attributes.</p>
<p>&nbsp;&nbsp;&nbsp; // In this case, no attribute is specified.</p>
<p>&nbsp;&nbsp;&nbsp; bstrAttrib = SysAllocString(L"");</p>
<p>&nbsp;&nbsp;&nbsp; if (NULL == bstrAttrib)</p>
<p>&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Failed SysAllocString\n");</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error;</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
</td>
<td width="450" valign="top">
<p>And finally, we define any additional attributes for the certificate (available attributes will be covered later).&nbsp; In this instance we do not request any additional attributes.</p>
</td>
</tr>
<tr>
<td valign="top">
<p>&nbsp;&nbsp;&nbsp; // Create the PKCS #10.</p>
<p>&nbsp;&nbsp;&nbsp; hr = pEnroll-&gt;createPKCS10( bstrDN, bstrOID, &amp;bstrReq );</p>
<p>&nbsp;&nbsp;&nbsp; // check status</p>
<p>&nbsp;&nbsp;&nbsp; if ( FAILED( hr ) )</p>
<p>&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Failed createPKCS10 - [%x]\n", hr);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error;</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
</td>
<td width="450" valign="top">
<p>Finally, time to create the request!&nbsp; Plug the distinguished name and the OID into the createPKCS10 function of the ICEnroll4 interface.&nbsp; The resulting PKCS10 request is returned to the bstrReq string value we defined in the beginning of the application.<br /><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa382820(v=vs.85).aspx">createPKCS10</a></p>
</td>
</tr>
<tr>
<td valign="top">
<p>&nbsp;&nbsp;&nbsp; // Submit the certificate request.</p>
<p>&nbsp;&nbsp;&nbsp; hr = pRequest-&gt;Submit( CR_IN_BASE64 | CR_IN_PKCS10,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bstrReq,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bstrAttrib,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bstrCertAuth,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;nDisp );</p>
<p>&nbsp;&nbsp;&nbsp; // Check status.</p>
<p>&nbsp;&nbsp;&nbsp; if ( FAILED( hr ) )</p>
<p>&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Failed Request Submit - [%x]\n", hr);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto error;</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; else</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Request submitted; disposition = %d\n", nDisp );</p>
</td>
<td width="450" valign="top">
<p>And, now that we have our request built we use the Submit function of the ICertRequest2 function to submit the request to the Server\CertAuth CA.&nbsp; Note that the format listed for this submission is Base-64 encoded PKCS #10.&nbsp; The CA will return a result based on the submission&rsquo;s disposition which is placed in the nDisp variable.&nbsp; If the submission code comes back successful (a.k.a. less than 0x80000000) we are done!</p>
</td>
</tr>
<tr>
<td valign="top">
<p>error:</p>
<p></p>
<p>&nbsp;&nbsp;&nbsp; // Done processing.</p>
<p>&nbsp;&nbsp;&nbsp; // Clean up object resources.</p>
<p>&nbsp;&nbsp;&nbsp; if ( NULL != pEnroll )</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pEnroll-&gt;Release();</p>
<p>&nbsp;&nbsp;&nbsp; if ( NULL != pRequest )</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pRequest-&gt;Release();</p>
<p></p>
<p>&nbsp;&nbsp;&nbsp; // Free BSTR variables.</p>
<p>&nbsp;&nbsp;&nbsp; if ( NULL != bstrDN )</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SysFreeString ( bstrDN );</p>
<p>&nbsp;&nbsp;&nbsp; if ( NULL != bstrOID )</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SysFreeString ( bstrOID );</p>
<p>&nbsp;&nbsp;&nbsp; if ( NULL != bstrCertAuth )</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SysFreeString ( bstrCertAuth );</p>
<p>&nbsp;&nbsp;&nbsp; if ( NULL != bstrReq )</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SysFreeString ( bstrReq );</p>
<p>&nbsp;&nbsp;&nbsp; if ( NULL != bstrAttrib )</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SysFreeString ( bstrAttrib );</p>
<p>}</p>
</td>
<td width="450" valign="top">
<p>Error handling code, only invoked if things do not go as planned&hellip;</p>
</td>
</tr>
</tbody>
</table>]]></content:encoded>
    </item>
    <item>
      <title>PKI Certificates and the X.509 Standard</title>
      <link>https://docs.microsoft.com/archive/blogs/option_explicit/pki-certificates-and-the-x-509-standard</link>
      <pubDate>Mon, 09 Apr 2012 07:51:00 GMT</pubDate>
      <dc:creator><![CDATA[Michael Melone]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/option_explicit/2012/04/09/pki-certificates-and-the-x-509-standard/</guid>
      <description><![CDATA[In my previous post&nbsp;in the PKI series we covered some history of asymmetric cryptography as...]]></description>
      <content:encoded><![CDATA[<p>In my previous post&nbsp;in the PKI series we covered some history of asymmetric cryptography as well as&nbsp;some of the basic uses of PKI.&nbsp; In this post, we will cover&nbsp;a bit more on how the cryptographic relationship in PKI works as well as how to request a new certificate.&nbsp; All content in this post assumes that the reader is familiar with the concepts discussed in the previous post in the series.&nbsp; If you are new to PKI and find yourself unfamiliar with terminology used in this post please read its predecessor, <a title="PKI Series Part 1 - Basics and History of PKI" href="http://blogs.technet.com/b/option_explicit/archive/2012/03/10/pki-series-part-1-_2d00_-basics-and-history-of-pki.aspx">http://blogs.technet.com/b/option_explicit/archive/2012/03/10/pki-series-part-1-_2d00_-basics-and-history-of-pki.aspx</a>.</p>
<h1>So, what is PKI?</h1>
<p>PKI is a system that leverages certificates and asymmetric cryptography to exchange encryption keys paired with&nbsp;trustworthy attributes through use of a hierarchical trust system and revocation infrastructure.&nbsp; The entire basis of PKI surrounds the certificate, a document containing the public key of the asset being certified (the one holding the corresponding private key) as well as a number of attributes about that system digitally signed by (in most cases) a certification authority (CA) that chains up to a trusted source (commonly a root CA).&nbsp; The attributes on these certificates are used to prove different aspects about the user or computer with the associated private key to include:</p>
<ul>
<li>A subject (or subject alternative name) which can be used to match an identity associated with a certified asset (i.e. DNS name, user name, e-mail address, etc.)</li>
<li>A validity period for the certificate</li>
<li>A location where revocation information for the certificate could be found</li>
<li>A location where the certificate issuer's certificate can be found to validate the relationship</li>
</ul>
<h1>The X.509 Certificate</h1>
<p>The basis of any PKI is the X.509 certificate.&nbsp; This certificate contains a number of values used to identify the certified entity and prove its validity and trust to the remote end.&nbsp;</p>
<h2>History of the X.509 Standard</h2>
<p>PKI is governed by a the X.509 standard published by the International Telecommunications Union (ITU-T) (<a href="http://www.itu.int/ITU-T/">http://www.itu.int/ITU-T/</a>) as part of the X.500 series of standards governing directory services.&nbsp; Those of you familiar with Active Directory or Exchange will be familiar with X.500, the standard responsible for LDAP, the Directory Information Tree (DIT), Directory Systems Agent (DSA), and a number of other Active Directory foundations (<a href="http://www.itu.int/rec/T-REC-X.500-200811-I">http://www.itu.int/rec/T-REC-X.500-200811-I</a>).</p>
<p>The X.509 standard is one of the more active X.500 standards undergoing (as of this writing) a total of 20 revisions since its initial publish in November of 1988.&nbsp; This high level of activity speaks to the level of evolution in the standard driven by its widespread use.&nbsp; The initial X.509 standard was labeled as&nbsp; "X.509 : The Directory - Authentication framework" , however this was changed to "X.509 : Information Technology - Open Systems Interconnection - The Directory: Public-key and attribute certificate frameworks" in its fourth revision in March of 2000.&nbsp; This name change reflects the change in use of the X.509 standard due to its widespread use for purposes other than directory authentication.</p>
<p>In the original X.509 standard PKI is referred to as "strong authentication" leveraging a family of cryptographic systems known as Public Key Cryptographic Systems (PKCS).&nbsp; The standard does not necessitate a specific encryption algorithm, but rather describes itself as a "framework... applicable to any suitable public key cryptosystem" which remains consistent in all subsequent versions of the X.509 standard (<a href="http://www.itu.int/rec/T-REC-X.509-198811-S">http://www.itu.int/rec/T-REC-X.509-198811-S</a>).&nbsp; This is an important note since it demonstrates that PKI is not a specific cryptographic algorithm, but rather a means to use an asymmetric algorithm of the user's choosing to prove a set of meta data which enables identification and trust.</p>
<h2>Certificate Versions and Attributes</h2>
<p>&nbsp;X.509 certificates are currently in their third format since the original ITU specification.&nbsp; Each subsequent version of the certificate was designed to be backwards compatible with any prior versions and thus will contain all attributes from the prior version.&nbsp; Due to this backwards-compatibility attributes will be provided in association with the version in which they were established.&nbsp; In cases where the purpose or use of the attribute changed over time the change will be noted in the initial declaration of the attribute.</p>
<h4>Version 1 (RFC 1422 <a href="http://www.ietf.org/rfc/rfc1422">http://www.ietf.org/rfc/rfc1422</a>)</h4>
<p>Version 1 of the X.509 certificate standard was established in 1993 despite being originally established by the ITU&nbsp;in November of 1988.&nbsp; At this time the focus of the standard was directory services authentication and did not include any mechanisms to obtain the public key or revocation information.&nbsp; Fields on a version 1 certificate are as follows:</p>
<ul>
<li><strong>Version Number</strong><br />The version number field denotes the version of the X.509 certificate.&nbsp; Version 1 certificates have this value set to 0.</li>
<li><strong>Serial Number</strong><br />The unique serial number of the certificate assigned by the certification authority.&nbsp; The size of the serial number (data size) should be consistent for all certificates issued by a certification authority.</li>
<li><strong>Signature and Signature Algorithm</strong><br />This field holds the digital signature from the issuing authority as well as the algorithm used to perform the signature.&nbsp; This signature is what protects and proves the integrity of the attributes stored in the certificate.&nbsp; The signature is verified using the public key of the issuing CA.</li>
<li><strong>Issuer Name</strong><br />The issuer name was, at this time, the distinguished name of the issuing CA used to uniquely identify the certifying authority for trust validation.&nbsp; In version 2 of the X.509 standard they realized the rigidity of the standard and established an additional field, issuerUniqueIdentifier, which could be used in lieu of the distinguished name of the CA.</li>
<li><strong>Validity Period</strong><br />This field contains the start and end of the time period which the certificate will be valid written in coordinated universal time (UTCT) format based on Greenwich Mean Time (GMT).&nbsp; In addition, it&nbsp;is recommended that the granularity of time used in this field be no more than a minute, however flexibility is permitted.</li>
<li><strong>Subject Name</strong><br />This field contains&nbsp;the X.500&nbsp;Distinguished Name (DN) used to&nbsp;uniquely identify the object.&nbsp; The intent in X.509 version 1 was to tie the entity to a location in a directory, however later modifications of this field now use it as a way to uniquely identify the principal that owns the certificate (for example, the DN does not need to be the same as an object's DN in Active Directory).&nbsp; This modification started in X.509v2 (the subjectUniqueIdentifier field was established to allow the authenticating entity to use this field in the event that the DN was reassigned).&nbsp; To allow additional flexibility, the subjectAlternativeName attribute became available in version 3 (discussed later in this post).</li>
<li><strong>Subject Public Key</strong><br />This field holds the public key of the subject as well as the algorithm identifier.</li>
</ul>
<h4>Version 2 (ITU-T Recommendation X.509, Nov 1993 <a href="http://www.itu.int/rec/T-REC-X.509-199311-S">http://www.itu.int/rec/T-REC-X.509-199311-S</a>)</h4>
<p>Version 2 of the X.509 certificate was very short-lived and rarely used.&nbsp; In fact, the Internet Engineering Task Force (IETF) did not turn version 2 of the certificate into a RFC standard whatsoever.&nbsp; The key change from X.509v1 to X.509v2 was the improved flexibility in identifying the issuer and the subject.&nbsp; Fields added by the X.509v2 standard are the following:</p>
<ul>
<li>
<p><strong>Issuer Unique Identifier</strong><br />The issuer unique identifier field allowed another (optional) means to uniquely identify the certification authority.</p>
</li>
<li>
<p><strong>Subject Unique Identifier</strong><br />As with the issuer unique identifier, the subject unique identifier was an optional field that could be used to provide a unique ID for the subject.&nbsp; The explanation for this is to allow reassignment of a distinguished name while still maintaining the ability to uniquely identify the subject (see note 2 under section 8)</p>
</li>
</ul>
<h4>Version 3 (RFC 2549 <a href="http://tools.ietf.org/html/rfc2459">http://tools.ietf.org/html/rfc2459</a>)</h4>
<p>Version 3 of the X.509 certificate is the most common format found today.&nbsp; In this version of the certificate a single field was added that allows the extensibility required to support multiple applications and is likely the reason that this version is still in use today.</p>
<ul>
<li><strong>Extensions</strong><br />The extensions field of a certificate is defined as a series of data type Extension.&nbsp; Each extension has three parts:</li>
<ul>
<li><strong>Extension ID (extnId)</strong><br />A value designed to hold an object identifier (or OID) which is used to uniquely identify the value that follows</li>
<li><strong>Critical</strong><br />Critical is a Boolean value with a default value of false.&nbsp; If set to true, applications processing the certificate will be expected to validate the setting in order to ensure the identity of the certificate holder (in other words, the validation of the extension is critical to properly identifying the certificate holder).</li>
<li><strong>Extension Value (extnValue)</strong><br />This is a DER-encoded value formatted as specified by the extension type.&nbsp; For example, if the extension ID was the OID associated with RFC822Name (commonly used to denote e-mail addresses) this value would hold the e-mail address.</li>
</ul>
</ul>
<p>Another important thing to note about this standard is the awareness of the upcoming century change.&nbsp; Note 2 under section 8 specified that two-digit UTC year notations with a value of 00 to 49 would be treated as years 2000 &ndash; 2049 while two-digit year notations of 50 &ndash; 99 would denote 1950 &ndash; 1999.</p>
<h4>Extensions (based on RFC 5280, May 2008 <a href="http://www.ietf.org/rfc/rfc5280.txt">http://www.ietf.org/rfc/rfc5280.txt</a>)</h4>
<p>With the new capability came a set of new extensions.&nbsp; At this time we will depart from the historical context behind these changes and focus on the fields and their purposes.</p>
<ul>
<li><strong>Authority Key Identifier</strong><br />This field identifies the public key that can be used to verify the issuer of the certificate.&nbsp; The authority key identifier field enables the use of distinct keys by the same certification authority (for example, in the event of a key renewal).&nbsp; The three means to identify this key relationship are through the serial number of the issuer&rsquo;s certificate, a unique ID established by the certification authority, or through use of any manner of identification listed as part of the GeneralName data type.&nbsp; The GeneralName data type allows the use of any of the means provided by the Subject Alternative Name class. &nbsp;&nbsp;Most commonly, the AKI is populated with a hash of the public key used by the issuing CA.&nbsp; The important part of this field is that its value must match that of the subject key identifier on the issuing CA.</li>
<li><strong>Subject Key Identifier</strong><br />The subject key identifier is used to identify the current public key being certified.&nbsp; It can be populated with any of the values available to the authority key identifier.</li>
<li><strong>Key Usage</strong><br />The key usage field is used to define the purposes that the public key can be used.&nbsp; Values that can exist for key usage are:
<ul>
<li><strong>DigitalSignature</strong><br />For verification of digital signatures</li>
<li><strong>Non-Repudiation (later named contentCommitment)</strong><br />For verifying digital signatures used to prevent false denial of an action (i.e. to identify falsehood in a claim that an action did not occur)</li>
<li><strong>Key Encipherment</strong><br />For enciphering keys or other security information</li>
<li><strong>Data Encipherment</strong><br />For enciphering information that does not fall into the category of keys or security information</li>
<li><strong>Key Agreement</strong><br />For use as a public key agreement key</li>
<li><strong>Certificate Signing (keyCertSign)</strong><br />For verification of CA signatures on certificates</li>
<li><strong>CRLSigning</strong><br />For verifying a CA&rsquo;s signature on a certificate revocation list (CRL) (this topic will be covered in a later post)</li>
<li><strong>Encipher Only</strong><br />For enciphering data during key agreement (requires the keyAgreement bit)</li>
<li><strong>Decipher Only</strong><br />For deciphering data during key agreement (requires the keyAgreement bit)</li>
</ul>
</li>
<li><strong>Extended Key Usage</strong><br />This field may be used in conjunction with or in replacement of the key usages specified above and allows for more specific controls over what purposes the certificate is valid for.&nbsp; The following list identifies enhanced key usages defined by RFC 5280 (please note, there are many of these that exist and are not listed in the standard):</li>
<ul>
<li>TLS WWW server authentication</li>
<li>TLS WWW client authentication</li>
<li>Signing of executable code (code-signing)</li>
<li>E-mail protection</li>
<li>Time stamping</li>
<li>OCSP signing</li>
</ul>
<li><strong>Authority Information Access (AIA)<br /></strong>The AIA field of a certificate is very important to validating the trust chain of a certificate.&nbsp; This multivariate field contains one or more HTTP or LDAP paths to the signing CA's certificate.&nbsp; This field must be reachable by the client to validate the signature of a certificate and trace a path to a trusted root CA.&nbsp; In addition, this field may conain one or more URLs that point to Online Certificate Status Protocol (OCSP) servers to improve revocation checking performance.&nbsp; OCSP will be covered in part 4 of the PKI series.</li>
<li><strong>CRL Disribution Point (CDP)</strong><br />The CDP field is a pointer to HTTP or LDAP distribution points for certificate revocation lists (CRL).&nbsp; The CRL is a means of ensuring the certificate's current validity and can cause certificates to be incorrectly identified as revoked if&nbsp;the path is&nbsp;unreachable.</li>
<li><strong>Private Key Usage Period<br /></strong>The maximum period of time that the private key is allowed to be used (deprecated)</li>
<li><strong>Certificate Policies</strong><br />Entries in this section provide links to the certification authoritiy's Certification Practice Statement (CPS) as well as the user notice.&nbsp; The CPS is a legal document governing the practices associated with certificate handling for an organization.</li>
<li><strong>Policy Mappings</strong><br />This field is used to map certificate policies&nbsp;between the issuing CA and the certified entity by policy ID.</li>
<li><strong>Supported Algorithms</strong><br />A list of algorithms supported by the certified entity</li>
<li><strong>Subject Alternative Name</strong><br />The subject alternative name (SAN) field&nbsp;can contain one or more alternate identities for the certified entity.&nbsp; These entries can be any&nbsp;instance of&nbsp;GeneralName.&nbsp; Valid types for GeneralName are:</li>
<ul>
<li><strong>Other Name</strong><br />Yet another reference to extend the naming capability, use of this allows specification of anything available in the OTHER-NAME information object class</li>
<li><strong>RFC 822 Name</strong><br />Another name for rfc822Name is the subject's e-mail address</li>
<li><strong>DNS Name</strong><br />A DNS name meeting specifications outlined in RFC 1034 (<a href="http://www.ietf.org/rfc/rfc1034.txt">http://www.ietf.org/rfc/rfc1034.txt</a>)</li>
<li><strong>X.400 Address</strong><br />The X.400&nbsp;standard governs message handling and look similar to the X.500 directory services standard, however addressing elements such as the country name, organization name, given name, surname, initials, etc.)</li>
<li><strong>Directory Name</strong><br />This is the distinguished name of the subject</li>
<li><strong>Electronic Data Identifier (EDI)&nbsp;Party Name</strong><br />The ediPartyName attribute allows the certificate to specify an alternative authority (referred to as a nameAssigner) that has assigned a name to the subject.&nbsp; An example of where this might be of use is in federation whereby another directory service is asserting the name of a certified entity.</li>
<li><strong>Uniform Resource Identifier (URI)</strong><br />This field contains a uniform resource identifier, or URI, conforming to RFC 3986 (<a href="http://www.ietf.org/rfc/rfc3986.txt">http://www.ietf.org/rfc/rfc3986.txt</a>).&nbsp; URIs usually look similar to a uniform resource locator (URL), however they are used to provide a hierarchical association of an attribute.&nbsp; URIs are commonly used in XML to uniquely identify a&nbsp;schema and are commonly confused with URLs due to their similarity, however a URI does not need to be a reachable networked location.</li>
<li><strong>IP Address</strong><br />IP address of the certified entity</li>
<li><strong>Registered ID</strong><br />An object identifier (OID) that can be used to identify the certified entity</li>
</ul>
<li><strong>Issuer Alternative Name</strong><br />As with the subject alternative name, the issuer alternative name provides other valid names which may be used to identify a certificate's issuer.&nbsp;&nbsp;All names provided by the GeneralNames type (the same one used in the previous Subject Alternative Name field) are valid for this field.</li>
<li><strong>Subject Directory Attributes</strong><br />The subject directory attributes field contains attributes of the certified entity (for example, perhaps a user's nationality) and cannot (per standard) be marked as a critical extension.&nbsp; A good example of how this might be used would be when you want to assert a non-identifying attribute about the certified entity.</li>
<li><strong>Certification Path Constraints: Basic Constraints</strong><br />This field is used to determine whether the current certificate is a certification authority as well as an integer value limiting the maximum depth allowed in the CA chain.&nbsp; Put simply, this field can prevent certificates not intended to be used as a CA from acting as one (doing so would add to the path length and violate the certificate's constraint)</li>
<li><strong>Certification Path Constraints: Name Constraints</strong><br />The name constraints field can be used to limit what&nbsp;name spaces the CA is authoritative for.&nbsp; For example, it could enforce that a CA is only valid for names ending in .microsoft.com thus preventing issued certificates from being valid for .live.com addresses, etc.</li>
<li><strong>Certification Path Constraints: Policy Constraints</strong><br />The policy constraints field can be used to either enforce or prohibit&nbsp;the definition of a&nbsp;CA policy in issued certificates.</li>
</ul>
<h2>The Object Identifier (OID)</h2>
<p>Data in X.509 certificate is organized by object identifiers, or OIDs.&nbsp; OIDs are a hierarchical dotted integer notation used to describe the different types of data stored in a certificate and their associated formatting and have enabled the success of X.509 certificates due to their extensibility (organizations or software wishing to add custom attributes to a certificate are able to by establishing their own unique identifier structure).&nbsp; As this topic is primarily formatting-related and quite lengthy I will refer anyone interested in digging into this to the Open Group's specification located here: <a href="http://pubs.opengroup.org/onlinepubs/009609799/index.htm">http://pubs.opengroup.org/onlinepubs/009609799/index.htm</a>.</p>
<h2>Common File Formats for X.509 Certificates</h2>
<p>Certificate files are written using Abstract Syntax Notation (ASN.1) and require a converter to become human-readable.&nbsp; The most common encoding of individual certificates are DER encoded binary x.509 or Base-64 encoded X.509, or Public Key Cryptography Standard (PKCS) #7 formats (see RFC 2315 <a href="http://tools.ietf.org/html/rfc2315">http://tools.ietf.org/html/rfc2315</a> and RFC 5652 <a href="http://tools.ietf.org/html/rfc5652">http://tools.ietf.org/html/rfc5652</a>).&nbsp; PKCS #7 also enables the storage of multiple certificates in a single file and can be useful to establish trusts with non-public certification authorities where the AIA path may not be accessible (this topic will be covered later).&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Basics and History of PKI</title>
      <link>https://docs.microsoft.com/archive/blogs/option_explicit/basics-and-history-of-pki</link>
      <pubDate>Sat, 10 Mar 2012 04:36:00 GMT</pubDate>
      <dc:creator><![CDATA[Michael Melone]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/option_explicit/2012/03/10/basics-and-history-of-pki/</guid>
      <description><![CDATA[One of the most commonly used and misunderstood concepts of IT that I have encountered is the Public...]]></description>
      <content:encoded><![CDATA[<p>One of the most commonly used and misunderstood concepts of IT that I have encountered is the Public Key Infrastructure, also known as PKI.&nbsp; PKI is one of the most effective methods of ensuring the confidentiality or integrity of data available today; however, an improper implementation of PKI can severely damage the availability of a service.&nbsp; This post begins a series of posts on the topic of PKI and its common uses, ultimately leading up to advanced topics to include Active Directory authentication with an external certification authority (CA).</p>
<div>
<h1>The History of PKI</h1>
</div>
<p>PKI is based on an advanced mathematic relationship called asymmetric cryptography discovered by two Stanford mathematicians, Whitfield Diffie and Martin Hellman, in 1976 (ref: <a href="http://purl.umn.edu/107353"><span style="color: #0000ff;" color="#0000ff">http://purl.umn.edu/107353</span></a>).&nbsp; These mathematicians were faced with two major problems in cryptography: key distribution and identification.&nbsp; In response to these issues, Diffie and Hellman identified a relationship between large prime numbers whereby data encrypted with one key could only be decrypted by its paired key.&nbsp; Due to the difficulty involved in establishing the relationship between these large prime numbers, it is unfeasible to reverse-engineer the relationship with a key of any significant size.&nbsp; This mathematic relationship was eventually called the Diffie-Hellman &nbsp;key exchange (ref: <a href="http://cr.yp.to/bib/1988/diffie.pdf"><span style="color: #0000ff;" color="#0000ff">http://cr.yp.to/bib/1988/diffie.pdf</span></a>, patent: <a href="http://www.docstoc.com/docs/31206972/Public-Key-Cryptographic-Apparatus-And-Method---Patent-4218582"><span style="color: #0000ff;" color="#0000ff">http://www.docstoc.com/docs/31206972/Public-Key-Cryptographic-Apparatus-And-Method---Patent-4218582</span></a>).</p>
<p>Interestingly enough, another set of mathematicians by the names of Ron Rivest, Adi Shamir, and Leonard Adleman identified the same relationship in 1978 and published it as the RSA (based on their initials) algorithm (ref: <a href="http://people.csail.mit.edu/rivest/Rsapaper.pdf"><span style="color: #0000ff;" color="#0000ff">http://people.csail.mit.edu/rivest/Rsapaper.pdf</span></a>, patent: <a href="http://www.patents.com/us-4405829.html"><span style="color: #0000ff;" color="#0000ff">http://www.patents.com/us-4405829.html</span></a>).&nbsp; Though Diffie and Hellman discovered the concept of asymmetric cryptosystems first, RSA monetized the concept more effectively ultimately resulting in RSA Corporation, now owned by EMC.</p>
<p>PKI as we know it began with establishment of the X.509 certificate standard in 1993 with the establishment of RFC 1422 (ref: <a href="http://tools.ietf.org/html/rfc1422"><span style="color: #0000ff;" color="#0000ff">http://tools.ietf.org/html/rfc1422</span></a>).&nbsp; This standard created the concepts of certification authorities, certificate revocation lists (CRL), and certificate trusts that provided the framework for more advanced PKI-based technologies in-use today.</p>
<div>
<h1>Asymmetric Cryptography</h1>
</div>
<p>In asymmetric cryptography two mathematically related keys are generated; the public key and the private key. The relationship of these keys is such that any data encrypted by one key can only be decrypted by its matched pair. To clarify this relationship, the public key cannot decrypt data encrypted by the public key and the private key cannot decrypt data encrypted by the private key.</p>
<p>In this relationship, the private key identifies the identity of the certified asset, while the public key is widely distributed to validate its identity. An important thing to note at this point is that the compromise of the private key must immediately result in invalidation of this relationship (the means to accomplish this will be discussed later).</p>
<p>The relationship between these keys enables two important cryptographic capabilities based on use: confidentiality and integrity.</p>
<div>
<h2>Confidentiality</h2>
</div>
<p>PKI can be used to ensure the confidentiality of data transmission through use of the recipient's public key. Two common examples of this are in secure sockets layer (SSL) encryption and e-mail encryption</p>
<div>
<h3>Secure Sockets Layer (SSL)</h3>
</div>
<p>In SSL encryption, a Web server is configured to use a PKI certificate to establish a trust and cryptographic relationship between clients and the server. In this design, the SSL client requests the server's certificate (containing its pubic key) for encryption of a symmetric key that will be shared by both parties for further communications. Because the client has the server's public key it can be reasonably assured that only servers having the private key will be able to decrypt the symmetric key and therefore ensuring confidentiality. There is much more to this topic than discussed in this section, some of which will be discussed later in&nbsp;a later&nbsp;post.</p>
<div>
<h3>E-mail Encryption</h3>
</div>
<p>Similar to SSL encryption, e-mail encryption leverages the recipient's public key (available in their certificate) to ensure that only recipients of the e-mail will be able to read the message. In this form of encryption, the e-mail message is encrypted using symmetric encryption. The resulting key is then encrypted separately with each recipient's public key to ensure only the intended recipients of the message are able to view its contents (due to their possession of their corresponding private key).&nbsp; This concept will be discussed in-depth in a later post.</p>
<div>
<h2>Integrity, Authentication, and Non-Repudiation</h2>
</div>
<p>Another common use of PKI is to ensure the integrity, authenticity, or to prevent repudiation (refusal to acknowledge an action). In these operations, the private key to guarantee the sender through cryptography. It is important to make the distinction that cryptographic operations performed by the private key usually do not provide confidentiality (rather obfuscation at best) due to the intended wide distribution of the public key. Once common example of this is the use of digital signatures.</p>
<div>
<h3>Digital Signatures</h3>
</div>
<p>You may have received a digitally signed e-mail (identified in Outlook by a red ribbon) or have seen a warning message that a driver or piece of software was not digitally signed. Both of these scenarios leverage the relationship between the public and private key to certify that the digitally signed information (the e-mail, software, or driver) was produced by a trusted source and has not changed since the digital signature.</p>
<p>Digital signatures begin by taking the data to be signed (either the e-mail contents or the compiled code in the above examples) and passing it through a hashing algorithm. Hashing algorithms are special formulas that produce a unique fixed-length output when given a specific input (for more information on this research HMAC or CBCMAC formulas). In addition, effective hashing algorithms will change the entire result if any part of the source message changes. Also, the resulting hash should not be able to be reverse engineered to provide the original message.</p>
<p>The hash alone only proves that the message has not changed. To prove the identity of the sender this hash is then encrypted using the sender's private key resulting in a digital signature. This digital signature can then be used to verify the identity of the sender (the ability to decrypt the signature) as well as to validate the integrity of the message through performing the same hashing algorithm and comparing.&nbsp; As with the previous topics, this will be discussed in-depth in an upcoming post.<span style="font-family: Calibri; font-size: small;" size="3" face="Calibri">&nbsp;</span></p>]]></content:encoded>
    </item>
    <item>
      <title>RPC and Network Load Balancing Technologies</title>
      <link>https://docs.microsoft.com/archive/blogs/option_explicit/rpc-and-network-load-balancing-technologies</link>
      <pubDate>Mon, 27 Feb 2012 10:43:41 GMT</pubDate>
      <dc:creator><![CDATA[Michael Melone]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/option_explicit/2012/02/27/rpc-and-network-load-balancing-technologies/</guid>
      <description><![CDATA[What is RPC?
Many applications today use Remote Procedure Calls to link client and server...]]></description>
      <content:encoded><![CDATA[<p><span style="font-size: medium;" size="4"><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Cambria;" face="Cambria">What is RPC?</span></span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Many applications today use Remote Procedure Calls to link client and server communications over a network.&nbsp; RPC allows client applications to easily perform function calls to local and network-connected server applications using native Windows APIs.&nbsp; Among the benefits of using RPC are:</span></span></p>
<ul>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Flexible communications as defined by an Interface Definition Language (IDL) file supporting a wide range of protocols to include TCP, UDP, and NetBIOS</span></span></li>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Ability to automate network port selection to avoid conflicts</span></span></li>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Offloading of authentication, packet integrity (digital signatures), and strong encryption</span></span></li>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Ability for clients to locate remotely published server services locations through use of the RPC Endpoint Mapper</span></span></li>
</ul>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Because of these benefits (as well as many others) RPC is an attractive communications platform for software development and is used widely in client-server communications.&nbsp; </span></span></p>
<p><span style="font-size: medium;" size="4"><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Cambria;" face="Cambria">Firewalls and RPC</span></span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">RPC provides a large number of security benefits as discussed above, however it does have an associated cost.&nbsp; Many applications that use RPC leverage a feature called dynamic port allocation.&nbsp; When an application uses&nbsp;dynamic port allocation&nbsp;it offloads the network port number selection to the RPC server service that it is being hosted on.&nbsp; The result of this is&nbsp;that each server will use a different&nbsp;TCP port to host the same service.&nbsp; As a result, white papers specifying ports that must be opened to allow these servers to communicate across firewalls include a range of thousands of (commonly TCP) ports which must be opened.&nbsp; In addition, using implicit bindings means exposing any other RPC-hosted services in an accessible manner to services hosted in a different and possibly lower security zone.&nbsp; In the case of domain membership, this runs the risk of exposing the very core of a network&rsquo;s authentication mechanism (Active Directory)&nbsp;to the risk of compromise due to vulnerability in a&nbsp;service hosted on a domain controller whose communication may not even be necessary for domain membership.</span></span></p>
<p><span style="font-size: medium;" size="4"><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Cambria;" face="Cambria">How does RPC work?</span></span></span></p>
<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">When a service uses RPC on Windows it registers with the RPC Endpoint Mapper service using one of a number of functions.&nbsp; There are a large number of ways that an application can register an endpoint on the endpoint mapper, many of which are listed at </span><a href="http://msdn.microsoft.com/en-us/library/aa375262(v=vs.80).aspx"><span style="color: #0000ff; font-family: Calibri; font-size: small;" face="Calibri" color="#0000ff" size="3">http://msdn.microsoft.com/en-us/library/aa375262(v=vs.80).aspx</span></a><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">.&nbsp; The most important aspect of this registration when discussing load balancing is the difference between explicitly specifying the TCP port that the application uses versus allowing the application to leverage the RPC server&rsquo;s dynamic port allocation capability.</span></span></p>
<p><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Cambria;" face="Cambria"><span style="font-size: small;" size="3">Dynamic Port Allocation</span></span></span></p>
<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">Applications leveraging dynamic port allocation will use a function such as RpcServerUseProtseq(), RpcServerUseAllProtSeqs(), RpcServerUseAllProtseqsEx(), or RpcServerUseProtseqEx() to enable the RPC server to dynamically choose a TCP port to host the service on (ref: </span><a href="http://msdn.microsoft.com/en-us/library/aa378682(v=vs.80).aspx"><span style="color: #0000ff; font-family: Calibri; font-size: small;" face="Calibri" color="#0000ff" size="3">http://msdn.microsoft.com/en-us/library/aa378682(v=vs.80).aspx</span></a><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">).&nbsp; When an application uses a function like this the RPC server will dynamically pick a port from a range between 1024 and 65535 by default (this behavior can be modified as outlined in the following Microsoft KB </span><a href="http://support.microsoft.com/kb/250367"><span style="color: #0000ff; font-family: Calibri; font-size: small;" face="Calibri" color="#0000ff" size="3">http://support.microsoft.com/kb/250367</span></a><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3"> or through changing the TCP dynamic ports as outlined in the following KB </span><a href="http://support.microsoft.com/default.aspx?scid=kb;EN-US;929851"><span style="color: #0000ff; font-family: Calibri; font-size: small;" face="Calibri" color="#0000ff" size="3">http://support.microsoft.com/default.aspx?scid=kb;EN-US;929851</span></a><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">).</span></span></p>
<p><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Cambria;" face="Cambria"><span style="font-size: small;" size="3">Explicit Port Allocation</span></span></span></p>
<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">If the software developer wants to explicitly specify the TCP port that they want to use they have the option of using a function such as RpcServerUseProtSeqEp() or RpcServerUseProtseqEx() to specify a specific TCP port to use for the application.&nbsp; After getting an endpoint from one of the above functions, the application will usually then call RpcEpRegister() to register the new port with the Endpoint Mapper.&nbsp; In many Microsoft applications (such as Active Directory and Exchange) this option is used only if a given registry key is configured (references &ndash; Active Directory: </span><a href="http://support.microsoft.com/kb/224196"><span style="color: #0000ff; font-family: Calibri; font-size: small;" face="Calibri" color="#0000ff" size="3">http://support.microsoft.com/kb/224196</span></a><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">, Exchange 2010: </span><a href="http://social.technet.microsoft.com/wiki/contents/articles/configure-static-rpc-ports-on-an-exchange-2010-client-access-server.aspx"><span style="color: #0000ff; font-family: Calibri; font-size: small;" face="Calibri" color="#0000ff" size="3">http://social.technet.microsoft.com/wiki/contents/articles/configure-static-rpc-ports-on-an-exchange-2010-client-access-server.aspx</span></a><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">).&nbsp; In this event, the software will try to use the given TCP port rather than leveraging the dynamic port allocation abilities of the RPC server.</span></span></p>
<p><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Cambria;" face="Cambria"><span style="font-size: small;" size="3">How Clients Locate a RPC Service</span></span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The next logical question that comes to mind is &ldquo;If the TCP port is randomly assigned, how does a client on the network find out which port to connect to?&rdquo;&nbsp; Associating these ephemeral ports to the hosted server application is a function of the RPC Endpoint Mapper.&nbsp; The RPC Endpoint Mapper is essentially a phone book containing a list of mapped ports and their associated UUID (a unique ID specified by the application mapping the connection).&nbsp; Applications wanting to connect to a service indexed by the endpoint mapper will first connect to the hosting server on TCP port 135 using&nbsp;a function such as RpcStringBindingCompose() to search the server&rsquo;s endpoint mapper for the serivce's UUID (ref: <span style="color: #0000ff;" color="#0000ff"><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa378481(v=vs.85).aspx">http://msdn.microsoft.com/en-us/library/windows/desktop/aa378481(v=vs.85).aspx</a>)</span>. &nbsp;The UUID is an identity specified by the application developer during the development of the application and is commonly done through use of an Interface Definition Language (IDL) file (ref: <a href="http://pubs.opengroup.org/onlinepubs/9629399/chap4.htm"><span style="color: #0000ff;" color="#0000ff">http://pubs.opengroup.org/onlinepubs/9629399/chap4.htm</span></a>).&nbsp; For an example of an IDL file perform a search for *.idl in your %ProgramFiles% directory.&nbsp; Once a client finds the location of the service it closes the connection to TCP 135 and initiates a new connection to the server on the referenced TCP endpoint.</span></span></p>
<p><span style="font-size: medium;" size="4"><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Cambria;" face="Cambria">How Load Balancers can cause Issues with RPC Traffic</span></span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">When an application uses a load balancer, multiple instances of the server are housed under the same DNS name or IP address.&nbsp; The problem is that in a load balanced scenario without persistence the back-end server that the client is communicating with can change without notice.&nbsp; Once bound, the client software commonly makes the assumption that these services will remain available throughout its session with the load balanced server and may make subsequent calls directly to the ephemeral port hosting the service without contacting the RPC Endpoint Mapper.</span></span><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">&nbsp;&nbsp;If port allocation for this service is dynamic it is highly unlikely that multiple servers performing the same role will use the same TCP port for the same RPC service.&nbsp; As such, a load balancer that cannot maintain session persistence is subject to connection failures anytime the load balancer switches the client&rsquo;s back-end server.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">For this example we will use a network consisting of two servers (&ldquo;Server A&rdquo; and &ldquo;Server B&rdquo;) that each host a service (&ldquo;Service X&rdquo;) &nbsp;and are load balanced by a network load balancing device (&ldquo;loadbalancer.mycompany.com&rdquo;).</span></span></p>
<p align="center"><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/92/97/3618.TestNetwork.gif" original-url="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-92-97/3618.TestNetwork.gif"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/92/97/3618.TestNetwork.gif" original-url="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-92-97/3618.TestNetwork.gif" /></a></span></span></p>
<p align="center"><em><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Test Network Diagram</span></span></em></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The client connects to &ldquo;loadbalancer.mycompany.com&rdquo; and gets &ldquo;Server A&rdquo; on the other side of the load balancer.&nbsp; Due to RPC dynamic port assignment, &ldquo;Server A&rdquo; hosts &ldquo;Service X&rdquo; on TCP port 11111, while &ldquo;Server B&rdquo; hosts &ldquo;Service X&rdquo; on TCP port 22222.&nbsp; The client has an application installed that uses &ldquo;Service X&rdquo; over RPC and is configured to connect to it using &ldquo;loadbalancer.mycompany.com&rdquo;.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">&nbsp;At this time, the client uses RpcEpResolveBinding() to find the location of &ldquo;Service X&rdquo; for &ldquo;loadbalancer.mycompany.com&rdquo;.&nbsp; The load balancer forwards the connection to &ldquo;Server A&rdquo; which responds that it hosts &ldquo;Service X&rdquo; on TCP port 11111.&nbsp; At this time, the client calls RpcStringBindingCompose() to connect the software to &ldquo;Service X&rdquo; on TCP port 1111 at &ldquo;loadbalancer.mycompany.com&rdquo;, and finally RpcBindingFromStringBinding() to obtain a handle to this resource.&nbsp; When the client makes this call to the load balancer the load balancer fails to persist the client to &ldquo;Server A&rdquo; and instead forwards the connection to &ldquo;Server B&rdquo;.&nbsp; Since &ldquo;Server B&rdquo; does not have this port open it responds to the TCP SYN packet with a TCP RST-ACK (ref: </span></span><a href="http://support.microsoft.com/kb/175523"><span style="color: #0000ff; font-family: Calibri; font-size: small;" face="Calibri" color="#0000ff" size="3">http://support.microsoft.com/kb/175523</span></a><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3">).&nbsp; The client will continue this until it reaches TCP_MAX_RETRANSMISSIONS (ref: </span><a href="http://support.microsoft.com/kb/170359"><span style="color: #0000ff; font-family: Calibri; font-size: small;" face="Calibri" color="#0000ff" size="3">http://support.microsoft.com/kb/170359</span></a><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">) at which time it determine the network connection to be failed. &nbsp;When the client calls RpcBindingFromStringBinding() it is returned the following error: RPC_S_INVALID_NET_ADDR (ref: <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa378645(v=vs.85).aspx">http://msdn.microsoft.com/en-us/library/windows/desktop/aa378645(v=vs.85).aspx</a>).&nbsp; At this time, the client must make the assumption that the service is unavailable and will invoke its error handling functions as designed.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">In this configuration, this condition can happen due to multiple causes (ex. &ldquo;loadbalancer.mycompany.com&rdquo; fails to persist the connection to the originating server, the service on &ldquo;Server A&rdquo; stops or restarts causing the load balancer to move the connection, etc.).&nbsp; In any of these situations the client will repeat the above scenario thus resulting in connection issues.</span></span></p>
<p><span style="font-size: medium;" size="4"><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Cambria;" face="Cambria">How to Prevent this RPC Connection Issue</span></span></span></p>
<p><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3">To effectively mitigate these issues all servers hosting one of two things must occur:</span></span></p>
<ul>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The RPC service must be configured to use the same explicit RPC port(s) across all servers providing the service under the load balanced name or</span></span></li>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"></span></span><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The RPC client must be developed to contact the RPC endpoint mapper in the event that it receives a RPC_S_INVALID_NET_ADDR error <span style="text-decoration: underline;">and</span> the network load balancing device must be able to reasonably persist connections to the same server (we have to ensure that the TCP endpoint mapper call and the immediate following call to the RPC-hosted service are successful).&nbsp; Also, in the event that this persistence is not maintainable over a length of time this solution will be unnecessarily chatty.</span></span></li>
</ul>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Since most systems administrators do not have source code access to the software they are maintaining the RPC server service must be configured to utilize the same TCP port across all server services hosted under the load balanced DNS name.&nbsp; For example, if the server service hosted by the cluster is Exchange then all Exchange servers must be configured to use the same ports for Exchange services across all nodes in a cluster.&nbsp; In addition, the clustered application must be able to handle session transitions between servers to accommodate for a failover condition (i.e. in the event that the session is sent from one server to the other it must be able to recover or restart the session without reinitialization).</span></span></p>]]></content:encoded>
    </item>
  </channel>
</rss>