On Wed, Nov 30, 2005 at 04:28:04PM -0000, Mark wrote:

> Hi Bear, 
> 
> > Mark wrote:
> > > What feature of a certificate could I use to provide an unique key
> > > in a database table for this?  How could this be extracted in a
> > > program?
> > 
> > The Common Name.  You could use it as an LDAP key, convert it to a
> > string and use that a key into a database, etc.
> 
> How can this be done?  I can find virtually no documentation on the
> relevant X509 functions.  I know I can get a pointer to an X509
> object using SSL_get_peer_certificate(...) but I don't know how
> to read certificate parameters from this.
> 

>From the Postfix 2.3-20051128 snapshot (the 2.3 code is simplified
relative to 2.2 and earlier):

src/tls/tls_verify.c:

#ifndef DONT_GRIPE
#define DONT_GRIPE 0
#define DO_GRIPE 1
#endif

/* tls_text_name - extract certificate property value by name */

static char *tls_text_name(X509_NAME *name, int nid, char *label, int gripe)
{
    int     len;
    char   *text;

    if ((len = X509_NAME_get_text_by_NID(name, nid, 0, 0)) < 0) {
        if (gripe != DONT_GRIPE) {
            msg_warn("peer certificate has no %s", label);
            tls_print_errors();
        }
        return (0);
    }

    /*
     * Since the peer CN is used in peer verification, take care to detect
     * truncation due to excessive length or internal NULs.
     */
    if (len >= CCERT_BUFSIZ) {
        msg_warn("peer %s too long: %d", label, (int) len);
        return (0);
    }
    text = mymalloc(len + 1);
    X509_NAME_get_text_by_NID(name, nid, text, len + 1);
    if (strlen(text) != len) {
        msg_warn("internal NUL in peer %s", label);
        myfree(text);
        text = 0;
    }
    return (text);
}

/* tls_peer_CN - extract peer common name from certificate */

char   *tls_peer_CN(X509 *peercert)
{
    char   *cn;

    cn = tls_text_name(X509_get_subject_name(peercert),
                       NID_commonName, "CN", DO_GRIPE);
    return (cn);
}

/* tls_issuer_CN - extract issuer common name from certificate */

char   *tls_issuer_CN(X509 *peer)
{
    X509_NAME *name;
    char   *cn;

    name = X509_get_issuer_name(peer);

    /*
     * If no issuer CN field, use Organization instead. CA certs without a CN
     * are common, so we only complain if the organization is also missing.
     */
    if (!(cn = tls_text_name(name, NID_commonName, "issuer CN", DONT_GRIPE)))
        cn = tls_text_name(name, NID_organizationName,
                           "issuer Organization", DO_GRIPE);
    return (cn);
}

-- 
        Viktor.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to