1

I am trying to establish connection between client and server in my local machine in Jdeveloper 11.1.1.7 and weblogic 10.3

I follow the steps in the following blogs:

One size doesn't fit all: One-Way SSL with JAX-WS using JDeveloper 11gR1 and WLS 10.3.1

Gerard Davison's Blog: Security Policy Worked Example

All steps works fine for me. But the connection is not establish.

I have key store and self-signed certificate for both client and server. I exchange the certificates between the client and server. So, each one of them have the certificate of the other in his keystore file as trusted certificate.

From the client side I am trying to call the server from the auto generated port class by Jdeveloper where every thing is setup, all what I need is to fill the values for username, password, keyStore,...... etc.

But I am getting the following exception in the client side.

java.lang.SecurityException: Can not find public key for alias: "serversidecert"
  at weblogic.wsee.security.util.CertUtils.getCertificate(CertUtils.java:106)
  at testClient.TestWSPortClient.getBSTCredentialProvider(TestWSPortClient.java:97)
  at testClient.TestWSPortClient.setPortCredentialProviderList(TestWSPortClient.java:71)
  at testClient.TestWSPortClient.main(TestWSPortClient.java:41)

Note 1: I am not able to reach the server yet, this exception is happening at the client side.

Note 2: The error indicate that system could not find the public key of the specified alias. What I know that the public key is included in the certificate. So when the certificate is added to the trusted keystore everything should go smoothly(Correct me if I am wrong).

------------------------------- EDIT-------------------------------------

I figure out that I am doing something wrong in the code because the application worked from Http Analyzer in Jdeveloper. But I am not seeing what is wrong in the code.

The following is the auto generated port class from Jdeveloper and the values a fill it in:

Note 3: ClientSideKeyStore.jks is the keystore for the client and it contains the self-signed certificates for the client and the server certificate as trusted certificated

public class TestWSPortClient
{
  @WebServiceRef
  private static TestWSService testWSService;

