00001
00002
00003
00004
00005
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
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(X509_get_notBefore(cert->get_cert())) > 0)
00070 return BEFORE_VALID;
00071
00072 if (X509_cmp_current_time(X509_get_notBefore(cert->get_cert())) < 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
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