title: IBM-MQ: Configuring mutual TLS authentication between client and queue manager
body: <p>I'm trying to set up TLS mutual authentication between client and IBM-MQ queue manager (using the <a href="https://hub.docker.com/r/ibmcom/mq/" rel="nofollow noreferrer">ibmcom/mq Docker image</a>). The certificates are self-signed and created according to this <a href="https://developer.ibm.com/messaging/learn-mq/mq-tutorials/secure-mq-tls/" rel="nofollow noreferrer">article</a>. As stated in the <a href="https://github.com/ibm-messaging/mq-container/blob/master/docs/usage.md" rel="nofollow noreferrer">docs</a>, it should be possible to bake in the server's private key and both certificates into the image. My <code>Dockerfile</code> looks like this:</p>
  
  <pre><code>FROM ibmcom/mq
  
  USER mqm
  COPY --chown=mqm:mqm 20-config.mqsc /etc/mqm/ # creation of additional queues, no problems here
  COPY --chown=mqm:mqm keys_mq1/key.key /etc/mqm/pki/keys/mykey/
  COPY --chown=mqm:mqm keys_mq1/key.crt /etc/mqm/pki/keys/mykey/
  COPY --chown=mqm:mqm keys_client/client.crt /etc/mqm/pki/trust/0/
  </code></pre>
  
  <p>The files can be found in the running container:</p>
  
  <pre><code>/etc/mqm/pki/keys/mykey
  drwxr-xr-x 1 mqm mqm 4096 Feb 16 11:18 .
  drwxr-xr-x 1 mqm mqm 4096 Feb 16 11:18 ..
  -rwxr-xr-x 1 mqm mqm 1253 Feb 16 10:54 key.crt
  -rwxr-xr-x 1 mqm mqm 1704 Feb 16 10:53 key.key
  
  /etc/mqm/pki/trust/0
  drwxr-xr-x 2 mqm mqm 4096 Feb 16 13:34 .
  drwxr-xr-x 3 mqm mqm 4096 Feb 16 13:34 ..
  -rwxr-xr-x 1 mqm mqm 1054 Feb 16 13:29 client.crt
  </code></pre>
  
  <p>One thing to notice is that, according to the <a href="https://developer.ibm.com/messaging/learn-mq/mq-tutorials/secure-mq-tls/" rel="nofollow noreferrer">docs</a>, the channel details should now show the following entry: <code>CERTLABL(mykey)</code>. In my case, it's just <code>CERTLABL( )</code>. However, I'm not sure if that's the problem here, authentication of the server without client authentication <em>seems</em> to be working (see below).</p>
  
  <pre><code>DISPLAY CHANNEL(DEV.APP.SVRCONN)
       1 : DISPLAY CHANNEL(DEV.APP.SVRCONN)
  AMQ8414I: Display Channel details.
     CHANNEL(DEV.APP.SVRCONN)                CHLTYPE(SVRCONN)
     ALTDATE(2020-02-16)                     ALTTIME(13.34.47)
     CERTLABL( )                             COMPHDR(NONE)
     COMPMSG(NONE)                           DESCR( )
     DISCINT(0)                              HBINT(300)
     KAINT(AUTO)                             MAXINST(999999999)
     MAXINSTC(999999999)                     MAXMSGL(4194304)
     MCAUSER(app)                            MONCHL(QMGR)
     RCVDATA( )                              RCVEXIT( )
     SCYDATA( )                              SCYEXIT( )
     SENDDATA( )                             SENDEXIT( )
     SHARECNV(10)                            SSLCAUTH(OPTIONAL)
     SSLCIPH(ANY_TLS12)                      SSLPEER( )
     TRPTYPE(TCP)
  </code></pre>
  
  <p>On client side, I created two Java keystores (JKS), one with the server's certificate (truststore) and one with the client's keypair.</p>
  
  <p>My connection attempts were as followed:</p>
  
  <ol>
  <li>Connecting to the default queue manager <code>QM1</code> using the provided <code>app</code> user (no password) and <code>DEV.APP.SVRCONN</code> channel. The client application is an existing tool that perfectly works with the existing MQ infrastructure, I just exchanged the keystores and connection details.</li>
  </ol>
  
  <p>Client exception: <code>com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2035' ('MQRC_NOT_AUTHORIZED').</code></p>
  
  <p>MQ log:</p>
  
  <pre><code>AMQ5534E: User ID 'app' authentication failed
  AMQ5542I: The failed authentication check was caused by the queue manager CONNAUTH CHCKCLNT(REQDADM) configuration.
  </code></pre>
  
  <ol start="2">
  <li>Connecting using the provided <code>admin</code> user and <code>DEV.ADMIN.SVRCONN</code> channel via IBM MQ Explorer (in this scenario, I switched to <code>admin</code> because <code>app</code> has insufficient rights to be used with MQ Explorer, regardless of the authentication method). I checked the "no password" option, since I want to authenticate with the client's certificate.</li>
  </ol>
  
  <p>MQ Explorer error message:</p>
  
  <pre><code>Access not permitted. You are not authorized to perform this operation. (AMQ4036)
    Explanation: The queue manager security mechanism has indicated that the userid associated with this request is not authorized to access the object.
  </code></pre>
  
  <p>MQ log:</p>
  
  <pre><code>AMQ5540E: Application 'MQ Explorer 8.0.0' did not supply a user ID and password
  AMQ5541I: The failed authentication check was caused by the queue manager CONNAUTH CHCKCLNT(REQDADM) configuration.
  AMQ9557E: Queue Manager User ID initialization failed for 'admin'.
  </code></pre>
  
  <ol start="3">
  <li>Same as 2., but omitting the client's keystore and providing the password instead. <strong>Works</strong>. The idea here was to verify that at least the server's certificate is configured correctly (on the other hand, I'm not sure if MQ Explorer is enforcing the check of the server's certificate against the truststore in the first place).</li>
  </ol>
  
  <p>What am I missing?</p>
  
  <p>edit: my actual goal is to use mutual authentication for the <code>app</code> user and <code>DEV.APP.SVRCONN</code> channel.</p>