3.2.4.2.1 RegisterCertificate (Opnum 8)

The RegisterCertificate method MUST register an MQUSERSIGNCERT ([MS-MQMQ] section 2.2.22) in User.Certificates. Implementations of this protocol use certificates to verify the sender for messages that are requesting authentication and to ensure message integrity.

 HRESULT RegisterCertificate(
   [in, optional] VARIANT* Flags,
   [in, optional] VARIANT* ExternalCertificate
 );

Flags: A pointer to a VARIANT that contains a VT_I4 integer that corresponds to the MQCERT_REGISTER enumeration as defined in the following table.

Value

Meaning

MQCERT_REGISTER_ALWAYS

0x00000001

Register an MQUSERSIGNCERT ([MS-MQMQ] section 2.2.22) in User.Certificates.

If the ExternalCertificate input parameter is not specified or is NULL, the server MUST delete the certificate from the internal store and delete any existing MQUSERSIGNCERT ([MS-MQMQ] section 2.2.22) with a matching Digest property from User.Certificates.

The server MUST then add a newly created MQUSERSIGNCERT ([MS-MQMQ] section 2.2.22) to User.Certificates.

If the ExternalCertificate is not NULL, the server MUST add an MQUSERSIGNCERT ([MS-MQMQ] section 2.2.22), as specified by the ExternalCertificate input parameter, to User.Certificates.

MQCERT_REGISTER_IF_NOT_EXIST

0x00000002

Register an MQUSERSIGNCERT ([MS-MQMQ] section 2.2.22) in User.Certificates only if no certificate is registered in the internal store. This option cannot be used with ExternalCertificate.

If not specified by the client, the server MUST use the default value MQCERT_REGISTER_ALWAYS (0x00000001) instead of the unspecified value.

ExternalCertificate: A pointer to a VARIANT that contains a byte array (VT_ARRAY|VT_UI1) or a pointer (VT_BYREF) to a byte array that specifies the binary representation of the MQUSERSIGNCERT ([MS-MQMQ] section 2.2.22) that is to be registered. The MQUSERSIGNCERT MUST contain an X.509-encoded certificate, as specified in [RFC3280].

Return Values: The method MUST return S_OK (0x00000000) to indicate success or an implementation-specific error HRESULT on failure.<10>

When processing this call, the server MUST follow these guidelines:

  • If the ComputerName instance variable is not NULL:

    • Return E_NOTIMPL (0x80004001) and take no further action.

  • If the Flags input parameter is equal to MQCERT_REGISTER_IF_NOT_EXIST and the ExternalCertificate input parameter is not NULL:

    • Return MQ_ERROR_INVALID_PARAMETER (0xC00E0006) and take no further action.

  • Retrieve the User, referred to here as DirectoryUser, from the directory as follows:

    • Generate a Read Directory ([MS-MQDMPR] section 3.1.7.1.20) event with the following inputs, where invokerSID is the SID <11> of the user that calls the method.

      • iDirectoryObjectType = User.

      • iFilter = "SecurityIdentifier" EQUALS invokerSID.

      • iAttributeList = User.Certificates, User.CertificateDigestList.

    • If the rStatus return value is not equal to DirectoryOperationResult.Success:

      • Return an error HRESULT, and take no further action.

  • If the ExternalCertificate input parameter is specified and is not NULL:

    • Create a new MQUSERSIGNCERT ([MS-MQMQ] section 2.2.22) structure iExtMQCert with the following values:

      • aCert = The certificate that is contained in the ExternalCertificate input parameter.

      • Digest = The MD5 hash of the ExternalCertificate input parameter.

      • Identifier = A new GUID.

    • Add iExtMQCert to DirectoryUser.Certificates and iExtMQCert.Digest to DirectoryUser.CertificateDigestList.

  • Else:

    • Retrieve the InternalCertificate ([MS-MQDMPR] section 3.1.1.19) ADM element instance whose UserADM attribute matches DirectoryUser, referred to here as InternalCertificate, from the InternalCertificateCollection ADM attribute of the local QueueManager ADM element instance.

    • If InternalCertificate is found:

      • If the Flags input parameter is equal to MQCERT_REGISTER_IF_NOT_EXIST:

        • Return MQ_INFORMATION_INTERNAL_USER_CERT_EXIST (0x400E000A), and take no further action.

      • Else:

        • Verify that the DirectoryUser has permission to register a certificate by attempting to re-register the existing certificate as follows:

          • Generate a Write Directory ([MS-MQDMPR] section 3.1.7.1.24) event with the following inputs:

            • iDirectoryObject = DirectoryUser.

            • iAttributeList = User.Certificates, User.CertificateDigestList.

          • If the rStatus return value is not equal to DirectoryOperationResult.Success:

            • Return an error HRESULT, and take no further action.

        • Compute the MD5 hash of InternalCertificate as defined in [RFC1321].

        • Define directoryUserCertObject as the MQUSERSIGNCERT ([MS-MQMQ] section 2.2.22) in DirectoryUser.Certificates whose Digest matches the MD5 hash of InternalCertificate computed in the previous step.

        • Remove directoryUserCertObject from DirectoryUser.Certificates.

        • Delete the InternalCertificate from the InternalCertificateCollection ADM attribute of the local QueueManager ADM element instance.

    • Create an X.509-encoded certificate BLOB, as specified in [RFC3280]. Create an InternalCertificate ADM element instance with InternalCertificate.Certificate set to the created X.509 certificate and with InternalCertificate.User set to DirectoryUser, and add it to the InternalCertificateCollection ADM attribute of the local QueueManager ADM element instance.

    • Create a new MQUSERSIGNCERT ([MS-MQMQ] section 2.2.22) structure iIntMQCert with the following values:

      • aCert = The newly created certificate.

      • Digest = The MD5 hash of the newly created certificate.

      • Identifier = A new GUID.

    • Add iIntMQCert to DirectoryUser.Certificates and iIntMQCert.Digest to DirectoryUser.CertificateDigestList.

  • Update DirectoryUser in the directory as follows:

    • Generate a Write Directory ([MS-MQDMPR] section 3.1.7.1.24) event with the following inputs:

      • iDirectoryObject = DirectoryUser.

      • iAttributeList = User.Certificates, User.CertificateDigestList.

    • If the rStatus return value is not equal to DirectoryOperationResult.Success:

      • Return an error HRESULT, and take no further action.