 |
|
E-mail -  Live Messenger -  My main blog - |
|
| Edit in Browser | /_layouts/images/icxddoc.gif | /_layouts/formserver.aspx?XsnLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | FileType | xsn | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.2 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.3 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.4 | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsx | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsb | 255 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsx | 256 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsb | 256 |
|
|
| Edit in Browser | /_layouts/images/icxddoc.gif | /_layouts/formserver.aspx?XsnLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | FileType | xsn | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.2 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.3 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.4 | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsx | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsb | 255 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsx | 256 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsb | 256 |
|
|
| Edit in Browser | /_layouts/images/icxddoc.gif | /_layouts/formserver.aspx?XsnLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | FileType | xsn | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.2 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.3 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.4 | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsx | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsb | 255 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsx | 256 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsb | 256 |
|
|
|
|
|
|
 |
|
|
|
|
|
|
| с блек-джеком и шлюхами |
2010.08.23.In one of my recent posts I have posted a bug in AppLocker path rule processing (see: The case of another AppLocker bug). I have opened Technical Support case and AppLocker product group was able to repro the issue and provide a temporary workaround. Here is official Microsoft's response: We've investigated the issue and it appears to be a problem in the implementation of case-insensitive path comparison for characters outside the ASCII range. Fortunately it seems there is a workaround for the time being. If, in Local Security Policy, one specifies paths in all-uppercase characters, including uppercasing any non-ASCII characters as appropriate, then the rule will match properly. Concretely, for your example 'Mapīte', putting that string with lowercase ī in a rule's path in Local Security Policy will not work; however putting the string 'MAPĪTE' with uppercase Ī does seem to work. Therefore if path in the path rule contains non-english characters (outside the ASCII 1-127), write these characters in upper case. Unfortunately you cannot use PowerShell for that conversion (by using String.ToUpper() method), because console host doesn't display diacritic characters, so you will have to do this task manually. 2010.08.08.Many, many and many administrators requests new certificates and marks private keys as exportable. Is this a good solution? Definitely no. Are there a reasons to do that? In most cases — no. Do I need to explain the subject? Definitely yes. In many MS guides that are suited with custom certificate enrollment you may find certificate enrollment configuration INF file like this: [NewRequest] Subject = "CN=testca,O=Contoso,OU=nt" PrivateKeyArchive = FALSE Exportable = TRUE UserProtected = FALSE MachineKeySet = TRUE ProviderName = "Microsoft Enhanced Cryptographic Provider v1.0" UseExistingKeySet = FALSE RequestType = PKCS10 What exactly means selected line? This means that when certificate is issued, you can export the certificate with corresponding private key to a PFX container and move it to any other computer. Is this a risky? Let's see the examples. Scenario 1 One internet-banking system obtained SSL certificate from VeriSign. This can be EV (Extended Validation) certificate, so bank customers will see a great green bar when connects to internet-banking web site. Administrators used selected line in the INF file. Now if server is gone off, or disks are damaged, they can restore the site and attach existing certificate (from PFX) with corresponding private key to the site. Very helpful feature. Scenario 2 One internet-banking system obtained SSL certificate from VeriSign. This can be EV (Extended Validation) certificate, so bank customers will see a great green bar when connects to internet-banking web site. Administrators used selected line in the INF file. One malicious web administrator copied original web site content (customer registration window) to another malicious web server, exported the key from the original server and installed on fictional server. Now the administrator can send internet-banking customers to malicious web site and get an access to customer accounts and money. As a result, reputation of the bank will be lost with its consequences. Because multiple administrators have an access to web servers it is a big risk to allow to export the private key. Scenario 3 One bank has obtained a certificate with exportable private key from VeriSign for sensitive document signing. User want to buy a coffee and leave his workstation. It is common when a user forget to lock his workstation. During this time another user can open local certificate store and export signing certificate to USB flash. Now malicious user can impersonate legitimate user, change document contents and sign them. Legitimate user will lost his work. Because there always persist human factor, it is not possible to hold certificate private keys in a secure way, it strongly recommended to minimize the possibility of loss or theft. Scenario 4 Your organization has implemented network load balancing (NLB) cluster or a server cluster. Because all servers will serve the same host name, administrators generate single certificate with exportable private key and imports the same certificate on all cluster members. I would like to quote Brian Komar: A common misconception is that the same certificate and private key pair must be deployed at each Web server in the cluster. Each node in the cluster does require its own certificate, but it is not necessary to deploy the same certificate and key pair at each node in the cluster. If a node in the cluster fails, all Web clients connected to that node must reestablish connections to another node in the cluster. Remember that this is a new SSL connection, which requires that a new symmetric session key be negotiated between the Web client and the Web server. In fact, if you purchase your Web Server certificates from a commercial organization, such as VeriSign or RSA, you might be required to purchase separate Web Server certificates for each node. Scenario 5 Your organization implemented OCSP Responder for Offline CA (see more: The case of OCSP configuration for use with Standalone CAs). By default OCSP Responder re-enrolls signing certificate each 2 weeks. Because Offline CAs usually are turned off it is common when OCSP has independent signing certificate with longer validity period (from 6 months to several years). Because OCSP signing certificate never checked for revocation, it is an Epic Fail when the key is theft. If someone gets an access to the OCSP signing certificate private key, your revocation infrastructure will no longer trusted, because anyone (who has an access to the signing key) can fabricate OCSP responses. As a result, your PKI will become compromised and you will have to rebuild your PKI hierarchy from Root CA (if OCSP signing certificate was issued by Policy CA, not Root CA, because is is possible to revoke Policy CA certificate) or from the scratch (if OCSP Signing certificate was issued by Root CA, because it is not possible to revoke Root CA cert). Scenario 6 User has encrypted a confidential folder by using EFS. Is is common when users forget their passwords. Another user forget his password and asked tech support for password reset. Because EFS private keys are protected by original user password, after password reset the user will loose access to EFS encryption keys and encrypted confidential data. User will have to contact EFS recovery agent in order to get access to required confidential data. Scenario 7 Your organization implemented secure mail, so each mail message MUST be encrypted. So far all is ok, but SUDDENLY the hard disk is failed. Administrator created a new profile and connected a user to his own mailbox. However user cannot read mail messages, because messages are encrypted and decryption key was only on failed hard disk. We have discovered seven real-life scenarios and can tell that in some cases we MAY allow to export certificate private key and in other we MUST NOT allow this. Here is a little conclusion: - You SHOULD allow to export the private key that are used for data encryption. Because these keys don't allow user or computer impersonation it is recommended to implement private key archival or other key backup measurements. As a better (but more expensive) solution you MAY implement smart cards and hold user certificates on them.
- You MUST NOT allow to export the private keys that are used for data signing and principal impersonation (client authentication, document signing). Because even the private key is lost or stolen, users still will be able to access signed data and it is very easy to revoke lost/stolen certificate and issue new one. As a better (but more expensive) solution you MAY implement smart cards and hold user certificates on them.
- You MUST NOT allow to export computer private keys. Because computers don't sign or encrypts any long-term data except current secure communications. Therefore if particular computer certificate is stolen, or computer changed his affiliation, ceased operation, you MUST revoke the certificate and issue new one if required. As a better (but more expensive) solution you MAY store computer private keys on Hardware Security Module (HSM).
However I still don't understand why Microsoft in the most certificate enrollment-related documentation always include the flag Exportable = True, because there are no reasons except encryption certificate scenarios and the risk is higher than usability as we discussed in this post (Scenario 1), because your company reputation, data and money will gone off. Therefore if you see (even if this is Microsoft official document) the line: Exportable = True in the INF file, make sure if the supposed certificate is not EFS or mail encryption certificate and remove the line. The key words "MUST", "MUST NOT", "MAY", "SHOULD" are to be interpreted as follows: - MUST — this word mean that the definition is an absolute requirement of the specification.
- MUST NOT — this phrase mean that the definition is an absolute prohibition of the specification.
- MAY — This word, mean that an item is truly optional. One vendor may choose to include the item because a particular marketplace requires it or because the vendor feels that it enhances the product while another vendor may omit the same item.
- SHOULD — this word mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course.
(key word description source: RFC2119) 2010.08.04.Many of windows administrators requires to setup SSL on their web servers and mostly they wish to use certificates with the Subject Alternative Name extension that allows to map a single certificate to a multiple web sites. For example, you want to use a single certificate for https://www.domaon.com and https://owa.domain.com. In that case you need to have multiple subjects in the certificate. However X.509 certificates don't support multiple subject fields. To resolve this issue, Subject Alternate Name extension is used. You can add multiple (even wildcard) subjects to a certificate. Some time ago (in the case of Windows 2000 and Windows Server 2003), administrators had to use Enrollment Web Pages or use certreq.exe utility in conjunction with a custom INF file (not user-friendly way) because there is no way to generate a custom request from Certificates MMC snap-in. The life was beautiful until Windows Vista and Windows Server 2008 were released. Administrators tried to use a web enrollment to enroll computer certificates for a new OSs. And heck, this hadn't worked! Yes, old XEnroll ActiveX control is not supported by Windows Vista and higher. Administrators had to install update: KB922706 that adds CertEnroll (native for Windows Vista and higher) ActiveX control. And another heck, there is no option to enroll computer certificates at all! Many administrators overlooked extremely powerful updated Certificates MMC snap-in. Now it is very-very easy to enroll a certificate with a custom SAN extension. Prepare certificate template Most certificate templates are configured to build a subject from Active Directory. However this is not common for SSL certificates, because they usually use custom subject name instead of computer's FQDN. Therefore it is necessary to configure certificate template, that allows subject name supplying within certificate request. If you use default WebServer template, no additional steps are required. If you use custom certificate template you must ensure if the subject name is constructed from certificate request as shown: In addition you must assign Read and Enroll permissions in the Security tab for your web server *computer* account or a custom global or universal group that contains required computer accounts. Prepare Certification Authority Windows CA don't support certificate requests with SAN extension by default. To enable this support run the following command on the issuing CA server in elevated command prompt: certutil -setreg policy\EditFlags +EDITF_ATTRIBUTESUBJECTALTNAME2 net stop certsvc net start certsvc Make sure if certificate template is supported by issuing CA. Run CertSrv.msc MMC snap-in, expand your CA name and select Certificate Templates node. If required template is listed in the window, no additional steps are required. Otherwise right-click on the node, click New –> Certificate Template to Issue. In the list select required template and click Add. Certificate enrollment - Log on to the web server using domain account with local administrator permissions.
- On the Windows desktop
, click Start, and then click Run. - In the Run dialog box type mmc, and then click OK. If User Account Control is enabled, enter required account credentials or just click Yes on consent window.
- In the Console1 window, click File, and then click Add/Remove Snap-in.
- In the Add/Remove Snap-in dialog box, click Add.
- In the Add Standalone Snap-in dialog box, click Certificates and switch radiobutton to Computer account and click Next.
- In the Select computer dialog box use Local computer option (default value), click Finish and click Ok.
- Right-click on Personal node, click All Tasks and click Request new certificate.
- In the Before you begin page you can learn about certificate enrollment wizard. Click Next.
- If Select Enrollment Policy dialog box appear, select appropriate enrollment policy and click Next. You should see something like this:
- Select certificate template, and click the warning message and you will see the following dialog box:
- you may leave Subject field as empty if you decide to use subject alternative name extension. Expand drop-down Type list and select proper SAN format. For SSL certificates DNS type is common. In the value edit box type a name in the corresponding format and click Add. Repeat the procedure so mush times as it is necessary and click Ok when all SAN fields are complete.
- You will be returned to Certificate Enrollment wizard. You may notice that warning message is disappeared.
- Click Enroll to enroll a certificate.
Note: I advice to leave Subject field as empty in the case when you use multiple SAN fields. In that case Subject filed will be empty and one of the SANs will be used by clients. In addition, SAN extension will be marked as critical, because this will the only extension that will allow to identify server name. Tip: what means "extension is marked as critical"? Perhaps you remember one cool Slade song: "You know what my freedom means to me What it means, what it means to me Just exactly what my freedom means to me" This means that if an application see any critical extension, the application MUST process this extension. If critical extension is empty or unclear for that application (cannot recognize extension contained value), application MUST reject the certificate. Here are some issued certificate screenshots: See that SAN extension is marked as critical (yellow sign on the extension icon), as said this is because we have empty Subject field. There are no addition configuration steps required, because SAN criticality flag is automatically determined by CA policy module. HTH 2010.08.01.Recently I decided to perform little changes on my OCSP Responder. I'm using offline CA (root) and have configured to include OCSP URL to all issued certificates. But some time I haven't OCSP configuration for my root CA. And today I have completed all changes and now Root CA issues OCSP signing certs for appropriate OCSP configuration. You can find required info about the subject on TechNet: Online Responder Installation, Configuration, and Troubleshooting Guide or in AskDS blog: Implementing an OCSP responder: Part IV - Configuring OCSP for use with Standalone CAs. However both links contains incorrect settings, therefore I'll post correct steps. Assuming that OCSP Responder role is installed on a dedicated server (this is not a good practice to combine OCSP with Certification Authority role. However you can combine OCSP with Web enrollment and/or HTTP enrollment roles) and have Standalone CA running Windows Server 2003/2008/2008 R2. Prepare offline OCSP certificate request Log on to OCSP server with local administrator permissions. There are no special domain permissions, so local administrator will be enough for you. Administrator permissions will be required for all operations described below. On the desktop create a text file, for example 'ocsprequest.txt' and type the following text: [NewRequest] Subject = "CN=Root CA OCSP Signing,OU=corp,O=Company Name,C=US" MachineKeySet = True ProviderName = "Microsoft Enhanced Cryptographic Provider v1.0" KeyLength = 2048 [EnhancedKeyUsageExtension] OID="1.3.6.1.5.5.7.3.9" Note: NEVER, NEVER and NEVER mark private keys as exportable unless this is user encryption certificate. You MUST NEVER mark private keys as exportable especially for computer certificates. Since OCSP Signing certificate never checked for revocation you should carefully use this certificate, because if the key is compromised, you cannot revoke this certificate! You should edit Subject string to your custom values. Actually it is not necessary to set file extension as INF, because CertReq utility can read from TXT as well as from INF files. Run Command Prompt in elevated mode (by right-clicking on Command Prompt shortcut and pressing Run As Administrator). In the CMD type the following command: certreq –new desktop\ocsprequest.txt desktop\ocsprequest.req This will save a request file on your desktop. Copy request file (with .REQ extension) to a standalone CA using any removable media. Prepare Standalone CA Standalone CAs by default don't support id-pkix-ocsp-nocheck extension, so you will have to add this by running the following commands in elevated Command Prompt: certutil -v -setreg policy\EditFlags +EDITF_ENABLEOCSPREVNOCHECK certutil -v -setreg policy\EnableRequestExtensionList +1.3.6.1.5.5.7.48.1.5 The next thing we need to configure — certificate validity period. Since Standalone CA don't use certificate templates and certificate validity period is calculated as least from two values: By default ValidityPeriod property is set to 1 year. Since Standalone CAs used as a root and Policy CAs it is common to extend issued certificate validity period to 5, 10 or 15 years. However this would uncommon to set OCSP Response Signing certificate validity period to 15 years. 1 to 5 year would be enough for this scenario. Now we capture current validity period for issued certificates: certutil –getreg ca\validityperiodunits And configure new ValidityPeriod value as shown: certutil -setreg ca\ValidityPeriodUnits 5 net stop certsvc net start certsvc Note: don't forget to return this value to the original value after OCSP signing certificate issuance procedure. We are ready to submit our request to CA. In the opened elevated Command Prompt window type: certreq –submit path\ocsprequest.req In the dialog box select required CA server (usually there will be only local CA) and press Ok. You will see request ID and a message that the request is pending. Now open CertSrv.msc MMC snap-in and expand Pending Requests node. Locate request with required ID, right-click on it and click All tasks –> Issue. Switch to Issued Certificates node, locate the last certificate, open it, switch to Details tab and click Copy to file. Export the certificate to a file and transfer the file back to OCSP server. Confgure OCSP Responder We need to install issued certificate to certificate store. In the elevated Command Prompt type: certreq –accept path\ocspcert.cer if you don't see any errors, open ocsp.msc MMC snap-in. -
In the console select Revocation Configuration and in Action pane click Add Revocation Configuration. -
In the Getting Started wizard page read about the wizard and click Next. -
In the Name Revocation Configuration page specify configuration name. I use CA names for revocation configuration, so I can determine each revocation purpose by its name. Click Next. -
In the Select CA Certificate page switch to 'Select a certificate from the Local Store' and click Next. -
In the Choose CA Certificate page click Browse and select required Standalone CA certificate and click Next. -
In the Select Signing Certificate page switch to 'Manually select a signing certificate' and click Next. -
In Revocation Provider page click 'Provider…' and specify CA CRL location and click Finish. -
Expand Array Configuration and select array controller (marked with green arrow). In the central pane select created configuration and in Action pane click Assign Signing Certificate. In the dialog box locate and select the certificate we have imported in previous steps and click Ok. -
Right-click on Array Configuration and click Refresh Revocation Data. Tip: when you setup revocation configuration for Enterprise CAs the wizard automatically retrieves CA CRL URLs, but when you create revocation configuration for Standalone CAs and CAs running Windows 2000/Server 2003 the wizard don't retrieves CA CRL URLs. This is because the wizard uses ICertAdmin2::GetCAProperty(CR_PROP_CERTCDPURLS). This property is not available in Windows 2000/Server 2003 and Standalone CAs usually are disconnected from the network and are not accessible via DCOM. You should see a green icon for newly created revocation configuration. Now you can test your OCSP by using PKIView.msc, certutil.exe or other commercial (for example from Ascertia) tools. 2010.07.30.Update 18.08.2010: added workaround at the bottom of the post. Many Windows customers have received an error message in Application log when they try to update third-party root list. Prior to issue description I want to explain about the subject. Third-party root list is the list of third-party (non-Microsoft) root certification authorities (hereinafter CA) that participate in Microsoft Root Certificate Program. All these CAs are trusted by Windows and applications. About Program participants you can read the following article: Windows root certificate program members. You can add your own CAs to a trusted root list, but you cannot remove predefined CAs from computer. Therefore if new program member appears or retires, Microsoft issues update that will add or remove corresponding certificate to (from) Trusted Root CAs certificate container. Internally update contains a Certificate Trust List (CTL). Let's see the error message: Log Name: Application Source: Microsoft-Windows-CAPI2 Date: 2010.07.28. 4:28:10 Event ID: 4107 Task Category: None Level: Error Keywords: Classic User: N/A Computer: ComputerName Description: Failed extract of third-party root list from auto update cab at: <http://www.download.windowsupdate.com/msdownload/update/v3/static/trustedr/en/authrootstl.cab> with error: A required certificate is not within its validity period when verifying against the current system clock or the timestamp in the signed file. . Event Xml: <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event"> <System> <Provider Name="Microsoft-Windows-CAPI2" Guid="{5bbca4a8-b209-48dc-a8c7-b23d3e5216fb}" EventSourceName="Microsoft-Windows-CAPI2" /> <EventID Qualifiers="0">4107</EventID> <Version>0</Version> <Level>2</Level> <Task>0</Task> <Opcode>0</Opcode> <Keywords>0x8080000000000000</Keywords> <TimeCreated SystemTime="2010-07-28T01:28:10.499942000Z" /> <EventRecordID>5113</EventRecordID> <Correlation ActivityID="{00000100-0000-0000-C461-9AF48816CB01}" /> <Execution ProcessID="952" ThreadID="1428" /> <Channel>Application</Channel> <Computer>ComputerName</Computer> <Security /> </System> <EventData> <Data>http://www.download.windowsupdate.com/msdownload/update/v3/static/trustedr/en/authrootstl.cab</Data> <Data>A required certificate is not within its validity period when verifying against the current system clock or the timestamp in the signed file. </Data> </EventData> </Event> Download 'authrootstl.cab' file and open extracted file. You'll get the message: This certificate trust list is not valid. Certificate that signed the list is not valid.  What's happened with the signing certificate? Click 'View Signature' and you'll get detailed message about the error: This certificate is not valid for the requested usage. Right now, we need to find a source of the problem. Click 'View Certificate', switch to Details tab and scroll down to Enhanced Key Usage extension and check the value. Extension contains only single EKU: Root List Signer (1.3.6.1.4.1.311.10.3.9). However you MUST have at least 'Microsoft Trust List Signing' (1.3.6.1.4.1.311.10.3.1) EKU in order to sign CTL. Actually you can sign a CTL without this EKU, but this will cause that applications will ignore your signature and will not trust your CTL. But hey, the eventlog tell us that 'A required certificate is not within its validity period when verifying against the current system clock or the timestamp in the signed file'!!! Actually this is not true, because signing certificate is valid from 09 April 2010 to 09 July 2011. Current date is 28 July 2010, so the certificate is within it's validity period. In addition, the signature is timestamped. Therefore the signature will be considered as a valid after signing (or time stamp) certificate expiration. Experienced users may check my thought by using CAPI2 eventlog. Use Method 1 from the following article to enable CAPI2 logging: http://support.microsoft.com/kb/976235. And open again extracted CTL. After that check the most recent event with ID=11. You will see that certificate chaining engine will check the certificate against the following EKU: -ExtendedKeyUsage -Usage [ oid] 1.3.6.1.4.1.311.10.3.1 [ name] Microsoft Trust List Signing As you see in the last screenshot, required EKU is missing in the certificate and automatically raises the following text in the event: -ErrorStatus [ value] 10 [ CERT_TRUST_IS_NOT_VALID_FOR_USAGE] true What you should to do when you see mentioned error in Application eventlog? There is unofficial workaround: Backup and delete the content of the following folders: C:\Windows\System32\config\systemprofile\AppData\LocalLow\Microsoft\CryptnetUrlCache\Content C:\Windows\System32\config\systemprofile\AppData\LocalLow\Microsoft\CryptnetUrlCache\MetaData Backup and delete the certificates listed under "Certificates" key: HKEY_LOCAL_MACHINE\Software\Microsoft\SystemCertificates\AuthRoot\Certificates and restart the system. 2010.07.19.Update 23.08.2010: added workaround to resolve the issue. Today one customer claimed that AppLocker rules are not worked for his environment. He just created simple path rule and it didn't work. I have investigated this issue and I'm able to confirm that AppLocker don't apply path rules to a folder that contains non-english letters. Here is an example how to reproduce this issue. Assuming you have default Windows 7 Ultimate/Enterprise installation with C:\Windows as a system root folder. -
Logon with local administrator permissions. -
On the desktop create a folder that contains non-english letters. For example, the folder named Папка (here I use russian letters), or Mapīte (the word contains latvian letters). You can copy and paste these names as a folder name. -
Copy any your favorite executable to this folder. -
Click Start and in Search for programs or files edit box type Local Security Policy. You should see local security policy entry, click it. If prompted, confirm or enter your password in User Account Control prompt box. -
In the opened windows select and expand Application Control Policies node. -
Select and expand AppLocker node. -
Select Executable rules node. -
Right-click on the node and select Create Default Rules. This will create default rules, so you will be able to run any programs in elevated mode. -
Find and remove the rule that allows built-in administrators to run anything on the system. Here is a rule example: -
After that you will be able to run any program in %systemroot% and %programfiles% folders. All other folders will be restricted to run executables. Right-click on Executable rules and click Create New Rule. -
In the Before You Begin page you can get information about the wizard. Click Next. -
In the Permissions page ensure if Action is set to Allow and User or group is set to Everyone (default values). Click Next. -
In the Conditions page switch a radiobutton to Path and click Next. -
In the Path page click Browse Folders. Locate your created folder on the desktop (usually this is C:\Users\<YourAccountName>\Desktop\) and click Ok. In the Path page click Create. -
Minimize MMC console window. -
Switch to the desktop and try to run the file. You will get an error that the file was blocked. By this procedure you should be able to run any executable from this folder. However there is a bug (at least it looks like a bug) and if leaf folder in the rule contains non-english letters, the rule will not applied to the system and your application will be blocked. Now create another folder on the desktop so the folder contains only english letters and create the same rule for this folder (steps 10-16). And now any executable in the folder will successfully started. If you don't want to use AppLocker, return to minimized MMC console window, select Executable rules. In right pane select all rules and press Del. Confirm that you want to delete them and close all opened windows. There is available workaround to resolve the issue: The case of another AppLocker bug (resolved). HTH 2010.07.15.If you're looking for Enrollment Web Pages (hereinafter EWP) installation (or removal) without GUI — you're in correct place. At first I need to answer, why it necessary to script EWP installation. This may be very useful for CA administrator assistants, for example. In general, CA administrator will have to write a long step-by-step guide to install certain role. But using scripts, CA administrator may tell: "Take the script, run it with the XYZ parameters and get PROFIT" or something like this. It is common to script all (as possible) routine operations in the case of disaster recovery and so on, because it takes less time and easy to document. Feel free to think if CA role can be installed from the script — this is possible. In next post I'll show PowerShell code that will do that. But now we'll talk about web enrollment. As a start stage we need to find appropriate API and here it is: ICertSrvSetup. This CryptoAPI COM interface is the base interface for CA and/or EWP role installation. The following code will instantiate COM object: $EWPSetup = New-Object -ComObject CertOCM.CertSrvSetup.1
You must initialize the object to set required properties and install selected roles by invoking InitializeDefaults mthod. The method accepts two arguments:
- whether CA role will be installed;
- whether EWP role will be installed.
There are several rules for this method that are not covered in MSDN.
- If you wish to install both CA and EWP roles — pass (True, True) as a method arguments. Note that you cannot associate EWP with remote server, however. In that case EWP will be associated with local CA server.
- If you wish to install CA role only, without EWP — pass (True, False) as a method arguments;
- If you wish to install EWP role only, without CA — pass (False, True) as a method arguments. This is the only option to associate EWP with remote CA server. This option will be used in our case.
$EWPSetup.InitializeDefaults($false,$true)
We have initialized object to required state and we are ready to set required info — remote CA configuration string. As you should know, CA configuration string used in the following format: CAComputerName\CAName. To set remote CA config string we need to use SetWebCAInformation method as shown:
$EWPSetup.SetWebCAInformation("CA1\Company Issuing CA")
And now we can install the role:
$EWPSetup.Install()
In certain cases you may encounter an issue that you cannot instantiate COM object. This is because required binaries are not installed. In order to install them you should use ServerManager PowerShell module as shown:
PS C:\> Import-Module ServerManager
PS C:\> Get-WindowsFeature "ADCS*"
Display Name Name
------------ ----
[X] Certification Authority ADCS-Cert-Authority
[ ] Certification Authority Web Enrollment ADCS-Web-Enrollment
[X] Online Responder ADCS-Online-Cert
[ ] Network Device Enrollment Service ADCS-Device-Enrollment
[X] Certificate Enrollment Web Service ADCS-Enroll-Web-Svc
[X] Certificate Enrollment Policy Web Service ADCS-Enroll-Web-Pol
PS C:\> Add-WindowsFeature "ADCS-Web-Enrollment"
Success Restart Needed Exit Code Feature Result
------- -------------- --------- --------------
True No Success {Certification Authority Web Enrollment}
PS C:\>
you will need to add the check if binaries are installed at a start of script. Here is example script that will install EWP on local computer:
function Install-WebEnrollment {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[string]$CAConfig
)
# check if script running on Windows Server 2008 or Windows Server 2008 R2
$OS = Get-WmiObject Win32_OperatingSystem | select Version, ProductType
if ([int]$OS.Version[0] -ne 54 -and $OS.ProductType -ne 1) {
Write-Warning "Windows XP, Windows Server 2003 and Windows Server 2003 R2 are not supported!"
return
}
# check if web enrollment binaries are installed
Import-Module ServerManager
$status = (Get-WindowsFeature -Name ADCS-Web-Enrollment).Installed
# if still no, install binaries, otherwise do nothing
if (!$status) {$retn = Add-WindowsFeature -Name ADCS-Web-Enrollment
if (!$retn.Success) {
Write-Warning "Unable to install ADCS installation packages due of the following error:"
Write-Warning $retn.ExitCode
return
}
}
# instantiate COM object
try {
$EWPSetup = New-Object -ComObject CertOCM.CertSrvSetup.1
} catch {
Write-Warning "Unable to load necessary interfaces. Your Windows Server operating system is not supported!"
return
}
# initialize the object to install only web enrollment
$EWPSetup.InitializeDefaults($false,$true)
try {
# set required information and install the role
$EWPSetup.SetWebCAInformation($CAConfig)
$EWPSetup.Install()
}
catch {$_; return}
Write-Host "Successfully installed Enrollment Web Pages on local computer!" -ForegroundColor Green
}
And usage example:
Install-WebEnrollment "CA1\Company Issuing CA"
have a nice day with CryptoAPI scripting in PowerShell :) 2010.06.05.Hello again! Continuing Certificate Enrollment Service (CES) and Certificate Enrollment Policy (CEP) service subject I would like to post another PowerShell script that will install and remove CEP service. Like CES, CEP CryptoAPI COM interface is not documented yet. However you can manually find this interface in your registry: these keys are located in HKEY_CLASSES_ROOT hive. Actually there are a lot of interesting things that are not documented on MSDN. I don't know why, so don't ask me why, I'm not Microsoft guy. The code is quite similar as posted in the previous post, so I don't think that I need to additionally explain something else. Yes, I know, I'm bad PowerShell MVP, because my posts are quite complex and not all PowerShell users can understand it. Instead I provide (ate least I try) finished solutions for end-users. They just run my scripts and get the fun (or PROFIT!!!). Let's go: #####################################################################
# AddRemoveCEP.ps1
# Version 1.0
#
# Installs or removes Certificate Enrollment Policy service (CEP) instance
#
# Note: Requires Windows Server 2008 R2 Standard/Enterprise/Datacenter.
#
# Vadims Podans (c) 2010
# http://en-us.sysadmins.lv/
#####################################################################
#requires -Version 2.0
function Add-CEP {
<#
.Synopsis
Installs Certificate Enrollment Policy Service instance to local computer
.Description
This function installs Certificate Enrollment Policy Service instance to
local computer and configures IIS web application.
.Parameter Authentication
Specifies authentication type for communication. Possible values are:
Kerberos, UsrPwd or Certificate. Kerberos is used by default.
.Parameter Thumbprint
Specifies SSL certificate thumbprint.
.EXAMPLE
Add-CEP
Running command without parameters will install Certificate Enrollment Policy Service
instance with the default Kerberos authentication. If no valid SSL certificate is
found, the new one will be requested and assigned for CEP service.
.EXAMPLE
Add-CEP -Authentication Certificate -Thumbprint D485FFFD6C2CBC161667087B3209CCD765A32544
In this example CEP server will be configured to use Certificate authentication.
In addition, IIS Default Web Site will be configured to use SSL certificate
with thumbprint D485FFFD6C2CBC161667087B3209CCD765A32544. This certificate
must be stored in LocalMachine store and has private key.
#>
[CmdletBinding()]
param(
[ValidateSet("UsrPwd", "Kerberos", "Certificate")]
[string]$Authentication = "Kerberos",
[string]$Thumbprint
)
#region Check operating system
$OS = (Get-WmiObject Win32_OperatingSystem).Caption
if ($OS -notlike "Microsoft Windows Server 2008 R2*") {
Write-Warning "Only Windows Server 2008 R2 operating system is supported!"; return
}
#endregion
#region Check user permissions
# check if user has Enterprise Admins permissions
$elevated = $false
foreach ($sid in [Security.Principal.WindowsIdentity]::GetCurrent().Groups) {
if ($sid.Translate([Security.Principal.SecurityIdentifier]).IsWellKnown([Security.Principal.WellKnownSidType]::AccountEnterpriseAdminsSid)) {
$elevated = $true
}
}
if (!$elevated) {Write-Warning "You must be logged on with Enterprise Admins permissions!"; return}
#endregion
#region Obtain SSL certificate from local store or enroll new one
function Get-Cert {
# retrieve current domain name. this suffix is used to construct current computer FQDN
try {
$domain = ([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).Name
# if command above generates error, the computer is not a member of any AD domain
} catch {Write-Warning "Current computer is not a part of any Active Directory domain!"; return}
$fqdn = $env:COMPUTERNAME + "." + $domain
$validCerts = @()
# retrive all certificates from computer store that have private key and subject equals computer FQDN
$certs = @(Get-ChildItem cert:\localmachine\my | ?{$_.HasPrivateKey -and $_.subject -eq "CN=$fqdn"})
# loop extensions for EKU extension and check for Server Authentication OID
foreach ($cert in $certs) {
$eku = $cert.extensions | ?{$_.oid.value -eq "2.5.29.37"}
if ($eku) {
if ($eku.EnhancedKeyUsages | ?{$_.value -eq "1.3.6.1.5.5.7.3.1"}) {
# if certificate meet minimum requirements, write it to valid certs collection
$validCerts += $cert
}
}
}
# sort certificates in the collection by NotAfter and select one with the longest
# validity
if ($validCerts.count -gt 0) {
($validCerts | sort NotAfter | select -Last 1).Thumbprint
} else {
# if no valid certificate exist in the local store, enroll fro new one.
$enrollment = New-Object -ComObject X509Enrollment.CX509enrollment
# use ProductType of Win32_OperatingSystem class to determine computer role
# domain Controller or Member Server.
$ServerType = Get-WmiObject (Win32_OperatingSystem).ProductType
if ($ServerType -eq 2) {$enrollment.InitializeFromTemplate(0x3, "DomainController")}
elseif ($ServerType -eq 3) {$enrollment.InitializeFromTemplate(0x3, "Machine")}
try {$enrollment.Enroll()}
catch {
Write-Warning "Unable to enroll SSL certificate. In order to use CEP server"
Write-Warning "you will have to manually obtain SSL certificate and configure"
Write-Warning "IIS to use this certificate."
return
}
$base64 = $enrollment.Certificate(1)
$cert = New-Object Security.Cryptography.X509Certificates.X509Certificate2
$cert.Import($([Convert]::FromBase64String($base64)))
$cert.Thumbprint
}
}
#endregion
$auth = @{"Kerberos" = 2; "UsrPwd" = 4; "Certificate" = 8}
# we can use ServerManager module to install CEP binaries
Import-Module ServerManager
# at first check if CEP is already installed
$status = (Get-WindowsFeature -Name ADCS-Enroll-Web-Pol).Installed
# if still no, install binaries, otherwise do nothing
if (!$status) {$retn = Add-WindowsFeature -Name ADCS-Enroll-Web-Pol
if (!$retn.Success) {
Write-Warning "Unable to install CES service installation packages due of the following error:"
Write-Warning $retn.ExitCode
return
}
}
# instantiate CEP COM object
$CEP = New-Object -ComObject CERTOCM.CertificateEnrollmentPolicyServerSetup
$CEP.InitializeInstallDefaults()
if (!$Thumbprint) {$Thumbprint = $(Get-Cert)}
# set required properties. Here are only two available properties: Authentication and
# thumbprint.
$CEP.SetProperty(0x0, $auth.$Authentication)
$CEP.SetProperty(0x1, $Thumbprint)
Write-Host "Performing Certificate Enrollment Service installation with the following settings:" `
`n"Authentication type: $Authentication" `
`n"CEP server URL: $($CEP.GetProperty(0x2))" -ForegroundColor Cyan
if ($Thumbprint) {Write-Host "SSL certificate thumbprint: $Thumbprint" -ForegroundColor Cyan}
Write-Host ("-" * 50) `
`nInstallation results `
`n("-" * 50) -ForegroundColor Green
# install CEP instance
$CEP.Install()
if ($?) {Write-Host "CEP service was successfully installed!" -ForegroundColor Green}
}
function Remove-CEP {
<#
.Synopsis
Removes Certificate Enrollment Policy service instance from local computer.
.Description
Removes Certificate Enrollment Policy service instance from local computer.
.Parameter Force
Removes all CEP instances from local computer and removes role installation packages.
.EXAMPLE
Remove-CEP
Will remove all CEP instances but leaves installation packages.
.EXAMPLE
Remove-CEP -Force
Will remove all CEP instances and removes installation packages.
#>
[CmdletBinding()]
param (
[switch]$Force
)
#region Check operating system
$OS = (Get-WmiObject Win32_OperatingSystem).Caption
if ($OS -notlike "Microsoft Windows Server 2008 R2*") {
Write-Warning "Only Windows Server 2008 R2 operating system is supported!"; return
}
#endregion
#region User permissions
# check if user has Enterprise Admins permissions
$elevated = $false
foreach ($sid in [Security.Principal.WindowsIdentity]::GetCurrent().Groups) {
if ($sid.Translate([Security.Principal.SecurityIdentifier]).IsWellKnown([Security.Principal.WellKnownSidType]::AccountEnterpriseAdminsSid)) {
$elevated = $true
}
}
if (!$elevated) {Write-Warning "You must be logged on with Enterprise Admins permissions!"; return}
#endregion
$CEP = New-Object -ComObject CERTOCM.CertificateEnrollmentPolicyServerSetup
Write-Host "Performing Certificate Enrollment Service removal with the fillowing settings:" -ForegroundColor Cyan
if ($Force) {Write-Host "Remove installation packages: Yes" -ForegroundColor Cyan}
else {write-Host "Remove installation packages: No" -ForegroundColor Cyan}
Write-Host ("-" * 50) `
`nRemoval results `
`n("-" * 50) -ForegroundColor Green
$CEP.Uninstall()
if ($?) {Write-Host "CEP service successfully removed!" -ForegroundColor Green}
if ($Force) {
Import-Module ServerManager
$retn = Remove-WindowsFeature -Name ADCS-Enroll-Web-Pol
if (!$retn.Success) {
Write-Warning "CEP installation package removal failed due of the following error:"
Write-Warning $retn.ExitCode
}
else {Write-Host "CEP installation packages are successfully removed!" -ForegroundColor Green}
}
}
Dot-source this script and run the following command to install CEP instance:
Add-CEP –Authentication <UsrPwd> –Thumbprint <EB74DA32E86>
you don't need to specify '–Authentication' parameter for Kerberos authentication. This is because Kerberos is used by default in my script. Only 3 authentication methods are supported by CEP: Kerberos, UsrPwd (User name and Password) and Certificate. '-Thumbprint' is not mandatory parameter. However you may have to set CEP for non-domain or external users. In that case it is common when you will use Internet name for your CEP server. Therefore you will have to assign certificate that matches your server Internet name. By specifying your own thumbprint, this certificate will be assigned for CEP. By default this script will find or enroll new one that will matches your server domain name (FQDN). Therefore you don't need to specify '-Thumbprint' parameter for internal use (within your AD forest).
In order to remove CEP instance from your server run the following command:
Remove-CEP –Force
You can run the command without any parameter. '-Force' switch will remove installation packages too. The different is that when you run 'Remove-CEP', server manager will show that CEP role is installed, but not configured. When you run 'Remove-CEP –Force', the script will also remove CEP role from server manager.
As usually you may check internal script help by typing:
For script download click here:
feel free to ask me if you have comments or questions. 2010.05.30.Sometimes I don't understand Microsoft. They a lot of useful things, but thing implementation is quite poor. For example in Windows Server 2008 R2 we have an option to install certificate enrollment service (hereinafter CES) that will allow to securely enroll certificates outside of domain network perimeter. Also CES allows to enroll certificates from non-domain clients. Here is excellent whitepaper about the subject: Certificate Enrollment Web Services in Windows Server 2008 R2. You can setup only one CES instance via Server Manager snap-in. What if we have multiple CA servers and we need to configure CES to work with them? For example, one CA is configured to issue user certificates only and another CA is configured to issue computer certificates only. Also we need to issue these certificates to external clients. In that case we need to setup at least two Windows Server 2008 R2 servers, assign them public IP address and install required CES instance on each CES server. This is pretty ugly. Hopefully there is a trick to install additional CES instances on the same server via CryptoAPI COM interface: CERTOCM.CertificateEnrollmentServerSetup. Currently this interface is not documented on MSDN, therefore I cannot provide interface explanation links. However I wrote PowerShell script that will add additional CES instance and remove specified or all CES instances from local computer. I have commented some code parts for understanding, but the code generally is self-explanatory. Let's go: #####################################################################
# AddRemoveCES.ps1
# Version 1.3
#
# Installs or removes Certificate Enrollment Service (CES) instance
#
# Note: Requires Windows Server 2008 R2 Standard/Enterprise/Datacenter.
#
# Vadims Podans (c) 2010
# http://en-us.sysadmins.lv/
#####################################################################
#requires -Version 2.0
function Add-CES {
<#
.Synopsis
Installs Certificate Enrollment Service instance to local computer
.Description
This function installs Certificate Enrollment Service instance and configures it
to work with specified certification authority.
.Parameter CAConfig
Specifies certification authority configuration string in:
CAComputerName\CASamitizedName format. CAComputerName may be either
DNS or NetBIOS name. If this parameter is omitted, CA selection UI will be
displayed during instance installation.
.Parameter Authentication
Specifies authentication type for communication. Possible values are:
Kerberos, UsrPwd or Certificate. Kerberos is used by default.
.Parameter User
Sets CES AppPool account name. If this parameter is omitted, ApplicationPoolIdentity
account will be used.
.Parameter Password
Sets CES AppPool account password.
.Parameter RenewalOnly
Sets CES service mode to Renewal Only. In that case CES will process certificate
renewal requests only. No new certificate requests will be accepted.
.EXAMPLE
Add-CES
Running command without parameters will cause CA selection UI appearance. You will
need to select CA server for CES server. In addition, default Kerberos authentication
will be used.
.EXAMPLE
Add-CES -CAConfig CA1\Contoso-CA -Authentication Certificate -User CustomUser -Password CustomPassword
In this example CES server will be configured to CA server with Contoso-CA name
and that is hosted on the computer named CA1. CES server will use client
certificate for authentication and IIS AppPool will be configured to run
under CustomUser account that has CustomPassword password.
#>
[CmdletBinding()]
param(
[string]$CAConfig,
[ValidateSet("UsrPwd", "Kerberos", "Certificate")]
[string]$Authentication = "Kerberos",
[string]$User,
[string]$Password,
[switch]$RenewalOnly
)
#region Check operating system
$OS = (Get-WmiObject Win32_OperatingSystem).Caption
if ($OS -notlike "Microsoft Windows Server 2008 R2*") {
Write-Warning "Only Windows Server 2008 R2 operating system is supported!"; return
}
#endregion
#region Check user permissions
# check if user has Enterprise Admins permissions
$elevated = $false
foreach ($sid in [Security.Principal.WindowsIdentity]::GetCurrent().Groups) {
if ($sid.Translate([Security.Principal.SecurityIdentifier]).IsWellKnown([Security.Principal.WellKnownSidType]::AccountEnterpriseAdminsSid)) {
$elevated = $true
}
}
if (!$elevated) {Write-Warning "You must be logged on with Enterprise Admins permissions!"; return}
#endregion
#region Obtain SSL certificate from local store or enroll new one
function Get-Cert {
# retrieve current domain name. this suffix is used to construct current computer FQDN
try {
$domain = ([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).Name
# if command above generates error, the computer is not a member of any AD domain
} catch {Write-Warning "Current computer is not a part of any Active Directory domain!"; return}
$fqdn = $env:COMPUTERNAME + "." + $domain
$validCerts = @()
# retrive all certificates from computer store that have private key and subject equals computer FQDN
$certs = @(Get-ChildItem cert:\localmachine\my | ?{$_.HasPrivateKey -and $_.subject -eq "CN=$fqdn"})
# loop extensions for EKU extension and check for Server Authentication OID
foreach ($cert in $certs) {
$eku = $cert.extensions | ?{$_.oid.value -eq "2.5.29.37"}
if ($eku) {
if ($eku.EnhancedKeyUsages | ?{$_.value -eq "1.3.6.1.5.5.7.3.1"}) {
# if certificate meet minimum requirements, write it to valid certs collection
$validCerts += $cert
}
}
}
# sort certificates in the collection by NotAfter and select one with the longest
# validity
if ($validCerts.count -gt 0) {
($validCerts | sort NotAfter | select -Last 1).Thumbprint
} else {
# if no valid certificate exist in the local store, enroll fro new one.
$enrollment = New-Object -ComObject X509Enrollment.CX509enrollment
# use ProductType of Win32_OperatingSystem class to determine computer role
# domain Controller or Member Server.
$ServerType = Get-WmiObject (Win32_OperatingSystem).ProductType
if ($ServerType -eq 2) {$enrollment.InitializeFromTemplate(0x3, "DomainController")}
elseif ($ServerType -eq 3) {$enrollment.InitializeFromTemplate(0x3, "Machine")}
try {$enrollment.Enroll()}
catch {
Write-Warning "Unable to enroll SSL certificate. In order to use CES server"
Write-Warning "you will have to manually obtain SSL certificate and configure"
Write-Warning "IIS to use this certificate."
return
}
$base64 = $enrollment.Certificate(1)
$cert = New-Object Security.Cryptography.X509Certificates.X509Certificate2
$cert.Import($([Convert]::FromBase64String($base64)))
$cert.Thumbprint
}
}
#endregion
$auth = @{"Kerberos" = 2; "UsrPwd" = 4; "Certificate" = 8}
# we can use ServerManager module to install CES binaries
Import-Module ServerManager
# at first check if CES is already installed
$status = (Get-WindowsFeature -Name ADCS-Enroll-Web-Svc).Installed
# if still no, install binaries, otherwise do nothing
if (!$status) {$retn = Add-WindowsFeature -Name ADCS-Enroll-Web-Svc
if (!$retn.Success) {
Write-Warning "Unable to install CES service installation packages due of the following error:"
Write-Warning $retn.ExitCode
return
}
}
# instantiate CES COM object
$CES = New-Object -ComObject CERTOCM.CertificateEnrollmentServerSetup
$CES.InitializeInstallDefaults()
# use ICertConfig.GetConfig() to display CA selection UI
if ($CAConfig -eq "") {
$config = New-Object -ComObject CertificateAuthority.Config
try {
$bstr = $config.GetConfig(1)
} catch {Write-Warning "There is no available Enterprise Certification Authorities or user canceled operation."; return}
} else {$bstr = $CAConfig}
$Thumbprint = $(Get-Cert)
if ($User) {
$CES.SetApplicationPoolCredentials($User, $Password)
}
$CES.SetProperty(0x1, $bstr)
$CES.SetProperty(0x2, $auth.$Authentication)
$CES.SetProperty(0x3, $Thumbprint)
if ($RenewalOnly) {$CES.SetProperty(0x5, $true)}
Write-Host "Performing Certificate Enrollment Service installation with the following settings:" `
`n"CA configuration string: $bstr" `
`n"Authentication type: $Authentication" -ForegroundColor Cyan
if ($RenewalOnly) {Write-Host "Renewal mode: Yes" -ForegroundColor Cyan}
else {Write-Host "Renewal mode: No" -ForegroundColor Cyan}
Write-Host "CES server URL: $($CES.GetProperty(0x4))" -ForegroundColor Cyan
if ($Thumbprint) {Write-Host "SSL certificate thumbprint: $Thumbprint" -ForegroundColor Cyan}
Write-Host ("-" * 50) `
`nInstallation results `
`n("-" * 50) -ForegroundColor Green
$CES.Install()
if ($?) {Write-Host "CEP service was successfully installed!" -ForegroundColor Green}
}
function Remove-CES {
<#
.Synopsis
Removes Certificate Enrollment Service instance from local computer.
.Description
This function removes Certificate Enrollment Service instance or instances
if you wish to remove all CES instances from local computer.
.Parameter CAConfig
Specifies certification authority configuration string in:
CAComputerName\CASamitizedName format. CAComputerName may be either
DNS or NetBIOS name. If this parameter is omitted, CA selection UI will be
displayed during instance removal. If -Force switch is asserted, this paramter
will be ignored and all CES instances will be removed from local computer.
.Parameter Authentication
Specifies authentication type to remove for specified instance. Possible values are:
Kerberos, UsrPwd or Certificate. Kerberos is used by default. This parameter
may be used if multiple instances are installed to work with the same CA server
but they uses different authentication types.
.Parameter Force
Instructs to ignore CAConfig and Authentication parameters and remove all CES
instances from local computer.
.EXAMPLE
Remove-CES -CAConfig CA1\Contoso-CA
Will remove all CES instances that was configured for CA server named Contoso-CA
and that is hosted on CA1 computer.
.EXAMPLE
Remove-CES -Force
Will remove all CES instances from local computer.
#>
[CmdletBinding()]
param (
[string]$CAConfig,
[ValidateSet("UsrPwd", "Kerberos", "Certificate")]
[string]$Authentication = "Kerberos",
[switch]$Force
)
#region Check operating system
$OS = (Get-WmiObject Win32_OperatingSystem).Caption
if ($OS -notlike "Microsoft Windows Server 2008 R2*") {
Write-Warning "Only Windows Server 2008 R2 operating system is supported!"; return
}
#endregion
#region User permissions
# check if user has Enterprise Admins permissions
$elevated = $false
foreach ($sid in [Security.Principal.WindowsIdentity]::GetCurrent().Groups) {
if ($sid.Translate([Security.Principal.SecurityIdentifier]).IsWellKnown([Security.Principal.WellKnownSidType]::AccountEnterpriseAdminsSid)) {
$elevated = $true
}
}
if (!$elevated) {Write-Warning "You must be logged on with Enterprise Admins permissions!"; return}
#endregion
$auth = @{"Kerberos" = 2; "UsrPwd" = 4; "Certificate" = 8}
if ($CAConfig -eq "" -and !$Force) {
$config = New-Object -ComObject CertificateAuthority.Config
try {
$bstr = $config.GetConfig(1)
} catch {Write-Warning "There is no available Enterprise Certification Authorities or user canceled operation."; return}
}
elseif ($CAConfig -ne "" -and !$Force){$bstr = $CAConfig}
else {$bstr = $null; $auth.$Authentication = $null}
$CES = New-Object -ComObject CERTOCM.CertificateEnrollmentServerSetup
Write-Host "Performing Certificate Enrollment Service removal with the fillowing settings:" -ForegroundColor Cyan
if ($bstr -eq $null) {Write-Host "CA configuration string: Any" -ForegroundColor Cyan}
else {Write-Host "CA configuration string: $bstr" -ForegroundColor Cyan}
if ($auth.$Authentication -eq $null) {Write-Host "Authentication type: Any" -ForegroundColor Cyan}
else {Write-Host "Authentication type: $Authentication" -ForegroundColor Cyan}
if ($Force) {Write-Host "Remove installation packages: Yes" -ForegroundColor Cyan}
else {write-Host "Remove installation packages: No" -ForegroundColor Cyan}
Write-Host ("-" * 50) `
`nRemoval results `
`n("-" * 50) -ForegroundColor Green
$CES.Uninstall($bstr, $auth.$Authentication)
if ($?) {Write-Host "CES service successfully removed!" -ForegroundColor Green}
if ($Force) {
Import-Module ServerManager
$retn = Remove-WindowsFeature -Name ADCS-Enroll-Web-Svc
if (!$retn.Success) {
Write-Warning "CES installation package removal failed due of the following error:"
Write-Warning $retn.ExitCode
}
else {Write-Host "CES installation packages are successfully removed!" -ForegroundColor Green}
}
}
copy and paste the code to PowerShell console and run the following commands:
- to install first or additional CES instance:
Add-CES
Running command without parameters will cause CA selection UI appearance. You will need to select CA server for CES server. In addition, default Kerberos authentication will be used. Add-CES CA1\Contoso-CA certificate CustomUser CustomPassword
In this example CES server will be configured to CA server with Contoso-CA name and that is hosted on the computer named CA1. CES server will use client certificate for authentication and IIS AppPool will be configured to run under CustomUser account that has CustomPassword password.
- to remove CES instance (or all instances):
Remove-CES CA1\Contoso-CA
Will remove all CES instances that was configured for CA server named Contoso-CA and that is hosted on CA1 computer.
Remove-CES –Force
Will remove all CES instances from local computer. If you specify –Force switch, this will ignore CAConfig and Authentication parameters and will remove all CES instances from local computer.
Note: by default script configure IIS AppPool to ApplicationPoolIdentity. Currently I don't know how to configure AppPool to NetworkService identity, so you may have to manually switch application pool account settings after role installation. This will not required if there is at least one existing CES instance. In that case new CES instance will inherit application pool settings from existing CES instance.
If you have questions or comments — ask me :)
For script download click here:
Have a nice day! :) 2010.05.09.Looking to my previous posts I've noticed that I haven't described the methods how certificate extensions are encoded. Cryptography in overall relies on encoded data. For example, digital certificate is a byte array that contains encoded certificate fields. All certificate content is encoded using Abstract Syntax Notation 1 Distinguished Encoding Rules (simply ASN.1 DER). If certificate is stored in Base64 string format, system just converts Base64 content to a byte array. There are several encoding rules for each data type. For example, object identifiers (OIDs) has their own encoding rules, DateTime — their own encoding rules and so on. In this post I would like to demonstrate encoding rules for Object Identifier data type. Object Identifiers are used to encode Enhanced Key Usage, Application Policies, Certificate Policies and other certificate extensions. The following format is used: In the following example we will encode simple OID (1.3.6.1.5.5.7.3.1) using ASN.1 DER. Mostly 'Tag value' is set to 0x30 (48) that identifies 'constructed type'. The next byte represents string length. Data type for OID is 0x6 (6). The next byte represents encoded OID string length end the rest bytes is encoded data string (actual data). At first we will look to OID string encoding. The first encoded string byte represents first two OID octets. This is because the first OID string is limited to the following values: 0, 1 and 2. Second octet is limited to the value range 0-39 (in decimal). Therefore it is possible to encode first two octets by using one byte as follows: 0x00 = 0.0 0x01 = 0.1 0x27 = 0.39 0x28 = 1.0 0x29 = 1.1 0x4f = 1.39 0x50 = 2.0 0x51 = 2.1 and so on. Therefore first byte of actual data will be 0x2b that represents first two OID string octets (1.3). Here is another mathematical trick to determine first byte value: 40 * 1st OID octet + 2nd OID octet. For example, we have an OID that starts with 2.8.x.x.x. To calculate the first encoded byte we multiply 40 by 2 (as the first OID octet) and plus 8 (as the second OID octet) and we get 88 in decimal or 0x58 in hex. Since OID is numerical value only, each next octet is encoded by octet actual values (6.1.5.5.7.3.1) with the base 128: 0x06, 0x01, 0x05, 0x05, 0x07, 0x03 and 0x01. Now we can calculate the length of the actual encoded data string — 0x08. And the length of the same string with the data type octet — 0x0a (0x8 + 0x2). So we can construct the following encoded string: 30 0a 06 08 2b 06 01 05 07 03 01 (all values in hex). Since each subsequent octet has a base 128, the highest value of the byte can be 0x7f or 127 in decimal. What if OID octet is higher than 127? For example, 130. In that case current byte is set to 0x81 (0x80 is reserved for initial base) that will represent the value = 128 and the next byte will represent the remaining value (130 – 128 = 2) — 0x81 0x02. So the octets that are higher than 127 are encoded in two or more bytes — transitional byte (or bytes) and remaining value byte. If you increment transitional byte minor value by 1, the actual value is incremented by 128. Since minor byte value may have value range 0x0 — 0xf (16 values) the highest actual octet value can be 128 * 16 = 2048. when you increment byte minor value by one, the base will increment by 128. For example the OID octet value is 311, the encoded byte will be 0x82 0x37. Let's see how these values are got. 311 is greater than 127 and the difference between 311 and 128 is greater than 128, so current byte will become as transitional byte — 0x82 and base 256. The difference between 311 and 256 is less than 128 (55) so we set the transitional byte to 0x82 and the next byte will represent the difference between 311 and 256 (55 or 0x37 in hex). There is a simple formula: Actual value / 128 = Increment (rounding to lesser integer). In our case this is 311 / 128 = 2,43. Round the result to the lesser integer and we get 2. Increment 0x80 by 2 will result 0x82. In example of OID octet = 500 we will calculate as follows: 500 / 128 = 3,90. Round the result to the lesser integer will result 3. Therefore the transitional byte minor value will be 3 (0x83). Subtract actual value (500) from base (128 * 3 = 384) and we get 116. The next byte will represent this difference — 0x74 and the encoded bytes of this octet will be: 0x83 0x74. We can increment transitional byte minor value up to 0xf (0x8f) with the base = 1920 (0xf * 128) and the highest OID octet value for this base is 2047. What if an OID value is greater than 2048? In that case we increment transitional byte major value and set byte minor value to 0. For example an octet has the value = 2050. We increment transitional byte major value by one and get 90. The base now is 2048. 2050 (octet value) – 2048 (base) will result 2. This result must be encoded and placed after transitional byte — 0x90 0x02. Incrementing transitional byte major value will increment base by 2048. For example if transitional byte is 0xa0, the base will be 3968. If the transitional byte is 0xa1 will increment base by 128 and results the new base = 4096. Using this explanation we can produce resultant simple calculation formula. The calculation process will consist of the following steps: -
Divide octet value by 2048 and round result value to the lesser integer. If lesser integer is 0, continue with the next step. If lesser integer is greater than 0, set the transitional byte major value to: 8 + lesser integer. -
If transitional byte major value is greater than 0 set the base as 2048 * lesser integer. Otherwise set the base as 0. -
Subtract base from octet value and divide by 128. Round the result to the lesser integer. If lesser integer is 0, remove transitional byte. The value must be encoded by using single byte. -
If lesser integer is greater than 0, set the transitional byte minor value as lesser integer as: 128 * lesser integer. -
Set the transitional byte hex value as: 2048 * lesser integer produced at the step 1 (major value) and 128 * lesser integer produced at the step 3. -
Subtract actual octet value from resulting base and encode the difference by using single byte. Let's see several examples: Divide 5000 by 2048 = 2,44. Round the result to the lesser integer = 2. Set transitional byte major value to 0x8 + 0x2 = 0xa and set the base as 2048 * 2 = 4096. Subtract the base from from actual octet value: 5000 – 4096 = 904. Divide 904 by 128 = 7,06. Round this to the lesser integer = 7. Set transitional byte minor value to 0x7 and the base as: 4096 + 7 * 128 = 4992. The complete transitional byte is 0xa7. Subtract the base from octet value: 5000 – 4992 = 8. Encode this value as a single byte = 0x8. As a result, the encoded value of the OID octet = 5000 will be: 0xa7 0x08. Divide 10000 by 2048 = 4,88. Round the result to the lesser integer = 4. Set transitional byte major value to 0x8 + 0x4 = 0xC and set the base as 2048 * 4 = 8192. Subtract the base from actual octet value: 10000 – 8192 = 1808. Divide 1808 by 128 = 14,12. Round the result to the lesser integer = 14. Set transitional byte minor value to 0xe (14 in decimal) and set the base 8192 + 14 * 128 = 9984. The complete transitional byte is 0x4e. Subtract the base from the actual octet value: 10000 – 9984 = 16. Encode this value as a single byte = 0x10 (16 in decimal). As a result the encoded value of the OID octet = 10 000 will be: 0xCE 0x10. Divide 1500 by 2048 = 0,73. Round the result to the lesser integer = 0. Set the transitional byte major value to 0x8 + 0x0 = 0x8 and set the base as 2048 * 0 = 0. Subtract the base from actual octet value: 1500 – 0 = 1500. Divide 1500 by 128 = 11,71. Round the result to the lesser integer = 11. Set transitional byte minor value to 0xB and set the base 0 + 11 * 128 = 1408. The complete transitional byte is 0x8B. Subtract the base from the actual octet value: 1500 – 1408 = 92. Encode this value as a single byte = 0x5C (92 in decimal). As a result encoded value of the OID = 1500 will be: 0x8B 0x5C. Using these rules we can encode OID octets with the value up to 16383 (0xff 0x7f). What if the octet value is greater than 16383? In that case additional transitional byte is required. Additional transitional byte minor value increment the base by 16384 and transitional byte major value will increment the base by 262144. The following example will show the calculation process for the octet values greater than 16383: Divide 100 000 by 262144 = 0,38. Round the result to the lesser integer = 0. Set the first transitional byte major value to 0x8 + 0 = 0x8 and set the base as 262144 * 0 = 0. Subtract the base from the actual octet value: 100 000 – 0 = 100 000. Divide 100000 by 16384 = 6,1. Round this value to the lesser integer = 6. Set the first transitional byte minor value to 0x6 and set the base 0 + 6 * 16384 = 98304. The first transitional byte is 0x86. Subtract the base from the actual octet value: 100 000 – 983384 = 1696. Continue with the second transitional byte. Divide 1696 by 2048 = 0,82. Round the result to the lesser integer = 0. Set the second transitional byte major value to 0x8 + 0x0 = 0x8 and set the base to 98304 + 0x0 = 98304. Subtract the base from the actual octet value: 100 000 – 98304 = 1696. Divide 1696 by 128 = 13,25. Round the result to the lesser integer = 13. Set the second transitional byte minor value to 0xd and set the base to 0 + 13 * 128 = 1664. The complete second transitional byte is 0x8D. Subtract the base from the remainder: 1696 – 1664 = 32. Encode this value as a single byte = 0x20 (32 in decimal). As a result encoded value of this OID will be: 0x86 0x8D 0x20. Usually you don't need to manually convert OIDs to the encoded values. There are .NET class: X509EnhancedKeyUsageExtension and IX509ExtensionEnhancedKeyUsage COM interface that will do this task.
| Edit in Browser | /_layouts/images/icxddoc.gif | /_layouts/formserver.aspx?XsnLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | FileType | xsn | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.2 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.3 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.4 | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsx | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsb | 255 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsx | 256 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsb | 256 |
|
|
|
|
|
|
|
|