Programming and communication with the timestamp Server

Source: Internet
Author: User

Tag: Timestamp

In the previous blog, "Introduction to a French timestamp server", we introduced how to obtain the timestamp response in two steps:
1. Use OpenSSL to generate a timestamp request file;
2. Use the curl command in Linux to send timestamp requests and receive timestamp responses.

There are two ways to perform Step 1 in Windows:
1) download for the Windows platform to achieve the curl program, you can download to the http://curl.haxx.se/download.html;
2) You do not need to use the curl command to program and send timestamp requests and receive timestamp responses to the French timestamp server.

To better understand the details of the process of communicating with the timestamp server, here we will introduce the 2nd methods, namely programming implementation. First we will introduce the implementation of the C language:
A) In order to read the timestamp request file, the file size function must be implemented as follows:
File 1
Get_small_file_size.h


# Ifndef get_small_file_size_h # define get_small_file_size_h # ifdef _ cplusplusextern "C" {# endif /********************** * **************************** Function Name: getsmallfilesize * function: obtains the file size. The result is in bytes. * parameter: file_name [in] File Name: file_byte_size [out] File Size * returned value: 0 success-1 failure * remarks: this function has a limit on the actual file size. The file size cannot exceed (2g-1) bytes. Because the ftell () function is called, the return value of this function is of the long type, the maximum integer that can be expressed cannot exceed (2g-1) bytes *************************************** * *********/INT getsmallfilesize (char * file_name, long * file_byte_size); # ifdef _ cplusplus} # endif/* end of get_small_file_size_h */


File 2
Get_small_file_size.c

#include "get_small_file_size.h"#include <stdio.h>int GetSmallFileSize(char *file_name, long *file_byte_size){   FILE * fp;  if ( !(fp=fopen(file_name, "rb")) )  {    printf("Open file %s failed!\n", file_name);    return (-1);  }  fseek(fp, 0L, SEEK_END);   *file_byte_size=ftell(fp);   fclose(fp);   return 0; }


 

B) To communicate with the timestamp server, you need to implement a function that uses Windows Socket to communicate. The implementation process is as follows:
File 3
Socket_communication.h

# Ifndef socket_communication_h # define socket_communication_h # ifdef _ cplusplusextern "C" {# endif /********************** * **************************** Function Name: socket_communication * function: Send request data to the host with the specified IP address and port number through socket communication, and receive response data * parameter: IP [in] the IP address of the opposite host port [in] the port number used by the other host to receive data request [in] the first address of the buffer, this buffer is used to store the request data to be sent. The length of the request data to be sent is measured in bytes, this buffer is used to store the received response data response_buffer_len [in] the buffer size of the received response data, in bytes. The length of the response data actually received by response_len [out, in bytes * return value: 0 success-1 failure *********************************** * *************/INT socket_communication (unsigned char * IP, unsigned int port, unsigned char * request, unsigned int request_len, unsigned char * response, unsigned int response_buffer_len, unsigned int * response_len ); # ifdef _ cplusplus} # endif/* end of socket_communication_h */


 

File 4
Socket_communication.c

# Include "socket_communication.h" # include <stdio. h >#include <winsock2.h> # pragma comment (Lib, "ws2_32.lib") int socket_communication (unsigned char * IP, unsigned int port, unsigned char * request, unsigned int request_len, unsigned char * response, unsigned int response_buffer_len, unsigned int * response_len) {int result, eded_data_len; char * P; wsadata; socket sockclient; sockaddr_in addrsrv; Result = wsastartup (makeword (2, 2), & wsadata); If (result! = No_error) {printf ("wsastartup function failed with error: % d at % s, line % d! \ N ", result, _ file __, _ line _); Return (-1);} sockclient = socket (af_inet, sock_stream, ipproto_tcp ); if (sockclient = invalid_socket) {printf ("create socket failed with error: % lD at % s, line % d! \ N ", wsagetlasterror (), _ file __, _ line _); wsacleanup (); Return (-1);} addrsrv. sin_addr.s_addr = inet_addr (char *) (IP); addrsrv. sin_family = af_inet; addrsrv. sin_port = htons (port); Result = connect (sockclient, (sockaddr *) (& addrsrv), sizeof (sockaddr); If (result = socket_error) {printf ("INVOKE connect () function failed with error: % lD at % s, line % d! \ N ", wsagetlasterror (), _ file __, _ line _); closesocket (sockclient); wsacleanup (); Return (-1 );} /* Send a timestamp request */printf ("sending data... "); Result = Send (sockclient, (char *) request, (INT) request_len, 0); If (result =-1) {printf ("send data failed at % s, line % d! \ N ", _ file __, _ line _); closesocket (sockclient); wsacleanup (); Return (-1 );} printf ("% d bytes have been sent. \ n ", result);/* receive timestamp requests */printf (" processing ing data... "); P = (char *) response; received_data_len = 0; while (1) {result = Recv (sockclient, P, (response_buffer_len-received_data_len), 0 ); if (result =-1) {printf ("receive data failed at % s, line % d! \ N ", _ file __, _ line _); closesocket (sockclient); wsacleanup (); Return (-1);} If (result = 0) break; P + = result; received_data_len + = result;} * response_len = received_data_len; printf ("processing data complete. \ n "); printf (" % d bytes have been encoded ed. \ n ", received_data_len); Result = closesocket (sockclient); If (result = socket_error) {printf (" INVOKE closesocket () function failed with error: % LD at % s, line % d! \ N ", wsagetlasterror (), _ file __, _ line _); wsacleanup (); Return (-1);} wsacleanup (); Return 0 ;}


 

