[ 
https://issues.apache.org/jira/browse/QPID-4636?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Michal Zerola updated QPID-4636:
--------------------------------

    Description: 
*Motivation:*

The C++ broker implementation is based on the NSS library from Mozilla. The 
user creates a certificate database and configures the broker to load the 
database at start-up.  The NSS certificate database can store the private keys 
used by the broker as well as the public keys related to the connecting 
clients. The public keys can be divided into several groups - the keys of 
trusted CAs and the keys of trusted peers. The difference between the trusted 
CA and trusted peer is that the trusted CA allows logging in even to clients 
who have a certificate signed by the CA, while the peers allow logging in only 
to clients who have the certificate exactly matching the certificate loaded in 
the certificate database.

The SSL Client Authentication in the Java broker is based on the Java JSSE 
implementation. The certificates are stored in the JKS format. The JKS format 
doesn't distinguish between trusted peers and trusted CA. Therefore all public 
keys behave as trusted CAs. As a result, the current implementation cannot be 
used together with self signed certificates. As we found out, there seems to be 
no support for the trusted peers in the JKS truststores.

*Proposed solution:*

The current configuration for the SSL Client Authentication supports only one 
truststore . We can add a second configuration entry which would allow to 
specify "peerstore" . When creating the SSL context, the existing truststore 
would be handled as it is handled today. If the "peerstore" is specified, the 
new TrustManager will be added to the SSL context.  The custom TrustManager 
will use the peerstore to verify the peers only as peers.  The client will pass 
the authentication if it is authenticated either with the original Trustmanager 
against the keystore or by the custom trust manager against the peer store.

*Configuration and patch explanation:*

The current configuration model for the broker (trunk) is based on JSON.  We 
have added two optional attributes (peerStorePath, peerStorePassword):
{quote}
…
  "keyStorePath": "...",
  "keyStorePassword": "123456",
  "trustStorePath": "...",
  "trustStorePassword": "123456",
  {color:red}
  "peerStorePath": "...",
  "peerStorePassword": "123456",
  {color}
…
{quote}

Internally, the broker is prepared to handle multiple truststores, since it can 
store them in the collection. If the above new attributes were specified, the 
additional truststore is added into the collection (BrokerAdapter.java). A new 
truststore will have optional flag TrustStore.PEERS_ONLY set to True. The 
SSLContextFactory was extended for collection configuration. The Broker creates 
the SSLContext using the collection of truststores (either only single 
truststore or with a new peerstore). The SSLFactory parses the collection and 
depending on the TrustStore.PEERS_ONLY flag creates either regular JSSE 
trustmanager or uses a newly introduced one QpidPeersOnlyTrustManager.

The new QpidPeersOnlyTrustManager works as a wrapper around standard JSSE 
trustmanager. When client connects, the check is delegated to the underlying 
JSSE verification and if it succeeds, the additional check is done, whether the 
peer’s certificate (in the chain index 0) is present in the keystore file. Only 
then the client is authenticated, otherwise the CertificateException is thrown.

Since SSLContext.init method from the array of trustmanagers uses only the 
first one which is an instance of the X509TrustManager class, we have created 
also the extension. Otherwise, it would not be possible to use simultaneously 
trustmanager (JSSE implementation) and peermanager (our new implementation) 
because both implements X509TrustManager and only the first from the array 
would be considered. Therefore, we have introduced the QpidMultipleTrustManager 
which is doing nothing else but delegating the check to its underlying 
X509TrustManagers and only if all fails, the check itself fails. If some 
underlying manager succeeds, the check itself succeeds as well. This 
QpidMultipleTrustManager is loaded with truststore and peerstore manager and 
added into the array which is further passed to the SSLContext.init method.

The implementation attached in the patch seems to be working fine and adds the 
above requirements for peers only truststore.  It is also backwards compatible- 
anyone without interest for peerstores will not see any change.


  was:
*Motivation:*

The C++ broker implementation is based on the NSS library from Mozilla. The 
user creates a certificate database and configures the broker to load the 
database at start-up.  The NSS certificate database can store the private keys 
used by the broker as well as the public keys related to the connecting 
clients. The public keys can be divided into several groups - the keys of 
trusted CAs and the keys of trusted peers. The difference between the trusted 
CA and trusted peer is that the trusted CA allows logging in even to clients 
who have a certificate signed by the CA, while the peers allow logging in only 
to clients who have the certificate exactly matching the certificate loaded in 
the certificate database.

The SSL Client Authentication in the Java broker is based on the Java JSSE 
implementation. The certificates are stored in the JKS format. The JKS format 
doesn't distinguish between trusted peers and trusted CA. Therefore all public 
keys behave as trusted CAs. As a result, the current implementation cannot be 
used together with self signed certificates. As we found out, there seems to be 
no support for the trusted peers in the JKS truststores.

*Proposed solution:*

The current configuration for the SSL Client Authentication supports only one 
truststore . We can add a second configuration entry which would allow to 
specify "peerstore" . When creating the SSL context, the existing truststore 
would be handled as it is handled today. If the "peerstore" is specified, the 
new TrustManager will be added to the SSL context.  The custom TrustManager 
will use the peerstore to verify the peers only as peers.  The client will pass 
the authentication if it is authenticated either with the original Trustmanager 
against the keystore or by the custom trust manager against the peer store.

Configuration and patch explanation:

The current configuration model for the broker (trunk) is based on JSON.  We 
have added two optional attributes (peerStorePath, peerStorePassword):
{quote}
…
  "keyStorePath": "...",
  "keyStorePassword": "123456",
  "trustStorePath": "...",
  "trustStorePassword": "123456",
  {color:red}
  "peerStorePath": "...",
  "peerStorePassword": "123456",
  {color}
…
{quote}

Internally, the broker is prepared to handle multiple truststores, since it can 
store them in the collection. If the above new attributes were specified, the 
additional truststore is added into the collection (BrokerAdapter.java). A new 
truststore will have optional flag TrustStore.PEERS_ONLY set to True. The 
SSLContextFactory was extended for collection configuration. The Broker creates 
the SSLContext using the collection of truststores (either only single 
truststore or with a new peerstore). The SSLFactory parses the collection and 
depending on the TrustStore.PEERS_ONLY flag creates either regular JSSE 
trustmanager or uses a newly introduced one QpidPeersOnlyTrustManager.

The new QpidPeersOnlyTrustManager works as a wrapper around standard JSSE 
trustmanager. When client connects, the check is delegated to the underlying 
JSSE verification and if it succeeds, the additional check is done, whether the 
peer’s certificate (in the chain index 0) is present in the keystore file. Only 
then the client is authenticated, otherwise the CertificateException is thrown.

Since SSLContext.init method from the array of trustmanagers uses only the 
first one which is an instance of the X509TrustManager class, we have created 
also the extension. Otherwise, it would not be possible to use simultaneously 
trustmanager (JSSE implementation) and peermanager (our new implementation) 
because both implements X509TrustManager and only the first from the array 
would be considered. Therefore, we have introduced the QpidMultipleTrustManager 
which is doing nothing else but delegating the check to its underlying 
X509TrustManagers and only if all fails, the check itself fails. If some 
underlying manager succeeds, the check itself succeeds as well. This 
QpidMultipleTrustManager is loaded with truststore and peerstore manager and 
added into the array which is further passed to the SSLContext.init method.

The implementation attached in the patch seems to be working fine and adds the 
above requirements for peers only truststore.  It is also backwards compatible- 
anyone without interest for peerstores will not see any change.


    
> SSL Client Authentication in Java broker
> ----------------------------------------
>
>                 Key: QPID-4636
>                 URL: https://issues.apache.org/jira/browse/QPID-4636
>             Project: Qpid
>          Issue Type: New Feature
>          Components: Java Broker, Java Common
>    Affects Versions: 0.21
>            Reporter: Michal Zerola
>            Assignee: Robbie Gemmell
>            Priority: Minor
>         Attachments: ssl_new_trustmanager.patch
>
>
> *Motivation:*
> The C++ broker implementation is based on the NSS library from Mozilla. The 
> user creates a certificate database and configures the broker to load the 
> database at start-up.  The NSS certificate database can store the private 
> keys used by the broker as well as the public keys related to the connecting 
> clients. The public keys can be divided into several groups - the keys of 
> trusted CAs and the keys of trusted peers. The difference between the trusted 
> CA and trusted peer is that the trusted CA allows logging in even to clients 
> who have a certificate signed by the CA, while the peers allow logging in 
> only to clients who have the certificate exactly matching the certificate 
> loaded in the certificate database.
> The SSL Client Authentication in the Java broker is based on the Java JSSE 
> implementation. The certificates are stored in the JKS format. The JKS format 
> doesn't distinguish between trusted peers and trusted CA. Therefore all 
> public keys behave as trusted CAs. As a result, the current implementation 
> cannot be used together with self signed certificates. As we found out, there 
> seems to be no support for the trusted peers in the JKS truststores.
> *Proposed solution:*
> The current configuration for the SSL Client Authentication supports only one 
> truststore . We can add a second configuration entry which would allow to 
> specify "peerstore" . When creating the SSL context, the existing truststore 
> would be handled as it is handled today. If the "peerstore" is specified, the 
> new TrustManager will be added to the SSL context.  The custom TrustManager 
> will use the peerstore to verify the peers only as peers.  The client will 
> pass the authentication if it is authenticated either with the original 
> Trustmanager against the keystore or by the custom trust manager against the 
> peer store.
> *Configuration and patch explanation:*
> The current configuration model for the broker (trunk) is based on JSON.  We 
> have added two optional attributes (peerStorePath, peerStorePassword):
> {quote}
> …
>   "keyStorePath": "...",
>   "keyStorePassword": "123456",
>   "trustStorePath": "...",
>   "trustStorePassword": "123456",
>   {color:red}
>   "peerStorePath": "...",
>   "peerStorePassword": "123456",
>   {color}
> …
> {quote}
> Internally, the broker is prepared to handle multiple truststores, since it 
> can store them in the collection. If the above new attributes were specified, 
> the additional truststore is added into the collection (BrokerAdapter.java). 
> A new truststore will have optional flag TrustStore.PEERS_ONLY set to True. 
> The SSLContextFactory was extended for collection configuration. The Broker 
> creates the SSLContext using the collection of truststores (either only 
> single truststore or with a new peerstore). The SSLFactory parses the 
> collection and depending on the TrustStore.PEERS_ONLY flag creates either 
> regular JSSE trustmanager or uses a newly introduced one 
> QpidPeersOnlyTrustManager.
> The new QpidPeersOnlyTrustManager works as a wrapper around standard JSSE 
> trustmanager. When client connects, the check is delegated to the underlying 
> JSSE verification and if it succeeds, the additional check is done, whether 
> the peer’s certificate (in the chain index 0) is present in the keystore 
> file. Only then the client is authenticated, otherwise the 
> CertificateException is thrown.
> Since SSLContext.init method from the array of trustmanagers uses only the 
> first one which is an instance of the X509TrustManager class, we have created 
> also the extension. Otherwise, it would not be possible to use simultaneously 
> trustmanager (JSSE implementation) and peermanager (our new implementation) 
> because both implements X509TrustManager and only the first from the array 
> would be considered. Therefore, we have introduced the 
> QpidMultipleTrustManager which is doing nothing else but delegating the check 
> to its underlying X509TrustManagers and only if all fails, the check itself 
> fails. If some underlying manager succeeds, the check itself succeeds as 
> well. This QpidMultipleTrustManager is loaded with truststore and peerstore 
> manager and added into the array which is further passed to the 
> SSLContext.init method.
> The implementation attached in the patch seems to be working fine and adds 
> the above requirements for peers only truststore.  It is also backwards 
> compatible- anyone without interest for peerstores will not see any change.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to