> From [EMAIL PROTECTED] Fri Jun 14 07:24:32 2002
> Date: Fri, 14 Jun 2002 15:15:54 +0200
> From: Rabellino Sergio <[EMAIL PROTECTED]>
> To: [EMAIL PROTECTED]
> Subject: Re: LPRng: Need an OpenSSL expert
>
> This is a multi-part message in MIME format.
> --------------31F088C6826A8CC60CC8D5A8
> Content-Type: text/plain; charset=us-ascii
> Content-Transfer-Encoding: 7bit
>
> Patrick Powell wrote:
> >
> > Ah... an expert.
> >
> > OK. Welcome to the joys of "certificate revocation" and 'accept
> > users with certs signed only by this 'signer' cert'
> >
> > Certificate revocation is ugly.
> > I looked at the way that mod_ssl in Apache did it and was taken
> > aback.
> > You need to:
> > a) set up a 'certificate revocation list/directory MIT Hash Files Yet'
> > b) Do magic to read the certs in the CRL/CRL Dir
> > c) Write/add a callback so that on connection/ssl authentication
> > you check to see if the user/signer is in the revocation list.
> > (... and there are all sorts of nasty things...)
> >
> > Don't forget to use the 'cca' script to 'revoke' the cert,
> > put the cert into a revocation directory, and create the hash
> > to it OR append it to a file of revoked certs.
> >
> > So... I can go through the pain and agony of handling this a la mod_ssl
> > in Apache, or I can ... cheat.
> >
> > Now I just know that you will say 'write your own authentication callback'.
> > Nope. I looked at that code in the SSL distribution and it was... ugly.
> > And that is coming from me who has written some code that was so ugly
> > that monitors died before they would display it.
> >
> > But If I could simply EXTRACT the cert information, then I could
> > do something more audatious:
> >
> > Idea: use the LPRng lpd.perms and add a new option: AUTH_CHAIN
> >
> > This would have a value of all subject name and all of the signers
> > of a cert:
> >
> > h110: {33} % openssl x509 -noout -subject -issuer -in signer1.crt
> > subject= /C=US/ST=California/L=San
>[EMAIL PROTECTED]
> > issuer= /C=US/ST=California/L=San Diego/O=Astart/OU=Certificate
>Authority/CN=Astart [EMAIL PROTECTED]
> > h110: {34} % openssl x509 -noout -subject -issuer -in user1.crt
> > issuer= /C=US/ST=California/L=San
>[EMAIL PROTECTED]
> > subject= /C=US/ST=California/L=San
>[EMAIL PROTECTED]
> >
> > AUTH_CHAIN=
> > /C=US/ST=California/L=San [EMAIL PROTECTED]
> > /C=US/ST=California/L=San
>[EMAIL PROTECTED]
> > /C=US/ST=California/L=San Diego/O=Astart/OU=Certificate Authority/CN=Astart
>[EMAIL PROTECTED]
> >
> > (line folded to fit)
> >
> > This would represent the signature chain starting from the
> > bottom of the certificate and going to the top.
> >
> > Now you could 'cancel' a user with subject: '/.../ON=jsmith/...' using:
> > REJECT AUTHTYPE=SSL AUTH_CHAIN=*/ON=jsmith/*
> >
> > You probably would put these into a file, say /etc/lpd/ssl/revoke.list
> >
> > REJECT AUTHTYPE=SSL AUTH_CHAIN=</etc/lpd/ssl/revoke.list
> >
> > You can only accept certs signed by ON=jsmith using:
> >
> > REJECT AUTHTYPE=SSL NOT AUTH_CHAIN=*/ON=jsmith/*
> >
> > Now, I know that the SSL/OpenSSL community is having the dry
> > heaves at this method (I feel kinda queasy myself). But this
> > does have the benefit of allowing you to require a cert to have
> > a specific signer... and instead of enumerating all of the
> > allowed certs, to delegate this.
> >
> > Patrick Powell Astart Technologies,
> > [EMAIL PROTECTED] 9475 Chesapeake Drive, Suite D,
> > Network and System San Diego, CA 92123
> > Consulting 858-874-6543 FAX 858-279-8424
> > LPRng - Print Spooler (http://www.lprng.com)
> >
> ....
>
> If I understand your way to do the certificate checking, it's completely failing,
>because you don't use any of the mechanism along the
> certificate infrastructure; so checking only a textual part of the certificate, as
>the subject or the issuer, can lead anyone to forge a
> certificate for the connection.
Ooops... I forgot to mention that I am using the default OpenSSL certificate
verification.
> The best way to do the job is:
>
> 1) A directory with an hashed list of accepted CAs
Right.
> 2) A directory with an hashed list of CRL (ideally one for every CA)
Right.
>
> then check every certificate with a "standard" callback function,
> you don't need to change at all (I've attached a cbf as a full sample,
> grabbed an adjusted from apps/s_cb.c on openssl distribution)
>
> Then if the ssl connection is ok, you have certainly a "legal"
> certificate passed by the client (as the relative ca chain is legal...).
> You can now add every check in the code based on the subject or the issuer,
> as you need.
>
> The issuer can be catched with these lines (grabbed from apps/s_server.c on openssl
>distribution)
>
> peer=SSL_get_peer_certificate(con);
> X509_NAME_oneline(X509_get_issuer_name(peer),buf,BUFSIZ);
>
> where con is the SSL connection handler (SSL*)
> and buf is a buffer BUFSIZ bytes long, sufficient to hold the issuer string.
Right.
>
> Hope this help.
>
>
> Dott. Sergio Rabellino
>
> Technical Staff
> Department of Computer Science
> University of Torino (Italy)
> Member of the Internet Society
>
> http://www.di.unito.it/~rabser
> Tel. +39-0116706701
> Fax. +39-011751603
> --------------31F088C6826A8CC60CC8D5A8
> Content-Type: text/plain; charset=us-ascii;
> name="sslutil.c"
> Content-Transfer-Encoding: 7bit
> Content-Disposition: inline;
> filename="sslutil.c"
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <openssl/err.h>
> #include <openssl/x509.h>
> #include <openssl/ssl.h>
>
> int verify_depth=0;
> int verify_error=X509_V_OK;
>
> int verify_callback(int ok, X509_STORE_CTX *ctx)
> {
> char buf[256];
> X509 *err_cert;
> int err,depth;
>
> err_cert=X509_STORE_CTX_get_current_cert(ctx);
> err= X509_STORE_CTX_get_error(ctx);
> depth= X509_STORE_CTX_get_error_depth(ctx);
>
> X509_NAME_oneline(X509_get_subject_name(err_cert),buf,256);
> if (!ok)
> {
> if (verify_depth >= depth)
> {
> ok=1;
> verify_error=X509_V_OK;
> }
> else
> {
> ok=0;
> verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG;
> }
> }
> switch (ctx->error)
> {
> case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
> X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,256);
> break;
> case X509_V_ERR_CERT_NOT_YET_VALID:
> case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
> break;
> case X509_V_ERR_CERT_HAS_EXPIRED:
> case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
> break;
> }
> return(ok);
> }
>
But you have not set up your revocation lists.
Note that these checks are only done for information in
the certificates themselves. I looked at the code in
mod_ssl and discovered:
a) you need to set up and read a revocation file and/or
the files in a revocation list.
b) When you get a cert chain to check, you need to
look up the subject and the signer in the revocation
index/file/directory and make sure that they have
not been revoked.
If worst comes to worst, then I might be driven to adapt
the mod_ssl code, but I then need to add in the other parts
which have to do with the Netscape options, which are done
in the OpenSSL code but not in the mod_ssl code... Sigh...
Patrick
-----------------------------------------------------------------------------
YOU MUST BE A LIST MEMBER IN ORDER TO POST TO THE LPRNG MAILING LIST
The address you post from MUST be your subscription address
If you need help, send email to [EMAIL PROTECTED] (or lprng-requests
or lprng-digest-requests) with the word 'help' in the body. For the impatient,
to subscribe to a list with name LIST, send mail to [EMAIL PROTECTED]
with: | example:
subscribe LIST <mailaddr> | subscribe lprng-digest [EMAIL PROTECTED]
unsubscribe LIST <mailaddr> | unsubscribe lprng [EMAIL PROTECTED]
If you have major problems, send email to [EMAIL PROTECTED] with the word
LPRNGLIST in the SUBJECT line.
-----------------------------------------------------------------------------