PKISolutions / ADCS-CertMod

Represents a base ADCS Exit and Policy module developement framework.
MIT License
2 stars 1 forks source link

Handling exceptions from policy module #3

Closed phonexicum closed 2 months ago

phonexicum commented 3 months ago

Turns out handling of errors during certificate request processing is performed via COMExceptions.

  1. If the VerifyRequest will throw COMException (instead of returning PolicyModuleAction.Deny), the ADCS will:

    • store COMException::ErrorCode into certificate request Request Status Code property.
      • The CA will completely ignore the actual message in COMException, and instead store into Request Disposition Message the fixed message: Denied by Policy Module

    Personally, I prefered the mechanics of throwing COMException with some status code more informative for the end-user (e.g. ADCS windows administrator), instead of just silently returning Deny with status code 0 (interpreted as success). For example it could be something like this:

    throw new COMException("Some text.", unchecked((int)0x80070057)); // E_INVALIDARG
  2. Microsoft's native policy module (CertificateAuthority_MicrosoftDefault.Policy) may also send COMException.

    • Meaning for a developer: the proper exception handling must be performed;
  3. Microsoft's native module exceptions is not always "understandable". Here is an example of exception, thrown by native module:

    System.Runtime.InteropServices.COMException (0x80094012): CCertServerPolicy::GetRequestAttribute(CertificateTemplate): The requested property value is empty. 0x80094004 (-2146877436 CERTSRV_E_PROPERTY_EMPTY)

    The actual message in exception is weird, and misleading. But if we check the error code 0x80094012, which translates into:

    0x80094012 (-2146877422 CERTSRV_E_TEMPLATE_DENIED) -- 2148089874 (-2146877422)
    Error message text: The permissions on the certificate template do not allow the current user to enroll for this type of certificate.

    Now the situation become perfectly clear, indeed test user didn't obtain enroll privileges for a specified template.


This issue is infromative in the first place, because I didn't found any information about exception handling neither in microsoft's documentation (1, 2) or ADCS-CertMod docs.

Feel free to close the issue, but maybe you will find it appropriate to append some information about COMException handling in your documentation.

Crypt32 commented 3 months ago

Exception handling is beyond the scope of this framework. If you look in sources: https://github.com/PKISolutions/ADCS-CertMod/blob/f735ac1ba4185cffb7ef63bad34ccea26f2ab533/ADCS.CertMod.Managed/Policy/CertPolicyBase.cs#L51-L54 I'm only calling native (one level below) policy module. This method is virtual, which means that when you override this method, you are taking all the responsibility to handle all exceptions from native policy module and your own policy module.

Sample implementation can be found here: https://github.com/PKISolutions/ADCS-SID-Extension-Policy-Module/blob/4109679b24c9431b10e63a077df273371909b5ba/src/ADCS.SidExtension.PolicyModule/Policy.cs#L29 The idea is that in your override, you call base method (get estimated status returned by native policy module), then handle results and override if necessary. It is advised to not override behavior when native policy module returns Deny, because it will fail anyways eventually by CA engine.