HSM_SLOT_INFO * HSM_SLOT_INFO_get ( unsigned long num, HSM *hsm ) { HSM_SLOT_INFO *ret = NULL; if( !hsm ) { ret = (HSM_SLOT_INFO *) PKI_Malloc ( sizeof (HSM_SLOT_INFO)); memcpy( ret, &default_slot_info, sizeof( HSM_SLOT_INFO )); snprintf(ret->manufacturerID, MANUFACTURER_ID_SIZE, "%s", "OpenCA Labs"); snprintf(ret->description, DESCRIPTION_SIZE, "%s", "LibPKI Software HSM"); snprintf(ret->token_info.label, LABEL_SIZE, "%s", "LibPKI Software Token"); snprintf(ret->token_info.manufacturerID, MANUFACTURER_ID_SIZE, "%s", "OpenCA Labs"); snprintf(ret->token_info.model, MODEL_SIZE, "%s", "OpenSSL Library"); snprintf(ret->token_info.serialNumber, SERIAL_NUMBER_SIZE, "%s", "0000:0000"); } else if ( hsm->callbacks && hsm->callbacks->slot_info_get ) { ret = hsm->callbacks->slot_info_get ( num, hsm ); } else { ret = (HSM_SLOT_INFO *) PKI_Malloc ( sizeof (HSM_SLOT_INFO)); memcpy( ret, &default_slot_info, sizeof( HSM_SLOT_INFO )); }; return ( ret ); };
/*! \brief Returns the contents of the PKI_MEM in a string which is guaranteed * to carry all the contents of the original PKI_MEM and terminated (at * size + 1) with a NULL char. */ char * PKI_MEM_get_parsed(PKI_MEM *buf) { char *ret = NULL; if (!buf || !buf->data) return NULL; if (buf->size < 1) { ret = PKI_Malloc(1); *ret = '\x0'; return ret; } ret = PKI_Malloc(buf->size + 1); if (!ret) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return NULL; } memcpy(ret, buf->data, buf->size); ret[buf->size] = '\x0'; return ret; }
PKI_DIGEST *PKI_X509_CERT_fingerprint(const PKI_X509_CERT *x, const PKI_DIGEST_ALG *alg ){ PKI_DIGEST *ret = NULL; PKI_X509_CERT_VALUE *cert = NULL; unsigned char buf[EVP_MAX_MD_SIZE]; unsigned int ret_size = 0; /* Check that we have a valid certificate */ if( !x || !x->value || x->type != PKI_DATATYPE_X509_CERT ) return ( NULL ); cert = (PKI_X509_CERT_VALUE *) x->value; /* If no Algorithm is provided, we use the default one */ if( alg == NULL ) { alg = PKI_DIGEST_ALG_DEFAULT; } /* Calculate the Digest */ if (!X509_digest(cert,alg,buf,&ret_size)) { /* ERROR */ return ( NULL ); } /* Allocate the return structure */ if((ret = PKI_Malloc ( sizeof( PKI_DIGEST) )) == NULL ) { /* Memory Allocation Error! */ return( NULL ); } /* Allocate the buffer */ if((ret->digest = PKI_Malloc ( ret_size )) == NULL ) { /* Memory Error */ PKI_Free ( ret ); return( NULL ); } /* Set the size of the Digest */ ret->size = ret_size; /* Copy the Digest Data */ memcpy( ret->digest, buf, ret->size ); /* Sets the algorithm used */ ret->algor = alg; return ( ret ); }
static char * _xml_search_namespace_add ( char *search ) { char *my_search = NULL; char *my_arg = NULL; char *ret = NULL; int r = 0; int i = 0; // return strdup ( search ); /* Let's alloc enough memory for the arguments, maybe this is too much, but for the moment, let's keep it big */ my_arg = PKI_Malloc ( BUFF_MAX_SIZE ); my_search = PKI_Malloc ( BUFF_MAX_SIZE ); /* Now let's take care about setting the appropriate namespace if it is not passed, already */ i = 0; while( search[i] == LIBPKI_PATH_SEPARATOR_CHAR ) { i++; strncat(my_search, LIBPKI_PATH_SEPARATOR, BUFF_MAX_SIZE ); } while( (i < strlen( search )) && (sscanf( search + i, "%[^" LIBPKI_PATH_SEPARATOR "]%n", my_arg, &r ) > 0 )) { i = i + r; if( strchr( my_arg, ':' ) == NULL ) { strncat( my_search, PKI_NAMESPACE_PREFIX ":", BUFF_MAX_SIZE - strlen(my_search) ); } strncat( my_search, my_arg, BUFF_MAX_SIZE - strlen(my_search)); while( search[i] == LIBPKI_PATH_SEPARATOR_CHAR ) { i++; strncat(my_search, LIBPKI_PATH_SEPARATOR, BUFF_MAX_SIZE - strlen( my_search )); } } PKI_Free( my_arg ); ret = PKI_Malloc ( strlen( my_search ) + 1); strncpy( ret, my_search, strlen(my_search) ); PKI_Free ( my_search ); return( ret ); }
/* PEM <-> INTERNAL Macros --- fix for errors in OpenSSL */ PKI_OCSP_RESP *PEM_read_bio_PKI_OCSP_RESP( PKI_IO *bp, void *a, void *b, void *c ) { PKI_OCSP_RESP *ret = NULL; if (( ret = (PKI_OCSP_RESP *) PKI_Malloc ( sizeof( PKI_OCSP_RESP ))) == NULL ) { return NULL; } #if OPENSSL_VERSION_NUMBER < 0x0090800fL ret->resp = (PKI_X509_OCSP_RESP_VALUE *) PEM_ASN1_read_bio( (char *(*)()) d2i_OCSP_RESPONSE, PEM_STRING_OCSP_RESPONSE, bp, NULL, NULL, NULL); #else ret->resp = (PKI_X509_OCSP_RESP_VALUE *) PEM_ASN1_read_bio( (void *(*)()) d2i_OCSP_RESPONSE, PEM_STRING_OCSP_RESPONSE, bp, NULL, NULL, NULL); #endif if ( ret->resp == NULL ) { PKI_Free ( ret ); return NULL; } ret->bs = OCSP_response_get1_basic(ret->resp); return ret; }
char * PKI_OID_get_str ( PKI_OID *a ) { char *ret = NULL; BUF_MEM *buf_mem = NULL; BIO *mem = NULL; /* Check the Input */ if( !a ) return NULL; if((mem = BIO_new(BIO_s_mem())) == NULL ) { return ( NULL ); } i2a_ASN1_OBJECT( mem, a ); /* Copy the data from the BIO to the PKI_MEM structure */ BIO_get_mem_ptr(mem, &buf_mem); if( ( ret = PKI_Malloc ( (size_t) (buf_mem->length + 1))) == NULL ) { BIO_free_all( mem ); return ( NULL ); } memcpy(ret, buf_mem->data, (size_t) buf_mem->length ); ret[buf_mem->length] = '\x0'; BIO_free_all ( mem ); return ( ret ); }
int PKI_MEM_grow( PKI_MEM *buf, size_t data_size ) { size_t new_size = 0; if (!buf) return PKI_ERR; if (buf->data == NULL) { buf->data = PKI_Malloc(data_size); if (!buf->data) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return (PKI_ERR); } buf->size = data_size; } else { new_size = buf->size + data_size; buf->data = realloc(buf->data, new_size); buf->size = new_size; } return ((int) buf->size); }
char * PKI_DIGEST_get_parsed ( PKI_DIGEST *digest ) { char *ret = NULL; int i = 0; if( !digest ) return ( NULL ); if ((digest->size <= 0) || (!digest->digest )) return ( NULL ); ret = PKI_Malloc((digest->size * 3) + 1); // ret = PKI_Malloc ( 1024 ); ret[0] = '\x0'; for (i = 0; i < digest->size; i++) { unsigned char c; char kk[4]; if( i > 0 ) strcat (ret, ":" ); c = digest->digest[i]; sprintf(kk, "%2.2x%c", c,'\x0' ); strcat(ret, kk); } return ( ret ); }
PKI_OCSP_RESP *d2i_PKI_OCSP_RESP_bio ( PKI_IO *bp, PKI_OCSP_RESP **p ) { PKI_OCSP_RESP *ret = NULL; if (( ret = (PKI_OCSP_RESP *) PKI_Malloc ( sizeof( PKI_OCSP_RESP ))) == NULL ) { return NULL; } #if OPENSSL_VERSION_NUMBER < 0x0090800fL ret->resp = (PKI_X509_OCSP_RESP_VALUE *) ASN1_d2i_bio( (char *(*)(void))OCSP_RESPONSE_new, (char *(*)(void **, const unsigned char **, long)) d2i_OCSP_RESPONSE, bp, (unsigned char **) NULL); #else ret->resp = (PKI_X509_OCSP_RESP_VALUE *) ASN1_d2i_bio( (void *(*)(void))OCSP_RESPONSE_new, (void *(*)(void **, const unsigned char **, long)) d2i_OCSP_RESPONSE, bp, (void **) NULL); #endif if ( !ret->resp ) { PKI_Free ( ret ); return NULL; } ret->bs = OCSP_response_get1_basic(ret->resp); return ret; }
char *parse_url_table ( const URL * url ) { char *tmp_s = NULL; char *tmp_s2 = NULL; char *ret = NULL; char *dbname = NULL; size_t size = 0; if(!url || !url->path ) return (NULL); if((dbname = parse_url_dbname( url )) == NULL ) { return (NULL); } tmp_s = url->path + strlen(dbname) + 1; PKI_Free( dbname ); if((tmp_s2 = strchr( tmp_s, '/' )) == NULL ) { size = strlen( tmp_s ); } else { size = (size_t) (tmp_s2 - tmp_s); } if((ret = PKI_Malloc ( size + 1 )) == NULL ) { return(NULL); } memcpy(ret, tmp_s, size ); ret[size] = '\x0'; return( ret ); }
HSM_SLOT_INFO * HSM_OPENSSL_SLOT_INFO_get (unsigned long num, HSM *hsm) { HSM_SLOT_INFO *ret = NULL; ret = (HSM_SLOT_INFO *) PKI_Malloc ( sizeof (HSM_SLOT_INFO)); memcpy( ret, &openssl_slot_info, sizeof( HSM_SLOT_INFO )); return (ret); }
char *pkcs11_parse_url_getval ( URL * url, char *keyword ) { char * ret = NULL; char * tmp_s = NULL; char * tmp_s2 = NULL; char *col = NULL; char *val = NULL; if( !url || !url->path ) return( NULL ); tmp_s = url->path; while((tmp_s2 = strchr(tmp_s, '/')) != NULL ) { tmp_s2++; tmp_s = tmp_s2; } if((col = PKI_Malloc( 1024 )) == NULL ) { return( NULL ); } if((val = PKI_Malloc( 1024 )) == NULL ) { PKI_Free( col ); return (NULL); } while( sscanf(tmp_s, "(%[^=]=\"%[^\"])", col, val) > 1 ) { if( (strlen(col) == strlen(keyword)) && (strncmp_nocase( col,keyword,(int)strlen(keyword)) ) == 0 ) { ret = strdup( val ); goto end; } /* The tmp_s should point to the next token */ tmp_s += strlen(col) + strlen(val) + 3; } end: if( col ) PKI_Free ( col ); if( val ) PKI_Free ( val ); return( ret ); }
PKI_MEM *PKI_MEM_get_url_decoded(PKI_MEM *mem) { PKI_MEM *decoded = NULL; ssize_t data_size = 0; unsigned char *data = NULL; int i = 0; int enc_idx = 0; if(!mem || !mem->data || (mem->size == 0) ) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return NULL; } // Let's allocate a big buffer - same size of the encoded one // is enough as URL encoding expands the size (decoded is smaller) if ((data = PKI_Malloc(mem->size)) == NULL) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return NULL; } // Let's do the decoding for( i = 0; i < mem->size; i++ ) { int p; unsigned char k; if (sscanf((const char *)&mem->data[i], "%%%2x", &p) > 0) { k = (unsigned char) p; data[enc_idx++] = k; i += 2; } else { data[enc_idx++] = mem->data[i]; } } // Allocates the new PKI_MEM for the decoding operations if((decoded = PKI_MEM_new_data(enc_idx, data)) == NULL) { PKI_Free(data); PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return NULL; } // Free the allocated memory PKI_Free(data); // Returns the newly allocated url-decoded PKI_MEM return decoded; }
PKI_X509_EXTENSION *PKI_X509_EXTENSION_new( void ) { PKI_X509_EXTENSION *ret = NULL; ret = (PKI_X509_EXTENSION *) PKI_Malloc ( sizeof( PKI_X509_EXTENSION )); if( !ret ) return (NULL); ret->value = X509_EXTENSION_new(); if( !ret->value ) return (NULL); return (ret); }
PKI_OCSP_RESP *PKI_OCSP_RESP_new ( void ) { // Crypto Provider's specific data structures PKI_X509_OCSP_RESP_VALUE *r = NULL; OCSP_BASICRESP *bs = NULL; // Return container PKI_OCSP_RESP * ret = NULL; // Allocates the response object if ((r = OCSP_RESPONSE_new()) == NULL) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return NULL; } // Sets the initial state to "Success" if (!(ASN1_ENUMERATED_set(r->responseStatus, PKI_X509_OCSP_RESP_STATUS_SUCCESSFUL))) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); if (r) OCSP_RESPONSE_free (r); return NULL; } // Creates the basic response object if ((bs = OCSP_BASICRESP_new()) == NULL) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); if( r ) OCSP_RESPONSE_free ( r ); return ( NULL ); } // Let's now create the outer container if(( ret = (PKI_OCSP_RESP *) PKI_Malloc (sizeof(PKI_OCSP_RESP)))==NULL) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); if ( bs ) OCSP_BASICRESP_free ( bs ); if ( r ) OCSP_RESPONSE_free ( r ); return NULL; } // Transfer ownership of r and bs to the container ret->resp = r; ret->bs = bs; // Success - object created return ret; }
PKI_MEM *PKI_MEM_new_null ( void ) { PKI_MEM *ret = NULL; ret = PKI_Malloc ( sizeof( PKI_MEM )); if( !ret ) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return (NULL); }; return (ret); }
CA_LIST_ENTRY * CA_LIST_ENTRY_new ( void ) { CA_LIST_ENTRY * ca = NULL; if((ca = (CA_LIST_ENTRY *) PKI_Malloc ( sizeof (CA_LIST_ENTRY))) == NULL) { PKI_ERROR( PKI_ERR_MEMORY_ALLOC, NULL ); return ( NULL ); } return ( ca ); }
/* * \brief Allocates and return a new (empty) PKI_HMAC */ PKI_HMAC *PKI_HMAC_new_null(void) { PKI_HMAC *ret = NULL; ret = PKI_Malloc(sizeof(PKI_HMAC)); ret->key = NULL; ret->value = NULL; ret->digestAlg = NULL; ret->initialized = 0; HMAC_CTX_init(&ret->ctx); return ret; }
PKI_MEM *PKI_MEM_new ( size_t size ) { PKI_MEM *ret = NULL; ret = PKI_MEM_new_null(); if( !ret ) return (NULL); ret->data = PKI_Malloc ( size ); if( !ret->data ) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); PKI_MEM_free ( ret ); return (NULL); } ret->size = size; return(ret); }
static PKI_STACK_NODE * _PKI_STACK_NODE_new( void *data ) { PKI_STACK_NODE *ret = NULL; if ((ret = (PKI_STACK_NODE *) PKI_Malloc(sizeof(PKI_STACK))) == NULL) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return(NULL); } ret->next = NULL; ret->prev = NULL; ret->data = data; return (ret); }
PKI_STACK * PKI_STACK_new( void (*free)()) { PKI_STACK *ret = NULL; if((ret = (PKI_STACK *) PKI_Malloc (sizeof(PKI_STACK))) == NULL) { return(NULL); } ret->head = NULL; ret->tail = NULL; ret->elements = 0; if (ret->free) ret->free = free; else ret->free = PKI_Free; return(ret); }
HSM *HSM_OPENSSL_new ( PKI_CONFIG *conf ) { HSM *hsm = NULL; hsm = (HSM *) PKI_Malloc ( sizeof( HSM )); memcpy( hsm, &openssl_hsm, sizeof( HSM)); /* Not really needed! */ hsm->callbacks = &openssl_hsm_callbacks; if( conf ) { hsm->config = conf; } hsm->type = HSM_TYPE_SOFTWARE; return( hsm ); }
int PKI_X509_SCEP_DATA_set_ias ( PKI_X509_SCEP_DATA *scep_data, SCEP_ISSUER_AND_SUBJECT *ias ) { unsigned char *data = NULL; ssize_t size = 0; if ( !scep_data || !scep_data->value || !ias ) return PKI_ERR; if( (size = i2d_SCEP_ISSUER_AND_SUBJECT(ias, NULL)) <= 0 ) return PKI_ERR; if ((data = ( unsigned char * ) PKI_Malloc ( (size_t) size )) == NULL ) return PKI_ERR; if (i2d_SCEP_ISSUER_AND_SUBJECT( ias, &data ) <= 0 ) { PKI_Free ( data ); return PKI_ERR; } return PKI_X509_SCEP_DATA_set_raw_data ( scep_data, data, size ); }
CA_LIST_ENTRY * OCSPD_ca_entry_new ( OCSPD_CONFIG *handler, PKI_X509_CERT *x, PKI_CONFIG *cnf ) { CA_LIST_ENTRY *ret = NULL; if (!handler || !x || !cnf) return NULL; if (( ret = PKI_Malloc ( sizeof( CA_LIST_ENTRY ) )) == NULL ) return NULL; /* Let's get the CA_ENTRY_CERTID */ if ((ret->cid = CA_ENTRY_CERTID_new ( x, handler->digest )) == NULL) { CA_LIST_ENTRY_free ( ret ); return NULL; } return ret; }
char *parse_url_dbname ( const URL *url ) { char *tmp_s = NULL; char *ret = NULL; size_t size = 0; if( !url || !url->path ) return (NULL); if((tmp_s = strchr( url->path, '/')) == NULL ) { return (NULL); } size = (size_t) (tmp_s - url->path); if((ret = PKI_Malloc ( size + 1 )) == NULL ) { return(NULL); } memcpy(ret, url->path, size ); ret[size] = '\x0'; return( ret ); }
PKI_HTTP * PKI_HTTP_new ( void ) { PKI_HTTP *ret = NULL; if((ret = PKI_Malloc ( sizeof( PKI_HTTP ))) == NULL) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return NULL; } /* Standard Header Codes */ ret->code = 0; ret->type = NULL; ret->location = NULL; /* Data */ ret->body = NULL; ret->head = NULL; ret->path = NULL; return ( ret ); }
int thread_make ( int i ) { PKI_THREAD *th_id = NULL; int * id = NULL; // Basic Memory Check if (!ocspd_conf || !ocspd_conf->threads_list) return -1; // Gets the right pointer where to store the new thread identifier th_id = &ocspd_conf->threads_list[i].thread_tid; if ((id = (int *) PKI_Malloc(sizeof(int))) == NULL) { PKI_log_err("Memory allocation error!"); return -1; } // Assign the thread id *id = i; // Let's generate the new thread // if ((ret = PKI_THREAD_create(th_id, NULL, thread_main, (void *) &i)) != PKI_OK) if ((th_id = PKI_THREAD_new(thread_main, (void *) id)) == NULL) { PKI_log_err("ERROR::OPENCA_SRV_ERR_THREAD_CREATE"); return(-1); } // Copy the value of the thread structure memcpy(&ocspd_conf->threads_list[i].thread_tid, th_id, sizeof(PKI_THREAD)); // Frees the memory associated with the original structure PKI_Free(th_id); // Returns ok return OCSPD_SRV_OK; }
PKI_DIGEST *PKI_DIGEST_new ( PKI_DIGEST_ALG *alg, unsigned char *data, size_t size ) { EVP_MD_CTX md; char buf[EVP_MAX_MD_SIZE]; size_t digest_size = 0; PKI_DIGEST *ret = NULL; if( !data || !alg ) return ( NULL ); /* Let's initialize the MD context */ EVP_MD_CTX_init( &md ); /* Initialize the Digest by using the Alogrithm identifier */ if ((EVP_DigestInit_ex( &md, alg, NULL )) == 0 ) { EVP_MD_CTX_cleanup( &md ); return( NULL ); } /* Update the digest - calculate over the data */ EVP_DigestUpdate(&md, data, size); if ((EVP_DigestFinal_ex(&md, (unsigned char *) buf, NULL)) == 0) { /* Error in finalizing the Digest */ EVP_MD_CTX_cleanup( &md ); return( NULL ); } /* Set the size of the md */ digest_size = (size_t) EVP_MD_CTX_size( &md ); /* Allocate the return structure */ if ((ret = PKI_Malloc(sizeof(PKI_DIGEST))) == NULL) { /* Memory Allocation Error! */ EVP_MD_CTX_cleanup(&md); return( NULL ); } /* Allocate the buffer */ if ((ret->digest = PKI_Malloc(size)) == NULL) { /* Memory Error */ EVP_MD_CTX_cleanup(&md); PKI_Free (ret); return(NULL); } /* Set the size of the Digest */ ret->size = digest_size; /* Copy the Digest Data */ memcpy(ret->digest, buf, ret->size); /* Sets the algorithm used */ ret->algor = alg; /* Let's clean everything up */ EVP_MD_CTX_cleanup(&md); /* Return the Digest Data structure */ return ( ret ); }
/* * Parses the PKI_MEM that contains the header looking for specific HTTP * headers, the requested path, and the HTTP version and code. Returns * PKI_OK in case of success, PKI_ERR otherwise. */ int __parse_http_header(PKI_HTTP *msg) { // Let's parse the first line of the HTTP message char *eol = NULL; char *method = NULL; char *path = NULL; char *http_version = NULL; char *line = NULL; char *tmp_ptr = NULL; size_t line_size = 0; // Shortcut for msg->head PKI_MEM *m = NULL; // Checks the input if (msg == NULL || msg->head == NULL || msg->head->data == NULL || msg->head->size < 1) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return PKI_ERR; } // For better understanding, we use a proxy variable to access the head m = msg->head; // Let's parse the path and the details from the first line in the header if (((eol = strchr((char *)m->data, '\n')) == NULL) && (eol = strchr((char*)m->data, '\r')) == NULL) { // ERROR: here we should have at least one line (since we already // have the eoh detected, return the error by returning NULL return PKI_ERR; } // Let's parse the path and version number line_size = (size_t) (eol - (char*)m->data); if ((line = PKI_Malloc(line_size + 1)) == NULL) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return PKI_ERR; } // Copy the first line (strtok_r alters the original string) memcpy(line, m->data, line_size); // Retrieves the first token - [i.e., GET/POST/HTTP ...] method = strtok_r(line, " ", &tmp_ptr); if (method == NULL) { PKI_log_err("Can not parse HTTP method"); PKI_Free(line); return PKI_ERR; } if (strncmp_nocase(method, PKI_HTTP_METHOD_HTTP_TXT, 4) == 0) { // This is usually an HTTP response msg->method = PKI_HTTP_METHOD_HTTP; // Let's get the version and the code if (sscanf((const char *)msg->head->data,"HTTP/%f %d", &msg->version, &msg->code) < 1) { PKI_log_debug("ERROR Parsing HTTP Version and Code"); PKI_Free(line); return PKI_ERR; } } else if (strncmp_nocase(method, PKI_HTTP_METHOD_GET_TXT, 3) == 0 || strncmp_nocase(method, PKI_HTTP_METHOD_POST_TXT, 4) == 0) { if (strncmp_nocase(method, PKI_HTTP_METHOD_GET_TXT, 3) == 0) msg->method = PKI_HTTP_METHOD_GET; else msg->method = PKI_HTTP_METHOD_POST; path = strtok_r(NULL, " ", &tmp_ptr); if (path == NULL) { // This is an error, we should get the path for a POST or a GET PKI_Free(line); return PKI_ERR; } msg->path = strdup(path); http_version = strtok_r(NULL, " ", &tmp_ptr); if (http_version == NULL) { // This is an error, we should be able to get the HTTP version from the third token PKI_Free(line); return PKI_ERR; } else if(sscanf(http_version,"HTTP/%f", &msg->version) < 1) { PKI_log_debug("ERROR Parsing HTTP Version"); PKI_Free(line); return PKI_ERR; } } else { PKI_log_err("Unsupported HTTP Method detected (%s)", method); PKI_Free(line); return PKI_ERR; } // We do not need the line anymore, let's free the memory if (line) PKI_Free(line); // Success return PKI_OK; }
int PKI_HTTP_get_socket (const PKI_SOCKET * sock, const char * data, size_t data_size, const char * content_type, int method, int timeout, size_t max_size, PKI_MEM_STACK ** sk ) { size_t len = 0; const char *my_cont_type = "application/unknown"; PKI_HTTP *http_rv = NULL; int rv = -1; int ret = PKI_OK; size_t max_len = 0; size_t auth_len = 0; char *tmp = NULL; char *auth_tmp = NULL; char *head_get = "GET %s HTTP/1.1\r\n" "Host: %s\r\n" "User-Agent: LibPKI\r\n" "Connection: close\r\n" "%s"; char *head_post = "POST %s HTTP/1.1\r\n" "Host: %s\r\n" "User-Agent: LibPKI\r\n" "Connection: close\r\n" "Content-type: %s\r\n" "Content-Length: %d\r\n" "%s"; char *head = NULL; if ( timeout < 0 ) timeout = 0; if ( !sock || !sock->url ) return PKI_ERR; // Process the authentication information if provided by the caller if (sock->url && sock->url->usr && sock->url->pwd) { // Rough estimate for the auth string max_len = strlen(sock->url->usr) + strlen(sock->url->pwd) + 100; // Special case for when a usr/pwd was specified in the URL auth_tmp = PKI_Malloc(len); auth_len = (size_t)snprintf(auth_tmp, len, "Authentication: user %s:%s\r\n\r\n", sock->url->usr, sock->url->pwd); } else { // If we do not have the auth info, we just add the end of header auth_len = 2; auth_tmp = "\r\n"; } if (method == PKI_HTTP_METHOD_GET) { // Gets the right header head = head_get; // Estimate the header's final size max_len = strlen(head) + strlen(sock->url->path) + strlen(sock->url->addr) + 101; // Allocates enough space for the header tmp = PKI_Malloc ( max_len + auth_len ); // Prints the header into the tmp container len = (size_t) snprintf(tmp, max_len, head, sock->url->path, sock->url->addr, auth_tmp); } else if (method == PKI_HTTP_METHOD_POST) { // Gets the right head head = head_post; // Determines the right content type if ( content_type ) my_cont_type = content_type; else my_cont_type = "text/html"; // Checks the max len for the allocated header max_len = strlen(head) + strlen(sock->url->path) + strlen(sock->url->addr) + strlen(my_cont_type) + 101; // Allocates the memory for the header tmp = PKI_Malloc ( max_len + auth_len ); // Prints the header into the tmp container len = (size_t) snprintf(tmp, max_len, head, sock->url->path, sock->url->addr, my_cont_type, data_size, auth_tmp ); } else { PKI_log_err ( "Method (%d) not supported!", method ); return PKI_ERR; } // PKI_MEM *r = PKI_MEM_new_data(len, tmp); // URL_put_data("file://http_req.txt", r, NULL, NULL, 0, 0, NULL); // PKI_MEM_free(r); if ((rv = (int) PKI_SOCKET_write(sock, tmp, len)) < 0) { PKI_log_err("Can not write HTTP header to socket"); PKI_Free(tmp); goto err; } // Free the tmp pointer that held the request header if (tmp) PKI_Free (tmp); // If we were using a POST method, we need to actually send the data if(data != NULL) { PKI_log_err("{DEBUG} Writing Data -> data_size = %d, data = %p", data_size, data); if ((PKI_SOCKET_write(sock, data, data_size)) < 0) { PKI_log_err ("Can not write POST to socket."); goto err; } } // Let's now wait for the response from the server if ((http_rv = PKI_HTTP_get_message(sock, timeout, max_size)) == NULL) { PKI_log_err ("HTTP retrieval error\n"); goto err; } // We shall now check for the return code if (http_rv->code >= 400 ) { goto err; } else if (http_rv->code >= 300) { /* Redirection - let's try that */ if (http_rv->location == NULL) { PKI_log_debug ( "HTTP Redirection but no location provided!"); goto err; } PKI_log_debug("HTTP Redirection Detected [URL: %s]", http_rv->location ); if (strstr(http_rv->location, "://") != NULL) { URL *url_tmp = NULL; if( strncmp_nocase( http_rv->location, sock->url->url_s, (int) strlen(http_rv->location)) == 0) { PKI_log_debug( "HTTP cyclic redirection!"); goto err; } if ((url_tmp = URL_new ( http_rv->location )) == NULL) { PKI_log_debug("HTTP location is not a valid URI (%s)", http_rv->location ); goto err; } if ( sock->url->ssl == 0 ) { ret = PKI_HTTP_get_url ( url_tmp, data, data_size, content_type, method, timeout, max_size, sk, NULL ); } else { PKI_SSL *ssl2 = PKI_SSL_dup ( sock->ssl ); ret = PKI_HTTP_get_url ( url_tmp, data, data_size, content_type, method, timeout, max_size, sk, ssl2 ); } if ( url_tmp ) URL_free ( url_tmp ); goto end; } else { const char *prot_s = NULL; char new_url[2048]; URL *my_new_url = NULL; PKI_SSL *ssl2 = PKI_SSL_dup ( sock->ssl ); prot_s = URL_proto_to_string ( sock->url->proto ); if( !prot_s ) goto err; snprintf(new_url, sizeof(new_url),"%s://%s%s", prot_s, sock->url->addr, http_rv->location ); if( strncmp_nocase( new_url, sock->url->url_s, (int) strlen ( new_url )) == 0 ) { PKI_log_debug( "HTTP cyclic redirection!"); goto err; } my_new_url = URL_new ( new_url ); ret = PKI_HTTP_get_url ( my_new_url, data, data_size, content_type, method, timeout, max_size, sk, ssl2 ); if (ssl2) PKI_SSL_free ( ssl2 ); } } else if (http_rv->code != 200) { PKI_log_debug( "Unknown HTTP Return code [Code: %d]", http_rv->code ); goto err; } /* PKI_log_err("{DEBUG} method = %d, header->size = %d, body = %p, body_size = %d", http_rv->method, http_rv->head->size, http_rv->body, http_rv->body->size); URL_put_data("file://http-resp-header.txt", http_rv->head, NULL, NULL, 0, 0, NULL); URL_put_data("file://http-resp-data.txt", http_rv->body, NULL, NULL, 0, 0, NULL); */ // If a Pointer was provided, we want the data back if (sk) { // Checks if the caller provided an already allocated data // structure. If not, we allocate it. if (*sk) PKI_STACK_MEM_free_all(*sk); // Allocates a new structure if ((*sk = PKI_STACK_MEM_new()) == NULL) { // If a memory error occurs report it and exit PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); // Nothing more to do goto err; } // Add the returned value to the stack if (PKI_STACK_MEM_push(*sk, http_rv->body) != PKI_OK) { PKI_log_err("Can not push the HTTP result body in the result stack"); goto err; } // Remove ownership of the body PKI_MEM from the original // HTTP msg container http_rv->body = NULL; } end: // Finally free the HTTP message memory if (http_rv) PKI_HTTP_free(http_rv); // Returns the result return ret; err: // Error condition if (http_rv) PKI_HTTP_free ( http_rv ); // Free the locally allocated memory if (*sk) PKI_STACK_MEM_free_all(*sk); *sk = NULL; return PKI_ERR; }