C) functions for sending http post requests and receiving HTTP response messages from the timestamp server include: Reading the timestamp request file, generating an http post request, and sending it to the timestamp server, receives the HTTP message returned by the timestamp server, extracts the content from the HTTP message (this part is the timestamp response in ASN.1 encoding format), and outputs or saves it to the file. The implementation process is as follows:
File 5
Ts_communication.h

/*************************************** * *********** File Name: ts_communication.h * Author: Han Wei * Author's blog: http://blog.csdn.net/henter/ * Date: Aug 21st, 2014 *************************************** * **********/# ifndef time_stamp_communication_h # define time_stamp_communication_h # ifdef _ cplusplusextern "C" {# endif /********** **************************************** * Function Name: ts_communication * Function: Send the timestamp request file to the timestamp server and receive the timestamp response. * parameter: ts_request_file_name [in] timestamp request file name ts_server_ip [in] timestamp Server IP address ts_server_port [in] timestamp server receiving http post request port number save_file_flag [in] indicates whether to set the time the timestamp response returned by the timestamp server is saved to the file's flag variable ts_response_file_name [in] timestamp response file name * return value: 0 success-1 failure * remarks: 1. the timestamp server URL for communicating with this function is http://timestamping.edelweb.fr/whose IP address is 92.103.215.77. 2. For the timestamp request file specified by the input parameter ts_request_file_name, the size of the file must be smaller than 2 GB. The content is the ASN.1 encoding of the timestamp request, as specified in RFC 3161. 3. the input parameter save_file_flag is used to indicate whether to save the timestamp response returned by the timestamp server to a file. If the value is 0, it indicates that it does not need to be saved to the file, in this case, the input parameter ts_response_file_name will be ignored. When the value is any non-zero unsigned integer, it indicates that the timestamp response will be saved to the file. The file name is specified by ts_response_file_name. **************************************** * ********/INT ts_communication (char * ts_request_file_name, unsigned char * ts_server_ip, unsigned int ts_server_port, unsigned int save_file_flag, char * ts_response_file_name); # ifdef _ cplusplus} # endif/* end of destination */


 

File 6
Ts_communication.c

