the Windows Certification Authority has a built in feature (Windows Enterprise SKU) to send out emails to inform the PKI administrators if a new pending certificate request waiting for approval or if a new certificate has been issued. Just 2 examples.
The configuration must be done in the registry: See here for an example
http://social.technet.microsoft.com/wiki/contents/articles/2004.active-directory-certificate-services-smtp-exit-module-for-windows-server-2008-r2-example.aspx
Unfortunately you cannot configure it to send the issued certificate to the certificate requestor. For that I wrote a PowerShell script what is also working with the Windows Server 2008 R2 Standard Server.
Config file - sendcert_inc.ps1:
$sendcertpath=".\sendcert"
$msgFrom='noreply@frontoso.com'
$smtphost='127.0.0.1'
$certtmpl="1.3.6.1.4.1.311.21.8.5245527.10310595.8014498.11013764.15833798.137.13192380.4508386" #CorpWebServer
$certfileExt="txt" # fyi: extensions cer and der are blocked by Outlook
$mailbody="mailbody.txt"
$dbscanperiod="03:00" # 01:00 = 1 day, 1:15 = 1 day 15 hours; $dbscanperiod is the max time (now - $dbscanperiod) sendcert goes back in the certificate database, e.g. useful if you have already issued certs for years and you going to enable sendcert now
Mailbody.txt
Hello, attached is the requested certificate.
Please download the certificate and proceed with the SSL/TLS setup of your application.
For your convenience the certificate can be found as attachment and in the mail body.
Thank you,
----------------------------------------------------------------------------
Do not reply to this message. It was sent from an unmonitored email account.
sendcert.ps1
#
# Author: lutz.mueller-hipper@tribaldi.net
# Updates: lutz.mueller-hipper@insight.com
# Date: May 23, 2013 - v3.1
#
clear
import-module ActiveDirectory
# if not yet installed please install the ActiveDirectory PowerShell module
#dism /online /enable-feature /featurename:ActiveDirectory-PowerShell
if (-not (Test-Path .\sendcert_inc.ps1))
{
write-host "Error: sendcert_inc.ps1 configuration file not found." >>sendcert.log
exit;
} else {
. .\sendcert_inc.ps1
}
if (-not (Test-Path $sendcertpath)) { mkdir $sendcertpath >$null}
$Arr_SendCert = @()
write-host "=========================="
write-host Start Send certificate via email to certificate requestor
write-host "=========================="
write-host
#Disposition Description
#20 certificate was issued
#21 certificate is revoked
#30 certificate request failed
#31 certificate request is denied
$reqid_db = @()
$reqid_db = get-content $sendcertpath\reqid_do_not_remove.txt
$reqid_db2 = @()
foreach ( $line in $reqid_db) {
write-host "Line: "$line
$reqid_db2 = $reqid_db2 + $line
}
certutil.exe -view -out "Request.requestid,Request.requestid" -restrict "CertificateTemplate=$certtmpl,Disposition=20,NotBefore>now-$dbscanperiod" csv > $sendcertpath\sendcert_scope.csv
$collection = @(Import-CSV $sendcertpath\sendcert_scope.csv)
write-host Issued certs during period: $collection.count
if ($collection.count -gt 0) {
foreach($CADBentry in $collection)
{
$reqid = $CADBentry."request id"
if ($reqid_db2 -notcontains $reqid) {
write-host 'Preparing email for request: ' $reqid
$certview = certutil.exe -view -out "rawcertificate" -restrict "Request.requestid=$reqid"
$certemail = @()
$certattach = @()
foreach($line in $certview)
{
#write-host "Line: " $line
if ( $line -eq "-----BEGIN CERTIFICATE-----" ) { $certbegin="1" }
if ( $certbegin -eq "1") {
#write-host "next person in line pls"
$certemail = $certemail + $line.trim() + "`n" #+ "`r`n"
$certattach = $certattach + $line.trim() # + "`n" #+ "`r`n"
}
if ( $line -eq "-----END CERTIFICATE-----" ) { $certbegin="0" }
}
$cadb_requser= certutil.exe -view -out "Requester Name" -restrict "Request.requestid=$reqid" csv
$requser = $cadb_requser[1]
$requser = $requser.split("\")
$user = $requser[1]
$requser = $user.split("`"")
$user = $requser[0]
$aduser=""
try {
$aduser = get-aduser $user -Properties mail
#$aduser.mail
}
catch [Exception] {
write-host $_.Exception.Message
}
if ($aduser.mail.length -lt 1) {
write-host "no email address found"
} else {
$certattach > $sendcertpath\$reqid"."$certfileExt
$msg=new-object System.Net.Mail.MailMessage
$msg.From=$msgFrom
$msg.to.Add($aduser.mail)
$msg.Subject=$env:computername + ": SSL certificate " + $reqid
$msg.IsBodyHtml=$false
$mailbody = @()
$getmailbody = Get-Content mailbody.txt
foreach ($line in $getmailbody) {
$mailbody = $mailbody + $line + "`n"
}
$msg.Body=@"
$mailbody
$certemail
-
Ref $reqid_$env:computername
"@
$att = new-object Net.Mail.Attachment($sendcertpath + "\" + $reqid + "." + $certfileExt)
$msg.Attachments.Add($att)
$smtp=new-object System.Net.Mail.SmtpClient
$smtp.host=$smtphost
try {
$smtp.Send($msg)
$reqid >> $sendcertpath\reqid_do_not_remove.txt
}
catch {
write-host $_.Exception.Message
}
finally {
$smtp.dispose
$att.dispose()
}
}
}
}
}