Certificate.hpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * Copyright (c) 2002-2009 Moxie Marlinspike
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 3 of the
  7. * License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  17. * USA
  18. */
  19. #ifndef __CERTIFICATE_H__
  20. #define __CERTIFICATE_H__
  21. #include <openssl/pem.h>
  22. #include <openssl/conf.h>
  23. #include <openssl/x509v3.h>
  24. #include <openssl/ssl.h>
  25. #include <openssl/err.h>
  26. #include <openssl/rand.h>
  27. #include <boost/asio.hpp>
  28. #include <iostream>
  29. #include <string>
  30. #include "../util/Util.hpp"
  31. #include "../Logger.hpp"
  32. class BadCertificateException : public std::exception {
  33. public:
  34. virtual const char* what() const throw() {
  35. return "Could not parse certificate...";
  36. }
  37. };
  38. class Certificate {
  39. private:
  40. X509 *cert;
  41. EVP_PKEY *key;
  42. std::string name;
  43. std::list<std::string> ocspHosts;
  44. std::list<boost::asio::ip::address> ips;
  45. std::list<boost::asio::ip::address> ocspIps;
  46. std::string parseNameFromOCSPUrl(std::string &url) {
  47. int forwardSlash = url.find('/', 7);
  48. if (forwardSlash) forwardSlash -= 7;
  49. else forwardSlash = (int) std::string::npos;
  50. std::string name = url.substr(7, forwardSlash);
  51. return name;
  52. }
  53. void parseOCSPUrls(X509 *cert) {
  54. int crit = 0;
  55. int idx = 0;
  56. STACK_OF(ACCESS_DESCRIPTION) *ads =
  57. (STACK_OF(ACCESS_DESCRIPTION)*)X509_get_ext_d2i(cert, NID_info_access, &crit, &idx);
  58. int adsnum = sk_ACCESS_DESCRIPTION_num(ads);
  59. for(int i=0; i<adsnum; i++) {
  60. ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(ads, i);
  61. if (!ad) continue;
  62. if(OBJ_obj2nid(ad->method) == NID_ad_OCSP) {
  63. unsigned char * data = ASN1_STRING_data(ad->location->d.ia5);
  64. std::string url(strdup((const char*)data));
  65. std::string name = parseNameFromOCSPUrl(url);
  66. this->ocspHosts.push_back(name);
  67. Logger::logInit("Added OCSP URL: " + name);
  68. }
  69. }
  70. }
  71. void parseCommonName(X509 *cert) {
  72. std::string distinguishedName(cert->name);
  73. std::string::size_type cnIndex = distinguishedName.find("CN=");
  74. if (cnIndex == std::string::npos) throw BadCertificateException();
  75. std::string commonName = distinguishedName.substr(cnIndex+3);
  76. std::string::size_type nullIndex = commonName.find("\\x00");
  77. if (nullIndex != std::string::npos) this->name = commonName.substr(0, nullIndex);
  78. else this->name = commonName;
  79. }
  80. public:
  81. Certificate() {}
  82. Certificate(X509 *cert, EVP_PKEY* key, bool resolve) {
  83. this->cert = cert;
  84. this->key = key;
  85. parseCommonName(cert);
  86. parseOCSPUrls(cert);
  87. if (resolve) {
  88. if (!isWildcard())
  89. Util::resolveName(name, ips);
  90. std::list<std::string>::iterator i = ocspHosts.begin();
  91. std::list<std::string>::iterator end = ocspHosts.end();
  92. for ( ; i != end ; i++) {
  93. Util::resolveName(*i, ocspIps);
  94. }
  95. }
  96. Logger::logInit("Certificate Ready: " + this->name);
  97. }
  98. bool isOCSPAddress(boost::asio::ip::address &address) {
  99. std::list<boost::asio::ip::address>::iterator i = ocspIps.begin();
  100. std::list<boost::asio::ip::address>::iterator end = ocspIps.end();
  101. for ( ; i != end ; i++) {
  102. if ((*i) == address) return true;
  103. }
  104. return false;
  105. }
  106. bool isValidTarget(boost::asio::ip::address &address, bool wildcardOK) {
  107. if (wildcardOK && isWildcard()) {
  108. return true;
  109. }
  110. std::list<boost::asio::ip::address>::iterator i = ips.begin();
  111. std::list<boost::asio::ip::address>::iterator end = ips.end();
  112. for ( ; i != end ; i++) {
  113. if ((*i) == address) return true;
  114. }
  115. return false;
  116. }
  117. X509* getCert() {
  118. return cert;
  119. }
  120. EVP_PKEY* getKey() {
  121. return key;
  122. }
  123. void setCert(X509 *cert) {
  124. this->cert = cert;
  125. }
  126. void setKey(EVP_PKEY *key) {
  127. this->key = key;
  128. }
  129. std::string& getName() {
  130. return name;
  131. }
  132. bool isWildcard() {
  133. return name[0] == '*';
  134. }
  135. };
  136. #endif