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