I am trying to timestamp with itext tsaclient trough HTTPS connection, I am having problems with the connection in the moment of the sign, when tsaclient try to establish the connection against the server. Analizing by whireshark the traffic I have received
"Received fatal alert: bad_certificate"
The point is I can establish the connection but not from the tsaclient,
//Preparing keystore with Private Key
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
KeyStore ks = KeyStore.getInstance("pkcs12", provider.getName());
ks.load(new FileInputStream(Constantes.CERT), Constantes.PASS_CERT.toCharArray());
String alias = (String)ks.aliases().nextElement();
PrivateKey pk = (PrivateKey) ks.getKey(alias, Constantes.PASS_CERT.toCharArray());
Certificate[] chain = ks.getCertificateChain(alias);
//Adding Server public key to the keystore ks
FileInputStream is = new FileInputStream(new File(Constantes.SERVER_CERT_CER));
CertificateFactory cf = CertificateFactory.getInstance("X.509");
java.security.cert.X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
ks.setCertificateEntry("alias", cert);
//Preparing SSL Context
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, "pass".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(kmf.getKeyManagers(),tmf.getTrustManagers(), new SecureRandom());
SSLSocketFactory sf = ctx.getSocketFactory();
URL url = new URL("https://...");
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
conn.setSSLSocketFactory(sf);
conn.setConnectTimeout(0);
conn.connect();
//Until here the connection is OK, "Certificate Verify" say whireshark
//Preparing TSA Client and Sign
ExternalDigest digest = new BouncyCastleDigest();
TSAClient tsaClient = new TSAClientBouncyCastle("https://...");
ExternalSignature es = new PrivateKeySignature(pk,"SHA-1","BC");
MakeSignature.signDetached(appearance, digest, es, chain, null, null, tsaClient, 0, CryptoStandard.CMS);
It is in the moment of MakeSignature when I can't connect with the server.
I wasn't preparing well the connection from TSAClient, now I have implemented properly the client.
//Preparing keystore with my Private Key and Server Certificate
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
ks = KeyStore.getInstance("pkcs12", provider.getName()); //public static KeyStore ks;
ks.load(new FileInputStream(Constantes.CERT), Constantes.PASS_CERT.toCharArray());
String alias = (String)ks.aliases().nextElement();
PrivateKey pk = (PrivateKey) ks.getKey(alias, Constantes.PASS_CERT.toCharArray());
Certificate[] chain = ks.getCertificateChain(alias);
FileInputStream is = new FileInputStream(new File(Constantes.SERVER_CERT_CER));
CertificateFactory cf = CertificateFactory.getInstance("X.509");
java.security.cert.X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
ks.setCertificateEntry("alias_server_cert", cert);
//Making TSA and Sign
ExternalDigest digest = new BouncyCastleDigest();
TSAClient tsaClient = new Sellado("https://url");
//Digital signature
ExternalSignature es = new PrivateKeySignature(pk,"SHA-1","BC");
MakeSignature.signDetached(appearance,digest,es,chain,null,null,tsaClient,0,CryptoStandard.CMS);
and the TSAClient "Sellado" is based in TSAClientBouncycastle, changing the next class with SSL context.
public class Sellado implements TSAClient{
//Code
protected byte[] getTSAResponse(byte[] requestBytes)
throws IOException, NoSuchAlgorithmException, UnrecoverableKeyException, KeyStoreException, KeyManagementException
{
//Preparing SSL Context
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(EmpadronamientoI.ks, "pass".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(EmpadronamientoI.ks);
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(kmf.getKeyManagers(),tmf.getTrustManagers(), new SecureRandom());
SSLSocketFactory sf = ctx.getSocketFactory();
URL url = new URL(this.tsaURL);
HttpsURLConnection tsaconn = (HttpsURLConnection)url.openConnection();
tsaconn.setSSLSocketFactory(sf);
tsaconn.setConnectTimeout(0);
tsaconn.setDoInput(true);
tsaconn.setDoOutput(true);
tsaconn.setUseCaches(false);
tsaconn.setRequestProperty("Content-Type", "application/timestamp-query");
tsaconn.setRequestProperty("Content-Transfer-Encoding", "binary");
try{
tsaconn.connect();
}
catch (IOException ioe)
{
throw new IOException(MessageLocalization.getComposedMessage("failed.to.get.tsa.response.from.1", new Object[] { this.tsaURL }));
}
OutputStream out = tsaconn.getOutputStream();
out.write(requestBytes);
out.close();
InputStream inp = tsaconn.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte['?'];
int bytesRead = 0;
while ((bytesRead = inp.read(buffer, 0, buffer.length)) >= 0) {
baos.write(buffer, 0, bytesRead);
}
byte[] respBytes = baos.toByteArray();
String encoding = tsaconn.getContentEncoding();
if ((encoding != null) && (encoding.equalsIgnoreCase("base64"))) {
respBytes = Base64.decode(new String(respBytes));
}
return respBytes;
}
//Code
}
Related
I have a SpringBoot app that must call a REST API which requires a certificate. I was provided 2 files from the service that propose this REST Service : a P12 file and a CA Root file.
I first created a keystore (JKS) :
keytool -keystore keystore.jks -genkey -alias client
Then I added a CA root to the JKS file :
keytool -keystore keystore.jks -import -file certeurope_root_ca_3.cer -alias cacert
Now in my app I have to call the rest API :
public DocumentDto sendRequest(DocumentDto documentDto) throws Exception {
// Set variables
String ts = "C:\\keystore\\keystore.jks";
String ks = "C:\\keystore\\CERTIFICATE.p12";
String tsPassword = properties.getProperty("signature.api.passphrase");
String ksPassword = properties.getProperty("signature.api.passphrase");
KeyStore clientStore = KeyStore.getInstance("PKCS12");
clientStore.load(new FileInputStream(ks), ksPassword.toCharArray());
log.warn("# clientStore : " + clientStore);
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(clientStore, ksPassword.toCharArray());
KeyManager[] kms = kmf.getKeyManagers();
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(new FileInputStream(ts), tsPassword.toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(trustStore);
TrustManager[] tms = tmf.getTrustManagers();
SSLContext sslContext = null;
sslContext = SSLContext.getInstance("TLS");
sslContext.init(kms, tms, new SecureRandom());
// set the URL to send the request
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
URL url = new URL(properties.getProperty("signature.api.url.full"));
// opening the connection
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) { return true; }
};
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
HttpsURLConnection.setDefaultAllowUserInteraction( true );
HttpsURLConnection.setFollowRedirects( false );
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
urlConnection.setRequestMethod("POST");
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.setUseCaches(false);
urlConnection.setAllowUserInteraction(true);
urlConnection.setReadTimeout(15000);
// create the JSON String
ObjectMapper mapper = new ObjectMapper();
// convert an oject to a json string
String jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(documentDto);
InputStreamReader isr=null;
try(OutputStream os = urlConnection.getOutputStream()) {
byte[] input = jsonInString.getBytes(StandardCharsets.UTF_8);
os.write(input, 0, input.length);
// check 400 & 403
if(urlConnection.getResponseCode() == 400 || urlConnection.getResponseCode() == 403) {
isr = new InputStreamReader(urlConnection.getErrorStream(), StandardCharsets.UTF_8);
String st= IOUtils.toString(isr);
log.warn("# errorStream :" + st );
} else if(urlConnection.getResponseCode() != 200) {
isr = new InputStreamReader(urlConnection.getErrorStream(), StandardCharsets.UTF_8);
String st= IOUtils.toString(isr);
} else {
isr = new InputStreamReader(urlConnection.getInputStream(), StandardCharsets.UTF_8);
}
}
// read the response
try(BufferedReader br = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), StandardCharsets.UTF_8))) {
StringBuilder response = new StringBuilder();
String responseLine = null;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
System.out.println(response.toString());
}
System.out.println(jsonInString);
return documentDto;
}
I also changed my port server : server.port=8443. I have 2 issues :
If i have : TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
I obtain : javax.net.ssl.SSLHandshakeException: No trusted certificate found
If I have : TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
I obtain : javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
I'm stuck on that stuff for a while and I don't see what's going wrong.
Well i found out a solution which may not be the most elegant at all. But at least it work. I also made some refactor...
public DocumentCreateRequestDto sendRequest(DocumentDto documentDto) throws CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException, IOException {
// Set variables
String certificate = properties.getProperty("signature.api.certificate");
String PwdPk12 = properties.getProperty("signature.api.passphrase");
String httpsRestUrl = properties.getProperty("signature.api.url.full");
HttpsURLConnection con = getHttpsURLConnection(certificate, PwdPk12, httpsRestUrl);
// create the JSON String
ObjectMapper mapper = new ObjectMapper();
// convert an oject to a json string
String jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(documentDto);
jsonInString = "[" + jsonInString + "]";
StringBuilder response = getStringBuilder(con, jsonInString);
String output = response.toString();
output = output.substring(1, output.length()-1);
return mapper.readValue(output, DocumentCreateRequestDto.class);
}
private HttpsURLConnection getHttpsURLConnection(String certificate, String pwdPk12, String httpsRestUrl) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, KeyManagementException {
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(new FileInputStream(certificate), pwdPk12.toCharArray());
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
#Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
#Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
#Override
public X509Certificate[] getAcceptedIssuers() {
// return new X509Certificate[0];
return null;
}
}
};
SSLContext ctx = SSLContext.getInstance("TLS");
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) { return true; }
};
KeyManagerFactory kmf = KeyManagerFactory.getInstance( "SunX509" );
kmf.init( ks, pwdPk12.toCharArray() );
ctx.init( kmf.getKeyManagers(), trustAllCerts, new SecureRandom() );
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
HttpsURLConnection.setDefaultAllowUserInteraction( true );
HttpsURLConnection.setFollowRedirects( false );
HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
URL url = new URL(httpsRestUrl);
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
//connection
con.setRequestMethod("POST");
con.setDoOutput(true);
con.setRequestProperty("Accept-Encoding", "gzip,deflate");
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Connection", "Keep-Alive");
con.setRequestProperty("User-Agent", "Apache-HttpClient/4.1.1 (java 1.5)");
con.setReadTimeout(15000);
con.setDoInput(true);
con.setUseCaches(false);
con.setAllowUserInteraction(true);
return con;
}
And :
private StringBuilder getStringBuilder(HttpsURLConnection con, String jsonInString) throws IOException {
InputStreamReader isr = null;
try (OutputStream os = con.getOutputStream()) {
byte[] input = jsonInString.getBytes(StandardCharsets.UTF_8);
os.write(input, 0, input.length);
// check 400 & 403
if (con.getResponseCode() == 400 || con.getResponseCode() == 403) {
isr = new InputStreamReader(con.getErrorStream(), StandardCharsets.UTF_8);
String st = IOUtils.toString(isr);
log.warn("# errorStream :" + st);
} else if (con.getResponseCode() != 200) {
isr = new InputStreamReader(con.getErrorStream(), StandardCharsets.UTF_8);
} else {
isr = new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8);
}
}
// read the response
String responseLine;
StringBuilder response = new StringBuilder();
try (BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8))) {
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
}
return response;
}
I would like to sign and add LTV to yet not signed PDF.
I've copied coding from iText examples and qustions
http://developers.itextpdf.com/question/how-enable-ltv-timestamp-signature
Basic part of main method:
Security.addProvider(new BouncyCastleProvider());
EncryptPDF pdf = new EncryptPDF();
OCSPVerifier ocspVerifier = new OCSPVerifier(null, null);
OcspClient ocsp = new OcspClientBouncyCastle(ocspVerifier);
pdf.signPDF(file_src, file_temp, ocsp);
pdf.addLtvNoTS(file_temp, file_dest, ocsp);
Method signPDF has no problem with signing (or now commented encrypting). Temp file is OK.
private void signPDF(String src, String dest, OcspClient ocsp) {
try {
PdfReader reader = new PdfReader(src);
KeyStore ks = KeyStore.getInstance("pkcs12", "BC");
ks.load(new FileInputStream(cert2_src), keystore_password.toCharArray());
String alias = null;
Enumeration<String> en = ks.aliases();
while(en.hasMoreElements()) {
alias = en.nextElement();
System.out.println("alias name: " + alias);
}
PrivateKey pk = (PrivateKey) ks.getKey(alias, key_password.toCharArray());
Certificate[] chain = ks.getCertificateChain(alias);
PdfStamper stamper = PdfStamper.createSignature(reader, new FileOutputStream(dest), '\0', null, true);
// appearance
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setImage(Image.getInstance(res_src));
appearance.setVisibleSignature(new Rectangle(172, 132, 572, 232), 1, "SignatureField");
// Certificate cert = getPublicCertificate(cert_src);
// stamper.setEncryption(new Certificate[]{cert},
// new int[]{PdfWriter.ALLOW_PRINTING}, PdfWriter.ENCRYPTION_AES_128 ); //| PdfWriter.DO_NOT_ENCRYPT_METADATA
// digital signature
ExternalSignature es = new PrivateKeySignature(pk, "SHA-256", "BC");
ExternalDigest digest = new BouncyCastleDigest();
MakeSignature.signDetached(appearance, digest, es, chain, null, ocsp, null, 0, CryptoStandard.CMS);
} catch (FileNotFoundException e){
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
In method addLtvNoTS I'm getting error "Signature defined. Must be closed in PdfSignatureAppearance." on last line stamper.close(). I'm not able to figure it out. Please, help.
private void addLtvNoTS(String src, String dest, OcspClient ocsp)
throws IOException, DocumentException, GeneralSecurityException {
PdfReader r = new PdfReader(src);
FileOutputStream fos = new FileOutputStream(dest);
PdfStamper stamper = PdfStamper.createSignature(r, fos, '\0', null, true);
LtvVerification v = stamper.getLtvVerification();
AcroFields fields = stamper.getAcroFields();
ArrayList<String> names = fields.getSignatureNames();
String sigName = names.get(names.size() - 1);
PdfPKCS7 pkcs7 = fields.verifySignature(sigName);
v.addVerification(sigName, ocsp, null,
LtvVerification.CertificateOption.WHOLE_CHAIN,
LtvVerification.Level.OCSP,
LtvVerification.CertificateInclusion.NO);
stamper.close();
}
Your addLtvNoTS method seems to first have been a copy of the addLtv method in the article which you then incompletely edited to become a copy of the addLtvNoTS method there.
In particular your addLtvNoTS method still contains this line from the article addLtv method
PdfStamper stamper = PdfStamper.createSignature(r, fos, '\0', null, true);
while in the article addLtvNoTS method the corresponding line is this:
PdfStamper stp = new PdfStamper(r, fos, '\0', true);
Thus, you create a PdfStamper for signing or time stamping (so iText eventually complains about you doing neither) while you should create one which is not.
I am trying to port a .net application to JavaFx that has an integrated web browser that opens a website that requires a certificate. In windows the certificate was installed from a provided .pfx file and a pass phrase.
When the browser calls the website, a pop up shows the installed certificates, user chose the right one if there is more than one and website opens.
With the following code, I get the website to open connect using my certificate.
private void Connect() throws NoSuchAlgorithmException, FileNotFoundException, KeyStoreException, IOException, CertificateException, UnrecoverableKeyException, KeyManagementException {
SSLContext ctx = SSLContext.getInstance("TLS");
KeyManager[] keyManagers;
KeyStore keyStore = KeyStore.getInstance("pkcs12");
FileInputStream keyStoreFile = new FileInputStream(new File("Certificate.pfx"));
String keyStorePassword = "password";
keyStore.load(keyStoreFile, keyStorePassword.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, keyStorePassword.toCharArray());
keyManagers = kmf.getKeyManagers();
ctx.init(keyManagers, null, new SecureRandom());
SSLSocketFactory sslSocketFactory = ctx.getSocketFactory();
URL url = new URL("https://example.com");
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setSSLSocketFactory(sslSocketFactory);
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
}
in.close();
}
How can I get this working in WebView control?
Thanks
I solved the issue after spending days researching.
Adding this lines of code before opening the website will make it work.
System.setProperty("javax.net.ssl.keyStore", "/path/to/certificate.pfx");
System.setProperty("javax.net.ssl.keyStorePassword","password");
Hope this help!
Here is an example of getting tokem using WSTrustChannelFactory. From here.
var stsBinding = new WS2007HttpBinding();
stsBinding.Security.Mode = SecurityMode.TransportWithMessageCredential;
stsBinding.Security.Message.EstablishSecurityContext = false;
stsBinding.Security.Message.NegotiateServiceCredential = false;
stsBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
WSTrustChannelFactory trustChannelFactory = new WSTrustChannelFactory(
stsBinding
, new EndpointAddress(tokenurl)
);
trustChannelFactory.TrustVersion = System.ServiceModel.Security.TrustVersion.WSTrust13;
X509Store myStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
myStore.Open(OpenFlags.ReadOnly);
X509Certificate2Collection coll = myStore.Certificates.Find(X509FindType.FindBySerialNumber, "MycertSerialNumber", true);
X509Certificate2 cert = coll[0];
trustChannelFactory.Credentials.ClientCertificate.Certificate = cert;
WSTrustChannel channel = (WSTrustChannel)trustChannelFactory.CreateChannel();
RequestSecurityToken rst = new RequestSecurityToken(RequestTypes.Issue, keyType);
rst.AppliesTo = new EndpointAddress(realm);
RequestSecurityTokenResponse rstr = null;
rst.TokenType = SecurityTokenTypes.Saml;
SecurityToken token = channel.Issue(rst, out rstr);
Now I don't have a username/password but the provider has given me certificate .pfx file.
How do I pass it to the WSTrushChannelFactory? I have tried using CertificateBinding but no success.
Updated Code above: 11/05/2014:
Getting this error: ID3242: The security token could not be authenticated or authorized.
Use the ClientCertificate property:
var stsBinding = new WS2007HttpBinding();
stsBinding.Security.Mode = SecurityMode.TransportWithMessageCredential;
stsBinding.Security.Message.EstablishSecurityContext = false;
stsBinding.Security.Message.NegotiateServiceCredential = false;
// select the authentication mode of Client Certificate
stsBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
var wifChannelFactory = new WSTrustChannelFactory(stsBinding, stsEndpoint);
wifChannelFactory.TrustVersion = TrustVersion.WSTrust13;
// Supply the credentials
wifChannelFactory.Credentials.ClientCertificate.Certificate = config.Certificate;
The PFX you can import to your certificate store via the certmgr.msc snapin. Make sure that the account your application is running as has access to the private key. You can reference it in the store using the x509certificate2 classes.
Here you go.
private static SecurityToken RequestSecurityToken()
{
// set up the ws-trust channel factory
var factory = new WSTrustChannelFactory(
new UserNameWSTrustBinding(
SecurityMode.TransportWithMessageCredential),
_idpAddress);
factory.TrustVersion = TrustVersion.WSTrust13;
var authCertificate = X509.LocalMachine.My.Thumbprint.Find(Properties.Settings.Default.RassCertificateThumbprint).FirstOrDefault();
if (authCertificate == null)
throw new InternalException(String.Format("No atuhentication certificate found in store with thumbprint {0}.", Properties.Settings.Default.ClientCertificateThumbprint));
// overenie je na zaklade certifikatu RASS
factory.Credentials.ClientCertificate.Certificate = authCertificate;
// create token request
var rst = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
KeyType = KeyTypes.Symmetric,
AppliesTo = new EndpointReference(_serviceAddress.AbsoluteUri)
};
// request token and return
return factory.CreateChannel().Issue(rst);
}
BTW: #Mitch is right about access to the private key. I just took your method and replaced few lines of code.
This is my scenario , i want to connect to ldap usign jndi , i am using custom SSLSOcketfactory which reads the truststore and keystore . The context is created successful but when i try to authenticate using the same credentials it throws an error telling that the authentication method is not supported.
here is my code of the custom ssl socket -
try {
StringBuffer trustStore = new StringBuffer("c:/Temp/certs/TrustStore");
StringBuffer keyStore = new StringBuffer("c:/Temp/certs/keystore.arun");
StringBuffer keyStorePass = new StringBuffer("xxxxx");
StringBuffer keyAlias = new StringBuffer("user");
StringBuffer keyPass = new StringBuffer("XXXX");
TrustManagerFactory tmf =TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
FileInputStream fis = new FileInputStream(trustStore.toString());
KeyStore ks1 = KeyStore.getInstance("jks");
ks1.load(fis, trustStorePass.toString().toCharArray());
fis.close();
tmf.init(ks1);
TrustManager[] tms = tmf.getTrustManagers();
FileInputStream fin = new FileInputStream(keyStore.toString());
KeyStore ks2 = KeyStore.getInstance("jks");
ks2.load(fin, keyStorePass.toString().toCharArray());
fin.close();
KeyManagerFactory kmf =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks2, keyStorePass.toString().toCharArray());
KeyManager[] kms = kmf.getKeyManagers();
if (keyAlias != null && keyAlias.length() > 0) {
for (int i = 0; i < kms.length; i++) {
// We can only deal with instances of X509KeyManager
if (kms[i] instanceof X509KeyManager)
kms[i] = new CustomKeyManager(
(X509KeyManager) kms[i], keyAlias.toString());
}
}
SSLContext context = SSLContext.getInstance("TLS");
context.init(kms,tms, null);
ssf = context.getSocketFactory();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static SocketFactory getDefault() {
return new CustomSSLSocketFactory();
}
And the jndi code which uses this CustomSSLSocketFactory is as follows
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldaps://wx64ads01a.vapps.esca.com:636");
env.put(Context.REFERRAL, "follow");
env.put("java.naming.ldap.derefAliases", "always");
env.put("java.naming.ldap.factory.socket","com.eterra.security.authz.dao.CustomSSLSocketFactory" );
try {
ctx = new InitialLdapContext(env, null);
// start ssl session for server authentication
}catch(Exception e ){
System.out.println(e);
}
try{
ctx.addToEnvironment(Context.SECURITY_AUTHENTICATION,
"EXTERNAL");
String path = "CN=domain,DC=casa,DC=com"
String inFilter = "(&(objectClass=*))";
SearchControls sc = new SearchControls();
sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration<SearchResult> results = null;
results = ctx.search(path, inFilter, sc);
}
My Context is created perfectly but when i try to authenticate and bind to the ldap , i get Invalid Authentication method . ANy help will be appreciated , Struggling with these error over a long time now . Thanks in advance .
Context.SECURITY_AUTHENTICATION, "EXTERNAL"
when i try to authenticate and bind to the ldap , i get Invalid Authentication method
So your LDAP server doesn't support EXTERNAL authentication.