PowerNets.psm1


function Find-NetsCertificate {
    param (
        [string]$Email,
        [switch]$CheckRevocation,
        [switch]$SkipRevoked
    )
    
    $searchDN="c=dk"
    $subjectAlternateNameUid = "2.5.29.17"

    #import .net assembly
    if ($PSVersionTable.PSEdition -eq "Desktop") {
        $ldapconnection = New-Object -TypeName Novell.Directory.LDAP.LdapConnection
    }
    else {
        $ldapconnection = New-Object -TypeName Novell.Directory.LDAP.VQ.LdapConnection
    }
    
    if($CheckRevocation) {
        #invoke webrequest is slow with progressbar for some reason
        $ProgressPreference = 'SilentlyContinue'
        #get crl lists
        $ica02 = Invoke-Webrequest http://crl.ica02.trust2408.com/ica02.crl
        $ica03 = Invoke-Webrequest http://crl.ica03.trust2408.com/ica03.crl
        $ica04 = Invoke-Webrequest http://crl.ica04.trust2408.com/ica04.crl
        $ica05 = Invoke-Webrequest http://crl.ica05.trust2408.com/ica05.crl

        $x509crlparserobj = New-Object Org.BouncyCastle.X509.X509CrlParser
        $x509certbc = New-Object Org.BouncyCastle.X509.X509CertificateParser

        $ica02crl = $x509crlparserobj.ReadCrl($ica02.Content)
        $ica03crl = $x509crlparserobj.ReadCrl($ica03.Content)
        $ica04crl = $x509crlparserobj.ReadCrl($ica04.Content)
        $ica05crl = $x509crlparserobj.ReadCrl($ica05.Content)
    }
    

    $ldapconnection.Connect("crtdir.certifikat.dk",389)
    $ldapscope = 2 #scope_sub
    
    
    #sanitize user input
    $certificatestring = $Email.Trim()
    try {
        
        #make connection to crtdir with ldap
        $cn = $ldapconnection.Search($searchDN,$ldapscope,"(mail=$certificatestring)",$null,$false)
        #this method has to be called before using count on object to check if any results are returned because it is blocking
        $cn.hasMore() | Out-Null
        #check if any results
        if ($cn.Count -eq 0) {
            throw "No certificate found"
        }

        $customobject = @()
        do {
            $dn = $cn.next()
            #get attribute from ldap entry in dn
            $ldapcert = $dn.getAttribute("userCertificate;binary")
            #put sbyte array into var
            $certificatebinary = $ldapcert.ByteValue
            #put binary data into .net certficate object.
            $Certobject = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 ` -ArgumentList @(,$certificatebinary)
            if($CheckRevocation){
                $certobjectBC = $x509certbc.ReadCertificate($certificatebinary)
            }
            $decimalserial = [convert]::ToInt64($certobject.SerialNumber,16)
            
            $Isrevoked = ""

            if($CheckRevocation) {
                if($certobjectBC.IssuerDN -eq "C=DK,O=TRUST2408,CN=TRUST2408 OCES CA II") {
                $Isrevoked = $ica02crl.IsRevoked($certobjectBC)
                }
                
                if ($certobjectBC.IssuerDN -eq "C=DK,O=TRUST2408,CN=TRUST2408 OCES CA III") {
                    $Isrevoked = $ica03crl.IsRevoked($certobjectBC)
                }

                if ($certobjectBC.IssuerDN -eq "C=DK,O=TRUST2408,CN=TRUST2408 OCES CA IV") {
                    $Isrevoked = $ica04crl.IsRevoked($certobjectBC)
                }
                
                if ($certobjectBC.IssuerDN -eq "C=DK,O=TRUST2408,CN=TRUST2408 OCES CA V") {
                    $Isrevoked = $ica05crl.IsRevoked($certobjectBC)
                }    
            }

            if($CheckRevocation -and $SkipRevoked -and $Isrevoked -eq $true) {
                continue
            }
            

            #put extesions into asn objects
            $extensions = $Certobject.Extensions
            $asnarray = @{}
            foreach ($e in $extensions) {
                $asn = New-Object -TypeName System.Security.Cryptography.AsnEncodedData($e.oid, $e.rawdata)
                $asnformatted= $asn.Format($true)
                $asnarray.add($asn.Oid, $asnformatted)
            }
            

            $mail = ""
            #for some reason asnencoded data parses diffrently with same lib between platforms, this happened after the bouncycastle addition.
            if ($PSVersionTable.Platform -eq "Unix") {
                $mail = ((($asnarray[($asnarray.Keys | Where-Object Value -eq $subjectAlternateNameUid)]) -replace "`r`n","").Split(':'))[1]
            }
            else {
                $mail = ((($asnarray[($asnarray.Keys | Where-Object Value -eq $subjectAlternateNameUid)]) -replace "`r`n","").Split('='))[1]
            }

            
            
            
            #check to see if certifcate has expired
            $expired = ""
                
            if($Certobject.NotAfter -lt (Get-Date)) {
                $expired = $true
            } else {
                $expired = $false
            }
            
            #make psobject with information
            $customobject += New-Object psobject -Property @{RawCertificate=$certificatebinary;Mail=$mail;Name=$Certobject.Subject;Created=$Certobject.NotBefore;Expires=$Certobject.NotAfter;SerialNumberDecimal=$decimalserial;SerialNumberHex=$Certobject.SerialNumber;Expired=$expired;Extensions=$extensions;Thumbprint=$Certobject.Thumbprint;Revoked=$Isrevoked}
            
        }  while ($cn.hasMore())

        return $customobject    
    } catch {
        if ($_.Exception.Message -like "*Exception calling `"SendRequest`" with `"2`" argument(s): `"Den tilladte*`"") {
            throw "More than five certificates found for this email"
        } else {
            throw $_
        }
    }
}
if ($PSVersionTable.PSEdition -eq "Desktop") {
    Add-Type -Path "$PSScriptRoot\Novell.Directory.LDAP.dll" #mono compatible assembly
}
else {
    Add-Type -Path "$PSScriptRoot\Novell.Directory.LDAP.VQ.dll" #.core assembly
}

Add-Type -Path "$PSScriptRoot\BouncyCastle.Crypto.dll" #responsible for crl parsing should be compatible with both versions