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
Show: