Bug 895535 - 'ssl_key' connection option is not working as expected
Summary: 'ssl_key' connection option is not working as expected
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise MRG
Classification: Red Hat
Component: qpid-tools
Version: Development
Hardware: Unspecified
OS: Unspecified
medium
unspecified
Target Milestone: 2.3
: ---
Assignee: Ken Giusti
QA Contact: Petr Matousek
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2013-01-15 13:34 UTC by Petr Matousek
Modified: 2013-03-06 18:53 UTC (History)
3 users (show)

Fixed In Version: qpid-tools-0.18-8, qpid-qmf-0.18-15
Doc Type: Bug Fix
Doc Text:
Cause Several QPID tools support the '--ssl-key' parameter. This parameter is used to specify a file which contains the private key used to sign the certificate that identifies the tool's user with the broker. The bug was due to a coding problem that caused the QPID tool to ignore the value supplied to the '--ssl-key' parameter. Consequence The broker against which the tool was run would not be able to authenticate the user of the tool. This would cause the broker to reject the connection attempt, and the tool's operation would fail. Fix The code was corrected to use the value passed via the '--ssl-key' parameter when providing authentication criteria to the broker. Result The tool's user is authenticated by the broker, and the QPID tool's operation is permitted.
Clone Of:
Environment:
Last Closed: 2013-03-06 18:53:16 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Apache JIRA QPID-4554 0 None None None Never
Red Hat Bugzilla 782806 0 medium CLOSED [RFE] Python qpid client ssl support 2021-02-22 00:41:40 UTC
Red Hat Bugzilla 850517 1 None None None 2021-01-20 06:05:38 UTC
Red Hat Bugzilla 895515 0 medium CLOSED '--ssl-key' option missing in several management tools 2021-02-22 00:41:40 UTC
Red Hat Bugzilla 895602 0 unspecified CLOSED Document python client SSL limitations 2021-02-22 00:41:40 UTC
Red Hat Product Errata RHSA-2013:0561 0 normal SHIPPED_LIVE Moderate: Red Hat Enterprise MRG Messaging 2.3 security update 2013-03-06 23:48:13 UTC

Internal Links: 782806 850517 895515 895602

Description Petr Matousek 2013-01-15 13:34:56 UTC
Description of problem:

The certificate file (passed with 'ssl_certfile' connection option) may contain the private key. In some cases, you can store the private key separate from the certificate. In that case, you'd have to also specify 'ssl_key' connection option and pass the separate keyfile.

Providing the keyfile separately from the certificate file is not working, please see Steps to Reproduce and Additional info below.

Version-Release number of selected component (if applicable):
python-qpid-0.18-4.el5
qpid-tools-0.18-7.el5

How reproducible:
100%

Steps to Reproduce:
1. Setup SSL broker requiring client authentication
2. Export client's certificate from the nss db in PEM format (use -nokeys option of openssl pkcs12)
3. Export client's private key from the nss db in PEM format (use -nocerts option of openssl pkcs12)
4. Try to connects with python client (ie. qpid-stat), provide the file exported in step2 to  '--ssl-certificate' option and the file exported in step3 to '--ssl-key' option
5. Failed: ConnectError - SSL_CTX_use_PrivateKey_file error
  
Actual results:
Providing the keyfile separately from the certificate file is not working.

Expected results:
Providing the keyfile separately from the certificate file is working as expected.

Additional info:

/etc/qpidd.conf:
cluster-mechanism=DIGEST-MD5 ANONYMOUS
auth=yes
ssl-cert-password-file=/var/lib/qpidd/ssl_pw_file
ssl-cert-db=/var/lib/qpidd/qpid_nss_db
ssl-cert-name="server_dhcp-37-228.lab.eng.brq.redhat.com"
ssl-require-client-authentication=yes

# pk12util -o /tmp/certkey.p12 -n "client" -d /var/lib/qpidd/qpid_nss_db/ -W ""
pk12util: PKCS12 EXPORT SUCCESSFUL
# openssl pkcs12 -in /tmp/certkey.p12 -out keycert.pem -nodes -clcerts -passin pass:""
MAC verified OK
# openssl pkcs12 -in /tmp/certkey.p12 -out certonly.pem -nodes -nokeys -clcerts -passin pass:""
MAC verified OK
# openssl pkcs12 -in /tmp/certkey.p12 -out keyonly.pem -nodes -nocerts -passin pass:""
MAC verified OK

# qpid-stat -b amqps://$(hostname):5671 -q --ssl-certificate=${PWD}/keycert.pem

Queues
  queue                                     dur  autoDel  excl  msg   msgIn  msgOut  bytes  bytesIn  bytesOut  cons  bind
  =========================================================================================================================
  9763f1ad-f12c-8b41-b266-d4a83a487a19:0.0       Y        Y        0     0      0       0      0        0         1     2
# qpid-stat -b amqps://$(hostname):5671 -q --ssl-certificate=${PWD}/certonly.pem
Failed: ConnectError - SSL_CTX_use_PrivateKey_file error
# qpid-stat -b amqps://$(hostname):5671 -q --ssl-certificate=${PWD}/certonly.pem --ssl-key=${PWD}/keyonly.pem
Failed: ConnectError - SSL_CTX_use_PrivateKey_file error
# qpid-stat -b amqps://$(hostname):5671 -q --ssl-certificate=${PWD}/certonly.pem --ssl-key=${PWD}/keycert.pem
Failed: ConnectError - SSL_CTX_use_PrivateKey_file error

Comment 1 Ken Giusti 2013-01-15 13:45:09 UTC
Hi Petr,

Is there a difference in behavior when running on RHEL 5 vs RHEL 6?  The underlying python SSL libraries have changed between the two.

-K

Comment 2 Petr Matousek 2013-01-15 13:48:14 UTC
No, the behaviour is the same on both RHEL 5 and RHEL 6.

Comment 3 Ken Giusti 2013-01-29 14:59:32 UTC
I think I've found a simple coding error that is the cause of this bug:

The qpid tools are based on the qpid python client library.  This library exports a Connection object that the tools use to connect to the broker.  This connection object is supplied all SSL related configuration parameters for the connection.

Those tools which accept the separate SSL keyfile parameter are passing it in the wrong argument to Connection.

Connection accepts this argument using the name "ssl_keyfile".  The tools are incorrectly providing this parameter using the name "ssl_key".  Thus the connection never "sees" the keyfile.

A "grep" of "ssl_*" in qpid/tools:


find . -type f -print0 | xargs -0 -e grep -n -i "ssl_"
./src/py/qpid-route:141:    if opts.ssl_certificate:
./src/py/qpid-route:142:        config._conn_options['ssl_certfile'] = opts.ssl_certificate
./src/py/qpid-cluster:298:        if opts.ssl_certificate:
./src/py/qpid-cluster:299:            conn_options['ssl_certfile'] = opts.ssl_certificate
./src/py/qpid-tool:180:    self.broker = self.session.addBroker(self.url, ssl_certfile=cert)
./src/py/qpid-printevents:150:  if options.ssl_certificate:
./src/py/qpid-printevents:151:    conn_options['ssl_certfile'] = options.ssl_certificate
./src/py/qpid-printevents:152:  if options.ssl_key:
./src/py/qpid-printevents:153:    conn_options['ssl_key'] = options.ssl_key
./src/py/qpid-config:318:    if opts.ssl_certificate:
./src/py/qpid-config:319:        conn_options['ssl_certfile'] = opts.ssl_certificate
./src/py/qpid-config:320:    if opts.ssl_key:
./src/py/qpid-config:321:        conn_options['ssl_key'] = opts.ssl_key
./src/py/qpid-stat:108:    if opts.ssl_certificate:
./src/py/qpid-stat:109:        conn_options['ssl_certfile'] = opts.ssl_certificate
./src/py/qpid-stat:110:    if opts.ssl_key:
./src/py/qpid-stat:111:        conn_options['ssl_key'] = opts.ssl_key
./src/py/qpid-queue-stats:136:  if options.ssl_certificate:
./src/py/qpid-queue-stats:137:    conn_options['ssl_certfile'] = options.ssl_certificate
./src/py/qpid-ha:61:        if opts.ssl_certificate:
./src/py/qpid-ha:62:            conn_options['ssl_certfile'] = opts.ssl_certificate
./src/py/qpid-ha:63:        if opts.ssl_key:
./src/py/qpid-ha:64:            conn_options['ssl_key'] = opts.ssl_key

Note the use of 'ssl_key' as the options name - that should be 'ssl_keyfile'.

Not to mention the tools that don't even allow the keyfile to be specified - that's an additional problem.

Comment 4 Petr Matousek 2013-01-29 17:01:39 UTC
Confirmed, when the client private key is provided to the Connection object separately using 'ssl_keyfile' argument instead of 'ssl_key' (as qpid-tools do), the connection is successful (the argument works as expected).

-> Changing component to qpid-tools.

I also believe that fix for this issue is easy and may be provided with 2.3 release, thus adding 2.3.0? and blocker?

