static int query_command(const char *data, char *digest, const EVP_MD *md, const char *policy, int no_nonce, int cert, const char *in, const char *out, int text) { int ret = 0; TS_REQ *query = NULL; BIO *in_bio = NULL; BIO *data_bio = NULL; BIO *out_bio = NULL; /* Build query object either from file or from scratch. */ if (in != NULL) { if ((in_bio = BIO_new_file(in, "rb")) == NULL) goto end; query = d2i_TS_REQ_bio(in_bio, NULL); } else { /* Open the file if no explicit digest bytes were specified. */ if (!digest && !(data_bio = BIO_open_with_default(data, "rb", stdin))) goto end; /* Creating the query object. */ query = create_query(data_bio, digest, md, policy, no_nonce, cert); /* Saving the random number generator state. */ } if (query == NULL) goto end; /* Write query either in ASN.1 or in text format. */ if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL) goto end; if (text) { /* Text output. */ if (!TS_REQ_print_bio(out_bio, query)) goto end; } else { /* ASN.1 output. */ if (!i2d_TS_REQ_bio(out_bio, query)) goto end; } ret = 1; end: ERR_print_errors(bio_err); /* Clean up. */ BIO_free_all(in_bio); BIO_free_all(data_bio); BIO_free_all(out_bio); TS_REQ_free(query); return ret; }
/* * Query-related method definitions. */ static int query_command(const char *data, char *digest, const EVP_MD *md, const char *policy, int no_nonce, int cert, const char *in, const char *out, int text) { int ret = 0; TS_REQ *query = NULL; BIO *in_bio = NULL; BIO *data_bio = NULL; BIO *out_bio = NULL; /* Build query object. */ if (in != NULL) { if ((in_bio = bio_open_default(in, 'r', FORMAT_ASN1)) == NULL) goto end; query = d2i_TS_REQ_bio(in_bio, NULL); } else { if (digest == NULL && (data_bio = bio_open_default(data, 'r', FORMAT_ASN1)) == NULL) goto end; query = create_query(data_bio, digest, md, policy, no_nonce, cert); } if (query == NULL) goto end; if (text) { if ((out_bio = bio_open_default(out, 'w', FORMAT_TEXT)) == NULL) goto end; if (!TS_REQ_print_bio(out_bio, query)) goto end; } else { if ((out_bio = bio_open_default(out, 'w', FORMAT_ASN1)) == NULL) goto end; if (!i2d_TS_REQ_bio(out_bio, query)) goto end; } ret = 1; end: ERR_print_errors(bio_err); BIO_free_all(in_bio); BIO_free_all(data_bio); BIO_free_all(out_bio); TS_REQ_free(query); return ret; }
UNSIGNED32 get_timestamp_response(const char* urlStr, char* hash, UNSIGNED32 hash_size, UNSIGNED32 httpTimeOut, TS_RESP** tsResponse) { UNSIGNED32 result = TINTERNALERROR; BIO* responseBio = NULL; Url* url = NULL; TS_REQ* tsRequest = NULL; BIO* requestBio = NULL; int requestHeaderLength; int requestLength; int requestContentLength; char requestHeader[2048 + 256]; char* request = NULL; void* contentBuffer = NULL; void* resultBuffer = NULL; int resultLength; TS_MSG_IMPRINT* msgImprint = NULL; ASN1_OCTET_STRING* hashedMessage = NULL; int hashedMessageLength; int httpResult; char *urlBuffer = NULL; int redirection = 0; /* Check if TS url is specified */ if (!urlStr) { goto end; } /* Get Request for timestamp */ tsRequest = get_timestamp_request(hash, hash_size, create_nonce(NONCE_LENGTH)); msgImprint = TS_REQ_get_msg_imprint(tsRequest); hashedMessage = TS_MSG_IMPRINT_get_msg(msgImprint); hashedMessageLength = ASN1_STRING_length((ASN1_STRING*)hashedMessage); if ((int)hash_size != hashedMessageLength) { goto end; } requestBio = BIO_new(BIO_s_mem()); if (requestBio == NULL) { goto end; } if (!i2d_TS_REQ_bio(requestBio, tsRequest)) { goto end; } contentBuffer = memory_alloc(BIO_number_written(requestBio)); if (contentBuffer == NULL) { goto end; } requestContentLength = BIO_read(requestBio, contentBuffer, BIO_number_written(requestBio)); /* Allocate memory buffer for timestamp server url */ urlBuffer = memory_alloc(strlen(urlStr) + 1); if (!urlBuffer) { goto end; } /* Copy TS url to allocated buffer */ strcpy(urlBuffer, urlStr); http_redirect: /* Parse and check URL */ url = parse_url(urlBuffer); if (url == NULL) { goto end; } if (strcmp(url->Scheme, "http") != 0) { goto end; } requestHeaderLength = sprintf(requestHeader, "POST %s HTTP/1.0\r\nHOST: %s\r\nPragma: no-cache\r\nContent-Type: application/timestamp-query\r\nAccept: application/timestamp-reply\r\nContent-Length: %d\r\n\r\n", urlBuffer, url->Host, requestContentLength); requestLength = requestHeaderLength + requestContentLength; request = (char*)memory_alloc(requestLength); if (request == NULL) { goto end; } memcpy(request, requestHeader, requestHeaderLength); memcpy(request + requestHeaderLength, contentBuffer, requestContentLength); httpResult = http_read(url->Host, request, requestLength, url->Port, httpTimeOut, 1, &resultBuffer, &resultLength); if (httpResult == HTTP_REDIRECTION && (resultBuffer) && !redirection) { free_url(url); url = NULL; memory_free(request); request = NULL; /* Allocated buffer for redirected url */ urlBuffer = memory_realloc(urlBuffer, resultLength); if (!urlBuffer) { goto end; } memcpy(urlBuffer, resultBuffer, resultLength); memory_free(resultBuffer); redirection++; goto http_redirect; } else if ((httpResult == HTTP_NOERROR) && (resultBuffer)) { responseBio = BIO_new(BIO_s_mem()); if (responseBio == NULL) { goto end; } BIO_write(responseBio, resultBuffer, resultLength); *tsResponse = d2i_TS_RESP_bio(responseBio, NULL); if (*tsResponse == NULL) { goto end; } result = TNOERR; } else { switch (httpResult) { case HTTP_NOLIVEINTERNET_ERROR: result = TNONET; break; case HTTP_TIMEOUT_ERROR: result = TTIMEOUT; break; case HTTP_RESPONSESTATUS_ERROR: result = TSERVERERROR; break; default: result = TINTERNALERROR; break; } } end: free_url(url); if (tsRequest != NULL) { TS_REQ_free(tsRequest); } if (requestBio != NULL) { BIO_free_all(requestBio); } if (responseBio != NULL) { BIO_free_all(responseBio); } if (request != NULL) { memory_free(request); } if (contentBuffer != NULL) { memory_free(contentBuffer); } if (resultBuffer != NULL) { memory_free(resultBuffer); } if (urlBuffer != NULL) { memory_free(urlBuffer); } return result; }