<div class="content"><p>The RegisterCertificate method MUST register an
MQUSERSIGNCERT (<a href="../ms-mqmq/b7cc2590-a617-45df-b6a3-1f31102b36fb" data-linktype="relative-path">[MS-MQMQ]</a>
section <a href="../ms-mqmq/c4c40ea9-150a-4939-8a49-5aab6cf6dd88" data-linktype="relative-path">2.2.22</a>)
in <a href="../ms-mqdmpr/76956265-66fd-4498-8b9a-709cba34ba0f" data-linktype="relative-path">User</a>.<b>Certificates</b>.
Implementations of this protocol use <a href="3b7be3f7-651c-4f9c-930b-a9a7c4355ad8#gt_7a0f4b71-23ba-434f-b781-28053ed64879" data-linktype="relative-path">certificates</a> to verify the
sender for <a href="3b7be3f7-651c-4f9c-930b-a9a7c4355ad8#gt_85c78cf0-1fb6-4e5d-85f5-a2e9f58a6b9e" data-linktype="relative-path">messages</a> that
are requesting authentication and to ensure message integrity.</p><dl>
<dd>
<div><pre> HRESULT RegisterCertificate(
   [in, optional] VARIANT* Flags,
   [in, optional] VARIANT* ExternalCertificate
 );
</pre></div>
</dd></dl><p><b>Flags: </b>A pointer to a <a href="3b7be3f7-651c-4f9c-930b-a9a7c4355ad8#gt_a3af3eaf-64b7-499b-a95f-193cd4c27812" data-linktype="relative-path">VARIANT</a> that contains a
VT_I4 integer that corresponds to the MQCERT_REGISTER enumeration as defined in
the following table.</p><dl>
<dd>
<table><thead>
  <tr>
   <th>
   <p>Value</p>
   </th>
   <th>
   <p>Meaning</p>
   </th>
  </tr>
 </thead><tbody><tr>
  <td>
  <p>MQCERT_REGISTER_ALWAYS</p>
  <p>0x00000001</p>
  </td>
  <td>
  <p>Register an MQUSERSIGNCERT ([MS-MQMQ] section 2.2.22)
  in User.<b>Certificates</b>.</p>
  <p>If the <i>ExternalCertificate</i> input parameter is
  not specified or is NULL, the <a href="3b7be3f7-651c-4f9c-930b-a9a7c4355ad8#gt_434b0234-e970-4e8c-bdfa-e16a30d96703" data-linktype="relative-path">server</a> MUST delete the
  certificate from the internal store and delete any existing MQUSERSIGNCERT
  ([MS-MQMQ] section 2.2.22) with a matching <b>Digest</b> property from User.<b>Certificates</b>.</p>
  <p>The server MUST then add a newly created
  MQUSERSIGNCERT ([MS-MQMQ] section 2.2.22) to User.<b>Certificates</b>.</p>
  <p>If the <b>ExternalCertificate</b> is not NULL, the
  server MUST add an MQUSERSIGNCERT ([MS-MQMQ] section 2.2.22), as specified by
  the <b>ExternalCertificate</b> input parameter, to User.<b>Certificates</b>.</p>
  </td>
 </tr><tr>
  <td>
  <p>MQCERT_REGISTER_IF_NOT_EXIST</p>
  <p>0x00000002</p>
  </td>
  <td>
  <p>Register an MQUSERSIGNCERT ([MS-MQMQ] section 2.2.22)
  in User.<b>Certificates</b> only if no certificate is registered in the
  internal store. This option cannot be used with <i>ExternalCertificate</i>.</p>
  </td>
 </tr></tbody></table>
