<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Huddled Masses &#187; Authenticode</title>
	<atom:link href="http://huddledmasses.org/tag/authenticode/feed/" rel="self" type="application/rss+xml" />
	<link>http://huddledmasses.org</link>
	<description>You can do more than breathe for free...</description>
	<lastBuildDate>Fri, 27 Apr 2012 05:42:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
<cloud domain='huddledmasses.org' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
		<item>
		<title>Signing PowerShell Scripts &#8211; Automatically</title>
		<link>http://huddledmasses.org/signing-powershell-scripts-automatically/</link>
		<comments>http://huddledmasses.org/signing-powershell-scripts-automatically/#comments</comments>
		<pubDate>Sun, 15 Nov 2009 05:53:56 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[Authenticode]]></category>
		<category><![CDATA[Code Signing]]></category>
		<category><![CDATA[Cryptography]]></category>
		<category><![CDATA[Digital signature]]></category>
		<category><![CDATA[FileSystemWatcher]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://huddledmasses.org/?p=1317</guid>
		<description><![CDATA[I write a lot of PowerShell scripts, and I work on modules a lot, including ones which I load automatically in my profile. Sometimes I forget to sign those modules before I restart my console/host, and then I get errors when they&#8217;re loaded from the profile. I wrote a script to solve this problem by [...]]]></description>
			<content:encoded><![CDATA[	<p>I write a lot of PowerShell scripts, and I work on modules a lot, including ones which I load automatically in my profile.  Sometimes I forget to sign those modules before I restart my console/host, and then I get errors when they&#8217;re loaded from the profile.  I wrote a script to solve this problem by automatically signing files every time they&#8217;re edited, and I figured I&#8217;d share it below, but first let me try explaining what code signing is, and why you should care.</p>

	<h3>What is code signing?</h3>

	<p><a href="http://en.wikipedia.org/wiki/Code_signing">Code signing</a> is the process of digitally signing files to confirm the author and guarantee that the file has not been altered or corrupted.  It&#8217;s essentially the same as signing emails: it guarantees that they were actually authored by the person claiming to be the author, and that they weren&#8217;t changed after the author signed them. (For more information see <a href="http://developer.apple.com/mac/library/documentation/Security/Conceptual/CodeSigningGuide/AboutCS/AboutCS.html#//apple_ref/doc/uid/TP40005929-CH3-SW3">Apple&#8217;s explanation</a> and <a href="http://msdn.microsoft.com/en-us/library/ms537361%28VS.85%29.aspx">Microsoft&#8217;s</a>).</p>

	<h3>How does digital signing work?</h3>

	<p>Basically, digital signing is cryptography, so a full understanding of it really requires taking a 400-level college course, but <a href="http://www.instantssl.com/code-signing/code-signing-process.html">here are the basics</a>:  You take some data (binary bits) and use a well-known algorithm to calculate what is called a &#8220;hash&#8221; of the bits. This hash is mathematically-generated from the source data, and so it can be re-calculated by the receiver.  The hash is then &#8220;signed&#8221; via another algorithm: using a private key (see <a href="http://www.answers.com/topic/pki#Computer_Desktop_Encyclopedia_d_ans">Public Key Infrastructure</a> (<span class="caps">PKI</span>) for more about how these keys are managed) the signer encrypts the hash and attaches it to the file.  </p>

	<p>With public/private key encryption, data that is encrypted by the private key can be decrypted by the public key, so the encryption of the hash (and sometimes the public key, as well) is attached to the file so that the end user can re-calculate the hash and decrypt the signature to verify: a) that it was encrypted by the private key belonging to the author, and b) that the hash matches the hash that the author signed.</p>

	<h3>What&#8217;s all this about keys?</h3>

	<p>In <span class="caps">PKI</span>, the &#8220;key&#8221; is actually part of what&#8217;s called an <a href="http://en.wikipedia.org/wiki/Ssl_certificate"><span class="caps">SSL</span> certificate</a> issued to you by a Certificate Authority (CA) who verifies your identity. Verisign introduced the idea of &#8220;classes&#8221; for certificates, and you can now get free, <strong>Class 1</strong> certificates for email signing from most CA&#8217;s now (like <a href="http://www.thawte.com/secure-email/personal-email-certificates/">Thawte</a> and <a href="http://www.thawte.com/secure-email/personal-email-certificates/">Comodo</a> and <a href="http://www.startssl.com/?app=1">StartCOM</a>), where the only thing they <em>verify</em> is that the person being issued the certificate can send/receive email at that address.</p>

	<p>Of course, if you want to verify yourself as the author of <strong>code,</strong> we want to know more about you than your email address.   So to sign code, you need <em>at least</em> a <strong>Class 2</strong> certificate, for which proof of identity is required.  This typically comes in the form of providing (photos of) your passport, driver&#8217;s license and/or other photo ID to verify that you are who you claim to be, and answering a few questions on the phone to validate that you own the phone number provided&#8230; or providing tax or other documents to prove the existence of an organization and that you&#8217;re qualified to speak for them. There are also additional classes: Class 3, 4, and 5 are extended validation certificates used for servers, software signing, b2b transactions and government security.</p>

	<h3>Why should I sign PowerShell scripts?</h3>

	<p>Well, the chances are, you don&#8217;t need to.  Script signing is really a feature for corporations.  The idea is that scripts from your IT department need to be verifiable and unalterable&#8230; code-signing gives companies a way to lock down and secure PowerShell scripts: setting a global policy requiring script signing, and ensuring that all scripts produced by the corporate administrators are properly signed&#8230;</p>

	<p>As an individual, script-signing doesn&#8217;t really offer you much unless you share your computer with other administrator users.  After all, what it protects you from is  intentional or accidental altering of the script.  If there&#8217;s no one else who has access to your computer, then nobody can alter your scripts.  Of course, if someone <em>hacks</em> your computer enough to alter or create files on your hard drive and wanted to do something malicious, scripts would be a silly thing to target  <img src='http://huddledmasses.org/wordpress/wp-includes/' alt=':)' class='wp-smiley' /> </p>

	<p>There is, however, one additional time when you might want to sign your scripts.  If you&#8217;re distributing scripts, whether via <a href="http://PoshCode.org">PoshCode.org</a>, the TechNet script gallery, or on CodePlex or the <span class="caps">MSDN</span> code gallery &#8230; signing them gives you (and your users) the assurance that <strong>you</strong> are the author, and they haven&#8217;t been altered.  In fact, the PoshCode Module which is available on <a href="http://PoshCode.org">PoshCode.org</a>, and which allows you to search and download (as well as upload) PoshCode scripts uses script signing to allow it to safely upgrade itself.  It features a <code>Get-PoshCode -Upgrade</code> command which will check for, and fetch, the latest version of the PoshCode module, and then validate it&#8217;s code signature is the same as the previous one before using it.</p>

	<p>Remember, code signing <strong>cannot</strong>:</p>

	<ul>
		<li>Guarantee that code is free of security vulnerabilities.</li>
		<li>Guarantee that a script doesn&#8217;t load unsafe or altered code during execution.</li>
	</ul>
	<ul>
		<li>Prevent copying or altering of your scripts (although PowerShell policies can prevent <em>accidental execution</em> of altered scripts).</li>
	</ul>

	<h2>How do I sign scripts?</h2>

	<p>Assuming that after skimming all of that, you want to try signing your scripts, you need a certificate. You can <a href="http://huddledmasses.org/code-signing-with-openssl-and-powershell/">generate one yourself</a> (although it&#8217;s not easy, and the signed scripts which will only work locally on your system, and won&#8217;t be trusted by anyone else) or you can get one from a public Certificate Authority (I recommend <a href="http://www.startssl.com/?app=2">StartCom/StartSSL</a> which only costs $40 for two year certificates).  </p>

	<p>Typically, your certificate will be a .pfx file which you can load using <code>Get-PfxCertificate</code>, or you might have imported it into your local certificate store using CertMgr.msc, in which case you can load it using Get-Item Cert:\CurrentUser\My\ with the thumbprint of the certificate.  In either case, you&#8217;ll have a certificate object you can pass to <code>Set-AuthenticodeSignature</code> along with the file path.</p>

	<h1>Wasn&#8217;t there supposed to be something automatic here?</h1>

	<p>Awhile back I wrote an <a href="http://poshcode.org/1473">Authenticode Script Module</a> which has wrappers for signing and testing signatures on scripts.  It uses a metadata file (which you have to create yourself) with a <code>PrivateData</code> variable that points to either the thumbprint of a certificate you&#8217;ve imported to your computer&#8217;s certificate store, or the path to a .pfx file &#8230; and allows you to sign files by just writing <code>sign .\FileToSign.ps1</code> without having to Get-PfxCertificate each time, or even remember to turn on the -TimeStampUrl feature so that your signed scripts stay signed even after the certificate expires.  That script helps a lot, but I&#8217;ve been wanting my text editor to sign the scripts automatically when I save them &#8230;</p>

	<p>I mostly use <a href="http://notepad-plus.sourceforge.net/">Notepad++</a> for editing PowerShell scripts (with a <a href="http://PoshCode.org/notepad++lexer">PowerShell Syntax lexer I helped create</a>), but after playing with the idea of writing a plugin to sign things after saving, I ended up deciding to go with something simpler: a PowerShell script to watch a folder for changes and sign any scripts I edit or save.</p>

	<p>I&#8217;ve added a function I call <code>Start-AutoSign</code> to my <a href="http://poshcode.org/1473">authenticode script module</a> which takes a path and a <code>-Recurse</code> flag and sets up a <a href="http://msdn.com/System.IO.FileSystemWatcher">System.IO.FileSystemWatcher</a> to detect saves, creates, and moves &#8230; and (re)sign the script if it needs it. Here is <code>Start-AutoSign</code> without the help docs or anything (so I can discuss it). You should just download the whole <a href="http://poshcode.org/1473">script module</a> if you want to use it  <img src='http://huddledmasses.org/wordpress/wp-includes/' alt=':)' class='wp-smiley' /> </p>

	<div class="posh code posh" style="font-family:monospace;"><span style="color: #666699; font-weight: bold;">PARAM</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$Path</span><span style="color: #66cc66;">=</span><span style="color: #009900;">&quot;.&quot;</span>, <span style="color: #660033; font-weight: bold;">$Filter</span><span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;*.ps*&quot;</span>, <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #666699; font-weight: bold;">Switch</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$Recurse</span>, <span style="color: #660033; font-weight: bold;">$CertPath</span>, <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #666699; font-weight: bold;">Switch</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$NoNotify</span><span style="color: #333;">&#41;</span><br />
<span style="color: #666699; font-weight: bold;">if</span><span style="color: #333;">&#40;</span><span style="color: #66cc66;">!</span><span style="color: #660033; font-weight: bold;">$NoNotify</span> <span style="color: #000066;">-and</span> <span style="color: #333;">&#40;</span><span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">Module</span></span> Growl <span style="color: #000066;">-ListAvailable</span> <span style="color: #000066;">-ErrorAction</span> <span style="color: #cc66cc;">0</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Import-<span style="font-style: normal;">Module</span></span> Growl<br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Register-<span style="font-style: normal;">GrowlType</span></span> AutoSign <span style="color: #009900;">&quot;Signing File&quot;</span> <span style="color: #000066;">-ErrorAction</span> <span style="color: #cc66cc;">0</span><br />
<span style="color: #333;">&#125;</span> <span style="color: #666699; font-weight: bold;">else</span> <span style="color: #333;">&#123;</span> <span style="color: #660033; font-weight: bold;">$NoNotify</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$false</span> <span style="color: #333;">&#125;</span><br />
<br />
<span style="color: #660033; font-weight: bold;">$realItem</span> <span style="color: #66cc66;">=</span> <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">Item</span></span> <span style="color: #660033; font-weight: bold;">$Path</span> <span style="color: #000066;">-ErrorAction</span> Stop<br />
<span style="color: #666699; font-weight: bold;">if</span> <span style="color: #333;">&#40;</span><span style="color: #66cc66;">-</span><span style="color: #333399; font-weight: bold; font-style: italic;">not</span> <span style="color: #660033; font-weight: bold;">$realItem</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span> <span style="color: #666699; font-weight: bold;">return</span> <span style="color: #333;">&#125;</span> <br />
<br />
<span style="color: #660033; font-weight: bold;">$Action</span> <span style="color: #66cc66;">=</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$InvalidForm</span> <span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;The form specified for the subject is not one supported or known by the specified trust provider&quot;</span><br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">ForEach</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$file</span> <span style="color: #666699; font-weight: bold;">in</span> <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">ChildItem</span></span> <span style="color: #660033; font-weight: bold;">$eventArgs</span>.<span style="color: #003366;">FullPath</span> <span style="color: #66cc66;">|</span> <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">AuthenticodeSignature</span></span> <span style="color: #66cc66;">|</span> <br />
&nbsp; &nbsp; &nbsp; Where<span style="color: #66cc66;">-</span>Object <span style="color: #333;">&#123;</span> <span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">Status</span> <span style="color: #000066;">-ne</span> <span style="color: #009900;">&quot;Valid&quot;</span> <span style="color: #000066;">-and</span> <span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">StatusMessage</span> <span style="color: #000066;">-ne</span> <span style="color: #660033; font-weight: bold;">$invalidForm</span> <span style="color: #333;">&#125;</span> <span style="color: #66cc66;">|</span> <br />
&nbsp; &nbsp; &nbsp; <span style="color: #0066cc; font-style: italic;">Select-<span style="font-style: normal;">Object</span></span> <span style="color: #000066;">-ExpandProperty</span> Path <span style="color: #333;">&#41;</span> <br />
&nbsp; &nbsp;<span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">if</span><span style="color: #333;">&#40;</span><span style="color: #66cc66;">!</span><span style="color: #660033; font-weight: bold;">$NoNotify</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Send-<span style="font-style: normal;">Growl</span></span> AutoSign <span style="color: #009900;">&quot;Signing File&quot;</span> <span style="color: #009900;">&quot;File $($eventArgs.ChangeType), signing:&quot;</span> <span style="color: #009900;">&quot;$file&quot;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">if</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$CertPath</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Set-<span style="font-style: normal;">AuthenticodeSignature</span></span> <span style="color: #000066;">-FilePath</span> <span style="color: #660033; font-weight: bold;">$file</span> <span style="color: #000066;">-Certificate</span> <span style="color: #660033; font-weight: bold;">$CertPath</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span> <span style="color: #666699; font-weight: bold;">else</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Set-<span style="font-style: normal;">AuthenticodeSignature</span></span> <span style="color: #000066;">-FilePath</span> <span style="color: #660033; font-weight: bold;">$file</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
<span style="color: #333;">&#125;</span><br />
<span style="color: #660033; font-weight: bold;">$watcher</span> <span style="color: #66cc66;">=</span> <span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">Object</span></span> IO.<span style="color: #003366;">FileSystemWatcher</span> <span style="color: #660033; font-weight: bold;">$realItem</span>.<span style="color: #003366;">Fullname</span>, <span style="color: #660033; font-weight: bold;">$filter</span> <span style="color: #000066;">-Property</span> @<span style="color: #333;">&#123;</span> IncludeSubdirectories <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$Recurse</span> <span style="color: #333;">&#125;</span><br />
<span style="color: #0066cc; font-style: italic;">Register-<span style="font-style: normal;">ObjectEvent</span></span> <span style="color: #660033; font-weight: bold;">$watcher</span> <span style="color: #009900;">&quot;Created&quot;</span> <span style="color: #009900;">&quot;AutoSignCreated$($realItem.Fullname)&quot;</span> <span style="color: #000066;">-Action</span> <span style="color: #660033; font-weight: bold;">$Action</span> <span style="color: #66cc66;">&amp;</span>gt; <span style="color: #660033; font-weight: bold;">$null</span><br />
<span style="color: #0066cc; font-style: italic;">Register-<span style="font-style: normal;">ObjectEvent</span></span> <span style="color: #660033; font-weight: bold;">$watcher</span> <span style="color: #009900;">&quot;Changed&quot;</span> <span style="color: #009900;">&quot;AutoSignChanged$($realItem.Fullname)&quot;</span> <span style="color: #000066;">-Action</span> <span style="color: #660033; font-weight: bold;">$Action</span> <span style="color: #66cc66;">&amp;</span>gt; <span style="color: #660033; font-weight: bold;">$null</span><br />
<span style="color: #0066cc; font-style: italic;">Register-<span style="font-style: normal;">ObjectEvent</span></span> <span style="color: #660033; font-weight: bold;">$watcher</span> <span style="color: #009900;">&quot;Renamed&quot;</span> <span style="color: #009900;">&quot;AutoSignChanged$($realItem.Fullname)&quot;</span> <span style="color: #000066;">-Action</span> <span style="color: #660033; font-weight: bold;">$Action</span> <span style="color: #66cc66;">&amp;</span>gt; <span style="color: #660033; font-weight: bold;">$null</span></div>

	<p>A few things to notice: first, I&#8217;m assuming you&#8217;re using <strong>my</strong> Set-AuthenticodeSignature wrapper, so by default I don&#8217;t pass it an actual certificate.  Second, in order to avoid eternally looping and re-signing the script over-and-over, you have to have a way to make sure you don&#8217;t re-sign it when it &#8220;changes&#8221; because you signed it.  The approach I took was to test and see if the signature was valid or not (and if it&#8217;s valid, then don&#8217;t sign it <em>again</em>).  Third: when you <code>Get-AuthenticodeSignature</code>, the Status codes leave much to be desired, returning the same &#8220;UnknownError&#8221; in several cases where they know <em>exactly</em> what the error is.  You can check the StatusMessage and see that they even <strong>tell</strong> you what the error was:</p>

	<ul>
		<li>The form specified for the subject is not one supported or known by the specified trust provider</li>
		<li>A certificate chain could not be built to a trusted root authority</li>
		<li>A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider</li>
	</ul>
	<ul>
		<li>A required certificate is not within its validity period when verifying against the current system clock or the timestamp in the signed file</li>
	</ul>

	<p>There may be other reasons too that I haven&#8217;t encountered yet, but the one thing we&#8217;re concerned with is the first one that the &#8220;form&#8221; isn&#8217;t supported. That means this is a file type which Set-AuthenticodeSignature can&#8217;t sign. PowerShell&#8217;s signing only works with executables, PowerShell scripts, modules, metadata, and xml files &#8230; so there&#8217;s no point trying to sign anything else.  You may also notice that in my script (by default) I&#8217;m only signing .ps* files (that is: scripts, modules, metadata and ps1xml files), and that&#8217;s because with .dll and .exe files, I would prefer to sign them as part of my build step anyway.</p>

	<p>One last thing: as with a few of my recent scripts, this one is designed to use <a href="http://GrowlForWindows.com">Growl for Windows</a> to notify you whenever it signs anything. If you don&#8217;t have the <a href="http://poshcode.org/1464">Growl module</a> available, it should just skip right over that without any problems, but you can disable it in any case with the <code>-NoNotify</code> switch.  Personally, I like seeing the popup so that I know it&#8217;s working, and know that I&#8217;m not accidentally signing something &#8230; and I love Growl for script notices because I can skin it, configure sounds, and forward the notices to other machines &#8230; or even temporarily disable them, all without having to tweak scripts.</p>

<div class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://reblog.zemanta.com/zemified/3a72101f-e58c-47ed-accc-fc1c866ae964/" title="Reblog this post [with Zemanta]"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_e.png?x-id=3a72101f-e58c-47ed-accc-fc1c866ae964" alt="Reblog this post [with Zemanta]" /></a><span class="zem-script more-related pretty-attribution"><script type="text/javascript" src="http://static.zemanta.com/readside/loader.js" defer="defer"></script></span></div>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/signing-powershell-scripts-automatically/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PowerShell Authenticode Signatures and trust&#8230;</title>
		<link>http://huddledmasses.org/powershell-authenticode-signatures-and-trust/</link>
		<comments>http://huddledmasses.org/powershell-authenticode-signatures-and-trust/#comments</comments>
		<pubDate>Wed, 25 Jun 2008 03:44:55 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[Apt-Get]]></category>
		<category><![CDATA[Authenticode]]></category>
		<category><![CDATA[Certificates]]></category>
		<category><![CDATA[Code Signing]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Repository]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[SSL]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/powershell-authenticode-signatures-and-trust/</guid>
		<description><![CDATA[The cool thing about the way authenticode signatures are implemented is that even if a script is signed with a self-issued certificate, you can still tell if the script has been tampered with&#8230; Check this out: [1]:ls SCRIPTS:\UnknownCert\Sample*.ps1,SCRIPTS:\TrustedCert\Sample*.ps1 &#124; gas Directory: SCRIPTS:\UnknownCert\ SignerCertificate Status Path &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- &#8212;&#8212;&#8212; &#8212;&#8212; 0DA3A2A2189CD74AE371E6C57504FEB9A59BB22E UnknownError Sample.ps1 0DA3A2A2189CD74AE371E6C57504FEB9A59BB22E HashMismatch SampleBAD.ps1 Directory: [...]]]></description>
			<content:encoded><![CDATA[	<p>The cool thing about the way authenticode signatures are implemented is that even if a script is signed with a self-issued certificate, you can still tell if the script has been tampered with&#8230; Check this out:</p>

<div class="code posh" style="background: black; color: #ccc; font-weight:bold; line-height:0.5em;">
<span style="color:#ffcc00;">[1]:</span>ls SCRIPTS:\UnknownCert\Sample*.ps1,SCRIPTS:\TrustedCert\Sample*.ps1 | gas<br />
<br />

    Directory: SCRIPTS:\UnknownCert\<br />
<br />

SignerCertificate                         Status        Path<br />

&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-                         &#8212;&#8212;&#8212;        &#8212;&#8212;<br />

0DA3A2A2189CD74AE371E6C57504FEB9A59BB22E  UnknownError  Sample.ps1<br />

0DA3A2A2189CD74AE371E6C57504FEB9A59BB22E  HashMismatch  SampleBAD.ps1<br />
<br />

    Directory: SCRIPTS:\TrustedCert\<br />
<br />

SignerCertificate                         Status        Path<br />

&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-                         &#8212;&#8212;&#8212;        &#8212;&#8212;<br />

B658C20AAD070B9FF105C69BBC47ADCF56FD5576  Valid         Sample.ps1<br />

B658C20AAD070B9FF105C69BBC47ADCF56FD5576  HashMismatch  SampleBAD.ps1
</div>

	<p>As you can see, in the case of a <span class="caps">UNTRUSTED</span>, but correct, signature, you get the <strong>UnknownError</strong> status. If you checked the output object, it has a <code>StatusMessage</code> which says <em>&#8220;A certificate chain could not be built to a trusted root authority&#8221;</em>. If the script has been altered (as in my SampleBAD.ps1 scripts) then the signature is incorrect, you get the <strong>HashMismatch</strong> status, and the corresponding <code>StatusMessage</code> is: <em>&#8220;The contents of file SCRIPTS:\TrustedCert\SampleBAD.ps1 may have been tampered because the hash of the file does not match the hash stored in the digital signature. The script will not execute on the system&#8230;&#8221;</em></p>

	<p>One odd thing is that the messages are inaccurate about not executing the script: if you have your execution policy set to Unrestricted, the signatures aren&#8217;t checked at all, and if you have it set to RemoteSigned they are only checked for remote scripts. Furthermore: if you do have your execution policy set to AllSigned, neither the <strong>UnknownError</strong> nor the <strong>HashMismatch</strong> script will execute &#8212; only the one <strong>Valid</strong> scripts will.</p>

	<h3>So what?</h3>

	<p>The bottom line is: you can verify that nothing has happened to the script &#8212; even if you don&#8217;t trust the person who signed it <em>nor</em> the person, group, or company that issued a certificate to them.  Why does this matter? Well, I recently wrote a post about <a href="http://huddledmasses.org/code-signing-with-openssl-and-powershell/">generating self-signed code-signing certificates</a> which can be used for signing PowerShell scripts, and if you chose to distribute scripts signed with one of those certificates, nobody would be able to verify the root CA(Certificate Authority) and so the signatures would never come out as valid.</p>

	<p>Is there any usefulness in this? Well, I guess that depends on your perspective, but basically, <span style="font-size: 1.1em; font-weight: bold; color:#cc3399;">I think that if I published my scripts signed and tell you on my blog what my certificate thumbprint is &#8230; that you&#8217;d be more able to trust those scripts than you are now (when they&#8217;re not signed at all)</span>.  Of course, I could go one step further, and publish my own self-signed root CA certificate so you could choose to trust that &#8230;</p>

	<p>I was recently having a conversation about the future of the <a href="http://PowerShellCentral.com/scripts/">PowerShell Script Repository</a> and it involved some discussion of whether it would be safe to use the <a href="http://huddledmasses.org/automating-the-powershell-script-repository/">Repository Scripts</a> to download dependencies automatically&#8230; The answer, obviously, is <strong>no</strong>. </p>

	<p>But it started me thinking again about scripts being signed. If you had already chosen to run a script provided by me (which was signed by a certificate you couldn&#8217;t verify), maybe you&#8217;d be willing to trust other scripts signed by the same certificate, so we <em>could</em> automatically download them.  Well, maybe even then you wouldn&#8217;t want to trust it, but lets assume that you were running a copy of the PowerShell Script Repository internally at your company &#8230;</p>

	<h3>Would you use automatic dependency downloading?</h3>

	<p>We could easily have a function that takes the script name and verifies that you have that script available &#8212; and if not, it could fetch the script from your designated repository and verify that the signature is valid even if the certificate isn&#8217;t signed by a root certificate authority you trust.</p>

	<p>Of course, such automatically downloaded scripts would need to be marked as &#8220;Remote&#8221; so if you had your Execution Policy set to AllSigned or Remote Signed, then the script would only run if you had trusted it&#8217;s author (and you wouldn&#8217;t even be offered the option if you hadn&#8217;t trusted the CA(Certificate Authority) that issued his script.  In that case you would need to review the script and re-sign it yourself &#8212; or manually remove the &#8220;remote&#8221; bit.</p>

	<p>Imagine something like this:</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #666666; font-style: italic;"># Get-Paste.ps1</span><br />
<span style="color: #666699; font-weight: bold;">function</span> <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">Paste</span></span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Resolve-<span style="font-style: normal;">Dependency</span></span> <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">Webfile</span></span><br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;"># lots of code here that uses the Get-Webfile function ...</span><br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">Webfile</span></span> http:<span style="color: #66cc66;">//</span>HuddledMasses.<span style="color: #003366;">org</span><span style="color: #66cc66;">/</span><br />
<span style="color: #333;">&#125;</span></div>

	<p>When you tried to execute Get-Paste, it would check for Get-Webfile, and if it couldn&#8217;t find it, would attempt to download it (presumably this would involve asking your permission, and placing it in some specific location that was in your <span class="caps">PATH</span>, so that the script could find it when it tried to execute it on the next line).</p>

	<h4>Or maybe, an Apt-Get?</h4>

	<p>Perhaps instead of this mechanism, we could use the new embeddable &#8220;Data Language&#8221; to provide a list of dependencies, like: <code>DATA Dependencies { scripts = Get-WebFile }</code> and run a <code>Resolve-Dependencies</code> function against each script before trying to execute it &#8212; this way, if you downloaded a script from the repository using <code>Get-Paste</code>, it could automatically <code>Resolve-Dependencies</code> and offer to download the other scripts at the same time.</p>

	<p>The fact is that doing this <em>correctly</em> will require some major reworking of the script repository to allow tracking new versions of scripts better, and to let the script repository track dependencies explicitly so that you don&#8217;t have to download the whole script to find out what it&#8217;s dependencies are, but this could be done, if people are actually interested in it.</p>

	<h3>A web of trust?</h3>

	<p>Ad I&#8217;m thinking about this, I&#8217;m wondering again about the possibility of creating an informal web-of-trust style code-signing certificate tree.  The idea would be that <span style="font-size: 1.05em; font-weight: bold; color:#cc3399;">the Script Repository would have a CA certificate of it&#8217;s own, and would issue code-signing certificates to PowerShell developers</span> <em>cheaply</em> (free?) by skipping over some of the usual verification steps. In an ideal world, Microsoft would issue the PowerShell Community a &#8220;SubCA&#8221; certificate signed by their root &#8212; in the interests of promoting code signing for PowerShell &#8230; </p>

	<p>However, if we couldn&#8217;t get a SubCA certificate for &#8220;free&#8221; or cheap, we could simply generate and self-sign our own, and publish it on the Script Repository website, requiring users to download and import it into their trusted roots if they wanted to use trust permissions. Regardless of whether they chose to trust it or not, they could still verify the scripts were valid, which is better than what we have now &#8212; the rest would be up to the user.</p>

	<p>Of course, if we were issuing certificates that were self-signed anyway, we could go a step further and sign SubCAs and distribute them to, say, the Microsoft PowerShell MVPs and trusted community leaders after verifying email addresses and physical mailing addresses etc &#8230; trusting <strong>them</strong> further to issue (less trusted) code-signing certificates to additional developers.</p>

	<h4>Call to action</h4>

	<p>All of this is extra work for the people maintaining the script repository web site (right now, that&#8217;s me), but it might be worth it if it makes it easier to use the script repository, easier to trust the scripts on it, and easier to verify that an author <strong>is</strong> who he says he is &#8230; what do <em>you</em> think?</p>

	<ol>
		<li>Should we put in the work to set up a web of trust or should we leave it up to individual developers to self-sign and generate their certificates (and publish their public roots on their websites <em>or something</em>)?
		<li>Should we just leave it at that (scripters can sign their scripts if they feel like it), or should we push and promote script signing? As an incomplete example of <em>promoting</em> code-signing, I mean:
	<ol>
		<li>We can use certificates as the primary (or only) way for authors to identify themselves (that is: no log-ins, unsigned scripts are marked &#8220;anonymous&#8221; ... but we track the thumbprints and allow you to browse scripts signed by the same author, etc).</li>
		<li>We can include the signature thumbprint with the short descriptions output on the search results and from the scripts which interact with repository.</li>
	</ol></li>
	<ol>
		<li>We can restrict &#8220;latest version&#8221; updates to only scripts which are signed, and optionally to new versions signed by the same certificate.</li>
	</ol></li>
	</ol>
	<ol>
		<li>Is there any point (or hope) in trying to get a <em>signed</em> CA certificate? Can Microsoft help us out? Do any of you work at a certificate authority?</li>
	</ol>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/powershell-authenticode-signatures-and-trust/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

