Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

SslCtx.cpp

Go to the documentation of this file.
00001 #include "headers.h"
00002 
00064 
00068 SslCtx::SslCtx()
00069 {
00070     SSL_METHOD *method;
00071     method = SSLv23_method();
00072     m_sslCtx = SSL_CTX_new(method);
00073     if (m_sslCtx == NULL) {
00074         debug(DEBUG_SSL, "Error creating SslCtx object");
00075         return;
00076     }
00077     
00078     setDefaultOptions();
00079 } // ctor
00080 
00081 
00082 SslCtx::~SslCtx()
00083 {
00084     if (m_sslCtx) {
00085         SSL_CTX_free(m_sslCtx);
00086     }
00087 } // dtor
00088 
00089 
00090 SSL_CTX* 
00091 SslCtx::getSslCtx()
00092 { 
00093     return m_sslCtx; 
00094 } // fn getSslCtx()
00095 
00096 
00097 int 
00098 SslCtx::verify_callback(int ok, X509_STORE_CTX *ctx)
00099 {
00100     //  char    buf[256];  
00101     //  X509    *current_cert;  
00102     //  int     depth, err;  
00103 
00104     //  current_cert = X509_STORE_CTX_get_current_cert(ctx);  
00105     //  X509_NAME_oneline(X509_get_subject_name(current_cert), buf, 256);  
00106 
00107     if(!ok) {
00108         //  err = X509_STORE_CTX_get_error(ctx);  
00109         //  depth = X509_STORE_CTX_get_error_depth(ctx);  
00110 
00111         switch(ctx->error) {
00112         case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
00113             debug(DEBUG_SSL, "error: unable to get issuer cert\n");
00114             break;
00115 
00116         case X509_V_ERR_CERT_NOT_YET_VALID:
00117             debug(DEBUG_SSL, "error: cert not yet valid\n");
00118             break;
00119 
00120 
00121         case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
00122             debug(DEBUG_SSL, "error: cert not before field\n");
00123             break;
00124 
00125         case X509_V_ERR_CERT_HAS_EXPIRED:
00126             debug(DEBUG_SSL, "error: cert has expired\n");
00127             break;
00128 
00129         case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
00130             debug(DEBUG_SSL, "error: cert not after field\n");
00131             break;
00132 
00133         default:
00134             debug(DEBUG_SSL, "error: no matching case\n");
00135             break;
00136         }
00137     }
00138 
00139     return ok;
00140 } // fn verify_callback
00141 
00142 /*
00143 int 
00144 SslCtx::key_callback(char *buf, int size, int rwflag, void* user_data)
00145 {
00146     int len;
00147     SslCtx* sc;
00148     
00149     sc = (SslCtx*) user_data;
00150     
00151     len = strlen(sc->m_privateKeyPassword);
00152     len = (len > size) ? size : len;
00153     memcpy(buf, sc->m_privateKeyPassword, len);
00154 
00155     return len;
00156 } // fn key_callback
00157 */
00158 
00159 int 
00160 SslCtx::getPrivateKeyPasswordCallback(char* buf, int size, int rwflag, void* user_data)
00161 {
00162     int len;
00163     SslCtx* sc;
00164     
00165     sc = (SslCtx*) user_data;
00166     
00167     len = sc->m_privateKeyPassword.size();
00168     len = (len > size) ? size : len;
00169     memcpy(buf, sc->m_privateKeyPassword.c_str(), len);
00170 
00171     return len;
00172 } // fn getPrivateKeyPasswordCallback
00173 
00174 
00175 /*
00176 int 
00177 SslCtx::useRsaPrivateKeyFile(char *key_file, char *key_passwd)
00178 {
00179     FILE *fp;
00180     RSA *rsa;
00181     int ret_val;
00182 
00183     fp = fopen(key_file, "r");
00184     if (!fp) {
00185         return -1;
00186     }
00187 
00188     m_privateKeyPassword = strdup(key_passwd);
00189     rsa = PEM_read_RSAPrivateKey(fp, NULL, key_callback, this);
00190     fclose(fp);
00191     if (!rsa) {
00192         return -1;
00193     }
00194 
00195     ret_val = SSL_CTX_use_RSAPrivateKey(m_sslCtx, rsa);
00196     RSA_free(rsa);
00197 
00198     return ret_val;
00199 } // fn use_rsaprivate_key_file
00200 */
00201 
00206 long
00207 SslCtx::setDefaultOptions() {
00208     // Enable all workaround bugs for faulty client/servers
00209     setOptions(SSL_OP_ALL);
00210 
00211     // Always create a new key when using ephemeral DH parameters.
00212     // This enables perfect forward secrecy (PFS).
00213     setOptions(SSL_OP_SINGLE_DH_USE);
00214 
00215     // Do not use SSLv2
00216     setOptions(SSL_OP_NO_SSLv2);
00217 
00218     return getOptions();
00219 } // fn setDefaultOptions
00220 
00221 
00225 long 
00226 SslCtx::setOptions(long options) {
00227     return SSL_CTX_set_options(m_sslCtx, options);
00228 } // fn setOptions
00229 
00230 
00234 long
00235 SslCtx::getOptions() {
00236     return SSL_CTX_get_options(m_sslCtx);
00237 } // fn getOptions
00238 
00239 
00243 void
00244 SslCtx::setPrivateKeyPassword(string password) {
00245     m_privateKeyPassword = password;
00246 
00247     // tell the SSL context to call this function when it needs to find out
00248     // the password to a private key file
00249     SSL_CTX_set_default_passwd_cb(m_sslCtx, getPrivateKeyPasswordCallback);
00250     
00251     // tell the SSL context to hand in "this" to that callback function whenever it
00252     // makes the call.
00253     SSL_CTX_set_default_passwd_cb_userdata(m_sslCtx, this);
00254 } // fn setPrivateKeyPassword
00255 
00256 
00264 bool
00265 SslCtx::setCertificateFile(string certificateFile) {
00266     // Load the certificate into the SSL context
00267     if (certificateFile.empty()) {
00268         return false;
00269     }
00270 
00271     int err = SSL_CTX_use_certificate_file(m_sslCtx, certificateFile.c_str(), SSL_FILETYPE_PEM);
00272     if (err != 1) {
00273         debug(DEBUG_SSL, "Error setting certificate file.");
00274         return false;
00275     }
00276 
00277     return true;
00278 } // fn setCertificateFile
00279 
00280 
00286 bool
00287 SslCtx::setPrivateKeyFile(string privateKeyFile) {
00288     if (privateKeyFile.empty()) {
00289         return false;
00290     }
00291     //err = useRsaPrivateKeyFile(key_file, key_passwd);
00292     int err = SSL_CTX_use_RSAPrivateKey_file(m_sslCtx, privateKeyFile.c_str(), SSL_FILETYPE_PEM);
00293     if (err <= 0) {
00294         debug(DEBUG_SSL, "Unable to set RSA private key file");
00295         return false;
00296     }
00297     
00298     err = SSL_CTX_check_private_key(m_sslCtx);
00299     if (!err) {
00300         debug(DEBUG_SSL, "Bad password for private key.");
00301         return false;
00302     }
00303     return true;
00304 } // fn setPrivateKeyFile
00305 
00306 
00310 bool
00311 SslCtx::setPrivateKeyFile(string privateKeyFile, string privateKeyPassword) {
00312     setPrivateKeyPassword(privateKeyPassword);
00313     return setPrivateKeyFile(privateKeyFile);
00314 } // fn setPrivateKeyFile
00315 
00316 
00331 bool
00332 SslCtx::setCertificateAuthorityFile(string caFile, string caPath) {
00333     if (caFile.empty()) {
00334         return false;
00335     }
00336 
00337     int err = SSL_CTX_load_verify_locations(m_sslCtx, caFile.c_str(), caPath.c_str());
00338     if (err <= 0) {
00339         debug(DEBUG_SSL, "Unable to load certificate verify locations.");
00340         return false;
00341     }
00342     
00343     // Set whether certificates are checked(verified) and/or sent (depending on
00344     // whether we are the client or server).
00345     //SSL_CTX_set_verify(m_sslCtx, SSL_VERIFY_PEER, verify_callback);
00346 
00347     return true;
00348 } // fn setCertificateAuthorityFile
00349 
00350 

Generated at Thu Jul 11 13:31:52 2002 for Peekabooty by doxygen1.2.9 written by Dimitri van Heesch, © 1997-2001