/*************************************** * *********** File Name: ts_communication.c * Author: Han Wei * Author's blog: http://blog.csdn.net/henter/ * Date: Aug 21st, 2014 *************************************** * **********/# include "get_small_file_size.h" # include "socket_communication.h" # include <stdio. h> # include <stdlib. h> # include <string. h> # define max_ip_packet_len (INT) (65535) int ts_communicatio N (char * handle, unsigned char * ts_server_ip, unsigned int ts_server_port, unsigned int handle, char * handle) {int error_code, I; file * input_fp, * output_fp; long input_file_length; unsigned char * request; unsigned char response [max_ip_packet_len]; unsigned int request_len, response_buffer_len, response_len, message_len = 0; unsigned char content_len [32], message [32 [Max_ip_packet_len]; unsigned char * P, * q, * content_start; If (! (Input_fp = fopen (ts_request_file_name, "rb") {printf ("Open File % s failed at % s, line % d! \ N ", ts_request_file_name, _ file __, _ line _); Return (-1);} If (error_code = getsmallfilesize (ts_request_file_name, & input_file_length )) {printf ("Get File % s length failed at % s, line % d! \ N ", ts_request_file_name, _ file __, _ line _); Return (-1);} request_len = (unsigned INT) input_file_length; printf ("Time Stamp request ASN.1 encode length is % d bytes \ n", request_len); If (! (Request = (unsigned char *) malloc (request_len) {printf ("INVOKE malloc () function failed at % s, line % d! \ N ", _ file __, _ line _); fclose (input_fp); Return (-1);} fread (request, request_len, 1, input_fp ); fclose (input_fp); printf ("Time Stamp request: \ n"); for (I = 0; I <(INT) (request_len); I ++) printf ("0x % x", request [I]); printf ("\ n"); memset (content_len, 0, sizeof (content_len); sprintf (char *) (content_len), "% d", request_len); memset (message, 0, sizeof (Message); strcat (char *) (Message), "post/Ser Vice/tsp http/1.1 \ n "); strcat (char *) (Message)," Host: timestamping. edelweb. fr \ n "); strcat (char *) (Message)," Content-Type: Application/timestamp-QUERY \ n "); strcat (char *) (Message), "Content-Length:"); strcat (char *) (Message), (char *) (content_len); strcat (char *) (Message), "\ n"); P = message + strlen (char *) (Message); message_len = strlen (char *) (Message )); memcpy (p, request, request _ Len); P = P + request_len; message_len + = request_len; * P = '\ n'; message_len ++; printf ("http post message length is % d bytes. \ n ", message_len); printf (" http post message: \ n "); for (I = 0; I <(INT) (message_len); I ++) printf ("% C", message [I]); printf ("\ n"); free (request); response_buffer_len = sizeof (response ); if (error_code = socket_communication (ts_server_ip, ts_server_port, message, message_len, Resp Onse, response_buffer_len, & response_len) {printf ("communicate with time stamp server failed at % s, line % d! \ N ", _ file __, _ line _); Return (-1);} printf (" HTTP time stamp response is % d bytes. \ n ", response_len); printf (" HTTP time stamp response: \ n "); for (I = 0; I <(INT) (response_len); I ++) printf ("% C", response [I]); printf ("\ n"); q = (unsigned char *) strstr (char *) response, "Content-Type: Application/timestamp-reply"); If (Q! = NULL) {q + = (strlen ("Content-Type: Application/timestamp-reply") + 4);/* Note that in the HTTP response returned by the timestamp server, the Content-Type: Application/timestamp-reply line has an empty line. Therefore, the line break after the line content has a total of four characters, namely, 0x0d 0x0a 0x0d 0x0a. After the pointer Q is moved to the four characters, the Pointer Points to the starting position of HTTP content */content_start = Q;} else {printf ("error at % s, line % d! \ N ", _ file __, _ line _); printf (" can't find string 'content-type: Application/timestamp-reply' in HTTP response! \ N "); Return (-1);} I = 0; printf (" \ ncontent: \ n "); While (q <(Response + response_len )) {printf ("0x % x", * q); q ++; I ++;} printf ("\ n"); printf ("content length is % d bytes. \ n ", I); If (save_file_flag! = 0) {If (! (Output_fp = fopen (ts_response_file_name, "WB") {printf ("Create File % s failed at % s, line % d! \ N ", ts_response_file_name, _ file __, _ line _); Return (-1);} fwrite (content_start, I, 1, output_fp ); fclose (output_fp); printf ("Save time stamp response ASN.1 encode into file % s succeeded! \ N ", ts_response_file_name);} return 0 ;}


 

D) Call existing subfunctions to send requests and receive responses to the French timestamp server. The implementation process is as follows:
File 7
Test. c

/*************************************** * *********** File Name: test. C * Author: Han Wei * Author's blog: http://blog.csdn.net/henter/ * Date: Aug 21st, 2014 *************************************** * **********/# include "ts_communication.h" # include <stdio. h> # include <stdlib. h> # include <string. h> int main (INT argc, char * argv []) {int error_code; unsigned char IP [64] = "92.103.215.77";/* IP address of the French timestamp Server Address */unsigned int Port = 80; unsigned int wrtie_file_flag = 1; if (argc! = 3) {printf ("invalid input! \ N "); System (" pause "); Return (-1);} If (error_code = ts_communication (argv [1], IP, port, wrtie_file_flag, argv [2]) {printf ("Send time stamp request or acquire time stamp response failed at % s, line % d! \ N ", _ file __, _ line _); Return (-1);} printf (" test sending time stamp request and processing ing time stamp response succeeded! \ N "); System (" pause "); Return 0 ;}

 

There are a total of 7 files. Assuming that the file name of the compiled EXE is ts_communication.exe, you can run the following command on the Windows Command Prompt interface:
Ts_communication timestamp request file name timestamp response file name
For example, you have used OpenSSL to generate a timestamp request file named ts_request.tsq. You want to save the timestamp response (ASN.1 encoding format) returned by the timestamp server to the ts_response.tsr file, the command is
Ts_communication ts_request.tsq ts_response.tsr

The above describes the implementation process of C language. If python is used for implementation, the implementation process will be much simpler because there is a library named httplib2!
The following is a rough example Program (no exception check and processing:

import httplib2in_file=open("TS_request.tsq", "rb")request=in_file.read()in_file.close()h=httplib2.Http(".cache")resp, content=h.request("http://timestamping.edelweb.fr/service/tsp", "POST", body=request, headers={'Content-Type':'application/timestamp-query'})out_file=open("TS_response.tsr","wb")out_file.write(content)out_file.close()


To add the httplib2 library to Python, two methods are described here:
1. You can download to the https://pypi.python.org/pypi/httplib2, the current latest version is 0.9, download the file httplib2-0.9.zip, decompress, to the decompressed directory, execute the command
Python setup. py install

2. if Pip has been installed in Python, run the following command:
PIP install httplib2

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.