    public static void main(String[] args) {
        try {
            testWSService = new TestWSService();
            TestWS testWS = testWSService.getTestWSPort();

            Map<String, Object> requestContext = ((BindingProvider) testWS).getRequestContext();
            setPortCredentialProviderList(requestContext);

             Add your code to call the desired methods.
            System.out.println("Client Side: "+testWS.sayhi("Testing Message"));

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    @Generated("Oracle JDeveloper")
    public static void setPortCredentialProviderList(Map<String, Object> requestContext) throws Exception {
        // TODO - Provide the required values
        String username = "weblogic";
        String password = "welcome1";
        String clientKeyStore = "C:\\Client_Server\\ClietSide\\ClientSideKeyStore.jks";
        String clientKeyStorePassword = "changeit";
        String clientKeyAlias = "clientsidecert";
        String clientKeyPassword = "changeit";
        String serverKeyStore = "C:\\Client_Server\\ClietSide\\ClientSideKeyStore.jks";
        String serverKeyStorePassword = "changeit";
        String serverKeyAlias ="serversidecert";
        List<CredentialProvider> credList = new ArrayList<CredentialProvider>();

        // Add the necessary credential providers to the list

        credList.add(getUNTCredentialProvider(username, password));

        credList.add(getBSTCredentialProvider(clientKeyStore, clientKeyStorePassword, clientKeyAlias, clientKeyPassword, serverKeyStore, serverKeyStorePassword, serverKeyAlias, requestContext));

        credList.add(getSAMLTrustCredentialProvider());

        requestContext.put(WSSecurityContext.CREDENTIAL_PROVIDER_LIST, credList);
    }

    @Generated("Oracle JDeveloper")
    public static CredentialProvider getSAMLTrustCredentialProvider() {
        return new SAMLTrustCredentialProvider();
    }

    @Generated("Oracle JDeveloper")
    public static CredentialProvider getUNTCredentialProvider(String username,
                                                              String password) {
        return new ClientUNTCredentialProvider(username.getBytes(), password.getBytes());
    }

    @Generated("Oracle JDeveloper")
    public static CredentialProvider getBSTCredentialProvider(String clientKeyStore,
                                                              String clientKeyStorePwd,
                                                              String clientKeyAlias,
                                                              String clientKeyPwd,
                                                              String serverKeyStore,
                                                              String serverKeyStorePwd,
                                                              String serverKeyAlias, Map<String, Object> requestContext) throws Exception {
        List serverCertList =
            CertUtils.getCertificate(serverKeyStore, serverKeyStorePwd, serverKeyAlias, "JKS");

        List clientCertList =
            CertUtils.getCertificate(clientKeyStore, clientKeyStorePwd, clientKeyAlias, "JKS");

        final X509Certificate serverCert =
            (serverCertList != null && serverCertList.size() > 0) ? (X509Certificate) serverCertList.get(0) : null;
        final X509Certificate clientCert =
            (clientCertList != null && clientCertList.size() > 0) ? (X509Certificate) clientCertList.get(0) : null;

        requestContext.put(WSSecurityContext.TRUST_MANAGER, new TrustManager()
       {
          public boolean certificateCallback(X509Certificate[] chain,
                                             int validateErr)
          {
             boolean result = (chain != null && chain.length > 0)
                              && (chain[0].equals(serverCert) || chain[0].equals(clientCert));
             return result;
          }
       });

        return new ClientBSTCredentialProvider(clientKeyStore, clientKeyStorePwd, clientKeyAlias, clientKeyPwd, "JKS", serverCert);
    }
}
bcintegrity
  • 213
  • 2
  • 11
Salman
  • 1,236
  • 5
  • 30
  • 59
  • If you're getting an exception in the client side looking for the servers public key, you're don't something wrong, because you don't need the servers public key at the client. Post some code. – user207421 Jun 12 '14 at 08:33
  • 1
    You're mixing up keystores and truststores here. Truststores contain certificates you want to trust, e.g. self-signed certificates of the peer. Keystores contain your own private key and its corresponding certificate, for sending to the peer. Using the same file for both is conceptually incorrect. – user207421 Jun 12 '14 at 09:49
  • @EJP I follow your suggestions. I separate keystore and truststore for the client and server. Keystore files contains the self-signed certificate and the turstStore files contains the trusted certificates. But Still getting the same error. Although I configure the new file locations in the code and in the weblogic configuration. – Salman Jun 12 '14 at 11:12

1 Answers1

0

Verify if the file C:\\Client_Server\\ClietSide\\ClientSideKeyStore.jks is readable by the client and if it really contains the certificate with the alias serversidecert:

keytool -list -v -keystore C:\\Client_Server\\ClietSide\\ClientSideKeyStore.jks -alias serversidecert

That said, are you sure that the client certificate ClientSideKeyStore is the server certificate that's needed here?

On the Weblogic doc, the server side certificates are (usually) initialized differently without the alias parameter. Perhaps you could try this as well:

X509Certificate serverCertInit = (X509Certificate) CertUtils.getCertificate(serverKeyStore);
Peter Keller
  • 7,526
  • 2
  • 26
  • 29
  • First: I checked if the certificate is exists in the keystore as you specified using the keytool command. The certificate is exists in the keysote file. Second: I tried the suggests way to initialize the certificates and I got the same error. @PeterSmith – Salman Jun 15 '14 at 05:10
  • @Salman If you got the same error then you may not have removed `List serverCertList = CertUtils.getCertificate(serverKeyStore, serverKeyStorePwd, serverKeyAlias, "JKS");` from `getBSTCredentialProvider`? – Peter Keller Jun 15 '14 at 05:27
  • @PeterSmith I did remove this statement before adding the suggested way by you. – Salman Jun 15 '14 at 05:29
  • @Salman Could you please show the altered code and the exception stacktrace (and mark the line where the exception was thrown)? – Peter Keller Jun 15 '14 at 05:32
  • @PeterSmith I think you are right. I did not remove the statement you mentioned. After I remove it I got new error `java.security.cert.CertificateException: Could not parse certificate: java.io.IOException: DerInputStream.getLength(): lengthTag=109, too big. at sun.security.provider.X509Factory.engineGenerateCertificate(X509Factory.java:109) at java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:305)`After quick search I found I out that I have to till the system it is JKS file. Please advise in this stiuation. – Salman Jun 15 '14 at 05:40
  • @Salman Perhaps your certificate is corrupt, see http://stackoverflow.com/questions/7399154/pkcs12-derinputstream-getlength-exception. Or it is not of format JKS, see http://stackoverflow.com/questions/23126282/java-apns-certificate-error-with-derinputstream-getlength-lengthtag-109-too. Or you can't use strong encryption due to american export regulations in encryption technologies, see http://stackoverflow.com/questions/132498/webservices-client-and-ssl. Or something else... – Peter Keller Jun 15 '14 at 06:00
  • @Salman Looks like CertUtils.getCertificate() required certificate in DER format, not JKS keystore. – user1516873 Jun 16 '14 at 15:31