</dd>
<dd>
<p>If not specified by the client, the server MUST use
the default value MQCERT_REGISTER_ALWAYS (0x00000001) instead of the
unspecified value.</p>
</dd></dl><p><b>ExternalCertificate: </b>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 <a href="https://go.microsoft.com/fwlink/?LinkId=90414" data-linktype="external">[RFC3280]</a>.</p><p><b>Return Values: </b>The method MUST return S_OK
(0x00000000) to indicate success or an implementation-specific error <a href="../ms-dtyp/a9046ed2-bfb2-4d56-a719-2824afce59ac" data-linktype="relative-path">HRESULT</a>
on failure.<a id="Appendix_A_Target_10"></a><a aria-label="Product behavior note 10" href="71c359c3-e9ec-4fe6-a101-aab1eabecdcf#Appendix_A_10" data-linktype="relative-path">&lt;10&gt;</a></p><p>When processing this call, the server MUST follow these
guidelines:</p><ul><li><p><span><span> 
</span></span>If the <i>ComputerName</i> instance variable is not NULL:</p>
<ul><li><p><span><span>  </span></span>Return
E_NOTIMPL (0x80004001) and take no further action.</p>
</li></ul></li><li><p><span><span> 
</span></span>If the <i>Flags</i> input parameter is equal to
MQCERT_REGISTER_IF_NOT_EXIST and the <i>ExternalCertificate</i> input parameter
is not NULL:</p>
<ul><li><p><span><span>  </span></span>Return
MQ_ERROR_INVALID_PARAMETER (0xC00E0006) and take no further action.</p>
</li></ul></li><li><p><span><span> 
</span></span>Retrieve the User, referred to here as <i>DirectoryUser</i>, from
the directory as follows:</p>
<ul><li><p><span><span>  </span></span>Generate
a <a href="../ms-mqdmpr/314c2287-dc0b-4079-b24a-550817c9e9ae" data-linktype="relative-path">Read
Directory</a> (<a href="../ms-mqdmpr/5eafe0a6-a22f-436b-a0d9-4cbc25c52b47" data-linktype="relative-path">[MS-MQDMPR]</a>
section 3.1.7.1.20) event with the following inputs, where <i>invokerSID</i> is
the <a href="3b7be3f7-651c-4f9c-930b-a9a7c4355ad8#gt_83f2020d-0804-4840-a5ac-e06439d50f8d" data-linktype="relative-path">SID</a> <a id="Appendix_A_Target_11"></a><a aria-label="Product behavior note 11" href="71c359c3-e9ec-4fe6-a101-aab1eabecdcf#Appendix_A_11" data-linktype="relative-path">&lt;11&gt;</a> of the user that calls the
method.</p>
<ul><li><p><span><span> 
</span></span><i>iDirectoryObjectType</i> = User.</p>
</li><li><p><span><span> 
</span></span><i>iFilter</i> = &#34;SecurityIdentifier&#34; EQUALS <i>invokerSID</i>.</p>
</li><li><p><span><span> 
</span></span><i>iAttributeList</i> = User.<b>Certificates</b>, User.<b>CertificateDigestList</b>.</p>
</li></ul></li><li><p><span><span>  </span></span>If
the <i>rStatus</i> return value is not equal to
DirectoryOperationResult.Success:</p>
<ul><li><p><span><span> 
</span></span>Return an error HRESULT, and take no further action.</p>
</li></ul></li></ul></li><li><p><span><span> 
</span></span>If the <i>ExternalCertificate</i> input parameter is specified
and is not NULL:</p>
<ul><li><p><span><span>  </span></span>Create
a new MQUSERSIGNCERT ([MS-MQMQ] section 2.2.22) structure <i>iExtMQCert</i>
with the following values:</p>
<ul><li><p><span><span> 
</span></span><i>aCert</i> = The certificate that is contained in the <i>ExternalCertificate</i>
input parameter.</p>
</li><li><p><span><span> 
</span></span><i>Digest</i> = The MD5 hash of the <i>ExternalCertificate</i>
input parameter.</p>
</li><li><p><span><span> 
</span></span><i>Identifier</i> = A new <a href="../ms-dtyp/001eec5a-7f8b-4293-9e21-ca349392db40" data-linktype="relative-path">GUID</a>.</p>
</li></ul></li><li><p><span><span>  </span></span>Add
<i>iExtMQCert</i> to <i>DirectoryUser</i>.Certificates and <i>iExtMQCert</i>.Digest
to <i>DirectoryUser</i>.CertificateDigestList.</p>
</li></ul></li><li><p><span><span> 
</span></span>Else:</p>
<ul><li><p><span><span>  </span></span>Retrieve
the <b>InternalCertificate</b> ([MS-MQDMPR] section <a href="../ms-mqdmpr/b9c56cb5-9c06-4c07-ad1a-6850ed9c7d6e" data-linktype="relative-path">3.1.1.19</a>)
ADM element instance whose <b>User</b>ADM attribute matches <i>DirectoryUser</i>,
referred to here as <i>InternalCertificate</i>, from the <b>InternalCertificateCollection</b>
ADM attribute of the local <b>QueueManager</b> ADM element instance.</p>
</li><li><p><span><span>  </span></span>If <i>InternalCertificate</i>
is found:</p>
<ul><li><p><span><span> 
</span></span>If the <i>Flags</i> input parameter is equal to
MQCERT_REGISTER_IF_NOT_EXIST:</p>
<ul><li><p><span><span> 
</span></span>Return MQ_INFORMATION_INTERNAL_USER_CERT_EXIST (0x400E000A), and
take no further action.</p>
</li></ul></li><li><p><span><span> 
</span></span>Else:</p>
<ul><li><p><span><span> 
</span></span>Verify that the <i>DirectoryUser</i> has permission to register a
certificate by attempting to re-register the existing certificate as follows:</p>
<ul><li><p><span><span> 
</span></span>Generate a Write Directory ([MS-MQDMPR] section <a href="../ms-mqdmpr/04b08a30-a6d8-43bb-b282-3b089bec1ffe" data-linktype="relative-path">3.1.7.1.24</a>)
event with the following inputs:</p>
<ul><li><p><span><span> 
</span></span>iDirectoryObject = <i>DirectoryUser</i>.</p>
</li><li><p><span><span> 
</span></span><i>iAttributeList</i> = User.<b>Certificates</b>, User.<b>CertificateDigestList</b>.</p>
</li></ul></li><li><p><span><span> 
</span></span>If the <i>rStatus</i> return value is not equal to
DirectoryOperationResult.Success:</p>
<ul><li><p><span><span> 
</span></span>Return an error HRESULT, and take no further action.</p>
</li></ul></li></ul></li><li><p><span><span> 
</span></span>Compute the MD5 hash of <i>InternalCertificate</i> as defined in <a href="https://go.microsoft.com/fwlink/?LinkId=90275" data-linktype="external">[RFC1321]</a>.</p>
</li><li><p><span><span> 
</span></span>Define <i>directoryUserCertObject</i> as the MQUSERSIGNCERT
([MS-MQMQ] section 2.2.22) in <i>DirectoryUser</i>.Certificates whose Digest
matches the MD5 hash of <i>InternalCertificate</i> computed in the previous
step.</p>
</li><li><p><span><span> 
</span></span>Remove <i>directoryUserCertObject</i> from <i>DirectoryUser</i>.Certificates.</p>
</li><li><p><span><span> 
</span></span>Delete the <i>InternalCertificate</i> from the <b>InternalCertificateCollection</b>
ADM attribute of the local <b>QueueManager</b> ADM element instance.</p>
</li></ul></li></ul></li><li><p><span><span>  </span></span>Create
an X.509-encoded certificate BLOB, as specified in [RFC3280]. Create an <b>InternalCertificate</b>
ADM element instance with <b>InternalCertificate.Certificate</b> set to the
created X.509 certificate and with <b>InternalCertificate.User</b> set to <i>DirectoryUser</i>,
and add it to the <b>InternalCertificateCollection</b> ADM attribute of the
local <b>QueueManager</b> ADM element instance.</p>
</li><li><p><span><span>  </span></span>Create
a new MQUSERSIGNCERT ([MS-MQMQ] section 2.2.22) structure iIntMQCert with the
following values:</p>
<ul><li><p><span><span> 
</span></span><i>aCert</i> = The newly created certificate.</p>
</li><li><p><span><span> 
</span></span><i>Digest</i> = The MD5 hash of the newly created certificate.</p>
</li><li><p><span><span> 
</span></span><i>Identifier</i> = A new <b>GUID</b>.</p>
</li></ul></li><li><p><span><span>  </span></span>Add
<i>iIntMQCert</i> to <i>DirectoryUser</i>.Certificates and <i>iIntMQCert</i>.Digest
to <i>DirectoryUser</i>.CertificateDigestList.</p>
</li></ul></li><li><p><span><span> 
</span></span>Update <i>DirectoryUser</i> in the directory as follows:</p>
<ul><li><p><span><span>  </span></span>Generate
a Write Directory ([MS-MQDMPR] section 3.1.7.1.24) event with the following
inputs:</p>
<ul><li><p><span><span> 
</span></span><i>iDirectoryObject</i> = <i>DirectoryUser</i>.</p>
</li><li><p><span><span> 
</span></span><i>iAttributeList</i> = User.Certificates,
User.CertificateDigestList.</p>
</li></ul></li><li><p><span><span>  </span></span>If
the <i>rStatus</i> return value is not equal to
DirectoryOperationResult.Success:</p>
<ul><li><p><span><span> 
</span></span>Return an error HRESULT, and take no further action.</p>
</li></ul></li></ul></li></ul></div>