Back to index

nordugrid-arc-nox  1.1.0~rc6
PayloadTLSStream.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <unistd.h>
00006 #ifndef WIN32
00007 #include <sys/poll.h>
00008 #else
00009 #define NOGDI
00010 #include <objbase.h>
00011 #include <io.h>
00012 #endif
00013 
00014 #include <sys/types.h>
00015 #include <sys/stat.h>
00016 #include <unistd.h>
00017 
00018 #include <openssl/err.h>
00019 #include <openssl/ssl.h>
00020 
00021 #include "PayloadTLSStream.h"
00022 
00023 namespace Arc {
00024 
00025 void PayloadTLSStream::HandleError(int code) {
00026    HandleError(logger_,code);
00027 }
00028 
00029 void PayloadTLSStream::HandleError(Logger& logger,int code) {
00030   unsigned long e = (code==SSL_ERROR_NONE)?ERR_get_error():code;
00031   while(e != SSL_ERROR_NONE) {
00032     if(e == SSL_ERROR_SYSCALL) {
00033       // Hiding system errors
00034       //logger.msg(ERROR, "SSL error: %d - system call failed",e); 
00035     } else {
00036       const char* lib = ERR_lib_error_string(e);
00037       const char* func = ERR_func_error_string(e);
00038       const char* reason = ERR_reason_error_string(e);
00039       logger.msg(ERROR, "SSL error: %d - %s:%s:%s", 
00040                         e, 
00041                         lib?lib:"",
00042                         func?func:"",
00043                         reason?reason:"");
00044     };
00045     e = ERR_get_error();
00046   }
00047 }
00048 
00049 void PayloadTLSStream::ClearError(void) {
00050   int e = ERR_get_error();
00051   while(e != 0) {
00052     e = ERR_get_error();
00053   }
00054 }
00055 
00056 PayloadTLSStream::PayloadTLSStream(Logger& logger,SSL* ssl):ssl_(ssl),logger_(logger) {
00057   //initialize something
00058   return;
00059 }
00060 
00061 PayloadTLSStream::PayloadTLSStream(PayloadTLSStream& stream):timeout_(stream.timeout_),ssl_(stream.ssl_),logger_(stream.logger_) {
00062 }
00063 
00064 PayloadTLSStream::~PayloadTLSStream(void) {
00065   ClearError();
00066 }
00067 
00068 bool PayloadTLSStream::Get(char* buf,int& size) {
00069   if(ssl_ == NULL) return false;
00070   //ssl read
00071   ssize_t l=size;
00072   size=0;
00073   l=SSL_read(ssl_,buf,l);
00074   if(l <= 0){
00075      HandleError(SSL_get_error(ssl_,l));
00076      return false;
00077   }
00078   size=l;
00079   return true;
00080 }
00081 
00082 bool PayloadTLSStream::Get(std::string& buf) {
00083   char tbuf[1024];
00084   int l = sizeof(tbuf);
00085   bool result = Get(tbuf,l);
00086   buf.assign(tbuf,l);
00087   return result;
00088 }
00089 
00090 bool PayloadTLSStream::Put(const char* buf,Size_t size) {
00091   //ssl write
00092   ssize_t l;
00093   if(ssl_ == NULL) return false;
00094   for(;size;){
00095      l=SSL_write(ssl_,buf,size);
00096      if(l <= 0){
00097         HandleError(SSL_get_error(ssl_,l));
00098         return false;
00099      }
00100      buf+=l; size-=l;
00101   }
00102   return true;
00103 }
00104 
00105 X509* PayloadTLSStream::GetPeerCert(void){
00106   X509* peercert;
00107   int err;
00108   if(ssl_ == NULL) return NULL;
00109   if((err=SSL_get_verify_result(ssl_)) == X509_V_OK){
00110     peercert=SSL_get_peer_certificate (ssl_);
00111     if(peercert!=NULL) return peercert;
00112     logger_.msg(ERROR,"Peer certificate cannot be extracted");
00113     HandleError();
00114   }
00115   else{
00116     logger_.msg(ERROR,"Peer cert verification fail");
00117     logger_.msg(ERROR,"%s",X509_verify_cert_error_string(err));
00118     HandleError(err);
00119   }
00120   return NULL;
00121 }
00122 
00123 X509* PayloadTLSStream::GetCert(void){
00124   X509* cert;
00125   if(ssl_ == NULL) return NULL;
00126   cert=SSL_get_certificate (ssl_);
00127   if(cert!=NULL) return cert;
00128   logger_.msg(WARNING,"Certificate cannot be extracted, make sure it is the case where client side authentication is turned off");
00129   HandleError();
00130   return NULL;
00131 }
00132 
00133 STACK_OF(X509)* PayloadTLSStream::GetPeerChain(void){
00134   STACK_OF(X509)* peerchain;
00135   int err;
00136   if(ssl_ == NULL) return NULL;
00137   if((err=SSL_get_verify_result(ssl_)) == X509_V_OK){
00138     peerchain=SSL_get_peer_cert_chain (ssl_);
00139     if(peerchain!=NULL) return peerchain;
00140     logger_.msg(ERROR,"Peer certificate chain cannot be extracted");
00141     HandleError();
00142   }
00143   else{
00144     logger_.msg(ERROR,"Peer cert verification fail");
00145     logger_.msg(ERROR,"%s",X509_verify_cert_error_string(err));
00146     HandleError(err);
00147   }
00148   return NULL;
00149 }
00150 
00151 } // namespace Arc