Export (0) Print
Expand All

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
 
Show:
© 2014 Microsoft