00001
00002
00003
00004
00005
00006
00007 #include "wvx509.h"
00008 #include "wvrsa.h"
00009 #include "wvcrl.h"
00010 #include "wvsslhacks.h"
00011 #include "wvdiriter.h"
00012 #include "wvcrypto.h"
00013 #include "wvstringlist.h"
00014 #include "wvbase64.h"
00015 #include "wvstrutils.h"
00016 #include "wvfileutils.h"
00017
00018 #include <openssl/pem.h>
00019 #include <openssl/x509v3.h>
00020 #include <openssl/err.h>
00021 #include <openssl/ssl.h>
00022 #include <openssl/sha.h>
00023 #include <openssl/pkcs12.h>
00024
00025 UUID_MAP_BEGIN(WvX509Mgr)
00026 UUID_MAP_ENTRY(IObject)
00027 UUID_MAP_END
00028
00029 static int ssl_init_count = 0;
00030
00031 namespace {
00032 class AutoClose {
00033 public:
00034 AutoClose(FILE *fp): fp(fp) { }
00035 ~AutoClose()
00036 {
00037 if (fp)
00038 fclose(fp);
00039 }
00040
00041 operator FILE *() const
00042 {
00043 return fp;
00044 }
00045
00046 private:
00047 FILE *fp;
00048 };
00049 }
00050
00051
00052
00053 void wvssl_init()
00054 {
00055 if (!ssl_init_count)
00056 {
00057 SSL_library_init();
00058 SSL_load_error_strings();
00059 ERR_load_BIO_strings();
00060 ERR_load_crypto_strings();
00061 OpenSSL_add_all_algorithms();
00062 OpenSSL_add_all_ciphers();
00063 OpenSSL_add_all_digests();
00064 }
00065
00066 ssl_init_count++;
00067 }
00068
00069
00070 void wvssl_free()
00071 {
00072 if (ssl_init_count >= 1)
00073 ssl_init_count--;
00074
00075 if (!ssl_init_count)
00076 {
00077 ERR_free_strings();
00078 EVP_cleanup();
00079 }
00080 }
00081
00082
00083 WvString wvssl_errstr()
00084 {
00085 char buf[256];
00086 ERR_error_string_n(ERR_get_error(), buf, sizeof(buf));
00087 buf[sizeof(buf)-1] = 0;
00088 return buf;
00089 }
00090
00091
00092 WvX509Mgr::WvX509Mgr(X509 *_cert)
00093 : debug("X509", WvLog::Debug5), pkcs12pass(WvString::null)
00094 {
00095 wvssl_init();
00096 cert = _cert;
00097 rsa = NULL;
00098 if (cert)
00099 {
00100 filldname();
00101 rsa = fillRSAPubKey();
00102 if (!rsa->isok())
00103 seterr("RSA Public Key Error: %s", rsa->errstr());
00104 }
00105 else
00106 ;
00107
00108
00109
00110
00111 }
00112
00113
00114 WvX509Mgr::WvX509Mgr()
00115 : debug("X509", WvLog::Debug5), pkcs12pass(WvString::null)
00116 {
00117 wvssl_init();
00118 cert = NULL;
00119 rsa = NULL;
00120 }
00121
00122
00123 WvX509Mgr::WvX509Mgr(WvStringParm hexified_cert,
00124 WvStringParm hexified_rsa)
00125 : debug("X509", WvLog::Debug5), pkcs12pass(WvString::null)
00126 {
00127 wvssl_init();
00128
00129 cert = NULL;
00130 rsa = new WvRSAKey(hexified_rsa, true);
00131 if (!rsa->isok())
00132 {
00133 seterr("RSA Error: %s\n", rsa->errstr());
00134 return;
00135 }
00136
00137 if (!!hexified_cert)
00138 unhexify(hexified_cert);
00139 else
00140 {
00141 seterr("No Hexified Cert.. aborting!\n");
00142 return;
00143 }
00144
00145 if (cert)
00146 filldname();
00147 }
00148
00149
00150 WvX509Mgr::WvX509Mgr(WvStringParm _dname, WvRSAKey *_rsa)
00151 : dname(_dname), debug("X509", WvLog::Debug5), pkcs12pass(WvString::null)
00152 {
00153 assert(_rsa);
00154
00155 wvssl_init();
00156 debug("Creating new certificate for %s\n", dname);
00157 cert = NULL;
00158 rsa = _rsa;
00159 create_selfsigned();
00160 }
00161
00162
00163 WvX509Mgr::WvX509Mgr(WvStringParm _dname, int bits)
00164 : dname(_dname), debug("X509", WvLog::Debug5)
00165 {
00166 wvssl_init();
00167 debug("Creating new certificate for %s\n", dname);
00168 cert = NULL;
00169 rsa = NULL;
00170
00171 if (!!dname)
00172 {
00173 rsa = new WvRSAKey(bits);
00174 create_selfsigned();
00175 }
00176 else
00177 seterr("Sorry, can't create an anonymous Certificate\n");
00178 }
00179
00180
00181 WvX509Mgr::~WvX509Mgr()
00182 {
00183 debug("Deleting.\n");
00184
00185 if (rsa)
00186 delete rsa;
00187
00188 if (cert)
00189 X509_free(cert);
00190
00191 wvssl_free();
00192 }
00193
00194
00195 bool WvX509Mgr::bind_ssl(SSL_CTX *ctx)
00196 {
00197 if (SSL_CTX_use_certificate(ctx, cert) <= 0)
00198 {
00199 return false;
00200 }
00201 debug("Certificate activated.\n");
00202
00203 if (SSL_CTX_use_RSAPrivateKey(ctx, rsa->rsa) <= 0)
00204 {
00205 return false;
00206 }
00207 debug("RSA private key activated.\n");
00208 return true;
00209 }
00210
00211
00212 const WvRSAKey &WvX509Mgr::get_rsa()
00213 {
00214 assert(rsa);
00215
00216 return *rsa;
00217 }
00218
00219
00220
00221
00222 #ifndef NID_domainComponent
00223 #define NID_domainComponent 391
00224 #endif
00225
00226 #ifndef NID_Domain
00227 #define NID_Domain 392
00228 #endif
00229
00230
00231
00232 static WvString set_name_entry(X509_NAME *name, WvStringParm dn)
00233 {
00234 WvString fqdn(""), force_fqdn("");
00235 X509_NAME_ENTRY *ne = NULL;
00236 int count = 0, nid;
00237
00238 WvStringList l;
00239 l.split(dn, ",");
00240
00241
00242
00243 WvStringList::Iter i(l);
00244 for (i.rewind(); i.next(); )
00245 {
00246 WvString s(*i), sid;
00247 char *cptr, *value;
00248
00249 cptr = s.edit();
00250 value = strchr(cptr, '=');
00251 if (value)
00252 *value++ = 0;
00253 else
00254 value = "NULL";
00255
00256 sid = strlwr(trim_string(cptr));
00257
00258 if (sid == "c")
00259 nid = NID_countryName;
00260 else if (sid == "st")
00261 nid = NID_stateOrProvinceName;
00262 else if (sid == "l")
00263 nid = NID_localityName;
00264 else if (sid == "o")
00265 nid = NID_organizationName;
00266 else if (sid == "ou")
00267 nid = NID_organizationalUnitName;
00268 else if (sid == "cn")
00269 {
00270 nid = NID_commonName;
00271 force_fqdn = value;
00272 }
00273 else if (sid == "dc")
00274 {
00275 nid = NID_domainComponent;
00276 if (!!fqdn)
00277 fqdn.append(".");
00278 fqdn.append(value);
00279 }
00280 else if (sid == "domain")
00281 {
00282 nid = NID_Domain;
00283 force_fqdn = value;
00284 }
00285 else if (sid == "email")
00286 nid = NID_pkcs9_emailAddress;
00287 else
00288 nid = NID_domainComponent;
00289
00290
00291 if (name == NULL)
00292 continue;
00293
00294 if (!ne)
00295 ne = X509_NAME_ENTRY_create_by_NID(NULL, nid,
00296 V_ASN1_APP_CHOOSE, (unsigned char *)value, -1);
00297 else
00298 X509_NAME_ENTRY_create_by_NID(&ne, nid,
00299 V_ASN1_APP_CHOOSE, (unsigned char *)value, -1);
00300 if (!ne)
00301 continue;
00302
00303 X509_NAME_add_entry(name, ne, count++, 0);
00304 }
00305
00306 X509_NAME_ENTRY_free(ne);
00307
00308 if (!!force_fqdn)
00309 return force_fqdn;
00310
00311 return fqdn;
00312 }
00313
00314
00315 void WvX509Mgr::create_selfsigned(bool is_ca)
00316 {
00317 assert(rsa);
00318
00319 if (cert)
00320 {
00321 debug("Replacing already existant certificate...\n");
00322 X509_free(cert);
00323 cert = NULL;
00324 }
00325
00326
00327 if (rsa->isok())
00328 debug("RSA Key is fine.\n");
00329 else
00330 {
00331 seterr("RSA Key is bad!\n");
00332 return;
00333 }
00334
00335 if ((cert = X509_new()) == NULL)
00336 {
00337 seterr("Error creating new X509 object");
00338 return;
00339 }
00340
00341
00342
00343 set_version();
00344
00345
00346
00347
00348
00349 srand(time(NULL));
00350 int serial = rand();
00351 set_serial(serial);
00352
00353
00354 set_lifetime(60*60*24*3650);
00355
00356 set_pubkey(rsa);
00357
00358 set_issuer(dname);
00359 set_subject(dname);
00360
00361 if (is_ca)
00362 {
00363 debug("Setting Extensions with CA Parameters.\n");
00364 debug("Setting Key Usage.\n");
00365 set_key_usage("critical, keyCertSign, cRLSign");
00366 debug("Setting Basic Constraints.\n");
00367 set_extension(NID_basic_constraints, "critical, CA:TRUE");
00368 debug("Setting Netscape Certificate Type.\n");
00369 set_extension(NID_netscape_cert_type, "SSL CA, S/MIME CA, Object Signing CA");
00370
00371
00372 }
00373 else
00374 {
00375 debug("Setting Key Usage with normal server parameters\n");
00376 set_nsserver(dname);
00377 set_key_usage("critical, digitalSignature, keyEncipherment, keyAgreement");
00378 set_extension(NID_basic_constraints, "CA:FALSE");
00379 set_ext_key_usage("TLS Web Server Authentication,"
00380 "TLS Web Client Authentication");
00381 }
00382
00383 debug("Ok - Parameters set... now signing certificate.\n");
00384 signcert(cert);
00385
00386 debug("Certificate for %s created\n", dname);
00387 }
00388
00389
00390 void WvX509Mgr::filldname()
00391 {
00392 assert(cert);
00393
00394 char *name = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
00395 dname = name;
00396 OPENSSL_free(name);
00397 }
00398
00399
00400
00401 WvRSAKey *WvX509Mgr::fillRSAPubKey()
00402 {
00403 EVP_PKEY *pkcert = X509_get_pubkey(cert);
00404 RSA *certrsa = EVP_PKEY_get1_RSA(pkcert);
00405 EVP_PKEY_free(pkcert);
00406 return new WvRSAKey(certrsa, false);
00407 }
00408
00409
00410 WvString WvX509Mgr::certreq()
00411 {
00412 EVP_PKEY *pk = NULL;
00413 X509_NAME *name = NULL;
00414 X509_REQ *certreq = NULL;
00415
00416 assert(rsa);
00417 assert(dname);
00418
00419
00420 if (rsa->isok())
00421 debug("RSA Key is fine.\n");
00422 else
00423 {
00424 seterr("RSA Key is bad!\n");
00425 return WvString::null;
00426 }
00427
00428 if ((pk=EVP_PKEY_new()) == NULL)
00429 {
00430 seterr("Error creating key handler for new certificate");
00431 return WvString::null;
00432 }
00433
00434 if ((certreq=X509_REQ_new()) == NULL)
00435 {
00436 seterr("Error creating new PKCS#10 object");
00437 EVP_PKEY_free(pk);
00438 return WvString::null;
00439 }
00440
00441 if (!EVP_PKEY_set1_RSA(pk, rsa->rsa))
00442 {
00443 seterr("Error adding RSA keys to certificate");
00444 X509_REQ_free(certreq);
00445 EVP_PKEY_free(pk);
00446 return WvString::null;
00447 }
00448
00449 X509_REQ_set_version(certreq, 0);
00450
00451 X509_REQ_set_pubkey(certreq, pk);
00452
00453 name = X509_REQ_get_subject_name(certreq);
00454
00455 debug("Creating Certificate request for %s\n", dname);
00456 set_name_entry(name, dname);
00457 X509_REQ_set_subject_name(certreq, name);
00458 char *sub_name = X509_NAME_oneline(X509_REQ_get_subject_name(certreq),
00459 0, 0);
00460 debug("SubjectDN: %s\n", sub_name);
00461 OPENSSL_free(sub_name);
00462
00463 if (!X509_REQ_sign(certreq, pk, EVP_sha1()))
00464 {
00465 seterr("Could not self sign the request");
00466 X509_REQ_free(certreq);
00467 EVP_PKEY_free(pk);
00468 return WvString::null;
00469 }
00470
00471 int verify_result = X509_REQ_verify(certreq, pk);
00472 if (verify_result == 0)
00473 {
00474 seterr("Self Signed Request failed!");
00475 X509_REQ_free(certreq);
00476 EVP_PKEY_free(pk);
00477 return WvString::null;
00478 }
00479 else
00480 {
00481 debug("Self Signed Certificate Request verifies OK!\n");
00482 }
00483
00484
00485
00486
00487 WvDynBuf retval;
00488 BIO *bufbio = BIO_new(BIO_s_mem());
00489 BUF_MEM *bm;
00490
00491 PEM_write_bio_X509_REQ(bufbio, certreq);
00492 BIO_get_mem_ptr(bufbio, &bm);
00493 retval.put(bm->data, bm->length);
00494
00495 X509_REQ_free(certreq);
00496 EVP_PKEY_free(pk);
00497 BIO_free(bufbio);
00498
00499 return retval.getstr();
00500 }
00501
00502
00503 WvString WvX509Mgr::signreq(WvStringParm pkcs10req)
00504 {
00505 assert(rsa);
00506 assert(cert);
00507 debug("Signing a certificate request with : %s\n", get_subject());
00508
00509
00510
00511 WvString pkcs10(pkcs10req);
00512
00513 char *begin = strstr(pkcs10.edit(), "\nMII");
00514 if (!begin)
00515 {
00516 debug("This doesn't look like PEM Encoded information...\n");
00517 return WvString::null;
00518 }
00519 char *end = strstr(begin + 1, "\n---");
00520 if (!end)
00521 {
00522 debug("Is this a complete certificate request?\n");
00523 return WvString::null;
00524 }
00525 *++end = '\0';
00526 WvString body(begin);
00527
00528
00529 WvDynBuf reqbuf;
00530 WvBase64Decoder dec;
00531 dec.flushstrbuf(body, reqbuf, true);
00532
00533
00534 size_t reqlen = reqbuf.used();
00535 const unsigned char *req = reqbuf.get(reqlen);
00536 X509_REQ *certreq = wv_d2i_X509_REQ(NULL, &req, reqlen);
00537 if (certreq)
00538 {
00539 WvX509Mgr newcert;
00540
00541 newcert.set_subject(X509_REQ_get_subject_name(certreq));
00542 newcert.set_version();
00543
00544
00545 srand(time(NULL));
00546 int serial = rand();
00547 newcert.set_serial(serial);
00548
00549 newcert.set_lifetime(60*60*24*3650);
00550
00551
00552
00553 EVP_PKEY *pk = X509_REQ_get_pubkey(certreq);
00554 X509_set_pubkey(newcert.get_cert(), pk);
00555 EVP_PKEY_free(pk);
00556
00557
00558 newcert.set_issuer(get_subject());
00559
00560 X509_EXTENSION *ex = NULL;
00561
00562
00563 newcert.set_key_usage("critical, digitalSignature, keyEncipherment");
00564
00565
00566
00567
00568 ex = X509V3_EXT_conf_nid(NULL, NULL, NID_basic_constraints,
00569 "CA:FALSE");
00570
00571 X509_add_ext(newcert.get_cert(), ex, -1);
00572 X509_EXTENSION_free(ex);
00573
00574 newcert.set_ext_key_usage("critical, TLS Web Client Authentication");
00575
00576 signcert(newcert.get_cert());
00577
00578 X509_REQ_free(certreq);
00579 return WvString(newcert.encode(CertPEM));
00580 }
00581 else
00582 {
00583 debug("Can't decode Certificate Request\n");
00584 return WvString::null;
00585 }
00586 }
00587
00588
00589 bool WvX509Mgr::test()
00590 {
00591 bool bad = false;
00592
00593 EVP_PKEY *pk = EVP_PKEY_new();
00594
00595 if (!cert)
00596 {
00597 seterr("no Certificate in X509 Manager!");
00598 bad = true;
00599 }
00600
00601 if (rsa && pk)
00602 {
00603 if (!EVP_PKEY_set1_RSA(pk, rsa->rsa))
00604 {
00605 seterr("Error setting RSA keys");
00606 bad = true;
00607 }
00608 else if (!bad)
00609 {
00610 int verify_return = X509_verify(cert, pk);
00611 if (verify_return != 1)
00612 {
00613
00614 WvString rsapub = encode(RsaPubPEM);
00615 WvRSAKey *temprsa = fillRSAPubKey();
00616 WvString certpub = temprsa->getpem(false);
00617 delete temprsa;
00618
00619
00620 if (certpub == rsapub)
00621 ;
00622 else
00623 {
00624
00625 seterr("Certificate test failed: %s\n", wvssl_errstr());
00626 bad = true;
00627 }
00628 }
00629 }
00630 }
00631 else
00632 {
00633 seterr("no RSA keypair in X509 manager");
00634 bad = true;
00635 }
00636
00637 if (pk)
00638 EVP_PKEY_free(pk);
00639
00640 return !bad;
00641 }
00642
00643
00644 void WvX509Mgr::unhexify(WvStringParm encodedcert)
00645 {
00646 if (!encodedcert)
00647 {
00648 seterr("X.509 certificate can't be decoded from nothing!\n");
00649 return;
00650 }
00651
00652 int hexbytes = strlen(encodedcert.cstr());
00653 int bufsize = hexbytes/2;
00654 unsigned char *certbuf = new unsigned char[bufsize];
00655 unsigned char *cp = certbuf;
00656 X509 *tmpcert;
00657
00658 if (cert)
00659 X509_free(cert);
00660
00661 ::unhexify(certbuf, encodedcert);
00662 tmpcert = cert = X509_new();
00663 cert = wv_d2i_X509(&tmpcert, &cp, hexbytes/2);
00664
00665
00666 if (cert && !test())
00667 {
00668 X509_free(cert);
00669 cert = NULL;
00670 }
00671
00672 if (!cert)
00673 seterr("X.509 certificate decode failed!");
00674
00675 deletev certbuf;
00676 }
00677
00678
00679 WvString WvX509Mgr::hexify()
00680 {
00681 size_t size;
00682 unsigned char *keybuf, *iend;
00683 WvString enccert;
00684
00685 size = i2d_X509(cert, NULL);
00686 iend = keybuf = new unsigned char[size];
00687 i2d_X509(cert, &iend);
00688
00689 enccert.setsize(size * 2 +1);
00690 ::hexify(enccert.edit(), keybuf, size);
00691
00692 deletev keybuf;
00693 return enccert;
00694 }
00695
00696
00697 bool WvX509Mgr::validate(WvX509Mgr *cacert, X509_CRL *crl)
00698 {
00699 bool retval = true;
00700
00701 if (cert != NULL)
00702 {
00703
00704 if (X509_cmp_current_time(X509_get_notAfter(cert)) == -1)
00705 {
00706 seterr("Certificate has expired!");
00707 retval = false;
00708 }
00709
00710 if (cacert)
00711 retval &= signedbyCA(cacert);
00712
00713
00714
00715
00716
00717
00718 }
00719 else
00720 debug("Peer doesn't have a certificate.\n");
00721
00722 return retval;
00723 }
00724
00725
00726 bool WvX509Mgr::signedbyCAinfile(WvStringParm certfile)
00727 {
00728 X509_STORE *cert_ctx = NULL;
00729 X509_STORE_CTX csc;
00730 X509_LOOKUP *lookup = NULL;
00731 int result = 0;
00732
00733 cert_ctx = X509_STORE_new();
00734 if (cert_ctx == NULL)
00735 {
00736 seterr("Unable to create Certificate Store Context");
00737 return false;
00738 }
00739
00740 lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
00741 if (lookup == NULL)
00742 {
00743 seterr("Can't add lookup method...\n");
00744 return false;
00745 }
00746
00747 if (!X509_LOOKUP_load_file(lookup, certfile, X509_FILETYPE_PEM))
00748 X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
00749
00750 X509_STORE_CTX_init(&csc, cert_ctx, cert, NULL);
00751 result = X509_verify_cert(&csc);
00752 X509_STORE_CTX_cleanup(&csc);
00753
00754 X509_STORE_free(cert_ctx);
00755
00756 if (result == 1)
00757 return true;
00758 else
00759 return false;
00760 }
00761
00762
00763 #ifndef _WIN32
00764 bool WvX509Mgr::signedbyCAindir(WvStringParm certdir)
00765 {
00766 WvDirIter i(certdir,false);
00767 for (i.rewind(); i.next(); )
00768 {
00769 if (!signedbyCAinfile(i->fullname))
00770 return false;
00771 }
00772 return true;
00773 }
00774 #endif
00775
00776
00777 bool WvX509Mgr::signedbyCA(WvX509Mgr *cacert)
00778 {
00779 int ret = X509_check_issued(cacert->cert, cert);
00780 if (ret == X509_V_OK)
00781 return true;
00782 else
00783 return false;
00784 }
00785
00786
00787 WvString WvX509Mgr::encode(const DumpMode mode)
00788 {
00789 WvString nil;
00790 WvDynBuf retval;
00791 BIO *bufbio = BIO_new(BIO_s_mem());
00792 BUF_MEM *bm;
00793
00794 switch(mode)
00795 {
00796 case CertPEM:
00797 debug("Dumping X509 certificate.\n");
00798 PEM_write_bio_X509(bufbio, cert);
00799 break;
00800
00801 case CertDER:
00802 debug("Dumping X509 certificate in DER format\n");
00803 i2d_X509_bio(bufbio, cert);
00804 break;
00805
00806 case RsaPEM:
00807 debug("Dumping RSA keypair.\n");
00808 BIO_free(bufbio);
00809 return rsa->getpem(true);
00810 break;
00811
00812 case RsaPubPEM:
00813 debug("Dumping RSA Public Key!\n");
00814 BIO_free(bufbio);
00815 return rsa->getpem(false);
00816 break;
00817
00818 case RsaRaw:
00819 debug("Dumping raw RSA keypair.\n");
00820 RSA_print(bufbio, rsa->rsa, 0);
00821 break;
00822
00823 default:
00824 seterr("Unknown Mode\n");
00825 return nil;
00826 }
00827
00828 BIO_get_mem_ptr(bufbio, &bm);
00829 retval.put(bm->data, bm->length);
00830 BIO_free(bufbio);
00831 if (mode == CertDER)
00832 {
00833 WvBase64Encoder enc;
00834 WvString output;
00835 enc.flushbufstr(retval, output, true);
00836 return output;
00837 }
00838 else
00839 return retval.getstr();
00840 }
00841
00842 void WvX509Mgr::decode(const DumpMode mode, WvStringParm pemEncoded)
00843 {
00844 if (!pemEncoded)
00845 {
00846 debug(WvLog::Error, "Not decoding an empty string. - Sorry!\n");
00847 return;
00848 }
00849
00850 BIO *membuf = BIO_new(BIO_s_mem());
00851 BIO_puts(membuf, pemEncoded);
00852
00853 switch(mode)
00854 {
00855 case CertPEM:
00856 debug("Importing X509 certificate.\n");
00857 if(cert)
00858 {
00859 debug("Replacing an already existant X509 Certificate!\n");
00860 X509_free(cert);
00861 cert = NULL;
00862 }
00863
00864 cert = PEM_read_bio_X509(membuf, NULL, NULL, NULL);
00865 if (cert)
00866 {
00867 filldname();
00868 if (!rsa)
00869 rsa = fillRSAPubKey();
00870 }
00871 else
00872 seterr("Certificate failed to import!");
00873 break;
00874 case RsaPEM:
00875 debug("Importing RSA keypair.\n");
00876 debug("Make sure that you load or generate a new Certificate!\n");
00877 if (rsa) delete rsa;
00878
00879
00880 rsa = new WvRSAKey(PEM_read_bio_RSAPrivateKey(membuf, NULL, NULL, NULL),
00881 true);
00882 if (!rsa->isok())
00883 seterr("RSA Key failed to import\n");
00884 break;
00885 case RsaPubPEM:
00886 debug("Importing RSA Public Key.\n");
00887 debug("Are you REALLY sure that you want to do this?\n");
00888 if (rsa) delete rsa;
00889 rsa = new WvRSAKey(PEM_read_bio_RSAPublicKey(membuf, NULL, NULL, NULL),
00890 true);
00891 if (!rsa->isok())
00892 seterr("RSA Public Key failed to import\n");
00893 break;
00894 case RsaRaw:
00895 debug("Importing raw RSA keypair not supported.\n");
00896 break;
00897
00898 default:
00899 seterr("Unknown Mode\n");
00900 }
00901 BIO_free_all(membuf);
00902 }
00903
00904
00905 void WvX509Mgr::write_p12(WvStringParm filename)
00906 {
00907 debug("Dumping RSA Key and X509 Cert to PKCS12 structure.\n");
00908
00909 AutoClose fp = fopen(filename, "wb");
00910
00911 if (!fp)
00912 {
00913 seterr("Unable to create: %s\n", filename);
00914 return;
00915 }
00916
00917 if (!!pkcs12pass)
00918 {
00919 if (rsa && cert)
00920 {
00921 EVP_PKEY *pk = EVP_PKEY_new();
00922 if (!pk)
00923 {
00924 seterr("Unable to create PKEY object.\n");
00925 return;
00926 }
00927
00928 if (!EVP_PKEY_set1_RSA(pk, rsa->rsa))
00929 {
00930 seterr("Error setting RSA keys.\n");
00931 EVP_PKEY_free(pk);
00932 return;
00933 }
00934 else
00935 {
00936 PKCS12 *pkg = PKCS12_create(pkcs12pass.edit(), "foo", pk,
00937 cert, NULL, 0, 0, 0, 0, 0);
00938 if (pkg)
00939 {
00940 debug("Write the PKCS12 object out...\n");
00941 i2d_PKCS12_fp(fp, pkg);
00942 PKCS12_free(pkg);
00943 EVP_PKEY_free(pk);
00944 }
00945 else
00946 {
00947 seterr("Unable to create PKCS12 object.\n");
00948 EVP_PKEY_free(pk);
00949 return;
00950 }
00951 }
00952 }
00953 else
00954 {
00955 seterr("Either the RSA key or the Certificate is not present\n");
00956 return;
00957 }
00958 }
00959 else
00960 {
00961 seterr("No Password specified for PKCS12 dump\n");
00962 return;
00963 }
00964 }
00965
00966 void WvX509Mgr::read_p12(WvStringParm filename)
00967 {
00968 debug("Reading Certificate and Private Key from PKCS12 file: %s\n", filename);
00969
00970 AutoClose fp = fopen(filename, "r");
00971
00972 if (!fp)
00973 {
00974 seterr("Unable to read from: %s\n", filename);
00975 return;
00976 }
00977
00978 if (!!pkcs12pass)
00979 {
00980 PKCS12 *pkg = d2i_PKCS12_fp(fp, NULL);
00981 if (pkg)
00982 {
00983 EVP_PKEY *pk = EVP_PKEY_new();
00984 if (!pk)
00985 {
00986 seterr("Unable to create PKEY object.\n");
00987 return;
00988 }
00989
00990
00991 PKCS12_parse(pkg, pkcs12pass, &pk, &cert, NULL);
00992 PKCS12_free(pkg);
00993
00994
00995
00996
00997 rsa = new WvRSAKey(EVP_PKEY_get1_RSA(pk), true);
00998
00999
01000 if (!rsa || !cert || test())
01001 {
01002 seterr("Could not fill in RSA and Cert with matching values.\n");
01003 return;
01004 }
01005 EVP_PKEY_free(pk);
01006 }
01007 else
01008 {
01009 seterr("Read in of PKCS12 file '%s' failed - aborting!\n", filename);
01010 return;
01011 }
01012 }
01013 else
01014 {
01015 seterr("No Password specified for PKCS12 file - aborting!\n");
01016 return;
01017 }
01018 }
01019
01020
01021 WvString WvX509Mgr::get_issuer()
01022 {
01023 if (cert)
01024 {
01025 char *name = X509_NAME_oneline(X509_get_issuer_name(cert),0,0);
01026 WvString retval(name);
01027 OPENSSL_free(name);
01028 return retval;
01029 }
01030 else
01031 return WvString::null;
01032 }
01033
01034
01035 void WvX509Mgr::set_issuer(WvStringParm issuer)
01036 {
01037 assert(cert);
01038 X509_NAME *name = X509_get_issuer_name(cert);
01039 set_name_entry(name, issuer);
01040 X509_set_issuer_name(cert, name);
01041 }
01042
01043
01044 WvString WvX509Mgr::get_subject()
01045 {
01046 if (cert)
01047 {
01048 char *name = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
01049 WvString retval(name);
01050 OPENSSL_free(name);
01051 return retval;
01052 }
01053 else
01054 return WvString::null;
01055 }
01056
01057
01058 void WvX509Mgr::set_subject(WvStringParm subject)
01059 {
01060 assert(cert);
01061 X509_NAME *name = X509_get_subject_name(cert);
01062 set_name_entry(name, subject);
01063 X509_set_subject_name(cert, name);
01064 }
01065
01066
01067 void WvX509Mgr::set_subject(X509_NAME *name)
01068 {
01069 X509_set_subject_name(cert, name);
01070 }
01071
01072
01073 void WvX509Mgr::set_pubkey(WvRSAKey *_rsa)
01074 {
01075 EVP_PKEY *pk = NULL;
01076
01077 if ((pk = EVP_PKEY_new()) == NULL)
01078 {
01079 seterr("Error creating key handler for new certificate");
01080 return;
01081 }
01082
01083
01084 if (!EVP_PKEY_set1_RSA(pk, rsa->rsa))
01085 {
01086 seterr("Error adding RSA keys to certificate");
01087 return;
01088 }
01089
01090 X509_set_pubkey(cert, pk);
01091
01092 if (pk)
01093 EVP_PKEY_free(pk);
01094 }
01095
01096
01097
01098 void WvX509Mgr::set_nsserver(WvStringParm servername)
01099 {
01100 assert(cert);
01101
01102 WvString fqdn;
01103
01104
01105
01106 if (strchr(servername, '='))
01107 fqdn = set_name_entry(NULL, servername);
01108 else
01109 fqdn = servername;
01110
01111 if (!fqdn)
01112 fqdn = "null.noname.null";
01113
01114 debug("Setting Netscape SSL server name extension to '%s'.\n", fqdn);
01115
01116
01117 set_extension(NID_netscape_cert_type, "server");
01118 set_extension(NID_netscape_ssl_server_name, fqdn);
01119 }
01120
01121
01122 WvString WvX509Mgr::get_nsserver()
01123 {
01124 return get_extension(NID_netscape_ssl_server_name);
01125 }
01126
01127
01128 WvString WvX509Mgr::get_serial()
01129 {
01130 if (cert)
01131 {
01132 return WvString(ASN1_INTEGER_get(X509_get_serialNumber(cert)));
01133 }
01134 else
01135 return WvString::null;
01136 }
01137
01138
01139 void WvX509Mgr::set_version()
01140 {
01141 X509_set_version(cert, 0x2);
01142 }
01143
01144
01145 void WvX509Mgr::set_serial(long serial)
01146 {
01147 assert(cert);
01148 ASN1_INTEGER_set(X509_get_serialNumber(cert), serial);
01149 }
01150
01151
01152 WvString WvX509Mgr::get_crl_dp()
01153 {
01154 assert(cert);
01155 return get_extension(NID_crl_distribution_points);
01156 }
01157
01158
01159 WvString WvX509Mgr::get_cp_oid()
01160 {
01161 assert(cert);
01162 return get_extension(NID_certificate_policies);
01163 }
01164
01165 void WvX509Mgr::set_cp_oid(WvStringParm oid, WvStringParm _url)
01166 {
01167 assert(cert);
01168 WvString url(_url);
01169 ASN1_OBJECT *pobj = OBJ_txt2obj(oid, 0);
01170 POLICYINFO *pol = POLICYINFO_new();
01171 POLICYQUALINFO *qual = NULL;
01172 STACK_OF(POLICYINFO) *sk_pinfo = sk_POLICYINFO_new_null();
01173 pol->policyid = pobj;
01174 if (!!url)
01175 {
01176 pol->qualifiers = sk_POLICYQUALINFO_new_null();
01177 qual = POLICYQUALINFO_new();
01178 qual->pqualid = OBJ_nid2obj(NID_id_qt_cps);
01179 qual->d.cpsuri = M_ASN1_IA5STRING_new();
01180 ASN1_STRING_set(qual->d.cpsuri, url.edit(), url.len());
01181 sk_POLICYQUALINFO_push(pol->qualifiers, qual);
01182 }
01183 sk_POLICYINFO_push(sk_pinfo, pol);
01184 X509_EXTENSION *ex = X509V3_EXT_i2d(NID_certificate_policies, 0,
01185 sk_pinfo);
01186 X509_add_ext(cert, ex, -1);
01187 X509_EXTENSION_free(ex);
01188 sk_POLICYINFO_free(sk_pinfo);
01189 }
01190
01191
01192 void WvX509Mgr::set_lifetime(long seconds)
01193 {
01194
01195 X509_gmtime_adj(X509_get_notBefore(cert), 0);
01196
01197
01198
01199
01200 X509_gmtime_adj(X509_get_notAfter(cert), seconds);
01201 }
01202
01203
01204 void WvX509Mgr::set_key_usage(WvStringParm values)
01205 {
01206 set_extension(NID_key_usage, values);
01207 }
01208
01209
01210 WvString WvX509Mgr::get_key_usage()
01211 {
01212 return get_extension(NID_key_usage);
01213 }
01214
01215
01216 void WvX509Mgr::set_ext_key_usage(WvStringParm values)
01217 {
01218 set_extension(NID_ext_key_usage, values);
01219 }
01220
01221
01222 WvString WvX509Mgr::get_ext_key_usage()
01223 {
01224 assert(cert);
01225 return get_extension(NID_ext_key_usage);
01226 }
01227
01228
01229 WvString WvX509Mgr::get_altsubject()
01230 {
01231 assert(cert);
01232 return get_extension(NID_subject_alt_name);
01233 }
01234
01235
01236 WvString WvX509Mgr::get_constraints()
01237 {
01238 assert(cert);
01239 return get_extension(NID_policy_constraints);
01240 }
01241
01242
01243 void WvX509Mgr::set_constraints(WvStringParm constraint)
01244 {
01245 assert(cert);
01246 set_extension(NID_policy_constraints, constraint);
01247 }
01248
01249
01250 void WvX509Mgr::set_aia(WvStringParm _identifier)
01251 {
01252 WvString identifier(_identifier);
01253 unsigned char *list;
01254 list = reinterpret_cast<unsigned char *>(identifier.edit());
01255 AUTHORITY_INFO_ACCESS *ainfo = sk_ACCESS_DESCRIPTION_new_null();
01256 ACCESS_DESCRIPTION *acc = ACCESS_DESCRIPTION_new();
01257 sk_ACCESS_DESCRIPTION_push(ainfo, acc);
01258 GENERAL_NAME_free(acc->location);
01259 i2d_GENERAL_NAME(acc->location, &list);
01260 #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
01261 const unsigned char** plist = const_cast<const unsigned char**>(&list);
01262 #else
01263 unsigned char** plist = &list;
01264 #endif
01265 d2i_GENERAL_NAME(&acc->location, plist, identifier.len());
01266 X509_EXTENSION *ex = X509V3_EXT_i2d(NID_info_access, 0, ainfo);
01267 X509_add_ext(cert, ex, -1);
01268 X509_EXTENSION_free(ex);
01269 sk_ACCESS_DESCRIPTION_free(ainfo);
01270 }
01271
01272
01273 WvString WvX509Mgr::get_aia()
01274 {
01275 return get_extension(NID_info_access);
01276 }
01277
01278
01279 WvStringList *parse_stack(WvStringParm ext,
01280 WvStringList *list, WvStringParm prefix)
01281 {
01282 WvStringList whole_aia;
01283 whole_aia.split(ext, "\n");
01284 WvStringList::Iter i(whole_aia);
01285 for (i.rewind();i.next();)
01286 {
01287 WvString stack_entry(*i);
01288 if (strstr(stack_entry, prefix))
01289 {
01290 WvString uri(stack_entry.edit() + prefix.len());
01291 list->append(uri);
01292 }
01293 }
01294 return list;
01295 }
01296
01297 WvStringList *WvX509Mgr::get_ocsp(WvStringList *responders)
01298 {
01299 return parse_stack(get_aia(), responders, "OCSP - URI:");
01300 }
01301
01302
01303 WvStringList *WvX509Mgr::get_ca_urls(WvStringList *urls)
01304 {
01305 return parse_stack(get_aia(), urls, "CA Issuers - URI:");
01306 }
01307
01308
01309 WvString WvX509Mgr::get_extension(int nid)
01310 {
01311 WvString retval = WvString::null;
01312
01313 if (cert)
01314 {
01315 X509 *copy = X509_dup(cert);
01316 int index = X509_get_ext_by_NID(copy, nid, -1);
01317 if (index >= 0)
01318 {
01319 X509_EXTENSION *ext = X509_get_ext(copy, index);
01320 if (ext)
01321 {
01322 X509V3_EXT_METHOD *method = X509V3_EXT_get(ext);
01323 if (!method)
01324 {
01325 WvDynBuf buf;
01326 buf.put(ext->value->data, ext->value->length);
01327 retval = buf.getstr();
01328 }
01329 else
01330 {
01331 void *ext_data = NULL;
01332 #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
01333 const unsigned char **ext_value_data;
01334 ext_value_data = (const_cast<const unsigned char **>
01335 (&ext->value->data));
01336 #else
01337 unsigned char **ext_value_data = &ext->value->data;
01338 #endif
01339 if (method->it)
01340 {
01341 ext_data = ASN1_item_d2i(NULL, ext_value_data,
01342 ext->value->length,
01343 ASN1_ITEM_ptr(method->it));
01344 debug("Applied generic conversion!\n");
01345 }
01346 else
01347 {
01348 ext_data = method->d2i(NULL, ext_value_data,
01349 ext->value->length);
01350 debug("Applied method specific conversion!\n");
01351 }
01352
01353 if (method->i2s)
01354 {
01355 debug("String Extension!\n");
01356 retval = method->i2s(method, ext_data);
01357 }
01358 else if (method->i2v)
01359 {
01360 debug("Stack Extension!\n");
01361 CONF_VALUE *val = NULL;
01362 STACK_OF(CONF_VALUE) *svals = NULL;
01363 svals = method->i2v(method, ext_data, NULL);
01364 if (!sk_CONF_VALUE_num(svals))
01365 retval = "EMPTY";
01366 else
01367 {
01368 WvStringList list;
01369 for(int i = 0; i < sk_CONF_VALUE_num(svals); i++)
01370 {
01371 val = sk_CONF_VALUE_value(svals, i);
01372 if (!val->name)
01373 list.append(WvString(val->value));
01374 else if (!val->value)
01375 list.append(WvString(val->name));
01376 else
01377 {
01378 WvString pair("%s:%s", val->name, val->value);
01379 list.append(pair);
01380 }
01381 }
01382 retval = list.join(";\n");
01383 }
01384 sk_CONF_VALUE_pop_free(svals, X509V3_conf_free);
01385 }
01386 else if (method->i2r)
01387 {
01388 debug("Raw Extension!\n");
01389 WvDynBuf retvalbuf;
01390 BIO *bufbio = BIO_new(BIO_s_mem());
01391 BUF_MEM *bm;
01392 method->i2r(method, ext_data, bufbio, 0);
01393 BIO_get_mem_ptr(bufbio, &bm);
01394 retvalbuf.put(bm->data, bm->length);
01395 BIO_free(bufbio);
01396 retval = retvalbuf.getstr();
01397 }
01398
01399 if (method->it)
01400 ASN1_item_free((ASN1_VALUE *)ext_data,
01401 ASN1_ITEM_ptr(method->it));
01402 else
01403 method->ext_free(ext_data);
01404
01405 }
01406 }
01407 }
01408 else
01409 {
01410 debug("Extension not present!\n");
01411 }
01412 if (copy)
01413 X509_free(copy);
01414 }
01415
01416 if (!!retval)
01417 {
01418 debug("Returning: %s\n", retval);
01419 return retval;
01420 }
01421 else
01422 return WvString::null;
01423 }
01424
01425 void WvX509Mgr::set_extension(int nid, WvStringParm _values)
01426 {
01427 WvString values(_values);
01428 X509_EXTENSION *ex = NULL;
01429 ex = X509V3_EXT_conf_nid(NULL, NULL, nid, values.edit());
01430 X509_add_ext(cert, ex, -1);
01431 X509_EXTENSION_free(ex);
01432 }
01433
01434
01435 bool WvX509Mgr::isok() const
01436 {
01437 return cert && rsa && WvError::isok();
01438 }
01439
01440
01441 WvString WvX509Mgr::errstr() const
01442 {
01443 if (WvError::geterr() == 0)
01444 {
01445
01446 if (!cert && !rsa)
01447 return "No certificate or RSA key assigned";
01448 else if (!cert)
01449 return "No certificate assigned";
01450 else if (!rsa)
01451 return "No RSA key assigned";
01452 }
01453 return WvError::errstr();
01454 }
01455
01456
01457 int WvX509Mgr::geterr() const
01458 {
01459 int ret = WvError::geterr();
01460 if (ret == 0 && (!cert || !rsa))
01461 {
01462
01463
01464 ret = -1;
01465 }
01466 return ret;
01467 }
01468
01469
01470 bool WvX509Mgr::signcert(X509 *unsignedcert)
01471 {
01472 if (unsignedcert == NULL)
01473 {
01474 debug("No certificate to sign??\n");
01475 return false;
01476 }
01477
01478 if (cert == unsignedcert)
01479 {
01480 debug("Self Signing!\n");
01481 printf("Looks like:\n%s\n", encode(WvX509Mgr::CertPEM).cstr());
01482 }
01483 else if (!((cert->ex_flags & EXFLAG_KUSAGE) &&
01484 (cert->ex_kusage & KU_KEY_CERT_SIGN)))
01485 {
01486 debug("This Certificate is not allowed to sign Certificates!\n");
01487 return false;
01488 }
01489
01490 debug("Ok, now sign the new cert with the current RSA key.\n");
01491 EVP_PKEY *certkey = EVP_PKEY_new();
01492 bool cakeyok = EVP_PKEY_set1_RSA(certkey, rsa->rsa);
01493 if (cakeyok)
01494 {
01495
01496 X509_sign(unsignedcert, certkey, EVP_sha1());
01497 }
01498 else
01499 {
01500 debug("No keys??\n");
01501 EVP_PKEY_free(certkey);
01502 return false;
01503 }
01504
01505 EVP_PKEY_free(certkey);
01506 return true;
01507 }
01508
01509 WvString WvX509Mgr::sign(WvStringParm data)
01510 {
01511 WvDynBuf buf;
01512 buf.putstr(data);
01513 return sign(buf);
01514 }
01515
01516 WvString WvX509Mgr::sign(WvBuf &data)
01517 {
01518 assert(rsa);
01519
01520 EVP_MD_CTX sig_ctx;
01521 unsigned char sig_buf[4096];
01522
01523 EVP_PKEY *pk = EVP_PKEY_new();
01524 if (!pk)
01525 {
01526 seterr("Unable to create PKEY object.\n");
01527 return WvString::null;
01528 }
01529
01530 if (!EVP_PKEY_set1_RSA(pk, rsa->rsa))
01531 {
01532 seterr("Error setting RSA keys.\n");
01533 EVP_PKEY_free(pk);
01534 return WvString::null;
01535 }
01536
01537 EVP_SignInit(&sig_ctx, EVP_sha1());
01538 EVP_SignUpdate(&sig_ctx, data.peek(0, data.used()), data.used());
01539 unsigned int sig_len = sizeof(sig_buf);
01540 int sig_err = EVP_SignFinal(&sig_ctx, sig_buf,
01541 &sig_len, pk);
01542 if (sig_err != 1)
01543 {
01544 seterr("Error while signing!\n");
01545 EVP_PKEY_free(pk);
01546 return WvString::null;
01547 }
01548
01549 EVP_PKEY_free(pk);
01550 EVP_MD_CTX_cleanup(&sig_ctx);
01551 WvDynBuf buf;
01552 buf.put(sig_buf, sig_len);
01553 debug("Signature size: %s\n", buf.used());
01554 return WvBase64Encoder().strflushbuf(buf, true);
01555 }
01556
01557 bool WvX509Mgr::verify(WvStringParm original, WvStringParm signature)
01558 {
01559 WvDynBuf buf;
01560 buf.putstr(original);
01561 return verify(buf, signature);
01562 }
01563
01564 bool WvX509Mgr::verify(WvBuf &original, WvStringParm signature)
01565 {
01566
01567 unsigned char sig_buf[4096];
01568 size_t sig_size = sizeof(sig_buf);
01569 WvBase64Decoder().flushstrmem(signature, sig_buf, &sig_size, true);
01570
01571 EVP_PKEY *pk = X509_get_pubkey(cert);
01572 if (!pk)
01573 {
01574 seterr("Couldn't allocate PKEY for verify()\n");
01575 return false;
01576 }
01577
01578
01579 EVP_MD_CTX sig_ctx;
01580 EVP_VerifyInit(&sig_ctx, EVP_sha1());
01581 EVP_VerifyUpdate(&sig_ctx, original.peek(0, original.used()), original.used());
01582 int sig_err = EVP_VerifyFinal(&sig_ctx, sig_buf, sig_size, pk);
01583 EVP_PKEY_free(pk);
01584 EVP_MD_CTX_cleanup(&sig_ctx);
01585 if (sig_err != 1)
01586 {
01587 debug("Verify failed!\n");
01588 return false;
01589 }
01590 else
01591 return true;
01592 }
01593
01594
01595 time_t ASN1_TIME_to_time_t(ASN1_TIME *t)
01596 {
01597 struct tm newtime;
01598 char *p = NULL;
01599 char d[18];
01600 memset(&d,'\0',sizeof(d));
01601 memset(&newtime,'\0',sizeof newtime);
01602
01603 if (t->type == V_ASN1_GENERALIZEDTIME)
01604 {
01605
01606
01607
01608 return 0;
01609 }
01610
01611 p = (char *)t->data;
01612 sscanf(p,"%2s%2s%2s%2s%2s%2sZ", d, &d[3], &d[6], &d[9], &d[12], &d[15]);
01613
01614 int year = strtol(d, (char **)NULL, 10);
01615 if (year < 49)
01616 year += 100;
01617 else
01618 year += 50;
01619
01620 newtime.tm_year = year;
01621 newtime.tm_mon = strtol(&d[3], (char **)NULL, 10) - 1;
01622 newtime.tm_mday = strtol(&d[6], (char **)NULL, 10);
01623 newtime.tm_hour = strtol(&d[9], (char **)NULL, 10);
01624 newtime.tm_min = strtol(&d[12], (char **)NULL, 10);
01625 newtime.tm_sec = strtol(&d[15], (char **)NULL, 10);
01626
01627 return mktime(&newtime);
01628 }
01629
01630 time_t WvX509Mgr::get_notvalid_before()
01631 {
01632 assert(cert);
01633 return ASN1_TIME_to_time_t(X509_get_notBefore(cert));
01634 }
01635
01636
01637 time_t WvX509Mgr::get_notvalid_after()
01638 {
01639 assert(cert);
01640 return ASN1_TIME_to_time_t(X509_get_notAfter(cert));
01641 }
01642
01643
01644 bool WvX509Mgr::signcrl(WvCRLMgr *crl)
01645 {
01646 assert(crl);
01647 assert(rsa);
01648
01649 if (!((cert->ex_flags & EXFLAG_KUSAGE) &&
01650 (cert->ex_kusage & KU_CRL_SIGN)))
01651 {
01652 debug("Certificate not allowed to sign CRLs!\n");
01653 return false;
01654 }
01655
01656 EVP_PKEY *certkey = EVP_PKEY_new();
01657 bool cakeyok = EVP_PKEY_set1_RSA(certkey, rsa->rsa);
01658 if (crl->getcrl() && cakeyok)
01659 {
01660
01661
01662 X509_CRL_set_version(crl->getcrl(), 1);
01663
01664 X509_CRL_set_issuer_name(crl->getcrl(), X509_get_subject_name(cert));
01665
01666 ASN1_TIME *tmptm = ASN1_TIME_new();
01667
01668 X509_gmtime_adj(tmptm, 0);
01669 X509_CRL_set_lastUpdate(crl->getcrl(), tmptm);
01670
01671 X509_gmtime_adj(tmptm, (long)60*60*24*30);
01672 X509_CRL_set_nextUpdate(crl->getcrl(), tmptm);
01673 ASN1_TIME_free(tmptm);
01674
01675
01676 X509_CRL_sign(crl->getcrl(), certkey, EVP_sha1());
01677 }
01678 else
01679 {
01680 debug("No keys??\n");
01681 EVP_PKEY_free(certkey);
01682 return false;
01683 }
01684 EVP_PKEY_free(certkey);
01685
01686 crl->setca(this);
01687
01688 return true;
01689 }
01690
01691
01692 WvString WvX509Mgr::get_ski()
01693 {
01694 assert(cert);
01695 return get_extension(NID_subject_key_identifier);
01696 }
01697
01698 WvString WvX509Mgr::get_aki()
01699 {
01700 assert(cert);
01701 return get_extension(NID_authority_key_identifier);
01702 }