I was silent for about 3 months or so. There was no interesting topics to discuss and I hardly worked on my public projects, including PowerShell PKI module, PS Cmdlet Help Editor and ASN.1 Editor (not yet public). Today I completed new PS PKI module release and there is something to talk about.
Hellya! We reached 2000 downloads in 6 months! I think, it is a good progress! :)
As promised, there was a need to move forward and use some more efficient tools. As the result, my underlying API library was migrated to .NET Framework 4.0. There are no plans to move to 4.5, so you can be safe about this. For some time. Windows PowerShell 2.0 do not support CLR 4.0 assemblies, therefore, Windows PowerShell 2.0 is out of support. Although, PowerShell scripts are written in PS v2.0 and do not use any features of new languages, I don’t think, it will be a big problem. Minimum supported PowerShell version is 3.0.
The biggest change in this release is CA database access experience. Previously we had only four commands to access some CA database contents:
In v2.8 I added another command: Get-IssuedCRL. Actually, this command was a PoC (or draft) to provide enhanced access to a CA database. What next? Get-Attribute, Get-Extension to access Attribute and Extension tables? It was simple solution, but would add too many commands. Finally, I decided to regroup the code and provide one universal CA dumping function called Get-DatabaseRow. This function allows to access any database row in any table. In other words, it is a super-function, while already mentioned 4 functions are subset of this function. These functions will not be discontinued, as they provide the most common access functionality. The syntax of new command is the same as in familiar Get-*Request. The only difference is that there is a new parameter which accepts the table name to access.
Let’s recap general access techniques. First, we need to get the schema of the table to be accessed:
PS C:\> get-ca dc2* | Get-CASchema -Table crl Name DisplayName DataType MaxLength IsIndexed ---- ----------- -------- --------- --------- CRLRowId CRL Row ID Long 4 True CRLNumber CRL Number Long 4 True CRLMinBase CRL Minimum Base Number Long 4 False CRLNameId CRL Name ID Long 4 False CRLCount CRL Count Long 4 False CRLThisUpdate CRL This Update DateTime 8 False CRLNextUpdate CRL Next Update DateTime 8 True CRLThisPublish CRL This Publish DateTime 8 False CRLNextPublish CRL Next Publish DateTime 8 True CRLEffective CRL Effective DateTime 8 False CRLPropagationComplete CRL Propagation Complete DateTime 8 True CRLLastPublished CRL Last Published DateTime 8 True CRLPublishAttempts CRL Publish Attempts Long 4 True CRLPublishFlags CRL Publish Flags Long 4 False CRLPublishStatusCode CRL Publish Status Code Long 4 True CRLPublishError CRL Publish Error Information String 8192 False CRLRawCRL CRL Raw CRL Binary 536870912 False PS C:\>
We can use column names to create filters. For example, retrieve CRLs issued during last week:
PS C:\> get-ca dc2* | Get-DatabaseRow -Table CRL -Filter "CRLThisUpdate -gt $((Get-Date).AddDays(-7))" CRLRowId : 15320 CRLNumber : 5079 CRLThisUpdate : 2014.08.05. 9:09:37 CRLNextUpdate : 2014.08.06. 10:29:37 CRLPublishStatusCode : 0 CRLPublishError : - RowId : 15320 RequestId : 0 ConfigString : dc2.contoso.com\contoso-DC2-CA Table : CRL CRLRowId : 15321 CRLNumber : 5079 CRLThisUpdate : 2014.08.05. 9:09:37 CRLNextUpdate : 2014.08.06. 10:29:37 CRLPublishStatusCode : 0 CRLPublishError : - RowId : 15321 RequestId : 0 ConfigString : dc2.contoso.com\contoso-DC2-CA Table : CRL <...>
There are many. You can display additional properties by using “-Property” parameter:
PS C:\> get-ca dc2* | Get-DatabaseRow -Table CRL -Filter "CRLRowId -eq 15349" -Property *
CRLRowId : 15349
CRLNumber : 5086
CRLMinBase : 5082
CRLNameId : 0
CRLCount : 0
CRLThisUpdate : 2014.08.11. 16:32:57
CRLNextUpdate : 2014.08.12. 17:52:57
CRLThisPublish : 2014.08.11. 16:42:57
CRLNextPublish : 2014.08.12. 16:42:57
CRLEffective : 2014.08.08. 9:09:25
CRLPropagationComplete : 2014.08.11. 17:42:57
CRLLastPublished : 2014.08.11. 16:42:57
CRLPublishAttempts : 1
CRLPublishFlags : 70
CRLPublishStatusCode : 0
CRLPublishError : Published by CONTOSO\Administrator
CRLRawCRL : MIICAjCB6wIBATANBgkqhkiG9w0BAQsFADBHMRMwEQYKCZImiZPyLGQBGRYDY29t
MRcwFQYKCZImiZPyLGQBGRYHY29udG9zbzEXMBUGA1UEAxMOY29udG9zby1EQzIt
Q0EXDTE0MDgxMTE2MzI1N1oXDTE0MDgxMjE3NTI1N1qgcDBuMB8GA1UdIwQYMBaA
FGYgLGecDj5NRfL5lwWXZhNUEyY2MBAGCSsGAQQBgjcVAQQDAgEAMAsGA1UdFAQE
AgIT3jAcBgkrBgEEAYI3FQQEDxcNMTQwODEyMTY0MjU3WjAOBgNVHRsBAf8EBAIC
E9owDQYJKoZIhvcNAQELBQADggEBABiCowGlISbadz3hyBkJBBvp/DarZdoznNUu
rA5xofYNqmFUIqDnBXOSYguqAPxfW2l4IVtyS6wC7WRd8YMvQxUV778wskQVORs4
WTUY99zJjPDnK0WU8VL2YmPX99vSw5E13E+mo/vt1Q3CN+XQmC/jgf/YmZedOUyy
B5QDbLZP6/SwWQy3bRP0+PxwL89wzdrBvzLYSNqNErReeRgdPlYXoeH4neFAUhNZ
9NjwpZGYIMX1V4/b+i0q7dqQechdmKctfIr5r15PmQ3vz782UduNAp+5GkDPt3VD
Jf1PB2qUtlPfv7TWy4f0+Wa+ZS6/ff6XtunW5HzAOWuy8XfR+0k=
RowId : 15349
RequestId : 0
ConfigString : dc2.contoso.com\contoso-DC2-CA
Table : CRL
PS C:\>
We can see all aspects associated with the specified CRL. CRLPublishError column tells us that this CRL wasn’t issued automatically, but was manually triggered by a specified user account.
The same concept is used to access Attribute and Extension tables:
PS C:\> get-ca dc2* | Get-CASchema -Table Attribute Name DisplayName DataType MaxLength IsIndexed ---- ----------- -------- --------- --------- AttributeRequestId Attribute Request ID Long 4 True AttributeName Attribute Name String 254 False AttributeValue Attribute Value String 8192 False PS C:\> get-ca dc2* | Get-DatabaseRow -Table Attribute -Filter "AttributeRequestId -eq 1510" AttributeRequestId : 1510 AttributeName : RequestOSVersion AttributeValue : 6.0.6002.2 RowId : 1510 RequestId : 0 ConfigString : dc2.contoso.com\contoso-DC2-CA Table : Attribute AttributeRequestId : 1510 AttributeName : RequestCSPProvider AttributeValue : Microsoft Software Key Storage Provider RowId : 1510 RequestId : 0 ConfigString : dc2.contoso.com\contoso-DC2-CA Table : Attribute AttributeRequestId : 1510 AttributeName : ccm AttributeValue : dc2.contoso.com RowId : 1510 RequestId : 0 ConfigString : dc2.contoso.com\contoso-DC2-CA Table : Attribute PS C:\>
I just collected attributes associated with the RequestID = 1510. As we can see, the command returned multiple entries, each entry per attribute. To get the associated request, we can grab a corresponding row from Request table:
PS C:\> get-ca dc2* | Get-DatabaseRow -Filter "RequestId -eq 1510" RequestID : 1510 Request.StatusCode : 0 Request.DispositionMessage : Issued Request.RequesterName : CONTOSO\DC2$ Request.SubmittedWhen : 2012.12.14. 20:57:51 Request.CommonName : CertificateTemplate : OCSP Response Signing RowId : 1510 ConfigString : dc2.contoso.com\contoso-DC2-CA Table : Request PS C:\>
Ok, this row contains a OCSP Signing certificate. Ok, now we can try to get extensions associated with the request:
PS C:\> get-ca dc2* | Get-CASchema -Table Extension
Name DisplayName DataType MaxLength IsIndexed
---- ----------- -------- --------- ---------
ExtensionRequestId Extension Request ID Long 4 True
ExtensionName Extension Name String 254 False
ExtensionFlags Extension Flags Long 4 False
ExtensionRawValue Extension Raw Value Binary 4096 False
PS C:\> get-ca dc2* | Get-DatabaseRow -Table Extension -Filter "ExtensionRequestId -eq 1510"
ExtensionRequestId : 1510
ExtensionName : 1.3.6.1.4.1.311.21.7
ExtensionFlags : 131074
ExtensionRawValue : MCcGHysGAQQBgjcVCImQBoO+uDuHwY8PhLjyKoHh71UlASACAWUCAQI=
RowId : 1510
RequestId : 0
ConfigString : dc2.contoso.com\contoso-DC2-CA
Table : Extension
ExtensionRequestId : 1510
ExtensionName : 2.5.29.37
ExtensionFlags : 131072
ExtensionRawValue : MAoGCCsGAQUFBwMJ
RowId : 1510
RequestId : 0
ConfigString : dc2.contoso.com\contoso-DC2-CA
Table : Extension
ExtensionRequestId : 1510
ExtensionName : 2.5.29.15
ExtensionFlags : 131073
ExtensionRawValue : AwIHgA==
RowId : 1510
RequestId : 0
ConfigString : dc2.contoso.com\contoso-DC2-CA
Table : Extension
ExtensionRequestId : 1510
ExtensionName : 1.3.6.1.4.1.311.21.10
ExtensionFlags : 131072
ExtensionRawValue : MAwwCgYIKwYBBQUHAwk=
RowId : 1510
RequestId : 0
ConfigString : dc2.contoso.com\contoso-DC2-CA
Table : Extension
ExtensionRequestId : 1510
ExtensionName : 1.3.6.1.5.5.7.48.1.5
ExtensionFlags : 131072
ExtensionRawValue : BQA=
RowId : 1510
RequestId : 0
ConfigString : dc2.contoso.com\contoso-DC2-CA
Table : Extension
ExtensionRequestId : 1510
ExtensionName : 2.5.29.35
ExtensionFlags : 131072
ExtensionRawValue : MBaAFJ39/KrFuybixJrV0EtdamEKirpD
RowId : 1510
RequestId : 0
ConfigString : dc2.contoso.com\contoso-DC2-CA
Table : Extension
ExtensionRequestId : 1510
ExtensionName : 2.5.29.14
ExtensionFlags : 65536
ExtensionRawValue : BBR+s0tID9GKTJbXTuuBdrCgF4Zkng==
RowId : 1510
RequestId : 0
ConfigString : dc2.contoso.com\contoso-DC2-CA
Table : Extension
ExtensionRequestId : 1510
ExtensionName : 2.5.29.31
ExtensionFlags : 131074
ExtensionRawValue : MDgwNqA0oDKGMGh0dHA6Ly93d3cuY29udG9zby5jb20vcGtpL2NvbnRvc28tREMy
LUNBKDIpLmNybA==
RowId : 1510
RequestId : 0
ConfigString : dc2.contoso.com\contoso-DC2-CA
Table : Extension
ExtensionRequestId : 1510
ExtensionName : 1.3.6.1.5.5.7.1.1
ExtensionFlags : 131074
ExtensionRawValue : MF8wNAYIKwYBBQUHMAKGKGh0dHA6Ly93d3cuY29udG9zby5jb20vcGtpL2RjMmlj
YSgyKS5jcnQwJwYIKwYBBQUHMAGGG2h0dHA6Ly9kYzIuY29udG9zby5jb20vb2Nz
cA==
RowId : 1510
RequestId : 0
ConfigString : dc2.contoso.com\contoso-DC2-CA
Table : Extension
ExtensionRequestId : 1510
ExtensionName : 2.5.29.19
ExtensionFlags : 131075
ExtensionRawValue : MAA=
RowId : 1510
RequestId : 0
ConfigString : dc2.contoso.com\contoso-DC2-CA
Table : Extension
ExtensionRequestId : 1510
ExtensionName : 2.5.29.17
ExtensionFlags : 131072
ExtensionRawValue : MBGCD2RjMi5jb250b3NvLmNvbQ==
RowId : 1510
RequestId : 0
ConfigString : dc2.contoso.com\contoso-DC2-CA
Table : Extension
PS C:\>
Here we see all extension published in the issued certificate. These are not extensions from request, but extensions published in the end certificate. CA server may ignore some request extensions and adds its own extensions, like CDP, AIA, AKI and so on.
The next improvement was in Remove-Request. The biggest problem with this command was that it removed database rows one-by-one and did not supported non-Request tables. I rewrote the function and renamed to more generic Remove-DatabaseRow, so it supports:
Bulk database removal is implemented in three parameters:
With these parameters we can specify the date and time before database row are considered old (I doubt that you are interesting in certificates expired 5 years ago) and safe for removal. In this case we don’t need to pass individual rows. The last example shows how you can greatly cleanup CA database from old entries in just two lines.
In the next post I will discuss about Set-Extension command and other interesting stuff.
Just to keep reference:
>> PowerShell PKI Module v3.0 <<
Post your comment:
Comments: