3.1.4.1.4 BACKUPKEY_RESTORE_GUID

The server MUST proceed as follows:

  1. Check whether the first four bytes of the wrapped secret (supplied in the pDataIn parameter) constitute an acceptable value of the dwVersion field, as specified in section 2.2.2. If so, go to step 2. If not, the server SHOULD check if the first four bytes of the wrapped secret match the fixed values specified in section 2.2.4 and, if so, it SHOULD<11> proceed as specified in section 3.1.4.1.2.1. Otherwise, the server MUST return a non-zero error code. The error code returned SHOULD be equal to ERROR_INVALID_PARAMETER (0x57). The server MUST<12> support at least one of the dwVersion values specified in section 2.2.2.

  2. Interpret the wrapped secret (supplied in the pDataIn parameter) as a Client-Side-Wrapped Secret (section 2.2.2), extract the value in the guidKey field. Let keyGuid denote this value, and let keyGuidString denote the GUIDString ([MS-DTYP] section 2.3.4.3) representation of keyGuid. Retrieve the value of the LSA (Domain Policy) Remote Protocol secret object named G$BCKUPKEY_keyGuidString, using the method specified in [MS-LSAD] section 3.1.4.6.6. This is the ClientWrap key pair that was used to wrap this secret. If this LSA (Domain Policy) Remote Protocol secret object is not found, or if its value is not in the format specified in section 2.2.5, stop processing and return a non-zero error code to the client. The error code SHOULD<13> be equal to ERROR_FILE_NOT_FOUND (0x2). Otherwise, use the Modulus and Private_Exponent fields of the ClientWrap key pair to construct an RSA private key, as specified in [RFC8017]. Let PrivKey denote this private key.

  3. Interpret the wrapped secret (supplied in the pDataIn parameter) as a Client-Side-Wrapped Secret (section 2.2.2), extract the value in the EncryptedSecret field. Reverse the order of bytes in this value and decrypt the result with PrivKey (computed in step 2) using the RSA algorithm with PKCS1 v1.5 padding (as specified in [RFC8017]). Let EncSecret denote the result of this decryption. If decryption fails, the server MUST return a non-zero error code. The error code returned SHOULD be equal to ERROR_INVALID_DATA (0xD).

  4. Using EncSecret and the value of dwVersion obtained in step 1, proceed as follows:

    1. If dwVersion is equal to 0x00000002, verify that EncSecret is formatted as specified in section 2.2.2.1. If so, let SecretValue denote the value of the Secret field and EncKey denote the value of the PayloadKey field. If not, the server MUST return an appropriate nonzero error code. The error code returned SHOULD be equal to ERROR_INVALID_DATA (0xD).

    2. If dwVersion is equal to 0x00000003, verify that EncSecret is formatted as specified in section 2.2.2.2. If so, let SecretValue denote the value of the Secret field and EncKey denote the value of the PayloadKey field. If not, the server MUST return an appropriate nonzero error code. The error code returned SHOULD be equal to ERROR_INVALID_DATA (0xD).

  5. Interpret the wrapped secret (supplied in the pDataIn parameter) as a Client-Side-Wrapped Secret (section 2.2.2), extract the value in the AccessCheck field. Using this value and the value of dwVersion obtained in step 1, proceed as follows:

    1. If dwVersion is equal to 0x00000002, decrypt the AccessCheck value using the 3DES algorithm (as specified in [SP800-67] section 3) with the first 24 bytes of EncKey as the key and the last 8 bytes of EncKey as the initialization vector (IV), and proceed to step 6.

    2. If dwVersion is equal to 0x00000003, decrypt the AccessCheck value using the AES algorithm (as specified in [FIPS197]) with the first 32 bytes of EncKey as the key and the last 16 bytes of EncKey as the initialization vector (IV), and proceed to step 7.

  6. Process the result of the first procedure in step 5, as follows:

    1. Verify that the result of the first procedure in step 5 is in the format specified in section 2.2.2.3. If not, the server MUST return an appropriate error code. The error code returned SHOULD be equal to ERROR_INVALID_DATA (0xD).

    2. Compute the SHA-1 hash [FIPS180-2] of the part of the structure preceding the Hash field, and compare the result against the value in the Hash field. If the values do not match, the server MUST return an appropriate nonzero error code. The error code returned SHOULD be equal to ERROR_INVALID_DATA (0xD).

    3. Extract the value in the SID field. Let this be called SecretSID. Proceed to step 8.

  7. Process the result of the second procedure in step 5, as follows:

    1. Verify that the result of the second procedure in step 5 is in the format specified in section 2.2.2.4. If not, the server MUST return an appropriate error code. The error code returned SHOULD be equal to ERROR_INVALID_DATA (0xD).

    2. Compute the SHA-512 hash [FIPS180-2] of the part of the structure preceding the Hash field, and compare the result against the value in the Hash field. If the values do not match, the server MUST return an appropriate nonzero error code. The error code returned SHOULD be equal to ERROR_INVALID_DATA (0xD).

    3. Extract the value in the SID field. Let this be called SecretSID. Proceed to step 8.

  8. Verify that the caller has access to this secret by comparing the SecretSID against the identity of the caller retrieved from the authenticated RPC connection. If this check fails, the server MUST return an appropriate error code. The error code returned SHOULD be equal to ERROR_INVALID_ACCESS (0xC).

  9. Using the ppDataOut and pcbDataOut parameters successfully, return the SecretValue (computed in step 4) to the caller in the format specified by section 2.2.3.