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, setFileNameMap
public 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.URLConnection
java.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.URLConnection
java.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.URLConnection
X509Certificate
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.URLConnection
key
- 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 null
java.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.URLConnection
key
- 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.URLConnection
key
- 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 null
java.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.URLConnection
timeout
- 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.URLConnection
setConnectTimeout(int)
public void setReadTimeout(int timeout)
setReadTimeout
in class java.net.URLConnection
timeout
- 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.URLConnection
public java.lang.String toString()
String
representation of this LdapURLConnection
object.toString
in class java.net.URLConnection
public 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.URLConnection
name
- 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.URLConnection
doinput
- 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.URLConnection
dooutput
- 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.URLConnection
allowuserinteraction
- 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.URLConnection
usecaches
- 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.URLConnection
ifmodifiedsince
- the ifmodifiedsince
value; ignored