public class LdapURLConnection
extends java.net.URLConnection
java.net.HttpURLConnection for connecting to a HTTP server, you
can use this LdapURLConnection class to connect to and search an
LDAP server. In its most simple case you only will have to create an
LdapURLConnection by calling method openConnection
on the LDAP URL object, set -- if required -- any request properties, and
finally call method getInputStream or
getContent for reading the search result:
// the ldap url
URL url = new URL("ldap://...");
// open connection
LdapURLConnection con = (LdapURLConnection)url.openConnection();
...
// set any request properties (if required)
...
// connect to the ldap server and read the result:
InputStream ldapIn = con.getInputStream();
From the input stream returned by calling getInputStream you now can read any certificate/crl objects returned as
result of the LDAP search. Alternatively you immediately may call method
getContent to return an array of
X509Certificate objects,
AttributeCertificate objects or
X509CRL objects, respectively, depending on which kind of
certificate/crl related information you have searched for, e.g. (when
searching for certificates):
// connect to the ldap server an read result
try {
// we have searched for certificates
X509Certificate[] certs = (X509Certificate[])con.getContent();
...
} catch (IOException ex) {
System.err.println("I/O error when reading ldap response: " + ex.toString());
}
However, since getContent reads all certificates into an array
it might be more appropriate to use method getInputStream and process any certificate indepently, especially when
expecting a large number of certificates as search result.
java.net URL framework. Regsitration can be performed in three
different ways:
java.protocol.handler.pkgs system property:
System.getProperties().put("java.protocol.handler.pkgs", "iaik.x509.net");
LdapURLStreamHandlerFactory for the IAIK LDAP URLStreamHandler:
URL.setURLStreamHandlerFactory(new LdapURLStreamHandlerFactory());
URLStreamHandler dynamically when creating an URL object,
e.g.:
URL u = new URL(null, "ldap://...", new iaik.x509.net.ldap.Handler());In this case the handler will be used for the one particular URL object only. Thus you may have to create all your ldap URLs in this way. Also note that you do not need to create a new Handler object each time, you can use the same for all URLs.
constructor, but this practice may not be
recommended since it bypasses the java.net URL framework in some
way:
URL url = new URL("ldap://...");
LdapURLConnection con = new LdapURLConnection(url);
...
LdapURLConnection object by calling
url.openConnection you can configure it by setting
connect and read
timeouts and specifying any of the following
request properties as required:
base dn: Specifies the distinguished name of the
entry that represents the search base (e.g. "c=at").
attributeDescription: Specifies the
attribute description to tell the server which attributes shall be returned
as search result (e.g. "caCertificate;binary" for
returning attributes that contain a DER encoded ca certificate).
scope: Specifies the search scope (
"base" for base object search (default),
"one" for one-level search, or
"sub" for subtree search).
filter: Specifies the search filter that shall be used
(e.g.: "(mail=Joe.TestUser@iaik.tugraz.at)"). By default the search filter is
built from the attributes to only search for entries that contain attributes
of the requested type.
sizeLimit: Specifies the maximum number of entries
of the search result (default: 0 for returning all entries).
security authentication method:
Specifies the method (e.g. "simple" or "DIGEST-MD5", default: "none") to be
used for authentication to the LDAP server.
security principal: Specifies the
principal identity (e.g. user name, DN) to be used for authentication to the
server, if required.
security credentials: Specifies the
credentials (e.g. a password) to be used for authenticating the user
(principal) to the LDAP server, if required.
Some of the request properties listed above (base dn, attribute description,
search scope, filter) also may be specified in the LDAP url according the
string format as specified by RFC 2255 (extensions are not supported and
therefore ignored unless they contain a critical extension, in which case an
exception is thrown when trying to create an LdapURLConnection
object):
ldapurl = scheme "://" [hostport] ["/"
[dn ["?" [attributes] ["?" [scope]
["?" [filter] ["?" extensions]]]]]]
For example, the following two program fragments would produce the same
search result:
// register ldap protocol handler
System.getProperties().put("java.protocol.handler.pkgs", "iaik.x509.net");
// all properties are given in the ldap url
String ldapurl = "ldap://demoldap.iaik.at/c=at?userCertificate;binary?sub?(cn=Joe%20TestUser)";
URL url = new URL(ldapurl);
LdapURLConnection con = (LdapURLConnection)url.openConnection();
// connect to the ldap server an read result
InputStream ldapIn = null;
// we have searched for certificates
try {
ldapIn = con.getInputStream();
// do until we get an EOF
while (true) {
// parse next certificate from stream
try {
X509Certificate cert = new X509Certificate(ldapIn);
...
} catch (CertificateException ex) {
System.err.println("Error parsing certificate: " + ex.toString());
}
}
} catch (EOFException ex) {
// ignore; finished
} catch (IOException ex) {
System.err.println("I/O error when reading ldap response: " + ex.toString());
} finally {
// close ldap input stream to disconnect from server
if (ldapIn != null) {
try {
ldapIn.close();
} catch (IOException ex) {
// ignore
}
}
}
is equivalent to (now all properties are specified as request properties):
// register ldap protocol handler
System.getProperties().put("java.protocol.handler.pkgs", "iaik.x509.net");
// all properties are set as request properties
String ldapurl = "ldap://demoldap.iaik.at/";
URL url = new URL(ldapurl);
LdapURLConnection con = (LdapURLConnection)url.openConnection();
// base dn
con.setRequestProperty(LdapURLConnection.RP_BASE_DN, "c=at");
// search for end enity certificates
con.setRequestProperty(LdapURLConnection.RP_ATTRIBUTE_DESCRIPTION,
LdapURLConnection.AD_USER_CERTIFICATE);
// search subtree
con.setRequestProperty(LdapURLConnection.RP_SEARCH_SCOPE,
LdapURLConnection.SEARCH_SCOPE_SUBTREE);
// set filter
con.setRequestProperty(LdapURLConnection.RP_FILTER,
"(cn=Joe TestUser)");
// connect to the ldap server an read result
InputStream ldapIn = null;
// we have searched for certificates
try {
ldapIn = con.getInputStream();
// do until we get an EOF
while (true) {
// parse next certificate from stream
try {
X509Certificate cert = new X509Certificate(ldapIn);
...
} catch (CertificateException ex) {
System.err.println("Error parsing certificate: " + ex.toString());
}
}
} catch (EOFException ex) {
// ignore; finished
} catch (IOException ex) {
System.err.println("I/O error when reading ldap response: " + ex.toString());
} finally {
// close ldap input stream to disconnect from server
if (ldapIn != null) {
try {
ldapIn.close();
} catch (IOException ex) {
// ignore
}
}
}
If some property is contained in the url, but also specified as request
property, the request property value is used. request property. In both
examples we get the same result: all end entity certificates that have been
issued to Joe TestUser in Austria available on the ldap server we are
contacting.
Whereas it might be a usual practice to search an ldap server (or a subtree
of an ldap server) for all certificates that match to a given property (e.g.
cn or email address), you usually may query for one single crl when searching
for a certificate revocation list, e.g. given in the
distribution point of the
CRLDistributionPoints
extension of a X.509 certificate, e.g.:
// register ldap protocol handler
System.getProperties().put("java.protocol.handler.pkgs", "iaik.x509.net");
// server url to which to connect to
URL url = new URL("ldap://ldap.demo.com/cn=demoCa,o=demoOrg,c=at?certificateRevocationList;binary");
LdapURLConnection con = (LdapURLConnection)url.openConnection();
// connect to the ldap server an read result
InputStream ldapIn = null;
// we have searched for a crl
try {
ldapIn = con.getInputStream();
// we only expect one crl
X509CRL crl = new X509CRL(ldapIn);
...
} catch (CRLException ex) {
System.err.println("Error parsing crl: " + ex.toString());
} catch (IOException ex) {
System.err.println("I/O error when reading ldap response: " + ex.toString());
} finally {
// close ldap input stream to disconnect from server
if (ldapIn != null) {
try {
ldapIn.close();
} catch (IOException ex) {
// ignore
}
}
}
If you expect a large crl you may use the stream based
crl implementation of IAIK-JCE for
parsing the revocation list. You also may use method getContent to load the requested CRL (however it might be more appropriate
to use method getInputStream, especially if you intend to load
more than only one CRL).
java.net.URLConnection class. For instance, you may not call
method setUseCaches since caching is not supported, or trying to
call setDoOutput or getOutputStream will give no
result since writing to an output stream is not supported. However, typically
you will need to call only the methods as shown in the examples above.
Also note that this LdapURLConnection is only designed for being used to search ldap dirctories, but not for adding entries to a directory or for modifying or removing entries. Furthermore you only can search for certificate, attribute certificate, or crl entries. Only attribute descriptions for these kind of attribute types are supported. The attribute description list has to contain only attributes that are "compatible" to each other. The attributes supported by this implementation can be separated into three groups, each of them containing attribute descriptions that are compatible to each other:
Thus, for instance, "caCertificate;binary" is compatible to "userCertificate;binary", but not to "certificateRevocationList;binary" (this implementation only allows you to search for either certificates or certificate revocation lists, but not for certificates and certificate revocation lists within the same search request).
demo.x509.net.ldap of this library contains a
simple certificate/crl searching example (SimpleLdapSearch), and
some simple command line tools for searching for certificates (
SimpleLdapSearch), attribute certificates (
LdapAttributeCertSearch) or certificate revocation lists (
LdapCrlSearch), respectively.URL,
URLConnection,
X509Certificate,
AttributeCertificate,
X509CRL,
X509CRLStream,
Handler,
LdapURLStreamHandlerFactory| Modifier and Type | Field and Description |
|---|---|
static java.lang.String |
AD_ATTRIBUTE_CERTIFICATE
Attribute description "attributeCertificate;binary".
|
static java.lang.String |
AD_AUTHORITY_REVOCATION_LIST
Attribute description "authorityRevocationList;binary".
|
static java.lang.String |
AD_CA_CERTIFICATE
Attribute description "caCertificate;binary".
|
static java.lang.String |
AD_CERTIFICATE
Attribute description "caCertificate;binary,userCertificate;binary".
|
static java.lang.String |
AD_CERTIFICATE_REVOCATION_LIST
Attribute description "certificateRevocationList;binary".
|
static java.lang.String |
AD_DELTA_REVOCATION_LIST
Attribute description "deltaRevocationList;binary".
|
static java.lang.String |
AD_REVOCATION_LIST
Attribute description
"authorityRevocationList;binary,certificateRevocationList;binary".
|
static java.lang.String |
AD_USER_CERTIFICATE
Attribute description "userCertificate;binary".
|
static java.lang.String |
RP_ATTRIBUTE_DESCRIPTION
Request property key "attributeDescription".
|
static java.lang.String |
RP_BASE_DN
Request property key distinguished name base "dn".
|
static java.lang.String |
RP_EXTENSIONS
Request property key "extensions".
|
static java.lang.String |
RP_FILTER
Request property key search "filter".
|
static java.lang.String |
RP_SEARCH_SCOPE
Request property key search "scope".
|
static java.lang.String |
RP_SECURITY_AUTHENTICATION
Request property key "securityAuthentication".
|
static java.lang.String |
RP_SECURITY_CREDENTIALS
Request property key "securityCredentials".
|
static java.lang.String |
RP_SECURITY_PRINCIPAL
Request property key "securityPrincipal".
|
static java.lang.String |
RP_SIZE_LIMIT
Request property key search "sizeLimit".
|
static java.lang.String |
SEARCH_SCOPE_BASE
Search scope "base" for a base object serach.
|
static java.lang.String |
SEARCH_SCOPE_ONELEVEL
Search scope "one" for a one-level search.
|
static java.lang.String |
SEARCH_SCOPE_SUBTREE
Search scope "sub" for a sub-tree search.
|
| Constructor and Description |
|---|
LdapURLConnection(java.net.URL url)
Creates a new LdapURLConnection for the specified url.
|
| Modifier and Type | Method and Description |
|---|---|
static void |
addConnectTimeoutEnvPropKey(java.lang.String key)
Registers the given connect timeout environment property key.
|
void |
addRequestProperty(java.lang.String key,
java.lang.String value)
Adds the given request property.
|
void |
connect()
Opens a connection to the LDAP server at the url used by this
LdapURLConnection.
|
void |
disconnect()
Disconnects from the server.
|
int |
getConnectTimeout()
Gets the value of the connect timeout.
|
java.lang.Object |
getContent()
Gets the content from this LDAP URL connection.
|
static int |
getDefaultConnectTimeout()
Gets the default connect timeout that is used.
|
static int |
getDefaultReadTimeOut()
Gets the default read timeout (search time limit) that is used.
|
java.lang.String |
getHeaderField(java.lang.String name)
Returns the value header field with the given name.
|
java.io.InputStream |
getInputStream()
Gets an input stream from which to read any certificates/crls retrieved
from the server as result of the search request.
|
int |
getReadTimeout()
Gets the read timeout (search time limit) that is used.
|
java.lang.String |
getRequestProperty(java.lang.String key)
Returns the value of the requested request property.
|
void |
setAllowUserInteraction(boolean allowuserinteraction)
Set the value of the
allowUserInteraction field; ignored. |
void |
setConnectTimeout(int timeout)
Sets the connect timeout to be used.
|
static void |
setDefaultConnectTimeout(int timeout)
Sets the default connect timeout to be used.
|
static void |
setDefaultReadTimeOut(int timeout)
Sets the default read timeout (search time limit) to be used.
|
void |
setDoInput(boolean doinput)
Sets the value of the
doInput field; ignored. |
void |
setDoOutput(boolean dooutput)
Sets the value of the
doOutput field; ignored. |
void |
setIfModifiedSince(long ifmodifiedsince)
Set the value of the
ifmodifiedsince field; ignored. |
void |
setReadTimeout(int timeout)
Sets the read timeout (search time limit) to be used.
|
void |
setRequestProperty(java.lang.String key,
java.lang.String value)
Sets the request property identified by the given key to the given value.
|
void |
setUseCaches(boolean usecaches)
Set the value of the
usecaches field; ignored. |
java.lang.String |
toString()
Returns a
String representation of this LdapURLConnection
object. |
protected java.lang.String |
unescape(java.lang.String escaped)
Unescapes any percent encoded octets.
|
getAllowUserInteraction, getContent, getContentEncoding, getContentLength, getContentLengthLong, getContentType, getDate, getDefaultAllowUserInteraction, getDefaultRequestProperty, getDefaultUseCaches, getDoInput, getDoOutput, getExpiration, getFileNameMap, getHeaderField, getHeaderFieldDate, getHeaderFieldInt, getHeaderFieldKey, getHeaderFieldLong, getHeaderFields, getIfModifiedSince, getLastModified, getOutputStream, getPermission, getRequestProperties, getURL, getUseCaches, guessContentTypeFromName, guessContentTypeFromStream, setContentHandlerFactory, setDefaultAllowUserInteraction, setDefaultRequestProperty, setDefaultUseCaches, setFileNameMappublic static final java.lang.String SEARCH_SCOPE_BASE
set as search scope request property (or specified in the url string), only the
base object is searched for the requested attributes:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty(LdapURLConnection.RP_SEARCH_SCOPE,
LdapURLConnection.SEARCH_SCOPE_BASE);
is equivalent to:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty("scope",
"base");
public static final java.lang.String SEARCH_SCOPE_ONELEVEL
set as search scope request property (or specified in the url string), only the
immediate child entries of the object are searched for the requested
attributes:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty(LdapURLConnection.RP_SEARCH_SCOPE,
LdapURLConnection.SEARCH_SCOPE_ONELEVEL);
is equivalent to:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty("scope",
"one");
public static final java.lang.String SEARCH_SCOPE_SUBTREE
set as search scope request property (or specified in the url string), the whole
subtree (including the base object) is searched for the requested
attributes:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty(LdapURLConnection.RP_SEARCH_SCOPE,
LdapURLConnection.SEARCH_SCOPE_SUBTREE);
is equivalent to:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty("scope",
"sub");
public static final java.lang.String AD_CA_CERTIFICATE
set as
attribute description request property
(or specified in the url string), the ldap server is instructed to return
attributes containing DER encoded CA certificates:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty(LdapURLConnection.RP_ATTRIBUTE_DESCRIPTION,
LdapURLConnection.AD_CA_CERTIFICATE);
is equivalent to:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty("attributeDescription",
"caCertificate;binary");
public static final java.lang.String AD_USER_CERTIFICATE
set as
attribute description request property
(or specified in the url string), the ldap server is instructed to return
attributes containing DER encoded end entity certificates:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty(LdapURLConnection.RP_ATTRIBUTE_DESCRIPTION,
LdapURLConnection.AD_USER_CERTIFICATE);
is equivalent to:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty("attributeDescription",
"userCertificate;binary");
public static final java.lang.String AD_CERTIFICATE
set as
attribute description request property
(or specified in the url string), the ldap server is instructed to return
attributes containing DER encoded end entity or ca certificates:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty(LdapURLConnection.RP_ATTRIBUTE_DESCRIPTION,
LdapURLConnection.AD_CERTIFICATE);
is equivalent to:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty("attributeDescription",
"caCertificate;binary,userCertificate;binary");
public static final java.lang.String AD_ATTRIBUTE_CERTIFICATE
set as
attribute description request property
(or specified in the url string), the ldap server is instructed to return
attributes containing DER encoded attribute certificates:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty(LdapURLConnection.RP_ATTRIBUTE_DESCRIPTION,
LdapURLConnection.AD_ATTRIBUTE_CERTIFICATE);
is equivalent to:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty("attributeDescription",
"attributeCertificate;binary");
public static final java.lang.String AD_CERTIFICATE_REVOCATION_LIST
set as
attribute description request property
(or specified in the url string), the ldap server is instructed to return
attributes containing DER encoded certificate revocation lists:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty(LdapURLConnection.RP_ATTRIBUTE_DESCRIPTION,
LdapURLConnection.AD_CERTIFICATE_REVOCATION_LIST);
is equivalent to:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty("attributeDescription",
"certificateRevocationList;binary");
public static final java.lang.String AD_AUTHORITY_REVOCATION_LIST
set as
attribute description request property
(or specified in the url string), the ldap server is instructed to return
attributes containing DER encoded authority revocation lists:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty(LdapURLConnection.RP_ATTRIBUTE_DESCRIPTION,
LdapURLConnection.AD_AUTHORITY_REVOCATION_LIST);
is equivalent to:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty("attributeDescription",
"authorityRevocationList;binary");
public static final java.lang.String AD_REVOCATION_LIST
set as
attribute description request property
(or specified in the url string), the ldap server is instructed to return
attributes containing DER encoded authority or certificate revocation
lists:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty(LdapURLConnection.RP_ATTRIBUTE_DESCRIPTION,
LdapURLConnection.AD_REVOCATION_LIST);
is equivalent to:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty("attributeDescription",
"authorityRevocationList;binary,certificateRevocationList;binary");
public static final java.lang.String AD_DELTA_REVOCATION_LIST
set as
attribute description request property
(or specified in the url string), the ldap server is instructed to return
attributes containing DER encoded delta revocation lists:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty(LdapURLConnection.RP_ATTRIBUTE_DESCRIPTION,
LdapURLConnection.AD_DELTA_REVOCATION_LIST);
is equivalent to:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty("attributeDescription",
"deltaRevocationList;binary");
public static final java.lang.String RP_BASE_DN
search scope only the base object itself is
searched (base search), or its immediate child
entries are searched (one level search), or the
whole subtree including the base object is searched (
sub tree search). set as request property, e.g:
URL url = ...; LdapURLConnection con = (LdapURLConnection)url.openConnection(); con.setRequestProperty(LdapURLConnection.RP_BASE_DN, "c=at");which is equivalent to:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty("dn", "c=at");
If a base dn is specified in the url and is also set as request property,
the request property dn is used.public static final java.lang.String RP_SEARCH_SCOPE
"base" for base object search (default),
"one" for one-level search, or
"sub" for subtree search. If "base" search is
enabled only the base object itself is searched. If "one" level search is
enabled only the immediate child entries of the base object are searched.
if "sub" tree search is enabled the whole subtree including the base object
is searched. set as request property, e.g:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty(LdapURLConnection.RP_SEARCH_SCOPE,
LdapURLConnection.SEARCH_SCOPE_SUB);
which is equivalent to:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty("scope", "sub");
If a scope is specified in the url and is also set as request property, the
request property scope is used.public static final java.lang.String RP_SIZE_LIMIT
URL url = ...; LdapURLConnection con = (LdapURLConnection)url.openConnection(); con.setRequestProperty(LdapURLConnection.RP_SIZE_LIMIT, 2);
public static final java.lang.String RP_FILTER
set as request
property, e.g:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty(LdapURLConnection.RP_FILTER,
"(mail=John.TestUser@iaik.tugraz.at)");
which is equivalent to:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty("filter", "(mail=John.TestUser@iaik.tugraz.at)");
If a filter is specified in the url and is also set as request property,
the request property filter is used.
If no filter is explicitly specified by url or by request property, the
search filter is built from the attributes to only search for entries that
contain attributes of the requested type. For instance, if searching for
end entity certificates with an attribute
description of "userCertificate;binary", the
search filter is set to (userCertificate;binary=*). This will
tell the server to only search for entries that contain a
userCertificate;binary attribute. Or if searching for ca and
end entity certificates with an attribute
description of "caCertificate;binary,userCertificate;binary", the search filter is set to
(|(caCertificate;binary=*)(userCertificate;binary=*)). This
will tell the server to only search for entries that contain a
caCertificate;binary or userCertificate;binary
attribute.
public static final java.lang.String RP_ATTRIBUTE_DESCRIPTION
"caCertificate;binary" for
returning attributes that contain a DER encoded ca certificate). set as request property, e.g:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty(LdapURLConnection.RP_ATTRIBUTE_DESCRIPTION,
LdapURLConnection.AD_USER_CERTIFICATE);
which is equivalent to:
URL url = ...;
LdapURLConnection con = (LdapURLConnection)url.openConnection();
con.setRequestProperty("attributeDescription", "userCertificate;binary");
If an attribute description is specified in the url and is also set as
request property, the request property attribute description is used.
However, when using method addRequestProperty additional attributes can be specified to those already
given in the url or set as request property. For instance
URL url = new URL("ldap://demoldap.iaik.at/c=at?caCertificate;binary");
LdapURLConnection con = (LdapURLConnection) url.openConnection();
con.addRequestProperty(LdapURLConnection.RP_ATTRIBUTE_DESCRIPTION,
LdapURLConnection.AD_USER_CERTIFICATE);
will give the attribute description
"caCertificate;binary,userCertificate;binary" to search for both ca and end
entity certificates. Note that any attribute that shall be added by calling
addRequestProperty has to be
compatible with any attribute that already has been set. For instance, it
is not possible to add a revocation list related attribute (e.g.
"certificateRevocationList;binary") to a certificate related attribute
(e.g. "userCertificate;binary").
The following attribute descriptions are supported by this LdapURLConnection implementation (any other certificate/crl related attribute description may be allowed, too):
"caCertificate;binary" to return attributes
containing DER encoded ca certificates
"userCertificate;binary" to return
attributes containing DER encoded end entity certificates
"caCertificate;binary,userCertificate;binary"
to return attributes containing DER encoded ca or end entity certificates
"attributeCertificate;binary" to
return attributes containing DER encoded attribute certificates
"certificateRevocationList;binary" to return attributes containing DER
encoded certificate revocation lists
"authorityRevocationList;binary"
to return attributes containing DER encoded authority revocation lists
"authorityRevocationList;binary,certificateRevocationList;binary" to
return attributes containing DER encoded certificate or authority
revocation lists
"deltaRevocationList;binary" to
return attributes containing DER encoded delta revocation lists
The final attribute description list has to contain only attributes that are "compatible" to each other. The attributes supported by this implementation can be separated into three groups, each of them containing attribute descriptions that are compatible to each other:
Thus, for instance, "caCertificate;binary" is compatible to "userCertificate;binary", but not to "certificateRevocationList;binary" (this implementation only allows you to search for either certificates or certificate revocation lists, but not for certificates and certificate revocation lists within the same search request).
public static final java.lang.String RP_EXTENSIONS
getRequestProperty:
String extension = con.getRequestProperty(LdapURLConnection.RP_EXTENSIONS);
public static final java.lang.String RP_SECURITY_AUTHENTICATION
public static final java.lang.String RP_SECURITY_PRINCIPAL
authentication method
is not "none".public static final java.lang.String RP_SECURITY_CREDENTIALS
authentication method is not
"none".public LdapURLConnection(java.net.URL url)
throws java.io.IOException
url.openConnection to create an LdapURLConnection object for
connecting to the requested server url:
URL url = ...; LdapURLConnection con = (LdapURLConnection)url.openConnection(); ... // configure LdapURLConnection, if required ... con.connect(); ...Of course, before using
url.openConnection it is necessary to
register the IAIK LDAP protocol handler, e.g.:
System.getProperties().put("java.protocol.handler.pkgs", "iaik.x509.net");
The string representation of the url is specified by RFC 2255:
ldapurl = scheme "://" [hostport] ["/"
[dn ["?" [attributes] ["?" [scope]
["?" [filter] ["?" extensions]]]]]]
For example:
ldapurl = "ldap://demoldap.iaik.at/c=at?userCertificate;binary?sub?(cn=John%20TestUser)Extensions are not supported and ignored unless they contain a critical extension (in which case an exception is thrown).
url - the url of the ldap server to which to connect tojava.io.IOException - if the given url is invalid or contains an unsupported critical
extensionpublic static void setDefaultConnectTimeout(int timeout)
Attention: setting the connection timeout may only work with the
LDAP ContextFactory of the SUN service provider
(com.sun.jndi.ldap.LdapCtxFactory) where the connection timeout value can
be specified via the "com.sun.jndi.ldap.connect.timeout" environment
property key. You may use method
addConnectTimeoutEnvPropKey to
register additional connect timeout environment keys (to be used with the
ContextFactories of some other service providers).
timeout - the default connect timeout to be used (in milliseconds)public static int getDefaultConnectTimeout()
Attention: setting the connection timeout may only work with the
LDAP ContextFactory of the SUN service provider
(com.sun.jndi.ldap.LdapCtxFactory) where the connection timeout value can
be specified via the "com.sun.jndi.ldap.connect.timeout" environment
property key. You may use method
addConnectTimeoutEnvPropKey to
register additional connect timeout environment keys (to be used with the
ContextFactories of some other service providers).
public static void addConnectTimeoutEnvPropKey(java.lang.String key)
setDefaultConnectTimeout or setConnectTimeout. However, setting the connection timeout may only work
with the LDAP ContextFactory of the SUN service provider
(com.sun.jndi.ldap.LdapCtxFactory) where the connection timeout value can
be specified via the "com.sun.jndi.ldap.connect.timeout" environment
property key. You may use this addConnectTimeoutEnvPropKey
addConnectTimeoutEnvPropKey} to register additional connect timeout
environment keys (to be used with the ContextFactories of some other
service providers).key - the connection timeout environment property keypublic static void setDefaultReadTimeOut(int timeout)
timeout - the default read timeout to be used (in milliseconds)java.lang.IllegalArgumentException - if the given timeout value is < 0public static int getDefaultReadTimeOut()
public void connect()
throws java.io.IOException
disconnect,
or by closing the LDAP input stream retrieved by having called method
getInputStream(). If you have used method
getContent() for reading certificates/crls sent by
the server, the connection is automatically closed after having parsed all
available certificate/crls.connect in class java.net.URLConnectionjava.io.IOException - if an error occurs when connecting to the serverpublic void disconnect()
public java.io.InputStream getInputStream()
throws java.io.IOException
// register ldap protocol handler
System.getProperties().put("java.protocol.handler.pkgs", "iaik.x509.net");
// server url to which to connect to
URL url = new URL("ldap://demoldap.iaik.at/c=at");
LdapURLConnection con = (LdapURLConnection)url.openConnection();
// search for end enity certificates
con.setRequestProperty(LdapURLConnection.RP_ATTRIBUTE_DESCRIPTION,
LdapURLConnection.AD_USER_CERTIFICATE);
// search subtree
con.setRequestProperty(LdapURLConnection.RP_SEARCH_SCOPE,
LdapURLConnection.SEARCH_SCOPE_SUBTREE);
// set filter
con.setRequestProperty(LdapURLConnection.RP_FILTER,
"(mail=John.TestUser@iaik.tugraz.at)");
// connect to the ldap server an read result
InputStream ldapIn = null;
// we have searched for certificates
try {
ldapIn = con.getInputStream();
// do until we get an EOF
while (true) {
// parse next certificate from stream
try {
X509Certificate cert = new X509Certificate(ldapIn);
...
} catch (CertificateException ex) {
System.err.println("Error parsing certificate: " + ex.toString());
}
}
} catch (EOFException ex) {
// ignore; finished
} catch (IOException ex) {
System.err.println("I/O error when reading ldap response: " + ex.toString());
} finally {
// close ldap input stream to disconnect from server
if (ldapIn != null) {
try {
ldapIn.close();
} catch (IOException ex) {
// ignore
}
}
}
Whereas it might be a usual practice to search an ldap server (or a subtree
of an ldap server) for all certificates that match to a given property
(e.g. cn or email address), you usually may query for one single crl when
searching for a certificate revocation list, e.g. given in the
distribution point of the
CRLDistributionPoints
extension of a X.509 certificate, e.g.:
// register ldap protocol handler
System.getProperties().put("java.protocol.handler.pkgs", "iaik.x509.net");
// server url to which to connect to
URL url = new URL("ldap://ldap.demo.com/cn=demoCa,o=demoOrg,c=at?certificateRevocationList;binary");
LdapURLConnection con = (LdapURLConnection)url.openConnection();
// connect to the ldap server an read result
InputStream ldapIn = null;
// we have searched for a crl
try {
ldapIn = con.getInputStream();
// we only expect one crl
X509CRL crl = new X509CRL(ldapIn);
...
} catch (CRLException ex) {
System.err.println("Error parsing crl: " + ex.toString());
} catch (IOException ex) {
System.err.println("I/O error when reading ldap response: " + ex.toString());
} finally {
// close ldap input stream to disconnect from server
if (ldapIn != null) {
try {
ldapIn.close();
} catch (IOException ex) {
// ignore
}
}
}
If you expect a large crl you may use the stream based
crl implementation of IAIK-JCE for
parsing the revocation list.getInputStream in class java.net.URLConnectionjava.io.IOException - if an I/O error occurs while reading from the streampublic java.lang.Object getContent()
throws java.io.IOException
X509Certificate objects or
AttributeCertificate objects or
X509CRL objects, respectively. After having read all
certificate(s)/crl(s) from the stream this method disconnects automatically
from the server:
// register ldap protocol handler
System.getProperties().put("java.protocol.handler.pkgs", "iaik.x509.net");
// server url to which to connect to
URL url = new URL("ldap://demoldap.iaik.at/c=at");
LdapURLConnection con = (LdapURLConnection)url.openConnection();
// search for end enity certificates
con.setRequestProperty(LdapURLConnection.RP_ATTRIBUTE_DESCRIPTION,
LdapURLConnection.AD_USER_CERTIFICATE);
// search subtree
con.setRequestProperty(LdapURLConnection.RP_SEARCH_SCOPE,
LdapURLConnection.SEARCH_SCOPE_SUBTREE);
// set filter
con.setRequestProperty(LdapURLConnection.RP_FILTER,
"(mail=John.TestUser@iaik.tugraz.at)");
// connect to the ldap server an read result
try {
// we have searched for certificates
X509Certificate[] certs = (X509Certificate[])con.getContent();
...
} catch (IOException ex) {
System.err.println("I/O error when reading ldap response: " + ex.toString());
}
Whereas it might be a usual practice to search an ldap server (or a subtree
of an ldap server) for all certificates that match to a given property
(e.g. cn or email address), you usually may query for one single crl when
searching for a certificate revocation list, e.g. given in the
distribution point of the
CRLDistributionPoints
extension of a X.509 certificate, e.g.:
// register ldap protocol handler
System.getProperties().put("java.protocol.handler.pkgs", "iaik.x509.net");
// server url to which to connect to
URL url = new URL("ldap://ldap.demo.com/cn=demoCa,o=demoOrg,c=at?certificateRevocationList;binary");
LdapURLConnection con = (LdapURLConnection)url.openConnection();
// connect to the ldap server an read result
try {
// we have searched for a crl
X509CRL[] crls = (X509CRL[])con.getContent();
...
} catch (IOException ex) {
System.err.println("I/O error when reading ldap response: " + ex.toString());
} finally {
// close ldap input stream to disconnect from server
if (ldapIn != null) {
try {
ldapIn.close();
} catch (IOException ex) {
// ignore
}
}
}
Note that, since this method parses all certificate(s)/crl(s) received from
the ldap server, it might take some certain time until you can access the
array returned by this method. For that reason -- and for avoiding memory
problems -- it might be more appropriate to use method
getInputStream() and process the
certificate(s)/crl(s) independently if you, for instance, expect a large
number of certificates as search result.getContent in class java.net.URLConnectionX509Certificate
objects or AttributeCertificate objects or
X509CRL objects depending if you have searched
for certificates, attribute certificates, or CRLs; the array maybe
empty if the search has not returned any certificates/crlsjava.io.IOException - if an error occurs while reading the certificate(s)/crl(s)
from the streamprotected java.lang.String unescape(java.lang.String escaped)
throws java.io.IOException
escaped - the escaped stringjava.io.IOException - if the given string is invalid escapedpublic void setRequestProperty(java.lang.String key,
java.lang.String value)
null the property is
reset to its default value.
base dn: Specifies the distinguished name of the
entry that represents the search base (e.g. "c=at").
attributeDescription: Specifies the
attribute description to tell the server which attributes shall be returned
as search result (e.g. "caCertificate;binary"
for returning attributes that contain a DER encoded ca certificate).
scope: Specifies the search scope (
"base" for base object search (default),
"one" for one-level search, or
"sub" for subtree search).
filter: Specifies the search filter that shall be
used (e.g.: "(mail=Joe.TestUser@iaik.tugraz.at)"). By default the search
filter is built from the attributes to only search for entries that contain
attributes of the requested type.
sizeLimit: Specifies the maximum number of
entries of the search result (default: 0 for returning all entries).
security authentication method:
Specifies the method (e.g. "simple" or "DIGEST-MD5", default: "none") to be
used for authentication to the LDAP server.
security principal: Specifies the
principal identity (e.g. user name, DN) to be used for authentication to
the server, if required.
security credentials: Specifies the
credentials (e.g. a password) to be used for authenticating the user
(principal) to the LDAP server, if required.
Some of the request properties listed above (base dn, attribute description, search scope, filter) also may be specified in the LDAP url according the string format as specified by RFC 2255:
ldapurl = scheme "://" [hostport] ["/"
[dn ["?" [attributes] ["?" [scope]
["?" [filter] ["?" extensions]]]]]]
For example, the following two program fragments would produce the same
search result:
// register ldap protocol handler
System.getProperties().put("java.protocol.handler.pkgs", "iaik.x509.net");
// all properties are given in the ldap url
String ldapurl = "ldap://demoldap.iaik.at/c=at?userCertificate;binary?sub?(cn=Joe%20TestUser)";
URL url = new URL(ldapurl);
LdapURLConnection con = (LdapURLConnection)url.openConnection();
// connect to the ldap server an read result
InputStream ldapIn = null;
// we have searched for certificates
try {
ldapIn = con.getInputStream();
// do until we get an EOF
while (true) {
// parse next certificate from stream
try {
X509Certificate cert = new X509Certificate(ldapIn);
...
} catch (CertificateException ex) {
System.err.println("Error parsing certificate: " + ex.toString());
}
}
} catch (EOFException ex) {
// ignore; finished
} catch (IOException ex) {
System.err.println("I/O error when reading ldap response: " + ex.toString());
} finally {
// close ldap input stream to disconnect from server
if (ldapIn != null) {
try {
ldapIn.close();
} catch (IOException ex) {
// ignore
}
}
}
is equivalent to (now all properties are specified as request properties):
// register ldap protocol handler
System.getProperties().put("java.protocol.handler.pkgs", "iaik.x509.net");
// all properties are set as request properties
String ldapurl = "ldap://demoldap.iaik.at/";
URL url = new URL(ldapurl);
LdapURLConnection con = (LdapURLConnection)url.openConnection();
// base dn
con.setRequestProperty(LdapURLConnection.RP_BASE_DN, "c=at");
// search for end enity certificates
con.setRequestProperty(LdapURLConnection.RP_ATTRIBUTE_DESCRIPTION,
LdapURLConnection.AD_USER_CERTIFICATE);
// search subtree
con.setRequestProperty(LdapURLConnection.RP_SEARCH_SCOPE,
LdapURLConnection.SEARCH_SCOPE_SUBTREE);
// set filter
con.setRequestProperty(LdapURLConnection.RP_FILTER,
"(cn=Joe TestUser)");
// connect to the ldap server an read result
InputStream ldapIn = null;
// we have searched for certificates
try {
ldapIn = con.getInputStream();
// do until we get an EOF
while (true) {
// parse next certificate from stream
try {
X509Certificate cert = new X509Certificate(ldapIn);
...
} catch (CertificateException ex) {
System.err.println("Error parsing certificate: " + ex.toString());
}
}
} catch (EOFException ex) {
// ignore; finished
} catch (IOException ex) {
System.err.println("I/O error when reading ldap response: " + ex.toString());
} finally {
// close ldap input stream to disconnect from server
if (ldapIn != null) {
try {
ldapIn.close();
} catch (IOException ex) {
// ignore
}
}
}
If some property is contained in the url, but also specified as request
property, the request property value is used.setRequestProperty in class java.net.URLConnectionkey - the key identifying the request property (e.g.
"scope")value - the new value of the request property (e.g.
"sub")java.lang.IllegalStateException - if the connection to the server has been already establishedjava.lang.NullPointerException - if the given key is nulljava.lang.IllegalArgumentException - if the given value does not represent a valid property (e.g.
not "base",
"one", or
"sub" for the
"scope" propertypublic java.lang.String getRequestProperty(java.lang.String key)
setRequestProperty for
information about the properties that are supported by this
LdapURLConnection class.getRequestProperty in class java.net.URLConnectionkey - the request property key (e.g. "scope""sub"), or null if the given key is null or the
requested request property is not setsetRequestProperty(java.lang.String, java.lang.String)public void addRequestProperty(java.lang.String key,
java.lang.String value)
attributeDescription can be added to any
already existing (attribute description) properties. Calling this method
for any other type of request property will not add, but set the given
request property by forwarding the call to method
setRequestProperty.
When adding an attribute description request property it has to be compatible with any attribute that already has been set. For instance
URL url = new URL("ldap://demoldap.iaik.at/c=at?caCertificate;binary");
LdapURLConnection con = (LdapURLConnection) url.openConnection();
con.addRequestProperty(LdapURLConnection.RP_ATTRIBUTE_DESCRIPTION,
LdapURLConnection.AD_USER_CERTIFICATE);
will give the attribute description
"caCertificate;binary,userCertificate;binary" to search for both ca and end
entity certificates.
The final attribute description list has to contain only attributes that are "compatible" to each other. The attributes supported by this implementation can be separated into three groups, each of them containing attribute descriptions that are compatible to each other:
Thus, for instance, "caCertificate;binary" is compatible to "userCertificate;binary", but not to "certificateRevocationList;binary" (this implementation only allows you to search for either certificates or certificate revocation lists, but not for certificates and certificate revocation lists within the same search request).
addRequestProperty in class java.net.URLConnectionkey - the key identifying the request property (e.g.
"attributeDescription")value - the new value of the request property (e.g.
"userCertificate;binary")java.lang.IllegalStateException - if the connection to the server has been already establishedjava.lang.NullPointerException - if the given key is nulljava.lang.IllegalArgumentException - if the given value does not represent a valid property (e.g.
not a certificate or crl related attribute description)public void setConnectTimeout(int timeout)
Attention: setting the connection timeout may only work with the
LDAP ContextFactory of the SUN service provider
(com.sun.jndi.ldap.LdapCtxFactory) where the connection timeout value can
be specified via the "com.sun.jndi.ldap.connect.timeout" environment
property key. You may use method
addConnectTimeoutEnvPropKey to
register additional connect timeout environment keys (to be used with the
ContextFactories of some other service providers).
setConnectTimeout in class java.net.URLConnectiontimeout - the connect timeout to be used (in milliseconds); default: -1 (not
specified)public int getConnectTimeout()
A value of 0 indicates an indefinite connect timeout. A value of -1 indicates that the connect timeout is not specified and System defaults (network, TCP timeout value) shall be used.
Attention: the connection timeout may only work with the LDAP
ContextFactory of the SUN service provider
(com.sun.jndi.ldap.LdapCtxFactory) where the connection timeout value can
be specified via the "com.sun.jndi.ldap.connect.timeout" environment
property key. You may use method
addConnectTimeoutEnvPropKey to
register additional connect timeout environment keys (to be used with the
ContextFactories of some other service providers).
getConnectTimeout in class java.net.URLConnectionsetConnectTimeout(int)public void setReadTimeout(int timeout)
setReadTimeout in class java.net.URLConnectiontimeout - the read timeout (default 0) to be used (in milliseconds)java.lang.IllegalArgumentException - if the given timeout value is < 0public int getReadTimeout()
getReadTimeout in class java.net.URLConnectionpublic java.lang.String toString()
String representation of this LdapURLConnection
object.toString in class java.net.URLConnectionpublic java.lang.String getHeaderField(java.lang.String name)
Querying for haeder field values only will give a result different from
null if asking for "content-encoding" (in which case "DER" is
returned), or "content-type" (in which case "certificate;binary",
"attributeCertificate;binary" or "revocationList;binary" is returned,
depending on which kind of certificate/crl related information you have
searched for).
getHeaderField in class java.net.URLConnectionname - the name of the requested header field value.null if the name
does not refer to a included header fieldpublic void setDoInput(boolean doinput)
doInput field; ignored.
This method only overrides the same method of the parent
URLConnection class to ignore the specified value;
doInput always is true.
setDoInput in class java.net.URLConnectiondoinput - the doinput value; ignoredpublic void setDoOutput(boolean dooutput)
doOutput field; ignored.
This method only overrides the same method of the parent
URLConnection class to ignore the specified value;
doOutput always is false.
setDoOutput in class java.net.URLConnectiondooutput - the dooutput value; ignoredpublic void setAllowUserInteraction(boolean allowuserinteraction)
allowUserInteraction field; ignored.
This method only overrides the same method of the parent
URLConnection class to ignore the specified value;
allowUserInteraction always is false.
setAllowUserInteraction in class java.net.URLConnectionallowuserinteraction - the allowUserInteraction value; ignoredpublic void setUseCaches(boolean usecaches)
usecaches field; ignored.
This method only overrides the same method of the parent
URLConnection class to ignore the specified value;
usecaches always is false.
setUseCaches in class java.net.URLConnectionusecaches - the usecaches value; ignoredpublic void setIfModifiedSince(long ifmodifiedsince)
ifmodifiedsince field; ignored.
This method only overrides the same method of the parent
URLConnection class to ignore the specified value;
ifmodifiedsince always is 0.
setIfModifiedSince in class java.net.URLConnectionifmodifiedsince - the ifmodifiedsince value; ignored