3.1.5.8.3 Security

If UserMessage.UserHeader.QueueManagerAddress is equal to QueueManager.Identifier and a SecurityHeader is present in the UserMessage Packet ([MS-MQMQ] section 2.2.20), the following logic MUST be applied to the message:

If the UserMessage.SecurityHeader.SecurityData.Signature field is set or the UserMessage.MultiQueueFormatHeader.Signature field is set, the protocol MUST perform the following steps to authenticate the packet:

  • If the UserMessage.SecurityHeader.SecurityData.Signature field is set:

    • Let RecreatedSignature equal the value obtained by computing the hash of the fields specified in [MS-MQMQ] section 2.5.2 for an MSMQ 2.0 digital signature, using the hash algorithm specified by the UserMessage.MessagePropertiesHeader.HashAlgorithm field.

    • Let OriginalSignature equal the value obtained by using Rivest-Shamir-Adleman (RSA) [RFC8017] and the public key contained in the UserMessage.SecurityHeader.SecurityData.SenderCert certificate to decrypt the value of the UserMessage.SecurityHeader.SecurityData.Signature field.

    • If RecreatedSignature and OriginalSignature match, set the UserMessage.SecurityHeader.Flags.AS field to 0x3.

    • If the two signatures do not match:

      • Set RecreatedSignature equal to the value obtained by computing the hash of the fields specified in [MS-MQMQ] section 2.5.1 for an MSMQ 1.0 digital signature, using the hash algorithm specified by the UserMessage.MessagePropertiesHeader.HashAlgorithm field.

      • If RecreatedSignature and OriginalSignature match, set the UserMessage.SecurityHeader.Flags.AS field to 0x1.

  • Else if the UserMessage.MultiQueueFormatHeader.Signature field is set:

    • Let RecreatedSignature equal the value obtained by computing the hash of the fields specified in [MS-MQMQ] section 2.5.3 for an MSMQ 3.0 digital signature, using the hash algorithm specified by the UserMessage.MessagePropertiesHeader.HashAlgorithm field.

    • Let OriginalSignature equal the value obtained by using Rivest-Shamir-Adleman (RSA) [RFC8017] and the public key contained in the UserMessage.SecurityHeader.SecurityData.SenderCert certificate to decrypt the value of the UserMessage.MultiQueueFormatHeader.Signature field.

    • If RecreatedSignature and OriginalSignature match, set the UserMessage.SecurityHeader.Flags.AS field to 0x5.

  • If RecreatedSignature and OriginalSignature do not match, the protocol MUST reject the message using the following logic:

  • If the UserMessage.SecurityHeader.Flags.ST field is nonzero, the protocol MUST perform the following steps to verify the identity of the sender:

    • The protocol MUST search the UserCertCache ADM element for a CachedUserCert (section 3.1.1.3.4) ADM element instance where CachedUserCert.UserCert.Certificate is bytewise identical to the certificate in the UserMessage.SecurityHeader.SecurityData.SenderCert field and CachedUserCert.SecurityID is equal to the UserMessage.SecurityHeader.SecurityData.SecurityID field.

    • If no such instance is found, the protocol MUST raise a Read Directory ([MS-MQDMPR] section 3.1.7.1.20) event with the following arguments:

      • iDirectoryObjectType: "User"

      • iFilter: "SecurityIdentifier" EQUALS UserMessage.SecurityHeader.SecurityData.SecurityID

    • If the query returns an rStatus value equal to DirectoryOperationResult.Success, the protocol MUST compare each of the certificates in rDirectoryObject.Certificates with the UserMessage.SecurityHeader.SecurityData.SenderCert field.

    • If a matching certificate is found in rDirectoryObject.Certificates, the protocol MUST perform the following steps:

      • Create a new CachedUserCert ADM element instance and initialize it as follows:

        • UserCert: A copy of the matching MQUSERSIGNCERT ([MS-MQMQ] section 2.2.22) from rDirectoryObject.Certificates.

        • SecurityID: The value of the UserMessage.SecurityHeader.SecurityData.SecurityID field.

        • CachedTime: The current system time. This value is the number of seconds elapsed since midnight (00:00:00), January 1, 1970 (UTC) according to the system clock.

      • Add the newly created CachedUserCert ADM element instance to the UserCertCache ADM element. If doing so would cause the number of entries in the list to exceed the value of the UserCertCacheSize ADM element, the protocol MUST create space in the list by sorting the entries by the CachedTime ADM attribute of each CachedUserCert ADM element instance and discarding the oldest (UserCertCacheSize / 2) entries.

      • Start the UserCertCache Cleanup Timer (section 3.1.2.13) with a duration of UserCertLifetime milliseconds if it is not already running.

    • If no matching certificate is found, or if the query returns an rStatus value not equal to DirectoryOperationResult.Success, the protocol MUST reject the message using the following logic:

      • If the UserMessage.MessagePropertiesHeader.Flags.NA bit field is set, the protocol MUST send a negative administration acknowledgment by raising a Send Administration Acknowledgment event with the following arguments:

        • iReceivedUserMessagePacket: UserMessage

        • iMessageClass: MQMSG_CLASS_NACK_BAD_SIGNATURE

      • If the rejected message contains a TransactionHeader ([MS-MQMQ] section 2.2.20.5), the protocol MUST send a negative FinalAck Packet by raising a Send Transactional Acknowledgment event with the following arguments:

        • iMessageClass: MQMSG_CLASS_NACK_BAD_SIGNATURE

        • iUserMessagePacket: UserMessage

      • The protocol MUST disregard the message and perform no further processing.

