3.1.4.1.6 ICertAdminD::PublishCRL (Opnum 8)

The PublishCRL method sends a request to the CA server to publish a new CRL.

 HRESULT PublishCRL(
   [in, string, unique] wchar_t const* pwszAuthority,
   [in] FILETIME FileTime
 );

pwszAuthority: See the pwszAuthority definition in ICertAdminD::SetExtension (section 3.1.4.1.1).

FileTime: Contains a 64-bit value that represents the number of 100-nanosecond intervals since January 1, 1601, according to Coordinated Universal Time (UTC). This is used to calculate the nextUpdate value of the CRL as specified in [RFC3280] section 5 in UTC-Greenwich Mean Time.

The following processing rules apply:

Note Although [RFC3280] specifies that revocation is a requirement, this protocol differs from that requirement.

  1. When this method is invoked, the CA SHOULD create a new base and/or delta CRL for each CA Signing_Private_Key in the Signing_Cert Table, as specified in the following steps. The type of CRL to create (base, delta, or both) for each CA key is determined as follows:<22>

    The CA SHOULD create a new base CRL for each CA key.

    If the CA has enabled delta CRLs, as indicated by a nonzero Config_Delta_CRL_Validity_Period value, the CA MUST create a new delta CRL in addition to a new base CRL for each CA key.

    If delta CRLs are currently disabled (Config_Delta_CRL_Validity_Period is 0) and were enabled previously (Previous_Delta_CRL_Validity_Period is not equal to zero), the CA MUST create a new delta CRL in addition to a new base CRL for each CA key.

  2. The CA server MUST check the Request Table to determine which certificates to include in a CRL. If Request_Revocation_Date is not NULL and is in the past:

    • If the Request_Disposition is not "certificate revoked", do not include the certificate Serial_Number in the CRL.

      An implication of this rule is that, if a previously revoked certificate is both released from hold and expires between the publishing times of two successive regularly published CRLs, the serial number of the certificate does not appear in the latter CRL. This outcome does not comply with [RFC3280] section 3.3, which specifies: "An entry MUST NOT be removed from the CRL until it appears on one regularly scheduled CRL issued beyond the revoked certificate's validity period."

    • If the Request_Disposition is "certificate revoked":

      1. For a delta CRL, exclude certificates whose value for the Request_Revoked_When field is before the CRL_This_Update of the oldest unexpired base CRL.

      2. If the Publish_Expired_Cert_In_CRL column is set to 1, the certificate Serial_Number MUST be included in CRLs regardless of the certificate's NotAfter time.

      3. If the Publish_Expired_Cert_in_CRL column is not set to 1:

        • If the certificate's NotAfter time is before the CRL_This_Publish of the last CRL, do not include the certificate's Serial_Number in the CRL.

        • If the certificate's NotAfter time is after or equal to the CRL_This_Publish of the last CRL, include the certificate's Serial_Number in the CRL.

  3. At CRL creation time, the CA SHOULD create a new CRL table entry for each type of CRL (base, and if enabled, delta) for each CA key. For each CRL table entry it creates, the CA MUST use the following rules to populate the individual data elements:<23>

    • CRL_Number: The CA MUST set this value to the CRL_Number of the last CRL created plus one.

    • CRL_Name_Id: The CA MUST set this value to the number that uniquely identifies the CA key for which the CRL is being created.

    • CRL_Min_Base: (only for a delta CRL). If all of the following conditions are true:

      • A delta CRL is being published.

      • Delta CRLs are disabled (Config_Delta_CRL_Validity_Period is 0).

      • Delta CRLs were enabled previously (Previous_Delta_CRL_Validity_Period is not equal to zero).

      The CA MUST set this value to the CRL_Number of the most recent base CRL (identified by selecting the CRL_Number from the CRL database row with CRL_Min_Base = 0, CRL_Name_ID matching the current row, and the highest CRL_Number).

      If the three conditions listed above are not all true, the CA MUST set this value to the CRL_Number of the latest fully propagated base CRL, selected based on a CRL_Propagation_Complete value that is in the past and the most recent CRL_This_Update value. If there are no fully propagated CRLs available, use the oldest unexpired base CRL as the CRL_Min_Base.

    • CRL_Effective: (only for a delta CRL): If this element is present, the CA MUST set its value to the CRL_This_Update value of the CRL table row corresponding to the base CRL whose CRL_Number is equal to the current delta CRL's CRL_Min_Base value.

    • CRL_Count: The CA MUST set this value to the number of serial numbers that will be included on the CRL.

    • CRL_This_Publish: The CA MUST set this value to the current time.

    • CRL_This_Update: The CA MUST set this value to the current time minus Config_CA_Clock_Skew_Minutes.<24> The value of CRL_This_Update MUST NOT be less than the NotBefore date of the current CA signing certificate. If the calculated value of CRL_This_Update is less than the NotBefore date of the current CA signing certificate, the CA MUST replace the CRL_This_Update value with the NotBefore date of the current CA signing certificate.

    • CRL_Next_Publish: The CA MUST set this data element to the current time plus Config_Base_CRL_Validity_Period for a base CRL or plus Config_Delta_CRL_Validity_Period for a delta CRL.

    • CRL_Propagation_Complete: The CA MUST set this data element to the current time plus the overlap period.

      The Microsoft CA computes the overlap period based on Config_Base_CRL_Overlap_Period for a base CRL and Config_Delta_CRL_Overlap_Period for a delta CRL as follows:

      1. If the registry value for Config_Base_CRL_Overlap_Period is configured and valid (valid means the units are correct and the value is present), this value is used as is. Similarly, if a valid Config_Delta_CRL_Overlap_Period exists, it is used as is.<25>

      2. If either of these values is not present or not valid, the CA uses the following algorithms to determine a value:

        For a base CRL:

        1. Interim_Base_CRL_Overlap_Period = MinimumOf(0.1*(Registry_Base_CRL_Validity_Period), 12Hours)

        2. Interim_Base_CRL_Overlap_Period = GreaterOf(Interim_Base_CRL_Overlap_Period, 1.5*(Config_CA_Clock_Skew_Minutes))

        3. Interim_Base_CRL_Overlap_Period = MinimumOf(Interim_Base_CRL_Overlap_Period, Registry_Base_CRL_Validity_Period)

        4. Config_Base_CRL_Overlap_Period = Interim_Base_CRL_Overlap_Period + Config_CA_Clock_Skew_Minutes

        For a delta CRL:

        1. Interim_Delta_CRL_Overlap_Period = MinimumOf(Registry_Delta_CRL_Validity_Period, 12Hours)

        2. Interim_Delta_CRL_Overlap_Period = GreaterOf(Interim_Delta_CRL_Overlap_Period, 1.5*(Config_CA_Clock_Skew_Minutes))

        3. Interim_Delta_CRL_Overlap_Period = MinimumOf(Interim_Delta_CRL_Overlap_Period, Registry_Base_CRL_Validity_Period)

        4. Config_Delta_CRL_Overlap_Period = Interim_Delta_CRL_Overlap_Period + Config_CA_Clock_Skew_Minutes

    • If a file time is provided, which is indicated by a nonzero FileTime parameter value, the CA MUST use it in the following manner:

      • If the FileTime value is less than the current time, the CA MUST fail with an error code ERROR_INVALID_PARAMETER.

      • Otherwise, the CA MUST use the value that is provided in the FileTime parameter, add overlap period plus the clock skew to it, and set it as the CRL_Next_Update.

    • If a file time is not provided, the CA MUST set CRL_Next_Update to the current time plus Config_Base_CRL_Validity_Period for a base CRL or Config_Delta_CRL_Validity_Period for a delta CRL plus overlap period.

      The CA SHOULD add a clock skew.<26>

    • CRL_Publish_Flags: The CA MUST update this data element with a bitwise OR of all values from the list below that apply, based on their descriptions in section 3.1.1.4.1.

      • CPF_BASE: Set this value for a base CRL.

      • CPF_DELTA: Set this value for a delta CRL.

      • CPF_MANUAL: Set this value if the uToken.Sids[uToken.UserIndex] is not NULL. This means that the identity of the caller who initiated the generation of the CRL is available.

      • CPF_SHADOW: If a delta CRL is being published, delta CRLs are disabled (Config_Delta_CRL_Validity_Period is 0), and if they were enabled previously (Previous_Delta_CRL_Validity_Period is not equal to zero), the CA MUST set this value.

  4. For each type of CRL (base and/or delta) required, and for each CA key, the CA MUST create a CRL and sign it with the corresponding Signing_Private_Key. The CA MUST allocate data to the various CRL fields whose structure and syntax are defined in [RFC3280] section 5.1, to the CRL extensions whose structure and syntax are defined in [RFC3280] section 5.2, and to the CRL entry extensions whose structure and syntax are defined in [RFC3280] section 5.3:

    • The signatureAlgorithm value is based on the public key and hash algorithm of the CA key and is derived from and has the syntax as specified in [RFC3280] section 5.1.1.2.

    • As specified in [RFC3280] section 5.1.1.3, a digital signature that is computed by using the ASN.1 DER–encoded tbsCertList MUST be used as the signatureValue field. The tbsCertList value is composed of the fields specified in the following list.

      • "V2" MUST be used for the version field (within the TBSCertList field), and its syntax is as specified in [RFC3280] section 5.1.

      • The same value previously used for signatureAlgorithm MUST be used for the signature field (within the TBSCertList field).

      • The distinguished name (DN) of the CA MUST be used for the issuer field (within the TBSCertList field). This is the same value as the value that is contained in the Issuer field in the CA certificate associated with the signing key. The syntax is as specified in [RFC3280] section 5.1.2.3.

      • CRL_This_Update MUST be used for the thisUpdate field of the CRL, and its syntax is as specified in [RFC3280] section 5.1.2.4.

      • CRL_Next_Update MUST be used for the nextUpdate field of the CRL, and its syntax is as specified in [RFC3280] section 5.1.2.5.

      • For each certificate that is determined in the preceding rule 3 to be included in the CRL, an entry in the revokedCertificates list MUST be created using the following logic:

        • If Request_Revoked_Reason is release from hold (0xffffffff) and a base CRL is being constructed, the certificate MUST NOT be included as an entry in the revokedCertificates list.

        • If Request_Revoked_Reason is release from hold (0xffffffff) and a delta CRL is being constructed, 8 MUST be used for the reasonCode CRL entry extension.

        • Serial_Number MUST be used for the userCertificate field.

        • Request_Revocation_Date MUST be used as the revocationDate field.

        • If Request_Revoked_Reason is not 0, it MUST be used for the reasonCode CRL entry extension.

        • The fields and CRL entry extensions within revokedCertificates have the ASN syntax as defined in [RFC3280] section 5.1.

    • The subject key identifier field of the CA certificate for which the CRL is being generated MUST be used for the AuthorityKeyIdentifier (AKI) CRL extension. The syntax is as defined in [RFC3280] section 5.2.1 (which in turn points to section 4.2.1.1 of the same RFC).

    • The CRL_Number SHOULD be used for the CRL number extension, which has the syntax that is defined in [RFC3280] section 5.2.3.<27>

    • For a delta CRL only, CRL_Min_Base MUST be used for the delta CRL indicator extension, which has the syntax that is defined in [RFC3280] section 5.2.3.<28>

    • The issuing distribution point is a CRL extension that MUST be populated with all entries in the Config_CA_CDP_Include_In_CRL_IDP_Extension element that is defined in [MS-WCCE] section 3.2.1.1.4. This CRL extension has the syntax that is defined in [RFC3280] section 5.2.5.

    • The freshest CRL extension (also known as the delta CRL distribution point) MUST be populated with all entries in the Config_CA_CDP_Include_In_CRL_Freshest_CRL_Extension element, as defined in [MS-WCCE] section 3.2.1.1.4. This CRL extension has the syntax that is defined in [RFC3280] section 5.2.6.

  5. In addition to the preceding extensions, the following custom extensions MUST be added to the CRL.

    • CRL_Next_Publish MUST be used for the CRL Next Publish custom extension, which is defined as follows:

      The OID (1) of the CRL Next Publish extension is 1.3.6.1.4.1.311.21.4.

      The extension value is DER-encoded and is defined in ASN.1 [X509] as the following:

       CHOICE {
           utcTime    UTCTime,
           generalTime    GeneralizedTime
       }
      

      If the time is after 1950 and before 2050, it is UTC time encoded with a two-digit year. Otherwise, it is Generalized time that is encoded with a four-digit year. The date is precise to seconds.

    • The CA Version extension MUST be populated with the value "{Signing_Cert_Version_ID}{Signing_Private_Key_Version_ID}" where Signing_Cert_Version_ID and Signing_Private_Key_Version_ID are replaced with their values as defined in [MS-WCCE] section 3.2.1.1.2.

      The OID (1) of the CA Version extension is 1.3.6.1.4.1.311.21.1.

      This extension MUST NOT be marked critical.

      The extension value is DER-encoded and is defined in ASN.1 [X509] as INTEGER.

    • The Published CRL Locations extension (an Active Directory path) MUST be populated with all entries from the Config_CA_CDP_Include_In_CRL_Publish_Locations_Extension ADM element, as defined in [MS-WCCE] section 3.2.1.1.4.

      The OID (1) of the Published CRL Locations extension is 1.3.6.1.4.1.311.21.14.

      This extension MUST NOT be marked critical.

      The extension value is DER-encoded and is defined in ASN.1 [X509] with the same syntax as the CRL distribution points certificate extension, as defined in [RFC3280] section 4.2.1.14.

  6. After each CRL is created, the CA MUST save it to the CRL_Raw_CRL data element of the corresponding CRL table entry.

  7. For each CRL created, immediately prior to publishing, the CA MUST verify the signature in the signatureValue field of the CRL. The inputs to signature verification are as follows:

    • The signature value itself.

    • The original message that was signed (in this case the CRL tbsCertList as defined in [RFC3280] section 5.1.1.1).

    • The CA public key (from the Subject Public Key Information field of the Signing_Cert_Certificate corresponding to the Signing_Private_Key the CA used to sign the CRL).

    • The signature algorithm, as identified in the signatureAlgorithm field of the CRL.

    The detailed signature verification process depends on the algorithm. Algorithms for signing CRLs are described in [RFC3279] section 2.2. If the verification is not successful, the CA MUST skip to step 8 below and use 0x80090006 for the error code.

  8. The CA MUST then consult the Config_CA_CDP_Publish_To_Base and Config_CA_CDP_Publish_To_Delta ADM elements and attempt to publish base CRLs and delta CRLs to all of the locations identified in the respective elements, including the local registry location defined in section 3.1.1.8, noting the success or failure of each publish attempt. In the case of failure, the CA MUST note the error code generated by the CA or returned from the lower layer system for each publishing attempt. Steps 8 and 9 of this section are performed once for each CRL and location combination. When writing to the local registry location, the server uses methods consistent with the communications specified in the Windows Remote Registry Protocol (see [MS-RRP] section 4.2) to write a new registry value. The operations to write a new registry value are as follows:

    1. First, read all CRLs in the CRL_Local element to determine whether a CRL of the same type (base or delta) and signed by the Signing_Private_Key that signed the CRL being published exists already. If one is found, compare its content to that of the current CRL being published. If the content is identical, do nothing.  If not, delete the existing CRL from CRL_Local. When all CRLs signed by the CRL being published have been evaluated, if no exact match was found, add the current CRL to CRL_Local as follows:

      • Obtain a handle to the root key HKEY_LOCAL_MACHINE by using the OpenLocalMachine method [MS-RRP] section 3.1.5.3.

        Open the HKEY_LOCAL_MACHINE root key with the following input:

        samDesired: 0x6

      • Use the handle returned from OpenLocalMachine with the BaseRegOpenKey method ([MS-RRP] section 3.1.5.15) to open a subkey. The BaseRegOpenKey method returns a handle to the subkey.

        • Open the subkey with the following input:

          dwOptions: 0 (nonvolatile)

          samDesired: 0x6

      • Use the handle to the subkey returned from BaseRegOpenKey with the BaseRegCreateKey method ([MS-RRP] section 3.1.5.7) to create a new subkey.

        § Create the new subkey with the following input:

        lpSubKey: The SHA-1 hash of the DER encoded CRL, including tbsCertList and appended signature (the 20 bytes of binary data output from the hash algorithm are converted to a string of 40 hexadecimal ASCII digits).

        lpClass: NULL

        dwOptions: 0 (nonvolatile)

        samDesired: 0x6

      • Use the handle to a subkey returned from BaseRegCreateKey to write values under the subkey by using the BaseRegSetValue ([MS-RRP] section 3.1.5.22) method.

        § Create the new value with the following input:

        lpValueName: "Blob"

        dwType: 3 (binary)

        lpData: Points to a buffer containing the DER encoded CRL. The buffer is constructed as follows: The first 12 bytes contain the values represented in hexadecimal as 03 00 00 00 01 00 00 00 14 00 00 00, followed by the 20-byte SHA-1 hash value used above. The SHA-1 hash value is followed by 8 bytes that contain the value represented in hexadecimal as 21 00 00 00 01 00 00 00, then 4 bytes that contain the value of the length of the CRL, followed by the DER encoded CRL.

        cbData: The length, in bytes, of the data referenced by lpdata.

      • After all required keys and values have been created and written, the client closes the open handles by using the BaseRegCloseKey method [MS-RRP] section 3.1.5.6.

    If a nonzero return value is returned from any of the above methods, the CA continues to attempt to publish CRLs as follows, and the CPF_CASTORE_ERROR flag is set in step 9 below.

    For each combination of new CRL table entry (created in preceding rule 3) and CDP location, there will be a publishing attempt, in which the CA attempts to write the CRL file to the location specified. Specifically, the publishing attempts are done as follows: <29>

    • If, for a delta CRL and a location that begins with "file://", the CPF_FILE_ERROR flag value was set for the corresponding base CRL, do not attempt to publish the delta CRL to the file:// location. The CA MUST generate a nonzero error code instead. The CA SHOULD use the error code E_ABORT (0x80004004). The server will mark the CPF_POSTPONED_BASE_FILE_ERROR flag when it updates the corresponding CRL table entry below. The CA MUST then preserve this error code and skip to step 9.

    • If, for a delta CRL and a location that begins with "ldap:///", the CPF_LDAP_ERROR flag value was set for the corresponding base CRL, do not attempt to publish the delta CRL to the ldap:/// location. The CA MUST generate a nonzero error code instead. The CA SHOULD use the error code E_ABORT (0x80004004). The server will mark the CPF_POSTPONED_BASE_LDAP_ERROR flag when it updates the corresponding CRL table entry below. The CA MUST then preserve this error code and skip to step 9.

    • If any CRL Publishing Locations that have the invalid prefix "ftp:", "http:", or any locations with a prefix other than "file:" that consists of 2, 3, or 4 characters followed by a colon (":"), are encountered, the CA MUST generate a nonzero error code. The CA SHOULD use the error code ERROR_BAD_PATHNAME (0x800700a1). The CA MUST then preserve this error code and skip to step 9.

    • When writing to a local file path, UNC path, or file:// location, a file system is invoked to write the CRL as a DER-encoded binary file to the path and file name specified. When the CRL publishing location starts with the prefix "file://", but the remaining portion of the location is not a path starting with "\\", the entire location is passed to the file system. When the location starts with the prefix "file://", and the remaining portion is a path starting with "\\", only the remaining portion is passed to the file system. When the location starts with "{DriveLetter}:" or with "\\", it is passed as is to the file system. A status or Win32 error code, when one was returned from the file system, is returned to the invoker (the CA). When a Win32 error code is returned from the file system, the server SHOULD convert this error code to a 4-byte HRESULT value using the pattern 0x8007XXXX, where XXXX is the first two bytes of the Win32 hex value 0x0000XXXX. Then, the server SHOULD preserve this HRESULT value, and go to step 9 (where the CA will set the CPF_FILE_ERROR publishing flag). For more information on writing remote files, see [MS-FASOD].<30>

    • For any ldap:/// locations identified, within the object and attribute specified, the CRL is DER encoded. The steps the CA uses are as follows:

      1. If the value of the CRL_Publish_AD_Connection is not NULL, then a previous Active Directory connection exists. Go to step 4 and use that Active Directory connection for publishing the CRLs.

        Otherwise, invoke the task "Initialize an ADConnection", as defined in [MS-ADTS] section 7.6.1.1, with the following parameters:

        • TaskInputTargetName: NULL.

        • TaskInputPortNumber: If the value of Config_CA_LDAP_Flags is 0, use 389; if it is 1, use port 636.

        • Store the new TaskReturnADConnection returned from the task as CRL_Publish_AD_Connection.

      2. Invoke the task "Setting an LDAP Option on an ADConnection", as defined in [MS-ADTS] section 7.6.1.2, on the Active Directory connection CRL_Publish_AD_Connection. Invoke the task one time for each of the following options. For each of these, the TaskInputAdConnection parameter is CRL_Publish_AD_Connection.

        • TaskInputOptionName: LDAP_OPT_GETDSNAME_FLAGS

        • TaskInputOptionValue: Bit R as defined by [MS-NRPC] section 3.5.4.3.1

        • TaskInputOptionName: LDAP_OPT_SIGN

        • TaskInputOptionValue: TRUE

        • TaskInputOptionName: LDAP_OPT_DNSDOMAIN_NAME

        • TaskInputOptionValue: Set to the domain DNS name of the joined domain.

      3. After the Active Directory connection is initialized and the options are set, the CA invokes the "Performing an LDAP Bind on an ADConnection" task, as specified in [MS-ADTS] section 7.6.1.4, on the connection CRL_Publish_AD_Connection, with the following parameters:

        TaskInputADConnection: CRL_Publish_AD_Connection

        If the TaskReturnStatus returned is not 0, skip to the error processing logic in step 5 below. Otherwise, continue.

      4. The CA invokes the "Performing an LDAP Operation on an ADConnection" task, as specified in [MS-ADTS] section 7.6.1.6, with the following parameters:

        • TaskInputADConnection: CRL_Publish_AD_Connection

        • TaskInputRequestMessage: protocolOp is set to modifyRequest ([RFC2251] section 4.6)

        The parameters of the ModifyRequest are set as follows:

        • The object field contains the Config_CA_CDP_Publish_To_Base or Config_CA_CDP_Publish_To_Delta entry that specifies an LDAP location (without the "ldap:///" prefix)

        • The modification sequence has one list entry whose operation field has the value "replace" and whose modification field contains the following:

          • The type field contains either "certificateRevocationList", for a base CRL, or "deltaRevocationList" for a delta CRL.

          • The vals field contains the CRL. <31>

        TaskOutputResultMessages: A task output parameter that is a list of LDAPMessage, as specified in [MS-ADTS] section 7.6.1.6, that contains the response from the directory server.  The result of a modify request is a modify response, which, as specified in [RFC2251], is an LDAPResult, which contains a resultCode and an errorMessage.

        If the TaskReturnStatus returned is not 0, perform to the error processing logic in step 5 below. Otherwise, skip step 5 and continue with step 9 below.

      5. When invoking an LDAP higher layer triggered event, a status or error code, when one was returned from the lower layer system, is returned to the invoker (the CA).

        • If a nonzero TaskReturnStatus is returned from step 3 above (while attempting to bind to the ADConnection), the CA SHOULD close the Active Directory connection by invoking the "Performing an LDAP Unbind on an ADConnection" task defined in [MS-ADTS] section 7.6.1.5, convert the TaskReturnStatus (an LDAP resultCode) that was returned from step 3 to a 4-byte HRESULT value as specified in the Conversion of LDAP results at the end of this step. Then, preserve this HRESULT value, clear the CRL_Publish_AD_Connection element, and go to step 9 below.

        • If a nonzero TaskOutputResultMessages.resultCode value is returned from step 4 above (the LDAP modify operation), that indicates that the Active Directory server is down, unavailable, or that there is a timeout, the CA MUST close the Active Directory connection by invoking the "Performing an LDAP Unbind on an ADConnection" task defined in [MS-ADTS] section 7.6.1.5, clear the CRL_Publish_AD_Connection element, and re-attempt one time to execute steps 1-4 above. If a nonzero TaskReturnStatus is returned from step 3 or 4 upon this single retry, the CA MUST close the Active Directory connection by invoking the "Performing an LDAP Unbind on an ADConnection" task defined in [MS-ADTS] section 7.6.1.5, convert the returned TaskReturnStatus from step 3 (in the case of a failure upon  bind) or TaskOutputResultMessages.errorMessage from step 4 (in the case of a failure upon modify) to a 4-byte HRESULT value as specified in the Conversion of LDAP results at the end of this step, preserve this HRESULT value, clear the CRL_Publish_AD_Connection element, and go to step 9.<32>

        • If any other nonzero TaskOutputResultMessages.resultCode value is returned from step 4 above (the LDAP modify operation), the server MUST convert the returned TaskOutputResultMessages.errorMessage to a 4-byte HRESULT value, as specified in the Conversion of LDAP results at the end of this step, preserve this HRESULT value, and go to step 9.

      Conversion of LDAP results (TaskReturnStatus or TaskOutputResultMessages) to HRESULT is as follows:

      • If TaskOutputResultMessages.errorMessage is at least 8 bytes long:

        • If each of the first 8 bytes is between '0' and '9' inclusive, or between 'a' and 'f' inclusive, or between 'A' and 'F' inclusive, then use this value as the hexadecimal representation of a Win32 error, which will be the input to the following HRESULT conversion.

        • If each of the first 8 bytes is 0, use ERROR_DS_GENERIC_ERROR (defined in [MS-ERREF] section 2.2, "Win32 Error Codes") as the Win32 error that will be input to the following HRESULT conversion.

      • Otherwise, use TaskOutputResultMessages.resultCode. Convert it to a Win32 error using the conversion specified in [MS-ERREF] section 2.4, "LDAP Error to Win32 Error Mapping", and use this value as the Win32 error, which will be the input to the following HRESULT conversion.

      • If there is no TaskOutputResultMessages (as in the case of the Bind task), use TaskReturnStatus (which is an LDAP resultCode). Convert this value to a Win32 error using the conversion specified in [MS-ERREF] section 2.4, "LDAP Error to Win32 Error Mapping", and use this value as input to the following HRESULT conversion.

      • Convert the Win32 obtained above to an HRESULT using the pattern 0x8007XXXX, where XXXX is the first two bytes of the Win32 hex value 0x0000XXXX.

  9. After each attempt to publish a CRL (that is, each combination of CRL and publishing location), the CA SHOULD update the corresponding CRL table row. For each row updated, the CA MUST use the following rules to update the individual data elements:<33>

    • CRL_Publish_Error: If this element is present, populate CRL_Publish_Error with the user name associated with the caller identity, in the form "Published by {domain\UserName}", where:

      • Domain is replaced with the domain name of the domain in which the user account exists.

      • UserName is the user name associated with the caller identity.

      The domain and UserName are found as follows:

      1. Call LsarOpenPolicy [MS-LSAT] section 3.1.4.2 with the following inputs:

        • SystemName: NULL

        • DesiredAccess: contains the bit value 0x00000800 for POLICY_LOOKUP_NAMES

      2. Call LsarLookupSids [MS-LSAT] section 3.1.4.11 on the returned PolicyHandle.

        • PolicyHandle: the PolicyHandle returned from LsarOpenPolicy above.

        • SidEnumBuffer: contains the SID from the ADM element uToken.Sids[UserIndex].

          The return values from the LsarLookupSIDs are as follows:

          • ReferencedDomains list: the domain name is found in the Name field of the Domains structure of the list entry whose index matches the DomainIndex of the Names structure of the entry in the TranslatedNames list that corresponds to the SID in question.

          • TranslatedNames contains the UserName in the Name field of the Names structure of the entry in the list corresponding to the SID in question (from the SidEnumBuffer input list).

      The Microsoft CA uses "–" instead of "Published by" for publish attempts made in the CA machine context, such as automatically scheduled CRL publishing attempts.

      If step 8 resulted in an error code or nonzero HRESULT, the caller identity information SHOULD be followed by the CRL publishing location to which the CRL could not successfully be published. The Microsoft CA appends the username information with a space, two hyphens, a space, and an integer. The integer indicates the index (in the list of CRL publishing locations that is written to the same data element) of the location to which publishing failed. If more than one location fails for one CRL table entry, then the index of each failed location is appended to this line, separated by spaces. This is followed by two line feed characters, followed by the path of each CRL publishing location to which the CRL could not successfully be published, separated by newline characters.

    • CRL_Publish_Flags: The CA MUST update this data element with a bitwise OR of its existing value and all values from the list below that apply, based on their descriptions in section 3.1.1.4.1:

      • CPF_BADURL_ERROR: Set this value if a Uniform Resource Locator (URL) that does not meet the format requirements specified in section 3.1.1.8 for Config_CA_CDP_Publish_To_Base and Config_CA_CDP_Publish_To_Delta was encountered during publishing of the CRL.

      • CPF_FILE_ERROR: Set this value if a local file path, UNC path, or file:// URI that does not meet the format requirements specified in section 3.1.1.8 for Config_CA_CDP_Publish_To_Base and Config_CA_CDP_Publish_To_Delta for a file location, was encountered during publishing of the CRL, or if step 8 resulted in an error code or nonzero HRESULT as a result of the publishing attempt to a file location.

      • CPF_HTTP_ERROR: Set this value if an HTTP URI (a URI with the prefix "http:") was encountered during publishing of the CRL.

      • CPF_FTP_ERROR: Set this value if an FTP URI (a URI with the prefix "ftp:") was encountered during publishing of the CRL.

      • CPF_LDAP_ERROR: Set this value if step 8 resulted in an error code or nonzero HRESULT as a result of the publishing attempt to an LDAP location.

      • CPF_POSTPONED_BASE_LDAP_ERROR: Set this value if the server postponed publishing a delta CRL due to a failure in publishing a base CRL to an ldap:/// location (see rule 7 above), for example, when the corresponding base CRL could not be published to an LDAP location because of an error.

      • CPF_POSTPONED_BASE_FILE_ERROR: Set this value if the server postponed publishing a delta CRL due to a failure in publishing a base CRL to a file:// location (see rule 7 above), for example, when the corresponding base CRL could not be published to a FILE location because of an error.

      • CPF_SIGNATURE_ERROR: Set this value if an error occurred when verifying the signature of the generated CRL prior to attempting to publish the CRL.

      • CPF_CASTORE_ERROR: Set this value if an error occurred when publishing the generated CRL to the default local registry location.

  10. After publishing attempts have been made for all CRL publishing locations for a given CRL, the CA MUST use the following rules to update the following CRL table data elements in the corresponding CRL table row:

    • CRL_Publish_Status_Code:

      • If an error code or nonzero HRESULT value was generated by the CA or returned from a lower layer system upon any of the previous attempts to publish the CRL (steps 8 and 9 above), the CA MUST set this value to the value generated or returned. If more than one error was generated or returned, the CA SHOULD set this value to the error code that resulted from the first unsuccessful publishing attempt. Error codes are specified in [MS-ERREF].

      • Otherwise, the CA MUST set this value to 0.

    • CRL_Publish_Flags:

      • CPF_COMPLETE: The CA MUST set this value if the CRL published successfully to all locations (that is, the CRL_Publish_Status_Code was set to 0).

    • CRL_Last_Published (for a base CRL only): If this element is present, the CA MUST set its value to the current time.

    • CRL_Publish_Attempts: If this element is present, the CA MUST set its value to 1 to indicate the publish attempt for the newly created CRL.

  11. After all publishing attempts have completed (for all base and delta CRLs for all CA keys to all locations), the CA MUST update the Config_CA_CRL_Next_Publish, OnNextRestart_Config_CA_CRL_Next_Publish, Config_CA_CRL_Delta_Next_Publish, and OnNextRestart_Config_CA_CRL_Delta_Next_Publish data elements. The CA MUST update the Config_CA_CRL_Next_Publish and OnNextRestart_Config_CA_CRL_Next_Publish configuration data elements with the value that was calculated for CRL_Next_Publish for the base CRL(s) (the current time plus Config_Base_CRL_Validity_Period), and the CA MUST update the Config_CA_CRL_Delta_Next_Publish and OnNextRestart_Config_CA_CRL_Delta_Next_Publish configuration data elements with the value that was calculated for CRL_Next_Publish for any delta CRL(s)created above (the current time plus Config_Delta_CRL_Validity_Period for a delta CRL).

  12. If steps 8 or 9 above resulted in an error code or nonzero HRESULT value from any attempt to publish any of the CRLs, set the value of the ADM elements Config_CA_CRL_Attempt_Republish and OnNextRestart_Config_CA_CRL_Attempt_Republish to "1" and set the timer documented in section 3.1.2.2. If none of the attempts to publish the CRLs failed, reset the ADM elements Config_CA_CRL_Attempt_Republish and OnNextRestart_Config_CA_CRL_Attempt_Republish to "0".

  13. The CA MUST then set the value of Previous_Delta_CRL_Validity_Period to the current value of Config_Delta_CRL_Validity_Period.

Return value: The method returns the first error code returned from the first CRL write attempt that failed or that was aborted. If none of the CRL write attempts failed, the method returns 0.