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