Author Posts

November 18, 2015 at 1:07 pm

Hey guys, so here is my current conundrum. i am trying to find a way to use a plugged in smart card to browse or download a file from a Smart card authenticated website, sharepoint in this case.
I have some working ideas, but passing the PIN to the script via command line is proving difficult. Not sure if i can simply pass it as i would a credential with a secure string.
Also, i would love to be able to get the script to navigate past certain pages, like splash pages for example.
And the kicker... i need to do it in PS v2.
here is the code i was working with, but im not attached to it 😛

Add-Type -AssemblyName System.Security
add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPo licy : ICertificatePolicy {
    public bool CheckValidationResult(
        ServicePoint srvPoint, X509Certificate certificate,
        WebRequest request, int certificateProblem) {
        return true;
    }
}
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

# You can do more filtering here if there are other cert requirements...
$ValidCerts = [System.Security.Cryptography.X509Certificates.X509Certificate2[]](dir Cert:\CurrentUser\My | where { $_.NotAfter -gt (Get-Date) })

#$ValidCerts | select subject, DnsNameList, Issuer, EnhancedKeyUsageList, Archived, NotAfter | fl
$Cert = $ValidCerts[0]



$Url = 'URL HERE'
$OutFilePath = 'OUTPUT FILE NAME HERE'
$Cert = 'USER CERT HERE'

if (Test-Path $OutFilePath) {
throw "'$OutFilePath' already exists!"
}

# Create webrequest that contains the selected certificate, and try to get a response
$Request = [System.Net.WebRequest]::Create($Url)
$Request.ClientCertificates.Add($Cert)

try {
$Response = $Request.GetResponse()
}
catch {
# You could present a nicer message here
Write-Error $_
}

if ($Response) {

# You'll probably want to check out the $Response object before doing anything with
# it (probably at least check $Response.StatusCode)

# There's probably a shorter/cleaner/better way to do this, but this will create a buffer and a filestream,
# then transfer the binary data from the $Response's stream to the filestream using the buffer...
$Buffer = New-Object byte[] 1024  # You can adjust the buffer size
$OutFileStream = [System.IO.File]::Create($OutFilePath)   # This will overwrite an existing file!
$ResponseStream = $Response.GetResponseStream()

while (($BytesRead = $ResponseStream.Read($Buffer, 0, $Buffer.Length))) {
    $OutFileStream.Write($Buffer, 0, $BytesRead)
}

# Cleanup
$OutFileStream.Flush()
$OutFileStream.Dispose()
$ResponseStream.Dispose()
$Response.Close()
} 

November 20, 2015 at 7:27 am

$cred = get-credential

#select smartcard and enter pin

$pin = $cred.getnetworkcredential().password