Score:0

How do I manually circumvent the AD FS certificate catch-22

mx flag

I can't start AD FS service. This is because it's configured with a certificate with an incorrect set of unnecessarily overcomplicated X509 extensions. This causes the service to fail with error 102, which is a null argument exception. Silently.

Exception details: 
System.ArgumentNullException: Value cannot be null.
Parameter name: certificate
   at System.IdentityModel.Tokens.X509SecurityToken..ctor(X509Certificate2 certificate, String id, Boolean clone, Boolean disposable)
   at Microsoft.IdentityServer.Service.Configuration.MSISSecurityTokenServiceConfiguration.Create(Boolean forSaml, Boolean forPassive)
   at Microsoft.IdentityServer.Service.Policy.PolicyServer.Service.ProxyPolicyServiceHost.ConfigureWIF()
   at Microsoft.IdentityServer.Service.SecurityTokenService.MSISConfigurableServiceHost.Configure()
   at Microsoft.IdentityServer.Service.Policy.PolicyServer.Service.ProxyPolicyServiceHost.Create()
   at Microsoft.IdentityServer.ServiceHost.STSService.StartProxyPolicyStoreService(ServiceHostManager serviceHostManager)
   at Microsoft.IdentityServer.ServiceHost.STSService.OnStartInternal(Boolean requestAdditionalTime)

Okay, so I need to change the certificate. Looking up how to do that, there's many resources. Each one wants you to open the AD FS MMC snap-in. Which posts the error:

ADMIN0017: An exception occurred while connecting to the configuration service (...) 
or the AD FS Windows Service is not running.

In other words, ADFS does something what I can only describe as incredibly dumb. That is

  • Allowing the user to configure it in a way that it won't start.
  • Not allowing the user to change the configuration if it's not running.

There's a powershell command that does the same thing;

Set-AdfsCertificate -CertificateType Service-Communications -Thumbprint <paste hex thumb>

Leading to the exact same sillyness:

Set-AdfsCertificate : Could not connect to net.tcp://localhost:1500/policy

The same goes for other adfs powershell commands.

But: Worst of all, the configuration is obtuse and arcane. Only one particular way of setting up the certs seems to work, and I'm lost in a sea of key extensions, extended key extensions, alternative names, key methods, computer permissions, user permissions, service account permissions, private key pfx details, pfx versions, crypto-service provider versions, and more. Microsoft documentation is out of date, 404'd, and/or incomplete.

So I need to replace this certificate a few dozen times through trial and error until something sticks. What is an easy way to change the certificate that ADFS uses that

  1. Does not involve using the AD FS MMC console. This will only work if the service can start, which it cannot.
  2. Does not involve ADFS powershell commands, which unfortunately also require the service to be running.

Edit: Even re-installing ADFS does not resolve the problem. Even if a different config database is selected. I'm still stuck at error 102. It appears the certificate settings are not actually stored in the database.

Looking a little further, by enabling auditing on the C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys folder, I noticed this error (private details obfuscated):

Subject:
    Security ID:        MYDOMAIN\adfsroot$
    Account Name:       adfsroot$
    Account Domain:     MYDOMAIN
    Logon ID:       0xFFFFFFF

Cryptographic Parameters:
    Provider Name:  Microsoft Software Key Storage Provider
    Algorithm Name: RSA
    Key Name:   {UUID-HERE}
    Key Type:   Machine key.

Cryptographic Operation:
    Operation:  Create Key.
    Return Code:    0x80090010

This points to a permission issue; the program could not create a RSA key as part of its startup. It's trying to access a machine key file, named as follows. Assume the key UUID and machine UUID are

12345678-90AB-CDEF-1234-567890ABCDEF
11223344-5566-7788-9900-AABBCCDDEEFF

The files seem to be named as:

1234567890ABCDEF1234567890ABCDEF_11223344-5566-7788-9900-AABBCCDDEEFF.sys

Containing a plaintext binary representation of the private key, guarded by NTFS permissions. ADFS generates four such files, and its user has permission to do so;

However, when I inspect one of the four private key files created, while it has the correct owner of MYDOMAIN\adfsroot$, it does not have correct permissions: effective permissions for adfsroot$ are no access at all. (Leading to the 102 error above). Apparently ADFS is throwing the proverbial key away after locking the door, or the file system is doing this in some way due to it misconfiguring the MachineKeys folder.

How do I get this badly written software to run?

Massimo avatar
ng flag
"Worst of all, the configuration is obtuse and arcane. Only one particular way of setting up the certs seems to work, and I'm lost in a sea of [...]". This is definitely not the way ADFS normally works, which is usually quite straightforward. Something really unusual must be going on in your system.
Massimo avatar
ng flag
Also, which Windows version are you running (2016, 2019, 2022)? This is quite important, because the ADFS version is directly related to the OS release.
Massimo avatar
ng flag
Also (2): the NTFS file system is not the proper place to grant access rights on a certificate. You should use the local computer certificates MMC.
Score:0
mx flag

Check that MachineKeys has correct permissions.

To fix the problem: I've granted the adfsroot user these advanced NTFS permissions, on the root MachineKeys folder:

List Folder 
Read attributes
Read extended attributes
Create files
Create folders
Write attributes
Write extended attributes
Read permissions

Make sure the Applies to value is This folder, subfolders and files (to enable inheritance). Using cacls or icacls, the notation would be:

MYDOMAIN\adfsroot$:(OI)(CI)(R,W)

For some reason, ADFS misbehaves here, and the default value as provided by the documentation does not work.

Massimo avatar
ng flag
The NTFS file system is not the proper place to grant access rights on a certificate. You should use the local computer certificates MMC.
Score:-1
kr flag

You are unable to start ADFS due to an expired TS cert.

Open PowerShell as an administrator: Input the following: while ($true){ Set-Date -Date "01/01/2023 12:45";Start-Service adfssrv }

This should get your ADFS service to start up again by temporarily backdating the system time to when you TS certificate hasn't expired.

Go ahead and reset the clock back to the original time, if it didn't do it automatically. Then while the ADFS service is still operational, proceed to renew your TS certificate.

Massimo avatar
ng flag
"You are unable to start ADFS due to an expired TS cert." No, this is not the case.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.