If the UserMessage.SecurityHeader.Flags.EB bit field is set, the protocol MUST perform the following steps to decrypt the message body:

  • Let SelectedCSP be a 16-bit NULL-terminated Unicode string that is initialized to a cryptography service provider (CSP) name based on the value of the UserMessage.MessagePropertiesHeader.PrivacyLevel field according to the following table. If the value of the UserMessage.MessagePropertiesHeader.PrivacyLevel field does not appear in the table, the protocol MUST reject the message using the following logic:

    • If the UserMessage.MessagePropertiesHeader.Flags.NA bit field is set, the protocol MUST send a negative administration acknowledgment by raising a Send Administration Acknowledgment event with the following arguments:

      • iReceivedUserMessagePacket: UserMessage

      • iMessageClass: MQMSG_CLASS_NACK_BAD_ENCRYPTION ([MS-MQMQ] section 2.2.18.1.6)

    • If the rejected message contains a TransactionHeader ([MS-MQMQ] section 2.2.20.5), the protocol MUST send a negative FinalAck Packet by raising a Send Transactional Acknowledgment event with the following arguments:

      • iMessageClass: MQMSG_CLASS_NACK_BAD_ENCRYPTION

      • iUserMessagePacket: UserMessage

    • The protocol MUST disregard the message and perform no further processing.

      PrivacyLevel Value

      SelectedCSP Value

      0x00000001

      "Microsoft Base Cryptographic Provider v1.0"

      0x00000003

      "Microsoft Enhanced Cryptographic Provider v1.0"

      0x00000005

      "Microsoft Enhanced RSA and AES Cryptographic Provider"<58>

  • The protocol SHOULD<59> search the ReceiveSymmetricKeyCache ADM element for a CachedSymmetricKey (section 3.1.1.3.3) ADM element instance where CachedSymmetricKey.CryptoServiceProvider is the same as SelectedCSP, CachedSymmetricKey.CryptoAlgorithm is the same as the UserMessage.MessagePropertiesHeader.EncryptionAlgorithm field, CachedSymmetricKey.RemoteQMGuid is the same as the UserMessage.UserHeader.SourceQueueManager field, and CachedSymmetricKey.EncryptedSymmetricKey is the same as the UserMessage.SecurityHeader.SecurityData.EncryptionKey field. If found, let UseCachedKey be a reference to the matching CachedSymmetricKey ADM element instance. If one is not found, the protocol MUST perform the following steps:

    • Create a new CachedSymmetricKey ADM element instance and initialize it as follows:

      • The RemoteQMGuid ADM attribute set to the value of the UserMessage.UserHeader.SourceQueueManager field.

      • The CryptoServiceProvider ADM attribute set to the value of SelectedCSP.

      • The CryptoAlgorithm ADM attribute set to the value of the UserMessage.MessagePropertiesHeader.EncryptionAlgorithm field.

      • The EncryptedSymmetricKey ADM attribute set to the value of the UserMessage.SecurityHeader.EncryptionKey field. It MUST be a SIMPLEBLOB (section 2.4.2) generated as described in section 3.1.7.1.5.

      • The SymmetricKey ADM attribute set to the result of decrypting the encryptedKey field of the SIMPLEBLOB in the UserMessage.SecurityHeader.EncryptionKey field according to the RSA key exchange algorithm ([RFC8017]). The private key used for the decryption is selected from implementation-dependent local storage according to the value of SelectedCSP.

      • The CachedTime ADM attribute set to the current date and time.

    • The newly created CachedSymmetricKey ADM element instance SHOULD<60> be added to the ReceiveSymmetricKeyCache ADM element. If doing so would cause the number of entries in the list to exceed the value of the ReceiveSymmetricKeyCacheSize ADM element, the protocol MUST create space in the list by sorting the entries by the CachedTime ADM attribute and by discarding the (ReceiveSymmetricKeyCacheSize / 2) entries that are oldest.

    • The protocol SHOULD<61> start the ReceiveSymmetricKeyCache Cleanup Timer (section 3.1.2.10) with a duration of SymmetricKeyShortLifetime milliseconds if it is not already running.

    • UseCachedKey MUST be set to refer to the newly created CachedSymmetricKey ADM element instance.

  • If SelectedCSP is "Microsoft Enhanced Cryptographic Provider v1.0" and the UserMessage.MessagePropertiesHeader.EncryptionAlgorithm field is 0x00006602 (RC2) and the RejectEnhancedRC2Using40BitKeys ADM element is TRUE and the final 88 bits of UseCachedKey.SymmetricKey are 0, the message MUST be rejected by performing the following steps:

    • If the UserMessage.MessagePropertiesHeader.Flags.NA bit field is set, the protocol MUST send a negative administration acknowledgment by raising a Send Administration Acknowledgment event with the following arguments:

      • iReceivedUserMessagePacket: UserMessage

      • iMessageClass: MQMSG_CLASS_NACK_BAD_ENCRYPTION

    • If the rejected message contains a TransactionHeader, the protocol MUST send a negative FinalAck Packet by raising a Send Transactional Acknowledgment event with the following arguments:

      • iMessageClass: MQMSG_CLASS_NACK_BAD_ENCRYPTION

      • iUserMessagePacket: UserMessage

    • The protocol MUST disregard the message and perform no further processing.

  • Decrypt the UserMessage.MessagePropertiesHeader.MessageBody field according to the method specified in the normative reference for the algorithm indicated by the UserMessage.MessagePropertiesHeader.EncryptionAlgorithm field (see the table in section 3.1.7.1.5) and using the key in UseCachedKey.SymmetricKey. For AES encryption, the AES algorithm specified in [FIPS197] is employed in Cipher Block Chaining (CBC) mode [SP800-38A] with a zero Initial Value (IV). If the decryption fails, the message MUST be rejected by performing the following steps:

    • If the UserMessage.MessagePropertiesHeader.Flags.NA bit field is set, the protocol MUST send a negative administration acknowledgment by raising a Send Administration Acknowledgment event with the following arguments:

      • iReceivedUserMessagePacket: UserMessage

      • iMessageClass: MQMSG_CLASS_NACK_BAD_ENCRYPTION

    • If the rejected message contains a TransactionHeader, the protocol MUST send a negative FinalAck Packet by raising a Send Transactional Acknowledgment event with the following arguments:

      • iMessageClass: MQMSG_CLASS_NACK_BAD_ENCRYPTION

      • iUserMessagePacket: UserMessage

    • The protocol MUST disregard the message and perform no further processing.

