Massimiliano Pala <[EMAIL PROTECTED]> writes:

> Lisa Lutz wrote:
> > 
> > I need to map certificate Subject DNs to LDAP User DNs.  I would like to be
> > handle complex cases such as:
> > 
> > Subject DN = CN=Fred+UID=FSMITH, OU=DEV, O=CompanyA
> > to
> > UserDN UID=CN=Fred+FSMITH, OU=DEV, O=CompanyA
> > 
> > Is there a standard certificate mapping syntax that I should follow?
> > Is there parsing code to handle this?
> 
> I'm quite sure my solution doesn't fit your needs, anyway, I suggest you
> to map certificates using the EMAIL address to LDAP directory : since
> this should be unique for each user you shouldn't have problems in
> finding the correct LDAP entry.
> 
> I use this method to manage certificates and seems to be working...
> 
> Obviously this works for me (and Netscape too... )!!!

I'm about to submit some code to the mod_ssl project that does effectively
the same thing as Massimiliano's patch, but in a more configurable way.
Hopefully we can merge the two very quickly.

The code that actually does the certificate verification and mapping from
certificate subject -> LDAP object mapping is easily reusable.

Basically, I had to write a function to convert from the internal X509
representation to something vaguely resembling an RFC1485 distinguished
name.  X509_name_oneline doesn't quite cut it.

The user provides a set of mappings from RDN -> LDAP attribute, and you
then do an ldap_search after converting to a query.  If the user provides
no mappings (NULL), then we assume that the subject cert maps into the
directory directly.  In the case of OpenSSL, this is highly unlikely
because of how the fake 1485 representation gets laid out.

So to map just email addresses, you would specify 'email=mail' as your
mapping.  You can also specify multiple mappings to narrow the search even
further.  So something like 'email=mail,uid' would result in an LDAP search
like (&([EMAIL PROTECTED])(uid=wmperry)).  If a match is found, we
pull out all the userCertificate (this attribute is configurable as well of 
course) values, and proceed to compare them.  If any of the values are
identical to the blob of data you passed in, the certificate is considered
valid.

Basic API for just the cert checking stuff is included below.  You could
just use 'LDAPCertConvertDN' if you wanted to.

This will be distributed under the standard Apache license when I finish
cleaning it up a little bit more.  This is stuff we've used in our SOCKS
server for a while, and I'm in the process of making it compile in mod_ssl
without any of our internal crap hanging around.

-Bill P.

struct av_ldap_config {
        int avlc_enabled;       /* Should we even try to use it?     */
        int avlc_timeout;       /* Timeout for LDAP queries          */
        char *avlc_server;      /* LDAP server to contact            */
        char *avlc_bind_dn;     /* Who to bind to the server as      */
        char *avlc_bind_pwd;    /* Password to bind with             */
        char *avlc_base;        /* Search base                       */
        char *avlc_scope;       /* Scope of the search               */
        char *avlc_mappings;    /* Attribute matching info           */
        char *avlc_cert_attr;   /* Attribute holding user certificate*/
        void (*avlc_log_function)(int, const char *);
};

/* Setup/teardown the subsystem */
extern void *LDAPCertSetConnection(struct av_ldap_config *);
extern void LDAPCertReleaseConnection(void *state);

/* Verify a single certificate in the directory.
** This just says whether a certificate you have been
** presented matches one in the directory.  Nothing
** else is exposed.
*/
extern LDAPCertError LDAPCertVerifyCertificate( void *state,
                                                const char *subjectDN,
                                                const unsigned char *certData,
                                                unsigned int certLength);

/* Generic certificate API.  This can be used to retrieve arbitrary
** certificates out of the directory.  Aventail uses these internally
** for completing certificate chains via an LDAP directory.
*/
typedef void *LDAPCertCertificateInfo;
extern LDAPCertError LDAPCertGetCertificateInfo(void *,const char 
*,LDAPCertCertificateInfo *);
extern int LDAPCertGetCertCount(LDAPCertCertificateInfo);
extern LDAPCertError LDAPCertGetCertificate(LDAPCertCertificateInfo,int,unsigned char 
**,unsigned int *);
extern void LDAPCertFreeCertificateInfo(LDAPCertCertificateInfo);

/* Expose some of our internals */
extern LDAP *LDAPCertGetHandle(void *state);
extern char *LDAPCertConvertDN(void *state,const char *);
extern char *LDAPCertErrorString(int rc);
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to