const char *OpenSSLQueryCipher(STREAM *S) { void *ptr; if (! S) return(NULL); ptr=STREAMGetItem(S,"LIBUSEFUL-SSL-CTX"); if (! ptr) return(NULL); #ifdef HAVE_LIBSSL const SSL_CIPHER *Cipher; char *Tempstr=NULL; Cipher=SSL_get_current_cipher((const SSL *) ptr); if (Cipher) { Tempstr=FormatStr(Tempstr,"%d bit %s",SSL_CIPHER_get_bits(Cipher,NULL), SSL_CIPHER_get_name(Cipher)); STREAMSetValue(S,"SSL-Cipher",Tempstr); Tempstr=SetStrLen(Tempstr,1024); Tempstr=SSL_CIPHER_description(Cipher, Tempstr, 1024); STREAMSetValue(S,"SSL-Cipher-Details",Tempstr); } DestroyString(Tempstr); return(STREAMGetValue(S,"SSL-Cipher")); #else return(NULL); #endif }
int STREAMInternalFinalWriteBytes(STREAM *S, const char *Data, int DataLen) { fd_set selectset; int result, count=0; struct timeval tv; if (! S) return(STREAM_CLOSED); if (S->out_fd==-1) return(STREAM_CLOSED); while (count < DataLen) { if (S->Flags & SF_SSL) { #ifdef HAVE_LIBSSL result=SSL_write((SSL *) STREAMGetItem(S,"LIBUSEFUL-SSL-CTX"), Data + count, DataLen - count); #endif } else { if (S->Timeout > 0) { FD_ZERO(&selectset); FD_SET(S->out_fd, &selectset); tv.tv_sec=S->Timeout; tv.tv_usec=0; result=select(S->out_fd+1,NULL,&selectset,NULL,&tv); if (result==-1) return(STREAM_CLOSED); if ((result == 0) || (! FD_ISSET(S->out_fd, &selectset))) return(STREAM_TIMEOUT); } if (S->Flags & SF_WRLOCK) flock(S->out_fd,LOCK_EX); result=write(S->out_fd, Data + count, DataLen - count); if (S->Flags & SF_WRLOCK) flock(S->out_fd,LOCK_UN); } if (result < 1 && ((errno !=EINTR) && (errno !=EAGAIN)) ) break; if (result < 0) result=0; count+=result; S->BytesWritten+=result; } //memmove any remaining data so that we add onto the end of it S->OutEnd -= count; if (S->OutEnd > 0) memmove(S->OutputBuff,S->OutputBuff+count, S->OutEnd); return(count); }
int STREAMIsPeerAuth(STREAM *S) { void *ptr; #ifdef HAVE_LIBSSL ptr=STREAMGetItem(S,"LIBUSEFUL-SSL-CTX"); if (! ptr) return(FALSE); if (SSL_get_verify_result((SSL *) ptr)==X509_V_OK) { if (SSL_get_peer_certificate((SSL *) ptr) !=NULL) return(TRUE); } #endif return(FALSE); }
const char *STREAMQuerySSLCipher(STREAM *S) { void *ptr; if (! S) return(NULL); ptr=STREAMGetItem(S,"LIBUSEFUL-SSL-CTX"); if (! ptr) return(NULL); #ifdef HAVE_LIBSSL return(SSL_get_cipher((SSL *) ptr)); #else return(NULL); #endif }
static void MMapSetup() { char *FName=NULL, *Tempstr=NULL; struct stat Stat; int MMapSize=4096, result; STREAM *S; if (! CrayonizerMMap) { FName=MCopyStr(FName, GetCurrUserHomeDir(), "/.crayonizer.mmap", NULL); result=stat(FName, &Stat); if ((result==-1) || (Stat.st_size < MMapSize)) { S=STREAMOpen(FName, "w"); if (S) { Tempstr=SetStrLen(Tempstr, MMapSize); memset(Tempstr, 0, MMapSize); STREAMWriteBytes(S, Tempstr, MMapSize); STREAMClose(S); } } S=STREAMOpen(FName, "r+M"); if (S) CrayonizerMMap=STREAMGetItem(S, "MMap"); } //Don't close! //STREAMClose(S); Destroy(Tempstr); Destroy(FName); }
int STREAMReadCharsToBuffer(STREAM *S) { fd_set selectset; int result=0, diff, read_result=0, WaitForBytes=TRUE; struct timeval tv; char *tmpBuff=NULL; int v1, v2,v3; void *SSL_CTX=NULL; if (! S) return(0); if (S->State & SS_EMBARGOED) return(0); SSL_CTX=STREAMGetItem(S,"LIBUSEFUL-SSL-CTX"); if (S->InStart >= S->InEnd) { S->InEnd=0; S->InStart=0; } diff=S->InEnd-S->InStart; if (S->InStart > (S->BuffSize / 2)) { memmove(S->InputBuff,S->InputBuff + S->InStart,diff); S->InStart=0; S->InEnd=diff; } v1=S->InStart; v2=S->InEnd; v3=S->BuffSize; //if no room in buffer, we can't read in more bytes if (S->InEnd >= S->BuffSize) return(1); //if there are bytes available in the internal OpenSSL buffers, when we don't have to //wait on a select, we can just go straight through to SSL_read #ifdef HAVE_LIBSSL if (S->Flags & SF_SSL) { if (SSL_pending((SSL *) SSL_CTX) > 0) WaitForBytes=FALSE; } //else #endif //if ((S->Timeout > 0) && (! (S->Flags & SF_NONBLOCK)) && WaitForBytes) if ((S->Timeout > 0) && WaitForBytes) { FD_ZERO(&selectset); FD_SET(S->in_fd, &selectset); tv.tv_sec=S->Timeout; tv.tv_usec=0; result=select(S->in_fd+1,&selectset,NULL,NULL,&tv); switch (result) { //we are only checking one FD, so should be 1 case 1: read_result=0; break; case 0: errno=ETIMEDOUT; read_result=STREAM_TIMEOUT; break; default: if (errno==EINTR) read_result=STREAM_TIMEOUT; else read_result=STREAM_CLOSED; break; } } //must do this, as we need it to be 0 if we don't do the reads result=0; if (read_result==0) { tmpBuff=SetStrLen(tmpBuff,S->BuffSize-S->InEnd); #ifdef HAVE_LIBSSL if (S->Flags & SF_SSL) { read_result=SSL_read((SSL *) SSL_CTX, tmpBuff, S->BuffSize-S->InEnd); } else #endif { if (S->Flags & SF_RDLOCK) flock(S->in_fd,LOCK_SH); read_result=read(S->in_fd, tmpBuff, S->BuffSize-S->InEnd); if (S->Flags & SF_RDLOCK) flock(S->in_fd,LOCK_UN); } if (read_result > 0) { result=read_result; S->BytesRead+=read_result; } else { if ((read_result == -1) && (errno==EAGAIN)) read_result=STREAM_NODATA; else read_result=STREAM_CLOSED; result=0; } } if (result !=0) read_result=result; if (result < 0) result=0; read_result=STREAMReadThroughProcessors(S, tmpBuff, result); //if (result==STREAM_DATA_ERROR) read_result=STREAM_DATA_ERROR; //We are not returning number of bytes read. We only return something if //there is a condition (like socket close) where the thing we are waiting for //may not appear DestroyString(tmpBuff); return(read_result); }
int OpenSSLVerifyCertificate(STREAM *S) { int RetVal=FALSE; #ifdef HAVE_LIBSSL char *Name=NULL, *Value=NULL, *ptr; int val; X509 *cert=NULL; SSL *ssl; ptr=STREAMGetItem(S,"LIBUSEFUL-SSL-CTX"); if (! ptr) return(FALSE); ssl=(SSL *) ptr; cert=SSL_get_peer_certificate(ssl); if (cert) { STREAMSetValue(S,"SSL-Certificate-Issuer",X509_NAME_oneline( X509_get_issuer_name(cert),NULL, 0)); ptr=X509_NAME_oneline( X509_get_subject_name(cert),NULL, 0); STREAMSetValue(S,"SSL-Certificate-Subject", ptr); ptr=GetNameValuePair(ptr,"/","=",&Name,&Value); while (ptr) { if (StrLen(Name) && (strcmp(Name,"CN")==0)) STREAMSetValue(S,"SSL-Certificate-CommonName",Value); ptr=GetNameValuePair(ptr,"/","=",&Name,&Value); } val=SSL_get_verify_result(ssl); switch(val) { case X509_V_OK: STREAMSetValue(S,"SSL-Certificate-Verify","OK"); RetVal=TRUE; break; case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: STREAMSetValue(S,"SSL-Certificate-Verify","unable to get issuer"); break; case X509_V_ERR_UNABLE_TO_GET_CRL: STREAMSetValue(S,"SSL-Certificate-Verify","unable to get certificate CRL"); break; case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: STREAMSetValue(S,"SSL-Certificate-Verify","unable to decrypt certificate's signature"); break; case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: STREAMSetValue(S,"SSL-Certificate-Verify","unable to decrypt CRL's signature"); break; case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: STREAMSetValue(S,"SSL-Certificate-Verify","unable to decode issuer public key"); break; case X509_V_ERR_CERT_SIGNATURE_FAILURE: STREAMSetValue(S,"SSL-Certificate-Verify","certificate signature invalid"); break; case X509_V_ERR_CRL_SIGNATURE_FAILURE: STREAMSetValue(S,"SSL-Certificate-Verify","CRL signature invalid"); break; case X509_V_ERR_CERT_NOT_YET_VALID: STREAMSetValue(S,"SSL-Certificate-Verify","certificate is not yet valid"); break; case X509_V_ERR_CERT_HAS_EXPIRED: STREAMSetValue(S,"SSL-Certificate-Verify","certificate has expired"); break; case X509_V_ERR_CRL_NOT_YET_VALID: STREAMSetValue(S,"SSL-Certificate-Verify","CRL is not yet valid the CRL is not yet valid."); break; case X509_V_ERR_CRL_HAS_EXPIRED: STREAMSetValue(S,"SSL-Certificate-Verify","CRL has expired the CRL has expired."); break; case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: STREAMSetValue(S,"SSL-Certificate-Verify","invalid notBefore value"); break; case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: STREAMSetValue(S,"SSL-Certificate-Verify","invalid notAfter value"); break; case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: STREAMSetValue(S,"SSL-Certificate-Verify","invalid CRL lastUpdate value"); break; case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: STREAMSetValue(S,"SSL-Certificate-Verify","invalid CRL nextUpdate value"); break; case X509_V_ERR_OUT_OF_MEM: STREAMSetValue(S,"SSL-Certificate-Verify","out of memory"); break; case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: STREAMSetValue(S,"SSL-Certificate-Verify","self signed certificate"); break; case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: STREAMSetValue(S,"SSL-Certificate-Verify","self signed certificate in certificate chain"); break; case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: STREAMSetValue(S,"SSL-Certificate-Verify","cant find root certificate in local database"); break; case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: STREAMSetValue(S,"SSL-Certificate-Verify","ERROR: unable to verify the first certificate"); break; case X509_V_ERR_CERT_CHAIN_TOO_LONG: STREAMSetValue(S,"SSL-Certificate-Verify","certificate chain too long"); break; case X509_V_ERR_CERT_REVOKED: STREAMSetValue(S,"SSL-Certificate-Verify","certificate revoked"); break; case X509_V_ERR_INVALID_CA: STREAMSetValue(S,"SSL-Certificate-Verify","invalid CA certificate"); break; case X509_V_ERR_PATH_LENGTH_EXCEEDED: STREAMSetValue(S,"SSL-Certificate-Verify","path length constraint exceeded"); break; case X509_V_ERR_INVALID_PURPOSE: STREAMSetValue(S,"SSL-Certificate-Verify","unsupported certificate purpose"); break; case X509_V_ERR_CERT_UNTRUSTED: STREAMSetValue(S,"SSL-Certificate-Verify","certificate not trusted"); break; case X509_V_ERR_CERT_REJECTED: STREAMSetValue(S,"SSL-Certificate-Verify","certificate rejected"); break; case X509_V_ERR_SUBJECT_ISSUER_MISMATCH: STREAMSetValue(S,"SSL-Certificate-Verify","subject issuer mismatch"); break; case X509_V_ERR_AKID_SKID_MISMATCH: STREAMSetValue(S,"SSL-Certificate-Verify","authority and subject key identifier mismatch"); break; case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: STREAMSetValue(S,"SSL-Certificate-Verify","authority and issuer serial number mismatch"); break; case X509_V_ERR_KEYUSAGE_NO_CERTSIGN: STREAMSetValue(S,"SSL-Certificate-Verify","key usage does not include certificate signing"); break; case X509_V_ERR_APPLICATION_VERIFICATION: STREAMSetValue(S,"SSL-Certificate-Verify","application verification failure"); break; } } else { STREAMSetValue(S,"SSL-Certificate-Verify","no certificate"); } DestroyString(Name); DestroyString(Value); #endif return(RetVal); }