The protocol MUST perform an access check to authorize the Security Identifier (SID) specified in the UserMessage.SecurityHeader.SecurityData.SecurityID field against the queue specified by the UserMessage.UserHeader.DestinationQueue field, using the following logic:

  • The protocol MUST declare the destinationQueue variable and set it equal to the Queue ([MS-MQDMPR] section 3.1.1.2) ADM element instance specified by the UserMessage.UserHeader.DestinationQueue field.

  • The protocol MUST declare the queueSecurityDescriptor variable and set it equal to destinationQueue.Security.

  • If destinationQueue.QueueType = Public, the destinationQueue security descriptor MUST be queried from the directory by raising a Read Directory event with the following arguments:

    • iDirectoryObjectType: "Queue"

    • iFilter: "Identifier" EQUALS destinationQueue.Identifier

  • If the query returns an rStatus value equal to DirectoryOperationResult.Success, the protocol MUST set queueSecurityDescriptor equal to rDirectoryObject.Security.

  • The protocol MUST declare the userSID variable and set it according to the following logic:

    • If UserMessage.SecurityHeader.Flags.ST is set to 0x2, indicating that UserMessage.SecurityHeader.SecurityID contains the queue manager GUID, userSID MUST be set to the well-known SID with string representation S-1-1-0 (relative identifier SECURITY_WORLD_RID combined with identifier authority SECURITY_WORLD_SID_AUTHORITY).

    • Otherwise, userSID MUST be set to the UserMessage.SecurityHeader.SecurityID ([MS-MQMQ] section 2.2.20.6) field.

  • The protocol MUST perform an access check by invoking the Access Check Algorithm ([MS-DTYP] section 2.5.3.2) with the following parameters:

    • SecurityDescriptor: queueSecurityDescriptor

    • Token: Perform the following actions to generate a token to represent the sender's authorization data. If any failure occurs in these actions, the protocol MUST continue as if access_denied is returned from the Access Check Algorithm.

      • Construct an RPC binding to the Local Security Authority (Translation Methods) Remote Protocol server on the local machine ([MS-LSAT] section 2.1).

      • Invoke the LsarOpenPolicy (Opnum 6) method ([MS-LSAT] section 3.1.4.2) to obtain a policy handle with the DesiredAccess parameter set to POLICY_LOOKUP_NAMES.

      • Invoke the LsarLookupSids (Opnum 15) method ([MS-LSAT] section 3.1.4.11) to obtain the account name of the message sender with the following parameters:

        • PolicyHandle: the policy handle obtained in the preceding step.

        • SidEnumBuffer: contains one SID, which is userSID.

        • ReferencedDomains: a pointer to a PLSAPR_REFERENCED_DOMAIN_LIST structure ([MS-LSAT] section 2.2.12).

        • TranslatedNames: a pointer to a PLSAPR_TRANSLATED_NAMES structure ([MS-LSAT] section 2.2.20). The sender's account name is placed in this parameter on successful return from LsarLookupSids.

        • LookupLevel: LsapLookupWksta

        • MappedCount: a pointer to an unsigned long integer.

      • Invoke the LsarClose (Opnum 0) method ([MS-LSAT] section 3.1.4.3) to close the policy handle.

      • Use the sender's account name to obtain its Privilege Attribute Certificate (PAC), [MS-PAC]) as specified in [MS-SFU] section 3.1.5.1.1.2.

      • Create a token and populate its Sids[] field with the SIDs of the user, the user's primary group and other groups contained in the PAC ([MS-PAC] section 2.5). The KERB_VALIDATION_INFO.LogonDomainId field is used to construct the SIDs from relative identifiers.

    • Access Request mask: MQSEC_WRITE_MESSAGE ([MS-MQMQ] section 2.2.25)

    • Object Tree: NULL

    • PrincipalSelfSubst SID: NULL

  • If the Access Check Algorithm does not return success, the protocol MUST reject the message using the following logic:

    • If the UserMessage.MessagePropertiesHeader.Flags.NA bit field is set, the protocol MUST send a negative administration acknowledgment by raising a Send Administration Acknowledgment event with the following arguments:

      • iReceivedUserMessagePacket: UserMessage

      • iMessageClass: MQMSG_CLASS_NACK_ACCESS_DENIED ([MS-MQMQ] section 2.2.18.1.6)

    • If the rejected message contains a TransactionHeader, the protocol MUST send a negative FinalAck Packet by raising a Send Transactional Acknowledgment event with the following arguments:

      • iMessageClass: MQMSG_CLASS_NACK_ACCESS_DENIED

      • iUserMessagePacket: UserMessage

    • The protocol MUST disregard the message and perform no further processing.