I have this function to convert html in put to xhtml:
char* cleanhtml(char* localhtml)
{
char *buffer_;
static char *cleansed_buffer;
// uses Libtidy to convert the buffer to XML
TidyBuffer output = {0};
TidyBuffer errbuf = {0};
int rc = -1;
bool ok;
TidyDoc tdoc;
tdoc = tidyCreate(); // Initialize "document"
ok = tidyOptSetBool( tdoc, TidyXhtmlOut, yes ); // Convert to XHTML
rc = tidySetErrorBuffer( tdoc, &errbuf ); // Capture diagnostics
rc = tidyParseString(tdoc, localhtml); // Parse the input
rc = tidyCleanAndRepair( tdoc ); // Tidy it up!
rc = tidyRunDiagnostics( tdoc ); // Kvetch// If error, force output.
rc = ( tidyOptSetBool(tdoc, TidyForceOutput, yes) ? rc : -1 );
rc = tidySaveBuffer( tdoc, &output ); // Pretty Print
cleansed_buffer = (char*) malloc(output.size + 1);
memcpy (cleansed_buffer, (char*)output.bp,output.size);
tidyBufFree( &output );
tidyBufFree( &errbuf );
tidyRelease( tdoc );
return cleansed_buffer;
}
But the problem is it is not working correctly...for some reason the xhtml being given out is not being able to be parsed and it is wrong format. So how can libtidy be used to convert a given string(huge string) to xhtml in right format.
And can somebody please give me link to the latest libtidy (dlls,includes) for C.I can't find it anywhere...not even on there website..
Related
So I'm trying to save onto a database a blob but it doesn't insert anything.
I checked the return errors and I always get "error 0: not an error"
I'm using the sqlite3.org example for blob management: https://www.sqlite.org/cvstrac/wiki?p=BlobExample
Anyway here is the exact code, maybe I'm forgetting something.
int Database::insertToDatabase(
const int zKey, /*Id of row */
const unsigned char *zBlob, /* Pointer to blob of data */
int nBlob, /* Length of data pointed to by zBlob */
){
char zSql[kMaxSqlFunctionSize];
snprintf(zSql, kMaxSqlFunctionSize, "INSERT INTO RECTS(ID,DATA)VALUES(%d,?)",zKey);
sqlite3_stmt *pStmt;
int rc;
do {
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, NULL);
if( rc!=SQLITE_OK ){
return rc;
}
sqlite3_bind_blob(pStmt, 1, zBlob, nBlob, SQLITE_STATIC);
rc = sqlite3_step(pStmt);
assert( rc!=SQLITE_ROW );
rc = sqlite3_finalize(pStmt);
} while( rc==SQLITE_SCHEMA );
return rc;
}
I use sqlite_open_v2 to open the database and the tables are created correctly (checked with sqlite studio), but idk why I can't get this insert to work.
(the data I'm trying to insert isn't more than 1k).
Thanks in advance.
I need to get the raw public key bytes (with openssl this is 'der' format) from a public key SecKeyRef to implement public key pinning with. The actual pinning function is already written, cannot change, and takes a unsigned char *pubkey, size_t pubkeylen with which to compare it's pins against.
This is what I have tried so far:
SecTrustRef trust;
OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
SecKeyRef keyRef = SecTrustCopyPublicKey(trust);
CFDataRef publicKeyBits;
OSStatus success = SecItemExport(keyRef, kSecFormatOpenSSL, 0, NULL, &publicKeyBits) == errSecSuccess;
//OSStatus success = SecItemExport(keyRef, kSecFormatPEMSequence, 0, NULL, &publicKeyBits) == errSecSuccess;
size_t pubkeylen = CFDataGetLength(publicKeyBits);
printf("pubkeylen: %d\n", pubkeylen);
unsigned char *pubkey = CFDataGetBytePtr(publicKeyBits);
The problem is this does not seem to be DER format at all, I expect pubkeylen to be 550 for this particular key, but it prints 526, and the data isn't correct either. I also tried kSecFormatPEMSequence and then base64 decoding it with the same results (it does change into the identical 526 length array as before, so at least it's consistent).
edit:
It looks like when exported to kSecFormatPEMSequence the PEM contains:
-----BEGIN RSA PUBLIC KEY-----
instead of the expected
-----BEGIN PUBLIC KEY-----
Which is a different format that does not base64-decode to DER, maybe it could be parsed with more API calls back into a DER format someway?
What am I missing? Thanks for any help!
edit:
I have also tried the following:
CFDataRef d_tag = CFDataCreate(NULL, "com.bob", 7);
const void *cKeys[] = {kSecClass, kSecAttrKeyType,
kSecAttrKeyClass, kSecValueData,
kSecReturnData
};
const void *cValues[] = {kSecClassKey, kSecAttrKeyTypeRSA,
kSecAttrKeyClassPublic, keyRef,
kCFBooleanTrue
};
CFDictionaryRef saveDict = CFDictionaryCreate(NULL, cKeys, cValues,
5L, NULL, NULL);
OSStatus secStatus = SecItemCopyMatching(saveDict, (CFTypeRef)&publicKeyBits);
if (secStatus == errSecDuplicateItem ) {
printf("errSecDuplicateItem\n");
SecItemDelete(saveDict);
secStatus = SecItemAdd(saveDict, (CFTypeRef)&publicKeyBits );
}
if ( secStatus != noErr ) {
printf("return NULL\n");
return NULL;
}
size_t pubkeylen = CFDataGetLength(publicKeyBits);
printf("pubkeylen: %d\n", pubkeylen);
unsigned char *pubkey = CFDataGetBytePtr(publicKeyBits);
And the results are even worse, pubkeylen is consistently 96, but the data in pubkey is always different!
I have also tried converting https://github.com/datatheorem/TrustKit/blob/master/TrustKit/Pinning/public_key_utils.m#L65 from objective-c, I get:
OSStatus resultAdd, resultDel = noErr;
CFDataRef d_tag = CFDataCreate(NULL, "com.bobe", 9);
const void *peerPublicKeyAddcKeys[] = {kSecClass, kSecAttrApplicationTag,
kSecValueRef, kSecAttrAccessible, kSecReturnData
};
const void *peerPublicKeyAddcValues[] = {kSecClassKey, d_tag,
keyRef, kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly,
kCFBooleanTrue
};
CFDictionaryRef peerPublicKeyAdd = CFDictionaryCreate(NULL, peerPublicKeyAddcKeys, peerPublicKeyAddcValues,
5L, NULL, NULL);
const void *publicKeyGetcKeys[] = {kSecClass, kSecAttrApplicationTag,
kSecReturnData
};
const void *publicKeyGetcValues[] = {kSecClassKey, d_tag,
kCFBooleanTrue
};
CFDictionaryRef publicKeyGet = CFDictionaryCreate(NULL, publicKeyGetcKeys, publicKeyGetcValues,
3L, NULL, NULL);
resultAdd = SecItemAdd(peerPublicKeyAdd, &publicKeyBits);
resultDel = SecItemDelete(publicKeyGet);
if ((resultAdd != errSecSuccess) || (resultDel != errSecSuccess))
{
// Something went wrong with the Keychain we won't know if we did get the right key data
printf("return NULL\n");
return NULL;
}
And this time publicKeyBits is always NULL, I'm starting to tear my hair out here!
This is the code i have., which will detect the faces in the image and draws rectangle around the face.
CvHaarClassifierCascade *cascade;
CvMemStorage *storage;
void detectFaces (IplImage *newframe);
int key;
int iImg;
int Num_Images=20;
int main( int argc, char** argv )
{
string filename = M:/Trend/FaceDetection/MyCascadeFolder/haarcascade_frontalface_alt2.xml";
storage = cvCreateMemStorage(0) ;
cascade = ( CvHaarClassifierCascade* )cvLoad( filename.c_str());
**//to load a single image**
**IplImage* inImage = cvLoadImage("M:/Trend/FaceDetection775/MyImages/face1.jpg",1);**
//IplImage* inImage = cvLoadImage(argv[1],1); >> It also works fine through command line
detectFaces( inImage );
cvShowImage("FaceDetection2",inImage);
cvSaveImage("M:/FaceDetection/MyImages/OpImages/faces.jpg",inImage);
cvReleaseImage( &inImage);
// **to load no. of images or a complete folder**
char buf[20];
for(iImg=0; iImg<=Num_Images; iImg++)
{
**sprintf(buf, "M:/FaceDetection/ImagesFolder/P%04d.jpg", iImg);**
*// sprintf(buf, argv[2], iImg); // I Tried with this., but its not working*
printf("\n");
inImage = cvLoadImage(buf, CV_LOAD_IMAGE_UNCHANGED);
printf("Input Image = P%04d.jpg\n", iImg);
detectFaces( inImage );
cvShowImage("FaceDetection",inImage);
cvReleaseImage( &inImage );
key= cvWaitKey(0);
if ( key == 'q' || key == 'Q' )
return(0);
}
cvReleaseHaarClassifierCascade( &cascade );
cvReleaseMemStorage( &storage );
return 0;
}
**// the actual detectfaces() function goes like this**
void detectFaces( IplImage *newframe)
{
CvSeq *faces = cvHaarDetectObjects( newframe, cascade, storage, 1.15, 5, 0, cvSize( 30, 30 ) );
for( int i = 0 ; i < ( faces ? faces->total : 0 ) ; i++ )
{
CvRect *r = ( CvRect *)cvGetSeqElem( faces, i );
cvRectangle(newframe,cvPoint( r->x, r->y ),cvPoint( r->x + r->width, r->y + r->height ),CV_RGB( 0, 255, 0 ), 2, 8, 0 );
}
}
Here., sprintf() method is taking multiple images statically (within the program itself). But I want to pass those multiple images as a single folder through command line argument.
I try to use cvLoadImage() function, but it also takes only one image as input instead of a folder.
Also I am not able to count the number of rectangles it draws for every single face in the image., how can I do that also...?
Please help me in this regards.
I am working on face detection project "www.MahdiRezaei.com" for my academics., and I am using visual studio-2010 with C, C++ and OpenCV.
Thankz in advance.
You can change the following code to use it with arguments.
#include<Windows.h>
#include<iostream>
#include<opencv2\highgui\highgui.hpp>
using namespace cv;
using namespace std;
int main()
{
WIN32_FIND_DATA data;
HANDLE h = FindFirstFile(L"c:\\Images\\*.*", &data); // first file is the current directory
FindNextFile(h, &data); //second file is the parent directory
vector<Mat> Images;
if (h != INVALID_HANDLE_VALUE)
{
while (FindNextFile(h, &data))
{
string filename = data.cFileName;
sprintf(filename, "%s%s","C:\\Images\\", filename.c_str());
Images.push_back(imread(filename, 1));
delete[] nPtr;
}
}
else
cout << "Error: No such folder." << endl;
FindClose(h);
return 0;
}
I'm writing a logger library in C and am currently trying to get better backtrace output by using addr2line. In order to do so, I need to be able to get the path of the current executable. At the moment I am just concerned about linux, but will be shooting for Mac OS support as well.
For linux support I'm trying to use readlink() and /proc/self/exe to resolve the current executable's path:
static char** getPrettyBacktrace( void* addresses[], int array_size ) {
// Used to return the strings generated from the addresses
char** backtrace_strings = (char**)malloc( sizeof( char ) * array_size );
for( int i = 0; i < array_size; i ++ ) {
backtrace_strings[i] = (char*)malloc( sizeof( char ) * 255 );
}
// Will hold the command to be used
char* command_string = (char*)malloc( 255 );
char* exe_path = (char*)malloc( 255 );
// Used to check if an error occured while setting up command
bool error = false;
// Check if we are running on Mac OS or not, and select appropriate command
char* command;
#ifdef __APPLE__
// Check if 'gaddr2line' function is available, if not exit
if( !system( "which gaddr2line > /dev/null 2>&1" ) ) {
command = "gaddr2line -Cfspe";
// TODO: get path for mac with 'proc_pidpath'
} else {
writeLog( SIMPLOG_LOGGER, "Function 'gaddr2line' unavailable. Defaulting to standard backtrace. Please install package 'binutils' for better stacktrace output." );
error = true;
}
#else
// Check if 'addr2line' function is available, if not exit
if( !system( "which addr2line > /dev/null 2>&1" ) ) {
command = "addr2line -Cfspe";
if( readlink( "/proc/self/exe", exe_path, sizeof( exe_path ) ) < 0 ) {
writeLog( SIMPLOG_LOGGER, "Unable to get execution path. Defaulting to standard backtrace." );
error = true;
}
} else {
writeLog( SIMPLOG_LOGGER, "Function 'addr2line' unavailable. Defaulting to standard backtrace. Please install package 'binutils' for better stacktrace output." );
error = true;
}
#endif
// If an error occured, exit now
if( error ) {
free( backtrace_strings );
free( command_string );
free( exe_path );
return NULL;
}
for( int i = 0; i < array_size; i++ ) {
// Compose the complete command to execute
sprintf( command_string, "%s %s %X", command, exe_path, addresses[i] );
// Execute the command
FILE* line = popen( command_string, "r" );
// Get the size of the command output
int line_size = fseek( line, 0, SEEK_END );
// Read the output into the return string
fgets( backtrace_strings[i] , line_size, line );
// Close the command pipe
pclose( line );
}
return backtrace_strings;
}
The path being returned by readlink() is: /home/nax��?. the first part is correct: /home/na, but everything after that is pure gibberish.
Why am I unable to get the current execution path in this way?
char* exe_path = (char*)malloc( 255 );
// ...
readlink( "/proc/self/exe", exe_path, sizeof( exe_path ) )
exe_path is a pointer, so it's size will be equal to sizeof(char*) (4 or 8), not 255.
change exe_path to char[255] or change the call to sizeof
btw, readlink does not append the NULL byte, so you should do something like this:
len = readlink( "/proc/self/exe", exe_path, sizeof( exe_path ) )
exe_path[len] = 0;
I have a server which would listen on HTTPS using OpenSSL. For this, I have to provide the certificate to use. However, the current implementation uses a filename to be provided to the OpenSSL API.
I want the certificate information to be read from memory, so that I don't have to ship the certificate file opening. I tried to google, but I didn't come up with any options.
Is is possible? If so, how do I read certificate files from memory instead of a file using OpenSSL?
EDIT: The following was moved from the comments to the question.
// CURRENT
void start_server()
{
const char *fileName = "cert_and_key.pem";
set_server_ssl_file(fileName);
}
set_server_ssl_file(const char *fileName)
{
//initialize context
SSL_CTX_use_certificate_file(CTX, pem, SSL_FILETYPE_PEM);
SSL_CTX_use_PrivateKey_file(CTX, pem, SSL_FILETYPE_PEM);
}
//REQUIRED
void start_server()
{
const char *cert = "--BEGIN CERTIFICATE--............";
const char *key = "--BEGIN RSA PRIVATE KEY--.......";
set_server_ssl_options(cert, key);
}
set_server_ssl_options(const char *cert, const char *key)
{
//IMPLEMENTATION REQUIRED
}
The following code did the job for me:
SSL_CTX *CTX;
X509 *cert = NULL;
RSA *rsa = NULL;
BIO *cbio, *kbio;
const char *cert_buffer = "";
const char *key_buffer = "";
cbio = BIO_new_mem_buf((void*)cert_buffer, -1);
cert = PEM_read_bio_X509(cbio, NULL, 0, NULL);
assert(cert != NULL);
SSL_CTX_use_certificate(CTX, cert);
kbio = BIO_new_mem_buf((void*)key_buffer, -1);
rsa = PEM_read_bio_RSAPrivateKey(kbio, NULL, 0, NULL);
assert(rsa != NULL);
SSL_CTX_use_RSAPrivateKey(CTX, rsa);
The other snippets will only load one certificate. The content of files like http://curl.haxx.se/ca/cacert.pem that contain a lot of different certificates need a new approach. This is adapted from openssl 1.0.1p (mostly openssl-1.0.1p\crypto\x509\by_file.c, char* buf contains the content of a *.pem file, ctx is a boost::asio::ssl::context), add error handling on your own:
BIO *cbio = BIO_new_mem_buf((void*)buf, (int)length);
X509_STORE *cts = SSL_CTX_get_cert_store(ctx.native_handle());
if(!cts || !cbio)
return false;
X509_INFO *itmp;
int i, count = 0, type = X509_FILETYPE_PEM;
STACK_OF(X509_INFO) *inf = PEM_X509_INFO_read_bio(cbio, NULL, NULL, NULL);
if (!inf)
{
BIO_free(cbio);//cleanup
return false;
}
//itterate over all entries from the pem file, add them to the x509_store one by one
for (i = 0; i < sk_X509_INFO_num(inf); i++) {
itmp = sk_X509_INFO_value(inf, i);
if (itmp->x509) {
X509_STORE_add_cert(cts, itmp->x509);
count++;
}
if (itmp->crl) {
X509_STORE_add_crl(cts, itmp->crl);
count++;
}
}
sk_X509_INFO_pop_free(inf, X509_INFO_free); //cleanup
BIO_free(cbio);//cleanup
unsigned char *cert_data = (....);
int cert_len = (....);
X509 *cert = d2i_X509(NULL, &cert_data, cert_len);
SSL_CTX_use_certificate(ctx, cert);
unsigned char *pkey_data = /* ... */;
int pkey_len = /* ... */;
RSA *pkey = d2i_RSAPrivateKey(NULL, &pkey_data, pkey_len);
SSL_CTX_use_RSAPrivateKey(ctx, pkey);
Don't forget & before cert_data and pkey_data - and note that OpenSSL modifies these pointers.
There is another response that uses X509_STORE_add_cert, which is up-voted but incorrect. That answer is a way to do SSL_CTX_load_verify_locations in memory, but does not load the server certificate chain. Replies to that comment also indicate that it does not work.
The following code is a load-from-memory implementation of SSL_CTX_use_certificate_chain_file based on the implementation of that function in OpenSSL:
bool load_cert_chain_from_shared_mem(SSL_CTX *context, const char *cert_buffer)
{
BIO *cbio = BIO_new_mem_buf((void*)cert_buffer, -1);
if (!cbio)
return false;
X509_INFO *itmp;
int i, count = 0, type = X509_FILETYPE_PEM;
STACK_OF(X509_INFO) *inf = PEM_X509_INFO_read_bio(cbio, NULL, NULL, NULL);
if (!inf)
{
BIO_free(cbio);
return false;
}
/* Iterate over contents of the PEM buffer, and add certs. */
BOOL first = TRUE;
for (i = 0; i < sk_X509_INFO_num(inf); i++) {
itmp = sk_X509_INFO_value(inf, i);
if (itmp->x509)
{
/* First cert is server cert. Remaining, if any, are intermediate certs. */
if (first)
{
first = FALSE;
/*
* Set server certificate. Note that this operation increments the
* reference count, which means that it is okay for cleanup to free it.
*/
if (!SSL_CTX_use_certificate(context, itmp->x509))
goto Error;
if (ERR_peek_error() != 0)
goto Error;
/* Get ready to store intermediate certs, if any. */
SSL_CTX_clear_chain_certs(context);
}
else
{
/* Add intermediate cert to chain. */
if (!SSL_CTX_add0_chain_cert(context, itmp->x509))
goto Error;
/*
* Above function doesn't increment cert reference count. NULL the info
* reference to it in order to prevent it from being freed during cleanup.
*/
itmp->x509 = NULL;
}
}
}
sk_X509_INFO_pop_free(inf, X509_INFO_free);
BIO_free(cbio);
return true;
Error:
sk_X509_INFO_pop_free(inf, X509_INFO_free);
BIO_free(cbio);
return false;
}