This discussion is archived
1 2 Previous Next 23 Replies Latest reply: Sep 13, 2011 3:01 PM by 888044 RSS

Socket.startHandshake with PKCS11 token

user10878887 Newbie
Currently Being Moderated
Hello
I have 2 pkcs11 tokens(a Oberthur and a Gemalto).
Oberthur works fine but Gemalto gives the following error
javax.net.ssl.SSLException: Received fatal alert: illegal_parameter
at the line "socket.startHandshake()".


Both tokens are working fine - I can sign files from java using them .

This is the code. I put a lot of debug information hoping I will find the cause. All println lines print the exact same thing for both tokens.

keystorePkcs11 = KeyStore.getInstance("pkcs11");
keystorePkcs11.load(null, PASSWORD_PKCS11);

kKeyManagerFactory = KeyManagerFactory.getInstance("sunx509");
kKeyManagerFactory.init(keystorePkcs11, PASSWORD_PKCS11);
System.out.println("getAlgorithm>>>" + kKeyManagerFactory.getAlgorithm());
System.out.println("get provider get info>>>" + kKeyManagerFactory.getProvider().getInfo());
System.out.println("get provider get name>>>" + kKeyManagerFactory.getProvider().getName());

SSLContext context = SSLContext.getInstance("TLS");
context.init(kKeyManagerFactory.getKeyManagers(), null, null);

factory = context.getSocketFactory();
socket = (SSLSocket)factory.createSocket("www.siui.ro", 443);

System.out.println("getCipherSuites>>>" + Arrays.toString(socket.getSSLParameters().getCipherSuites()));
System.out.println("getNeedClientAuth>>>" + socket.getSSLParameters().getNeedClientAuth());
System.out.println("getProtocols>>>" + Arrays.toString(socket.getSSLParameters().getProtocols()));
System.out.println("getWantClientAuth>>>" + socket.getSSLParameters().getWantClientAuth());

socket.startHandshake(); // here is the problem

This is the output:
getAlgorithm>>>sunx509

get provider get info>>>Sun JSSE provider(PKCS12, SunX509 key/trust factories, SSLv3, TLSv1)

get provider get name>>>SunJSSE

getCipherSuites>>>[SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]

getNeedClientAuth>>>false

getProtocols>>>[SSLv2Hello, SSLv3, TLSv1]

getWantClientAuth>>>false

javax.net.ssl.SSLException: Received fatal alert: illegal_parameter
     at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:190)
     at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1720)
     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:954)
     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1165)
     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1149)
     at client.Client.connect_tls(Client.java:119)
     at main_class.jButton1ActionPerformed(main_class.java:295)
     at main_class.access$500(main_class.java:26)
     at main_class$6.actionPerformed(main_class.java:152)
     at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
     at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
     at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
     at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
     at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
     at java.awt.Component.processMouseEvent(Component.java:6288)
     at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
     at java.awt.Component.processEvent(Component.java:6053)
     at java.awt.Container.processEvent(Container.java:2041)
     at java.awt.Component.dispatchEventImpl(Component.java:4651)
     at java.awt.Container.dispatchEventImpl(Container.java:2099)
     at java.awt.Component.dispatchEvent(Component.java:4481)
     at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
     at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
     at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
     at java.awt.Container.dispatchEventImpl(Container.java:2085)
     at java.awt.Window.dispatchEventImpl(Window.java:2478)
     at java.awt.Component.dispatchEvent(Component.java:4481)
     at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:643)
     at java.awt.EventQueue.access$000(EventQueue.java:84)
     at java.awt.EventQueue$1.run(EventQueue.java:602)
     at java.awt.EventQueue$1.run(EventQueue.java:600)
     at java.security.AccessController.doPrivileged(Native Method)
     at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
     at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
     at java.awt.EventQueue$2.run(EventQueue.java:616)
     at java.awt.EventQueue$2.run(EventQueue.java:614)
     at java.security.AccessController.doPrivileged(Native Method)
     at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
     at java.awt.EventQueue.dispatchEvent(EventQueue.java:613)
     at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
     at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
     at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
     at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
     at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
     at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)


