4.1.10.6.16 DecryptValuesIfNecessary
procedure DecryptValuesIfNecessary( hDrs: DRS_HANDLE, prefixTable: PrefixTable, var attrBlock: ATTRBLOCK): DWORD
Informative summary of behavior: The values of several attributes are encrypted by the server and conversely must be decrypted by the client before processing objectupdates. The client decrypts the encrypted data by using MD5 digest (as specified in [RFC1321]), a CRC32checksum (as specified in [ISO/IEC 13239]), and RC4 stream cipher (as specified in [RC4]). The DecryptValuesIfNecessary procedure specifies the process of attribute value decryption.
Following are the input parameters for this method.
-
hDrs: The DRS_HANDLE derived by sending IDL_DRSBind to the server.
-
prefixTable: The prefix table used to translate attribute IDs.
-
attrBlock: The ATTRBLOCK structure that is derived from the response of the IDL_DRSGetNCChanges message. If attrBlock has attribute values that need to be decrypted, then the values are decrypted in place. That is, at the end of the procedure call, the pVal field in the ATTRVAL structure refers to the decrypted attribute value.
The procedure returns a Windows error code on failure. Otherwise, it returns 0.
localAttid: ATTRTYP attr: ATTR pPayload: ADDRESS OF ENCRYPTED_PAYLOAD salt: sequence of BYTE sessionKey: sequence of BYTE i: integer j: integer crcComputed: ULONG crcReceived: ULONG md5Context: MD5_CTX
/* Get session key associated with the RPC connection. */ sessionKey := session key associated with security context of hDrs, as specified by [MS-RPCE] section 3.3.1.5.2, "Building and Using a Security Context", and [MS-KILE] section 3.1.1.2, "Cryptographic Material"
for j := 0 to (attrBlock.attrCount - 1)
attr := attrBlock.pAttr[j]
localAttid = LocalAttidFromRemoteAttid(prefixTable, attr.attrTyp)
if IsSecretAttribute(localAttid) then
/* Decrypt all values of this attribute. */
for i := 0 to (attr.AttrVal.valCount - 1)
pPayload := attr.AttrVal.pAVal[i].pVal
salt := pPayload^.Salt
/* Compute encryption key. */
MD5Init(md5Context)
MD5Update(md5context, sessionKey, sessionKey.length)
MD5Update(md5context, salt, 16)
MD5Final(md5Context)
Decrypt (attr.AttrVal.pAVal[i].valLen - 16) bytes starting at
the address of pPayload^.Checksum using the RC4 stream cipher
algorithm [RC4] with encryption key md5Context.digest. At the
end of this operation pPayload^.EncryptedData field contains
decrypted attribute value.
/* Calculate checksum of the clear value. */
crcComputed :=
CRC32 [ISO/IEC 13239] of the
(attr.AttrVal.pAVal[i].valLen - 20)
bytes starting at pPayload^.EncryptedData
crcReceived := pPayload^.Checksum
if (not crcComputed = crcReceived) then
/* Checksums don't match. Stop processing the reply message.
*/
return SEC_E_ALGORITHM_MISMATCH
endif
/* Modify ATTRVAL structure to have decrypted data. */
attr.AttrVal.pAVal[i].valLen :=
attr.AttrVal.pAVal[i].valLen - 20
attr.AttrVal.pAVal[i].pVal := ADR(pPayload^.EncryptedData)
endfor
endif
endfor
return 0