javascript - Apache HTTPClient sends no client cert during mutual authentication -
i'm getting handshake_failed exception when making restful post call api requires mutual authentication. have verified engineer on other side watching stack trace server-side certs exchanged , accepted client without issue, when server requests client-side cert side doesn't provide , handshake terminates.
the thing have no idea how verify whether sslsocketfactory unable identify right certificate or isn't looking in first place.
here code, js leveraging apache httpclient library.
importpackage(packages.org.apache.http.client); importpackage(packages.org.apache.http.client.methods); importpackage(packages.org.apache.http.impl.client); importpackage(packages.org.apache.http.message); importpackage(packages.org.apache.http.client.entity); importpackage(packages.org.apache.http.util); importpackage(packages.org.apache.commons.httpclient); importpackage(packages.org.apache.http.params); importpackage(packages.org.apache.http.ssl); importpackage(packages.org.apache.http.ssl.sslsocketfactory); importpackage(packages.java.security.keystore); importpackage(packages.org.apache.http.conn.ssl); importpackage(packages.javax.net.ssl); importpackage(packages.java.io); importpackage(packages.org.apache.http.impl.conn); importpackage(packages.org.apache.http.conn.scheme); //benchmark 1 var healthmessagestatus = "0"; var xtn_starttime = dateutil.getcurrentdate('yyyymmddhhmmss'); channelmap.put('xtn_starttime',xtn_starttime); var url = 'https://smr.prodposturl.net/authenticatingxmlserver.aspx' //http connection template var httpparams = new basichttpparams(); httpconnectionparams.setconnectiontimeout(httpparams, 3600000); httpconnectionparams.setsotimeout(httpparams, 3600000); //approach 3 var key_store_path = "c:\\phia\\certs\\mykeystore"; var key_store_password = "changeit"; var trust_store_path = "c:\\phia\\certs\\cacerts"; var trust_store_password = "changeit"; var keystore = new keystore.getinstance(keystore.getdefaulttype()); channelmap.put('keystore',keystore); var keystoreinput = new fileinputstream(key_store_path); keystore.load(keystoreinput, key_store_password.split('')); var keystoreline = "keystore has " + keystore.size() + " keys"; // load truststore var truststore = new keystore.getinstance(keystore.getdefaulttype()); var truststoreinput = new fileinputstream(trust_store_path); truststore.load(truststoreinput, trust_store_password.split('')); var truststoreline = "truststore has " + truststore.size() + " keys"; channelmap.put('keystoreline', keystoreline); channelmap.put('truststoreline', truststoreline); var schemeregistry = new schemeregistry(); var lschemesocketfactory = new org.apache.http.conn.ssl.sslsocketfactory("tlsv1", keystore, key_store_password, truststore, null, org.apache.http.conn.ssl.sslsocketfactory.allow_all_hostname_verifier);//, keystore); var lschemesocketfactorystring = string(lschemesocketfactory); channelmap.put('lschemesocketfactorystring',lschemesocketfactorystring); schemeregistry.register(new scheme("https", lschemesocketfactory, 443)); var httpclient = new defaulthttpclient(new org.apache.http.impl.conn.tsccm.threadsafeclientconnmanager(httpparams, schemeregistry), httpparams); httpclient.sethttprequestretryhandler(new defaulthttprequestretryhandler(10, false)); //benchmark 2 var xtn_posttime = dateutil.getcurrentdate('yyyymmddhhmmss'); channelmap.put('xtn_posttime',xtn_starttime); var httppost = new httppost(url); httppost.addheader("authorization", "basic rif2zsr0yxi2uzpquk4icv9ape0tdigj") httppost.addheader("content-type", "text/xml") //passes results string builder/entity var se = new org.apache.http.entity.stringentity(connectormessage.getencodeddata().tostring()); channelmap.put('se', se); //sets post request resulting string httppost.setentity(se); var httpcontents = string(httppost); channelmap.put('httpcontents',httpcontents); var keystorecontents = string(keystore); channelmap.put('keystorecontents',keystorecontents); var response = httpclient.execute(httppost); try { var statuscode = response.getstatusline().getstatuscode(); var entity = response.getentity(); var responsestring = entityutils.tostring(entity, "utf-8"); channelmap.put('statuscode', statuscode); channelmap.put('responsestring', responsestring); } { response.close(); } //benchmark 3 var xtn_finishtime = dateutil.getcurrentdate('yyyymmddhhmmss'); channelmap.put('xtn_finishtime',xtn_finishtime); //response calculations //var xtn_totalprocessing = (xtn_finishtimems - xtn_starttimems)/1000; var xtn_totalprocessing = xtn_finishtime - xtn_starttime; channelmap.put('xtn_totalprocessing',xtn_totalprocessing); //var xtn_totalposttime = (xtn_finishtimems - xtn_posttimems)/1000; var xtn_totalposttime = xtn_finishtime - xtn_posttime; channelmap.put('xtn_totalposttime', xtn_totalposttime); var finalstatuscheck = responsestring.indexof("<code>010</code>") var pendingstatuscheck = responsestring.indexof("<code>000</code>") var followupmessage = false; channelmap.put('finalstatuscheck',finalstatuscheck); if (finalstatuscheck == -1 & pendingstatuscheck == -1) { healthmessagestatus = "2"; channelmap.put('healthmessagestatus', healthmessagestatus); throw('bad http response code: ' + statuscode + ' guid file id: ' + $('guid') + '. response string: ' + responsestring); } else if (pendingstatuscheck > -1) { channelmap.put('healthmessagestatus', healthmessagestatus); channelmap.put('followupmessage', followupmessage) followupmessage = true; healthmessagestatus = "2"; throw('bad http response code: ' + statuscode + ' guid file id: ' + $('guid') + '. response string: ' + responsestring); } else { healthmessagestatus = "1"; channelmap.put('healthmessagestatus', healthmessagestatus); channelmap.put('followupmessage', followupmessage) }
here's exception get:
javascript writer error error message: error evaluating javascript writer com.mirth.connect.server.mirthjavascripttransformerexception: channel: 0 - inbound clinical pdf prod connector: surescripts prod api script source: javascript writer source code: 541: var httpcontents = string(httppost); 542: channelmap.put('httpcontents',httpcontents); 543: var keystorecontents = string(keystore); 544: channelmap.put('keystorecontents',keystorecontents); 545: 546: var response = httpclient.execute(httppost); 547: 548: try { 549: var statuscode = response.getstatusline().getstatuscode(); 550: var entity = response.getentity(); line number: 546 details: wrapped javax.net.ssl.sslhandshakeexception: received fatal alert: handshake_failure @ 3f792644-5e4b-4bbf-af2d-3ac8ef00b5db:546 (doscript) @ 3f792644-5e4b-4bbf-af2d-3ac8ef00b5db:598 @ com.mirth.connect.connectors.js.javascriptdispatcher$javascriptdispatchertask.call(javascriptdispatcher.java:184) @ com.mirth.connect.connectors.js.javascriptdispatcher$javascriptdispatchertask.call(javascriptdispatcher.java:122) @ java.util.concurrent.futuretask.run(unknown source) @ java.util.concurrent.threadpoolexecutor.runworker(unknown source) @ java.util.concurrent.threadpoolexecutor$worker.run(unknown source) @ java.lang.thread.run(unknown source) caused by: javax.net.ssl.sslhandshakeexception: received fatal alert: handshake_failure @ sun.security.ssl.alerts.getsslexception(unknown source) @ sun.security.ssl.alerts.getsslexception(unknown source) @ sun.security.ssl.sslsocketimpl.recvalert(unknown source) @ sun.security.ssl.sslsocketimpl.readrecord(unknown source) @ sun.security.ssl.sslsocketimpl.performinitialhandshake(unknown source) @ sun.security.ssl.sslsocketimpl.starthandshake(unknown source) @ sun.security.ssl.sslsocketimpl.starthandshake(unknown source) @ org.apache.http.conn.ssl.sslsocketfactory.connectsocket(sslsocketfactory.java:533) @ org.apache.http.conn.ssl.sslsocketfactory.connectsocket(sslsocketfactory.java:401) @ org.apache.http.conn.ssl.sslsocketfactory.connectsocket(sslsocketfactory.java:470) @ org.apache.http.conn.scheme.schemesocketfactoryadaptor.connectsocket(schemesocketfactoryadaptor.java:65) @ org.apache.http.impl.conn.defaultclientconnectionoperator.openconnection(defaultclientconnectionoperator.java:177) @ org.apache.http.impl.conn.abstractpoolentry.open(abstractpoolentry.java:144) @ org.apache.http.impl.conn.abstractpooledconnadapter.open(abstractpooledconnadapter.java:131) @ org.apache.http.impl.client.defaultrequestdirector.tryconnect(defaultrequestdirector.java:611)
the decision private key use when authenticating server made jre (jsse provider exact), not httpclient. 1 can override default behavior employing custom privatekeystrategy
sslcontext sslcontext = sslcontexts.custom() .loadkeymaterial(mykeystore, "mypassword".tochararray(), new privatekeystrategy() { @override public string choosealias(map<string, privatekeydetails> aliases, socket socket) { // pick cert alias based on socket endpoint, ssl session or private key details return "vip"; } }) .build(); closeablehttpclient client = httpclients.custom() .setsslcontext(sslcontext) .build();
Comments
Post a Comment