Thank you.
  • 1. Re: Socket.startHandshake with PKCS11 token
    830591 Newbie
    Currently Being Moderated
    Would you please enable the JSSE debug log (JVM option "-Djavax.net.debug=all"), and past the debug log? It seems that Gemalto run into cryptographic operation issues. What are the mechanisms (AES, RSA, RC4?) that the tokens support?
  • 2. Re: Socket.startHandshake with PKCS11 token
    user10878887 Newbie
    Currently Being Moderated
    The debug is too big to fit on this forum but I posted it here
    http://www.casnt.ro/out.gemalto

    I started testing with java wrapper for Microsoft CAPI but I didn't fix it yet.
    I still hope there is a simple solution to this.

    This are the cipher suites that the token Gemalto knows. They are identical with Oberthur.

    getCipherSuites>>>[SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
  • 3. Re: Socket.startHandshake with PKCS11 token
    user10878887 Newbie
    Currently Being Moderated
    After testing with java wrapper for Microsoft CAPI I get the exact same result (Oberthur works and Gemalto gives "illegal parameter").
    The problem is that I don't know what illegal parameter means and how can I fix it.
    Seems like a generic error.
  • 4. Re: Socket.startHandshake with PKCS11 token
    user10878887 Newbie
    Currently Being Moderated
    I foud the error "illegal parameter" listed as a bug here
    http://bugs.sun.com/view_bug.do?bug_id=6998053

    Is it possible this is a java bug?
  • 5. Re: Socket.startHandshake with PKCS11 token
    EJP Guru
    Currently Being Moderated
    That bug concerns SSLv2Hello, OpenSSL in a very old version, and probably Apache server.

    It is possible that this is a different bug, but I note that your client sent an empty certificate chain in response to the CertificateRequest. If the server is configured with needClientAuth=true, that will cause the handshake to fail anyway.
  • 6. Re: Socket.startHandshake with PKCS11 token
    830591 Newbie
    Currently Being Moderated
    It's not a bug of Java. I don't think it is a bug of the smart card according to the log.

    ---------------
    Cert Types: RSA
    Cert Authorities:
    <CN=MSANATATII CA, O=Ministerul SANATATII, L=Bucuresti, ST=Romania, C=RO>
    <CN=certSIGN Qualified CA Class 3, OU=certSIGN Qualified CA Class 3, O=certSIGN, C=RO>
    <CN=DIGISIGN PUBLIC, OU=Digisign Public CA, O=Digisign S.A., C=RO>
    <CN=TC TrustCenter Class 3 CA II, OU=TC TrustCenter Class 3 CA, O=TC TrustCenter GmbH, C=DE>
    *** ServerHelloDone
    *** Certificate chain
    ***
    *** ClientKeyExchange, RSA PreMasterSecret, TLSv1
    ----------------

    The server request a client certificate, however, the client send a empty certificate chain. I think you may want to check the certificate in the token to make sure:
    1. there is personal certification stored in the token.
    2. the certificate is of type RSA
    3. the certificate is issue by one of the above cert authorities.

    BTW, please pay attention that the server may be under TLS renegotiation attack. Your client Java RE is safe. For more information please refer to http://www.oracle.com/technetwork/java/javase/documentation/tlsreadme2-176330.html.

    Good luck!
  • 7. Re: Socket.startHandshake with PKCS11 token
    user10878887 Newbie
    Currently Being Moderated
    Than you both.
    I understand what is the problem now but I still can't get it to work.

    1. There is a certificate stored on the token. I can login on the token with COVE user tool and I can see the certificate and is valid until 2012.
    2. The "*signature algorithm*" is sha1RSA.
    3. I can see the certificate path from IE.
    The certificate path is TC TrustCenter Class 3 CA II / Trans Sped Qualified CA II /Maricica Timaru

    In the debug log I have "*TC TrustCenter Class 3 CA II*" as a trusted certificate authority, but I don't have "*Trans Sped Qualified CA II*" as a trusted authority.
    Can this be a problem? I downloaded the certificate for "*Trans Sped Qualified CA II*" and I installed it on my system but the chain is still empty in my debug log.

    I also checked the existence of a certificate like this:
    keystorePkcs11 = KeyStore.getInstance("pkcs11");
    keystorePkcs11.load(null, PASSWORD_PKCS11);
    java.util.Enumeration en = keystorePkcs11.aliases() ;
    while (en.hasMoreElements()) {
    String aliasKey = (String)en.nextElement() ;
    System.out.println("---> FOUND alias : " + aliasKey);
    }
    The result is "*---> FOUND alias : Maricica Timaru's Trans Sped SRL ID*"

    I also add these lines to my code, but the problem is the same - empty certificate chain:
    System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");
    System.setProperty("sun.security.ssl.allowLegacyHelloMessages", "true");

    I'm probably missing something very simple but I have no ideea what it is.

    Thank you.
  • 8. Re: Socket.startHandshake with PKCS11 token
    EJP Guru
    Currently Being Moderated
    2. The "signature algorithm" is sha1RSA.
    I'm not sure that matches what the server has specified.
    The certificate path is TC TrustCenter Class 3 CA II / Trans Sped Qualified CA II /Maricica Timaru

    In the debug log I have "*TC TrustCenter Class 3 CA II*" as a trusted certificate authority, but I don't have "*Trans Sped Qualified CA II*" as a trusted authority.
    No. As long as you have either of them it is OK.
  • 9. Re: Socket.startHandshake with PKCS11 token
    user10878887 Newbie
    Currently Being Moderated
    I foud a great documentation about debugging SSL here [http://download.oracle.com/javase/1.5.0/docs/guide/security/jsse/ReadDebug.html] and I applied it to my debug log.

    This is the client hello from the debug:

    *** ClientHello, TLSv1
    Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
    Compression Methods: { 0 }

    And this is the server hello where the server selects chiper suite "*SSL_RSA_WITH_3DES_EDE_CBC_SHA*" from the client available chipers.
    *** ServerHello, TLSv1
    Cipher Suite: SSL_RSA_WITH_3DES_EDE_CBC_SHA
    Compression Method: 0

    Next I should find in the debug log a line like this: "*matching alias: <my name>*". But this line is missing.
    No alias is found or no alias is matching. I guess no alias is matching because there is a alias on the token.
    But why?
    I think is somethig wrong with the certificate chain but I don't know how to fix it.

    This is the code:

    keystorePkcs11 = KeyStore.getInstance("pkcs11");
    keystorePkcs11.load(null, PASSWORD_PKCS11);
    kKeyManagerFactory = KeyManagerFactory.getInstance("sunx509");
    kKeyManagerFactory.init(keystorePkcs11, PASSWORD_PKCS11);
    SSLContext context = SSLContext.getInstance("TLS");
    context.init(kKeyManagerFactory.getKeyManagers(), null, null);
    factory = context.getSocketFactory();
    socket = (SSLSocket)factory.createSocket("www.siui.ro", 443);
    socket.startHandshake();


    Thank you.
  • 10. Re: Socket.startHandshake with PKCS11 token
    user10878887 Newbie
    Currently Being Moderated
    I guess I should use TrustManagerFactory class and pass an extra argument to init procedure from SSLContext.
    Like this: context.init(kKeyManagerFactory.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
    But how do I add to the TrustManagerFactory the missing chain?

    I tryed this:
    TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
    tmf.init(keystorePkcs11);

    But now I can't check the server certificate and the exception is
    "javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found"
  • 11. Re: Socket.startHandshake with PKCS11 token
    user10878887 Newbie
    Currently Being Moderated
    I tryed something else and I got a new error(I think this may be the source of the problem):
    "Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_MECHANISM_INVALID".
    But I found almost nothing about this error searching on the net.

    This is the code:
    keystorePkcs11 = KeyStore.getInstance("pkcs11");
    keystorePkcs11.load(null, PASSWORD_PKCS11);
    String aliasKey = (String)keystorePkcs11.aliases().nextElement(); //there is only one alias on the token
    Certificate c = keystorePkcs11.getCertificate(aliasKey);
    c.verify(c.getPublicKey(), keystorePkcs11.getProvider().getName()); // here I get the new exception

    java.security.ProviderException: Initialization failed
         at sun.security.pkcs11.P11Signature.initialize(P11Signature.java:294)
         at sun.security.pkcs11.P11Signature.engineInitVerify(P11Signature.java:353)
         at java.security.Signature$Delegate.engineInitVerify(Signature.java:1086)
    .............
    Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_MECHANISM_INVALID
         at sun.security.pkcs11.wrapper.PKCS11.C_VerifyInit(Native Method)
         at sun.security.pkcs11.P11Signature.initialize(P11Signature.java:289)
  • 12. Re: Socket.startHandshake with PKCS11 token
    user10878887 Newbie
    Currently Being Moderated
    I checked all the cipher suites supported by the client - they are listed at the end of my post and I tryed to create the socket with only one chiper activated like this:

    String[] ssuites = new String[1];
    ssuites[0]="SSL_RSA_WITH_RC4_128_MD5"; // I changed the chipper with this variable
    socket.setEnabledCipherSuites(ssuites);
    socket.startHandshake();

    All attempts to create the socket ended with error, most of the errors are "*handshake failure*".
    There were 2 errors "*illegal parameter*" when I set the chiper to "*SSL_RSA_WITH_3DES_EDE_CBC_SHA*" and "*TLS_RSA_WITH_AES_128_CBC_SHA*".
    This probably means that the server only knows these 2 chiper suites from the presented list.
    So my problem remains how to fix "*illegal parameter*" caused by the empty certificate chain send by the client in response to the CertificateRequest.
    However I can't see why the client doesn't send the certificate chain since everything seems to be alright.

    Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
  • 13. Re: Socket.startHandshake with PKCS11 token
    830591 Newbie
    Currently Being Moderated
    1. There is a certificate stored on the token.
    It's fine.
    2. The "signature algorithm" is sha1RSA.
    We normally need the public key algorithm here, rather than the signature algorithm in the cert.

    From the log, http://www.casnt.ro/out.gemalto, I can see the key algorithm is "RSA". So, it's fine again.
    3. I can see the certificate path from IE.
    It does not make sense. You use the smart card token as the key store. IE has no connect with the smart card.

    Again, from the log, I can only find one cert:
    Subject: CN=Maricica Timaru, SURNAME=Timaru, GIVENNAME=Maricica, OU=Functia: Administrator, O=Farmacia Mara S.R.L., C=RO
    Issuer: CN=Trans Sped Qualified CA II, OU=Individual Subscriber CA, O=Trans Sped SRL, C=RO

    The issuer of the certificate is not trusted by the server, i.e., it is not in the list of server required Cert Authorities.

    If you believe that the certificate can be chained to <CN=TC TrustCenter Class 3 CA II, OU=TC TrustCenter Class 3 CA, O=TC TrustCenter GmbH, C=DE>. It's clear that the smart card certificate cannot be act as a complete certification path, it cannot be chained to <CN=TC TrustCenter Class 3 CA II, OU=TC TrustCenter Class 3 CA, O=TC TrustCenter GmbH, C=DE>, the trusted cert.

    I think if you check the other workable smart card, you should be able to find a complete certification path to a trusted anchor.

    To solve the issue, you may need to import the intermediate certificates between the smart card cert (CN=Maricica Timaru ...) and the trusted cert (CN=TC TrustCenter ...) into the smart card. Or contact your smart card provider. Otherwise, there is no way to find the complete certification path to the server trusted issuers.

    Other tries you made do not make sense to solve the issue, some of them even are not reasonable.

    Good luck!
  • 14. Re: Socket.startHandshake with PKCS11 token
    user10878887 Newbie
    Currently Being Moderated
    827588 wrote:

    To solve the issue, you may need to import the intermediate certificates between the smart card cert (CN=Maricica Timaru ...) and the trusted cert (CN=TC TrustCenter ...) into the smart card. Or contact your smart card provider. Otherwise, there is no way to find the complete certification path to the server trusted issuers.
    It must be another solution. I write this because I made a test with another application made in visual basic that creates the socket successfully.
    It it strange that the "Issuer name" from the token it is not found in the certification path from IE. I will contact the provider for this issue.

    It must be possible to add the missing chain at run time. But how? Is this correct?
    3. I can see the certificate path from IE.
    It does not make sense. You use the smart card token as the key store. IE has no connect with the smart card.
    All my certificates from the tokens are installed in IE and I can find them there.
    You are right, I shouldn't look in IE while I use "*KeyStore.getInstance("pkcs11")*".
    Maybe when I use "*KeyStore.getInstance("Windows-MY")*" this would have meaning.

    >
    Again, from the log, I can only find one cert:
    Subject: CN=Maricica Timaru, SURNAME=Timaru, GIVENNAME=Maricica, OU=Functia: Administrator, O=Farmacia Mara S.R.L., C=RO
    Issuer: CN=Trans Sped Qualified CA II, OU=Individual Subscriber CA, O=Trans Sped SRL, C=RO

    The issuer of the certificate is not trusted by the server, i.e., it is not in the list of server required Cert Authorities.

    If you believe that the certificate can be chained to <CN=TC TrustCenter Class 3 CA II, OU=TC TrustCenter Class 3 CA, O=TC TrustCenter GmbH, C=DE>. It's clear that the smart card certificate cannot be act as a complete certification path, it cannot be chained to <CN=TC TrustCenter Class 3 CA II, OU=TC TrustCenter Class 3 CA, O=TC TrustCenter GmbH, C=DE>, the trusted cert.

    I think if you check the other workable smart card, you should be able to find a complete certification path to a trusted anchor.
    Yes, I can find a complete certification path with my working token - Oberthur.
1 2 Previous Next

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points