123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- /*
- * Copyright (c) 2002-2009 Moxie Marlinspike
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
- #ifndef __CERTIFICATE_H__
- #define __CERTIFICATE_H__
- #include <openssl/pem.h>
- #include <openssl/conf.h>
- #include <openssl/x509v3.h>
- #include <openssl/ssl.h>
- #include <openssl/err.h>
- #include <openssl/rand.h>
- #include <boost/asio.hpp>
- #include <iostream>
- #include <string>
- #include "../util/Util.hpp"
- #include "../Logger.hpp"
- class BadCertificateException : public std::exception {
- public:
- virtual const char* what() const throw() {
- return "Could not parse certificate...";
- }
- };
- class Certificate {
- private:
- X509 *cert;
- EVP_PKEY *key;
- std::string name;
- std::list<std::string> ocspHosts;
- std::list<boost::asio::ip::address> ips;
- std::list<boost::asio::ip::address> ocspIps;
- std::string parseNameFromOCSPUrl(std::string &url) {
- int forwardSlash = url.find('/', 7);
- if (forwardSlash) forwardSlash -= 7;
- else forwardSlash = (int) std::string::npos;
- std::string name = url.substr(7, forwardSlash);
-
- return name;
- }
- void parseOCSPUrls(X509 *cert) {
- int crit = 0;
- int idx = 0;
- STACK_OF(ACCESS_DESCRIPTION) *ads =
- (STACK_OF(ACCESS_DESCRIPTION)*)X509_get_ext_d2i(cert, NID_info_access, &crit, &idx);
- int adsnum = sk_ACCESS_DESCRIPTION_num(ads);
- for(int i=0; i<adsnum; i++) {
- ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(ads, i);
-
- if (!ad) continue;
-
- if(OBJ_obj2nid(ad->method) == NID_ad_OCSP) {
- unsigned char * data = ASN1_STRING_data(ad->location->d.ia5);
- std::string url(strdup((const char*)data));
- std::string name = parseNameFromOCSPUrl(url);
- this->ocspHosts.push_back(name);
- Logger::logInit("Added OCSP URL: " + name);
- }
- }
- }
- void parseCommonName(X509 *cert) {
- std::string distinguishedName(cert->name);
- std::string::size_type cnIndex = distinguishedName.find("CN=");
- if (cnIndex == std::string::npos) throw BadCertificateException();
- std::string commonName = distinguishedName.substr(cnIndex+3);
- std::string::size_type nullIndex = commonName.find("\\x00");
-
- if (nullIndex != std::string::npos) this->name = commonName.substr(0, nullIndex);
- else this->name = commonName;
- }
- public:
- Certificate() {}
- Certificate(X509 *cert, EVP_PKEY* key, bool resolve) {
- this->cert = cert;
- this->key = key;
-
- parseCommonName(cert);
- parseOCSPUrls(cert);
-
- if (resolve) {
- if (!isWildcard())
- Util::resolveName(name, ips);
-
- std::list<std::string>::iterator i = ocspHosts.begin();
- std::list<std::string>::iterator end = ocspHosts.end();
-
- for ( ; i != end ; i++) {
- Util::resolveName(*i, ocspIps);
- }
- }
- Logger::logInit("Certificate Ready: " + this->name);
- }
- bool isOCSPAddress(boost::asio::ip::address &address) {
- std::list<boost::asio::ip::address>::iterator i = ocspIps.begin();
- std::list<boost::asio::ip::address>::iterator end = ocspIps.end();
- for ( ; i != end ; i++) {
- if ((*i) == address) return true;
- }
- return false;
- }
- bool isValidTarget(boost::asio::ip::address &address, bool wildcardOK) {
- if (wildcardOK && isWildcard()) {
- return true;
- }
- std::list<boost::asio::ip::address>::iterator i = ips.begin();
- std::list<boost::asio::ip::address>::iterator end = ips.end();
- for ( ; i != end ; i++) {
- if ((*i) == address) return true;
- }
- return false;
- }
- X509* getCert() {
- return cert;
- }
- EVP_PKEY* getKey() {
- return key;
- }
- void setCert(X509 *cert) {
- this->cert = cert;
- }
- void setKey(EVP_PKEY *key) {
- this->key = key;
- }
- std::string& getName() {
- return name;
- }
- bool isWildcard() {
- return name[0] == '*';
- }
- };
- #endif
|