4.1.10.6.17 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 have to be decrypted by the client before processing object updates. The client decrypts the encrypted data by using MD5 digest (as specified in [RFC1321]), a CRC32 checksum (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