wvcrl.cc

00001 /* -*- Mode: C++ -*-
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2005 Net Integration Technologies, Inc.
00004  *
00005  * X.509v3 CRL management classe.
00006  */
00007 
00008 #include <openssl/x509v3.h>
00009 #include <openssl/pem.h>
00010 
00011 #include "wvcrl.h"
00012 #include "wvx509.h"
00013 #include "wvbase64.h"
00014 
00015 WvCRLMgr::WvCRLMgr(X509_CRL *_crl)
00016     : debug("X509_CRL", WvLog::Debug5), cacert(NULL), certcount(0), 
00017       issuer(WvString::null)
00018 {
00019     err.seterr("Not Initialized yet!");
00020     if (_crl)
00021     {
00022         crl = _crl;
00023         setupcrl();
00024         err.noerr();
00025         
00026         // Do something about CA Cert.
00027     }
00028     else
00029     {
00030         debug("Creating new CRL\n");
00031         if ((crl = X509_CRL_new()) == NULL)
00032         {
00033             err.seterr("Error creating new CRL object");
00034             return;
00035         }
00036     }
00037 }
00038 
00039 
00040 WvCRLMgr::~WvCRLMgr()
00041 {
00042     if (crl)
00043         X509_CRL_free(crl);
00044 }
00045     
00046 
00047 WvString WvCRLMgr::hexify()
00048 {
00049     return WvString::null;
00050 }
00051 
00052 
00053 WvCRLMgr::Valid  WvCRLMgr::validate(WvX509Mgr *cert)
00054 {
00055     assert(cacert);
00056     
00057     if (!cert)
00058         return CRLERROR;
00059     
00060     if (!(cert->get_issuer() == cacert->get_subject()))
00061         return NOT_THIS_CA;
00062     
00063     if (!(signedbyCA(cert)))
00064         return NO_VALID_SIGNATURE;
00065     
00066     if (isrevoked(cert))
00067         return REVOKED;
00068     
00069     if (X509_cmp_current_time(cert->get_notvalid_before()) > 0)
00070         return BEFORE_VALID;
00071 
00072     if (X509_cmp_current_time(cert->get_notvalid_after()) < 0)
00073         return AFTER_VALID;
00074     
00075     return VALID;
00076 }
00077 
00078 
00079 bool WvCRLMgr::signedbyCAindir(WvStringParm certdir)
00080 {
00081     return false;
00082 }
00083    
00084 
00085 bool WvCRLMgr::signedbyCAinfile(WvStringParm certfile)
00086 {
00087     return false;
00088 }
00089 
00090 
00091 bool WvCRLMgr::signedbyCA(WvX509Mgr *cert)
00092 {
00093     assert(cacert);
00094     return false;
00095 }
00096 
00097 
00098 void WvCRLMgr::setca(WvX509Mgr *_cacert)
00099 {
00100     assert(_cacert);
00101     cacert = _cacert;
00102     issuer = cacert->get_issuer();
00103 }
00104 
00105 
00106 WvString WvCRLMgr::encode(const DumpMode mode)
00107 {
00108     BIO *bufbio = BIO_new(BIO_s_mem());    
00109     BUF_MEM *bm;
00110     switch (mode)
00111     {
00112     case PEM:
00113         debug("Dumping CRL in PEM format:\n");
00114         PEM_write_bio_X509_CRL(bufbio, crl);
00115         break;
00116     case DER:
00117         debug("Dumping CRL in DER format:\n");
00118         i2d_X509_CRL_bio(bufbio, crl);
00119         break;
00120     case TEXT:
00121         debug("Dumping CRL in human readable format:\n");
00122         X509_CRL_print(bufbio, crl);
00123         break;
00124     default:
00125         err.seterr("Unknown mode!\n");
00126         return WvString::null;
00127     }
00128     
00129     WvDynBuf retval;
00130     BIO_get_mem_ptr(bufbio, &bm);
00131     retval.put(bm->data, bm->length);
00132     BIO_free(bufbio);
00133     if (mode == DER)
00134     {
00135         WvBase64Encoder enc;
00136         WvString output;
00137         enc.flushbufstr(retval, output, true);
00138         return output;
00139     }
00140     else
00141         return retval.getstr();
00142 }
00143 
00144 
00145 void WvCRLMgr::decode(const DumpMode mode, WvStringParm PemEncoded)
00146 {
00147     BIO *bufbio = BIO_new(BIO_s_mem());    
00148     WvBase64Decoder dec;
00149     WvDynBuf output;
00150 
00151     if (crl)
00152     {
00153         debug("Replacing already existant CRL\n");
00154         X509_CRL_free(crl);
00155         crl = NULL;
00156     }
00157     
00158     size_t output_size;
00159     switch (mode)
00160     {
00161     case PEM:
00162         debug("Decoding CRL from PEM format:\n");
00163         BIO_write(bufbio, PemEncoded.cstr(), PemEncoded.len());
00164         crl = PEM_read_bio_X509_CRL(bufbio, NULL, NULL, NULL);
00165         break;
00166     case DER:
00167         debug("Decoding CRL from DER format:\n");
00168         dec.flushstrbuf(PemEncoded, output, true);
00169         output_size = output.used();
00170         BIO_write(bufbio, output.get(output_size), output_size);
00171         crl = d2i_X509_CRL_bio(bufbio, NULL);
00172         break;
00173     case TEXT:
00174         debug("Sorry, can't decode TEXT format... try PEM or DER instead\n");
00175         break;
00176     default:
00177         err.seterr("Unknown mode!\n");
00178     }
00179     setupcrl();
00180     BIO_free(bufbio);
00181 }
00182 
00183 
00184 WvString WvCRLMgr::get_issuer()
00185 {
00186     if (crl)
00187         return issuer;
00188 
00189     return WvString::null;
00190 }
00191 
00192 
00193 bool WvCRLMgr::isrevoked(WvX509Mgr *cert)
00194 {
00195     if (cert && cert->isok())
00196         return isrevoked(cert->get_serial());
00197     else
00198     {
00199         debug(WvLog::Critical,"Given bad certificate... declining\n");
00200         return true;
00201     }
00202 }
00203 
00204 
00205 bool WvCRLMgr::isrevoked(WvStringParm serial_number)
00206 {
00207     if (!!serial_number)
00208     {
00209         ASN1_INTEGER *serial = serial_to_int(serial_number);
00210         if (serial)
00211         {
00212             X509_REVOKED mayberevoked;
00213             mayberevoked.serialNumber = serial;
00214             if (crl->crl->revoked)
00215             {
00216                 int idx = sk_X509_REVOKED_find(crl->crl->revoked, 
00217                                                &mayberevoked);
00218                 ASN1_INTEGER_free(serial);
00219                 if (idx >= 0)
00220                     return true;
00221             }
00222             else
00223             {
00224                 ASN1_INTEGER_free(serial);
00225                 debug("No CRL Revoked list? I guess %s isn't in it!\n", 
00226                       serial_number);
00227             }
00228             
00229         }
00230         else
00231             debug("Can't convert serial number...odd!\n");
00232     }
00233     else
00234     {
00235         debug("Can't check imaginary serial number!\n");
00236     }
00237     return false;
00238 }
00239     
00240 
00241 int WvCRLMgr::numcerts()
00242 {
00243     return certcount;
00244 }
00245 
00246 
00247 void WvCRLMgr::addcert(WvX509Mgr *cert)
00248 {
00249     if (cert && cert->isok())
00250     {
00251         ASN1_INTEGER *serial = serial_to_int(cert->get_serial());
00252         X509_REVOKED *revoked = X509_REVOKED_new();
00253         ASN1_GENERALIZEDTIME *now = ASN1_GENERALIZEDTIME_new();
00254         X509_REVOKED_set_serialNumber(revoked, serial);
00255         X509_gmtime_adj(now, 0);
00256         X509_REVOKED_set_revocationDate(revoked, now);
00257         // FIXME: We don't deal with the reason here...
00258         X509_CRL_add0_revoked(crl, revoked);
00259         ASN1_GENERALIZEDTIME_free(now);
00260         ASN1_INTEGER_free(serial);
00261         certcount++;
00262     }
00263     else
00264     {
00265         debug("Sorry, can't add a certificate that is either bad or broken\n");
00266     }
00267 }
00268 
00269 ASN1_INTEGER *WvCRLMgr::serial_to_int(WvStringParm serial)
00270 {
00271     debug(WvLog::Critical, "Converting: %s\n", serial);
00272     if (!!serial)
00273     {
00274         ASN1_INTEGER *retval = ASN1_INTEGER_new();
00275         ASN1_INTEGER_set(retval, serial.num());
00276         return retval;
00277     }
00278     else
00279         return NULL;
00280 }
00281 
00282 
00283 void WvCRLMgr::setupcrl()
00284 {
00285     char *name = X509_NAME_oneline(X509_CRL_get_issuer(crl), 0, 0);
00286     issuer = name;
00287     OPENSSL_free(name);
00288     STACK_OF(X509_REVOKED) *rev;
00289     rev = X509_CRL_get_REVOKED(crl);
00290     certcount = sk_X509_REVOKED_num(rev);
00291 }
00292 

Generated on Sun Sep 24 20:10:50 2006 for WvStreams by  doxygen 1.4.7