Comment 5 Petr Matousek 2013-01-29 17:34:09 UTC
(In reply to comment #3)
> Not to mention the tools that don't even allow the keyfile to be specified -
> that's an additional problem.

Note: there is already a bug reported for this issue, please see bug 895515

Comment 6 Ken Giusti 2013-01-29 18:07:50 UTC
Upstream JIRA:

https://issues.apache.org/jira/browse/QPID-4554

Comment 7 Ken Giusti 2013-01-30 19:08:45 UTC
Fix pushed to private BZ branch on mrg repo (0.18-mrg-kgiusti-bz895535):

http://mrg1.lab.bos.redhat.com/git/?p=qpid.git;a=commit;h=fb9108f75585bc17d03952cabac83e4bc634c26c

Comment 9 Petr Matousek 2013-02-08 14:26:39 UTC
Automated test shows that the '--ssl-key' option is still not working properly for all the management tools.

However all the qpid-tools were changed to support the correct connection option ('ssl_keyfile' instead of 'ssl_key'). It solves the issue on for qpid-config and qpid-stat. 

The ssl-key option is still not working properly for the following management tools: qpid-route qpid-cluster qpid-queue-stats

* Note qpid-tool still do not support '--ssl-key' option, please see Bug 895515 for details.

I believe that this issue is caused by the fact that qpid-stat and qpid-config pass the ssl options to the connection object, ie. Connection.establish(self.url, **conn_options), this is working fine.

But when the options are passed to another object (what the other qpid-tools do), ie.: BrokerManager the options do not work.

How the qpid-tools pass the connection options:

/usr/bin/qmf-tool
    self.connection = cqpid.Connection(self.url, **self.conn_options)
/usr/bin/qpid-cluster
    def __init__(self, config, conn_options):
        self.broker = self.qmf.addBroker(brokerUrl, self.config._connTimeout, **self.conn_options)
        bm = BrokerManager(config, conn_options)
/usr/bin/qpid-cluster-store
/usr/bin/qpid-config
        self.conn = Connection.establish(self.url, **conn_options)
/usr/bin/qpid-printevents
        er = EventReceiver(printer, host, conn_options)
/usr/bin/qpid-queue-stats
  def __init__(self, host, conn_options):
    self.broker  = self.session.addBroker(self.url, **conn_options)
  bm = BrokerManager(host, conn_options)
/usr/bin/qpid-route
        self.broker = self.qmf.addBroker(localBroker, config._connTimeout, **config._conn_options)
/usr/bin/qpid-stat
        self.connection = Connection.establish(self.url, **conn_options)

Comment 10 Petr Matousek 2013-02-08 14:27:03 UTC
test transcript:

<snip>
qpid-config: CMD: qpid-config -b amqps://127.0.0.1:6667 --ssl-certificate guest_cert --ssl-key=guest_pkey
Total Exchanges: 8
          topic: 3
        headers: 1
         fanout: 1
         direct: 3

   Total Queues: 6
        durable: 0
    non-durable: 6
PASS
qpid-stat: CMD: qpid-stat -q -b amqps://127.0.0.1:6667 --ssl-certificate guest_cert --ssl-key=guest_pkey
Queues
  queue                                     dur  autoDel  excl  msg   msgIn  msgOut  bytes  bytesIn  bytesOut  cons  bind
  =========================================================================================================================
  c22f2063-3c8e-4d47-af91-125131b1b35b:0.0       Y        Y        0     0      0       0      0        0         1     2
  qpid-perftest0                                                   0    10     10       0   10.2k    10.2k        0     1
  qpid-perftest_pub_done                                           0     1      1       0     16       16         0     1
  qpid-perftest_pub_start                                          0     1      1       0      5        5         0     1
  qpid-perftest_sub_done                                           0     1      1       0     17       17         0     1
  qpid-perftest_sub_ready                                          0     1      1       0      5        5         0     1
PASS
qpid-route: CMD: qpid-route route map amqps://127.0.0.1:6667 --ssl-certificate guest_cert --ssl-key=guest_pkey
Failed: sslerror - SSL_CTX_use_PrivateKey_file error
FAIL
qpid-cluster: CMD: qpid-cluster amqps://127.0.0.1:6667 --ssl-certificate guest_cert --ssl-key=guest_pkey
Failed: sslerror - SSL_CTX_use_PrivateKey_file error
FAIL
qpid-queue-stats: FAIL
Queue Name                                     Sec       Depth     Enq Rate     Deq Rate
========================================================================================
*** Error: Exception during connection setup: sslerror - SSL_CTX_use_PrivateKey_file error, retrying...
qpid-printevents: PASS
Fri Feb  8 10:41:10 2013 NOTIC qpid-printevents:brokerConnected broker=amqps://127.0.0.1:6667
Fri Feb  8 10:41:10 2013 org.apache.qpid.broker:bind exName=qmf.default.topic args={} qName=b313824d-1c21-6440-9cff-076c3caf8502:0.0 user=anonymous@QPID key=agent.ind.event.*.*.*.# rhost=127.0.0.1:6667-127.0.0.1:54273
</snip>

Comment 19 Petr Matousek 2013-02-14 14:55:02 UTC
This issue has been fixed.

Verified on rhel5.9 and rhel6.4 (x86_64, i386)

packages used for testing:
qpid-tools-0.18-8.el5
qpid-qmf-0.18-15.el5
python-qpid-0.18-4.el5

-> VERIFIED

Comment 21 errata-xmlrpc 2013-03-06 18:53:16 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

http://rhn.redhat.com/errata/RHSA-2013-0561.html


Note You need to log in before you can comment on or make changes to this bug.