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
- Does not involve using the AD FS MMC console. This will only work if the service can start, which it cannot.
- 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?