Claimstream Middleware Client

enabling pharmacies to electronically submit claims to third party insurers
- posted on March 30, 2014 by Vsevolod Geraskin in projects about c5 tls/ssl6 security7

Problem Statement

Pharmacies and Hospitals in British Columbia use secure electronic middleware to send claims to third-party Claimstream insurers, such as Alberta Blue Cross and Medavie Blue Cross. The insurers made several technological changes on the receiving end which immediately required a completely new system to enable insurance claim submissions by our clients.

Project Description

Alberta/Medavie Blue Cross communication software is a secure client application that transmits Canadian Pharmacists Association claim standard data from Applied Robotics WinRx pharmacy system to Claimstream, and captures claim responses from Alberta Blue Cross and Medavie third-party private insurers. The application is written in C and uses OpenSSL for handling certificates and encryption.

Project Outcomes

The application is currently deployed in production at several hundred client sites. Due to simplicity of the solution, all the clients had to do is to download the application from the website without having to install any components. I developed the application in about a day, and the total effort from initiating the project to testing with insurers and deploying at clients sites took about week.

comments


OpenSSL and select()

reading OpenSSL records correctly within C select() statement
- posted on February 21, 2014 by Vsevolod Geraskin in tutorials about c5 tls/ssl6 security7 openssl2 select1 code4

When old becomes new

In recent years, many event-driven server-side technologies, such as Node.js javascript library and lighttpd web server, enabled programmers to easily build applications which scale much better than traditional span new process or thread for each new connection servers, such as Apache. Both node.js javascript engine and lighttpd are written in C/C++ language using I/O multiplexors which have been in existence for many years. One of such multiplexors is C select() statement which has been around forever. Securing software communication channels is one of the major issues in today’s world, and, in this tutorial, we will examine how to read OpenSSL records using select() multiplexor, should we decide to create our own secure event-driven library or the hot new web server from ground up.

Traditional select() loop

while (TRUE) {
	temp_set = master_set;               // structure assignment
   		
	if ((select_result = select(max_fd_number + 1, &temp_set, NULL, NULL, NULL)) == -1) fatal("ERROR: select error\n");

	if (FD_ISSET(socket_id, &temp_set)) {
		// accept new client connection
		client_len = sizeof(client);
		this_socket_id = accept(socket_id, (struct sockaddr *) &client, &client_len);
	} else {
		// check clients for data
		for (i = 0; i <= client_index; i++)	{
			if ((socket_fd = clients[i]) < 0) continue;
				
			if (FD_ISSET(socket_fd, &temp_set)) {
				//read data	
						
				if (--select_result <= 0) break;        // no more readable descriptors
			}
		}
	}
   
	FD_SET (this_socket_id, &master_set);     // add new descriptor to set

	if (this_socket_id > max_fd_number) max_fd_number = this_socket_id;	// add to select
	if (i > client_index) client_index = i;	// new max index in client[] array
	if (--select_result <= 0) continue;	// no more readable descriptors
}

The above code shows one way to implement a select() read on non-encrypted socket connection. Basically, what happens above is we run select() statement, check if the file descriptor ready to be read in the select set is a listening socket or an existing connected socket, and either accept new connection or read data on the existing connection. The actual read data operation is simple: for instance, we can read bytes into buffer_array from socket using read statement as shown below.

if (FD_ISSET(socket_fd, &temp_set)) {
	//read data	
	if ((bytes_read = read(socket_fd, buffer_array, BUFFER_LENGTH)) > 0) { ... }
}

OpenSSL can of worms

Let’s say we had to secure the above connection. We would probably use OpenSSL library and use SSL_read statement instead to read and decrypt SSL record. Our read data operation could look like:

if (FD_ISSET(socket_fd, &temp_set)) {
	//read data	
	if ((bytes_read = SSL_read(SSL, buffer_array, BUFFER_LENGTH)) > 0) { ... }
}

But implementing the above code, select() could actually mislead the application and signal that SSL data is ready to read when, in fact, it is not ready. Why is that?
Because select() is solely concerned with the contents of the encrypted network buffer, while the SSL_read reads the SSL buffer into which OpenSSL places the decrypted data. SSL_read has to read the entire SSL record in order to deliver the first decrypted byte to the program, while select() returns immediately after the first encrypted byte is ready, creating the following situation:

  1. First select() call returns signalling encrypted data is ready to read.
  2. SSL_read empties network buffer, but is not ready to deliver the decrypted data in the SSL buffer to the application due to decryption overhead.
  3. Consecutive select() call does not return since network buffer is empty.

And the solution

We need another SSL read loop to make select() wait until SSL record is completely placed into SSL buffer and decrypted data becomes available:

if (FD_ISSET(socket_fd, &temp_set)) {
	//read data	
	do  {
		read_blocked = 0;
		bytes_read = SSL_read(SSL,buffer_array,BUFFER_LENGTH);;

		//check SSL errors
		switch(ssl_error = SSL_get_error(SSL,bytes_read)){
			case SSL_ERROR_NONE:
				//do our stuff with buffer_array here
			break;
			
			case SSL_ERROR_ZERO_RETURN:		
				//connection closed by client, clean up
			break;
			
			case SSL_ERROR_WANT_READ:
				//the operation did not complete, block the read
				read_blocked = 1;
			break;
			
			case SSL_ERROR_WANT_WRITE:
				//the operation did not complete
			break;
			
			case SSL_ERROR_SYSCALL:
				//some I/O error occured (could be caused by false start in Chrome for instance), disconnect the client and clean up
			break;
							
			default:
				//some other error, clean up
				
	} while (SSL_pending(SSL) && !read_blocked);
}

And Voila! In the above code, we obtain number of readable bytes buffered in an SSL object through SSL_pending function, and loop while there is still bytes to read. This loop makes select() wait until we have the complete decrypted SSL record. For a more complete description, please read this excellent RTFM Inc. paper part 1 and part 2 by Eric Rescorla which helped me solve this particular problem.

Activity diagram of SSL sockets + select()

Activity Diagram of SSL sockets + select()

comments


FAR-EMR System

allowing healthcare professionals in British Columbia securely exchange data in the form of clinical documents

Problem Statement

Currently, various healthcare providers in our province do not have immediate access to a patient’s health data upon receiving the patient into their care due to their technological or funding limitations. For example, doctors or emergency ambulance teams cannot promptly view patient medication history, which would allow them to make informed decisions on patient’s treatment. This medication history is available on the Pharmanet and is accessible by Patient’s pharmacist or nurse. The challenge is to get appropriate data from one healthcare professional to another in a prompt and simple manner, while conforming to various security and messaging standards.

Due to sensitivity of health data, government requires online healthcare systems to use two factor authentication. Therefore, in addition to usernames and passwords, the system must also have a secondary unrelated method of authenticating users. For example, two factor authentication can be something a user knows, such as a password, and something a user has, such as a client SSL certificate.

Finally, the exchange of healthcare data between various system is subject to health messaging standards. In this case, the data is exchanged in the form of clinical documents created by a pharmacist or a nurse and viewed by a doctor or emergency medical technician. The clinical document is an HL7 v3 XML file which contains base-64 encoded PDF segment containing patient health data.

Project Description

FAR-EMR system is a secure and scalable multi-part server I built as an alternative to costly EMR systems in order to allow clinical document exchange between healthcare professionals. The type of a clinical document the system is created to handle contains patient’s medication history and is created in pharmacy or nursing home by a pharmacist or a nurse for use by doctors or other relevant healthcare professionals. The project was sponsored by my current company, Applied Robotics Inc., and significantly enhanced our personal health record expertise.

FAR-EMR project used Agile development methodology, while closely following XP process. The small size of project team and close collaboration with nursing homes, pharmacies and various EMR vendors made Agile the appropriate methodology to develop a highly appealing end product with a focus on healthcare professionals and their EMR applications.

FAR-EMR system is composed of authentication server, resource server, database, and web service clients, which implement the following functionality:

  • authentication server uses two factor authentication method in the form of user credentials and SSL client certificate to grant users access to the resource server;
  • resource server provides a set of secure RESTful webservices allowing users to send and receive clinical documents, validate document structure, and create patients and practitioners;
  • database provides tables to store user information, patients, practitioners, and clinical
  • web service client allows pharmacy software to send clinical documents to the resource server from a command line.

Context Diagram of FAR-EMR System

Upon receiving a patient into their care, a health professional contacts their colleague to request a patient’s health information. Then, the recipient of a call generates a medication history report in their health system. After the report is complete and verified, the supplier’s health system invokes a command line client. Command-line client connects to FAR-EMR HTTPS Authentication server with the provided SSL client certificate and supplier’s username and password and receives a token upon successful authentication. Finally, the command line client connects to the resource server and submits the received token along with XML clinical document data. The resource server verifies the token and stores the data into MySQL database.

Once the data is available in the database, the health professional requesting health data connects to authentication server using their miscellaneous application and sends authentication credentials. The server then goes through the same authentication process described above and issues a token. Thus, using the token, a consumer application can request and receive clinical data from resource server.

Technologies used on this project are as follows:

  • MySQL database: FAR-EMR uses MySQL running on Linux server to store data. The database contains tables for storing Clinical Documents, Patients, Practitioners, and User Authentication information.

  • C Language: FAR-EMR lightweight authentication and resource servers are written entirely in C language.

  • OpenSSL Library: FAR-EMR uses OpenSSL library to create certificates, validate clients during first stage of authentication, and encrypt all communication between client and server.

  • Libxml2 Library: FAR-EMR uses Libxml2 to parse XML data and create XML responses.

Project Outcomes

FAR-EMR system satisfied project sponsor’s requirements: during acceptance testing, we were able to handle hundreds of simultaneous clinical document submissions and requests on a single laptop. The system is also a demonstration of a functioning scalable and secure EMR server without resorting to feature-rich, but difficult to configure and secure, web frameworks and servers. Furthermore, due to its event-driven architecture, FAR-EMR scales far better than EMRs deployed on process-driven servers such as Apache. While further development work is required to make FAR-EMR production ready, the proof-of-concept demonstration was a success, and the system could present a viable alternative to existing EMR products in the near future.

The XP/Agile principles were fulfilled as follows:

  • constantly refining user requirements in the form of user stories;
  • recognizing changing FAR-EMR requirements, and redesigning the product accordingly;
  • keeping the development process simple in the form of weekly iterations;
  • and using completed software demonstrations to project sponsor as the true measure of progress.

Testimonial

We now have a working internal system and are integrating that capability with the resources of a leading provider of laboratory results in BC to offer very soon a production version of a complete electronic patient health record… …I am confident that the results derived from this [FAR-EMR] project will form the foundation of a significant advance in the distribution of health information in our province and perhaps the rest of the country.

  • Dennis B., President, Applied Robotics Inc.

comments


Simple Two Factor Authentication Scheme

implementing multi-factor server-side authentication the easy way
- posted on January 14, 2014 by Vsevolod Geraskin in tutorials about tls/ssl6 security7 openssl2 http6 oauth2 shell2

Two factors too many

In a perfect world, we would not need any authentication. In a real world, we often feel protected enough by our Password1 universal password. Maintaining sufficient security is often a major pain for internet organizations, as security and usability are almost always in either or relationship.

Unfortunately, oftentimes, the single authentication factor is not enough. As it happens almost on a daily basis, hackers might steal your social account password and post spam under your account. Worse yet, somebody might gain access to your health record and make it public or steal your credit card information from your bank. Thus, most governments often require software businesses to be compliant with multi-factor authentication schemes when it comes to securing sensitive information, such as electronic health records.

Two factor authentication systems can be composed of something a user knows and something a user has. Also, third authentication factor can be something a user is, but, unfortunately, biometrics are beyond the scope of this post. For simplicity reasons, we will use client certificate as something a user has, and username and password as something a user knows.

In this example, let’s assume we have an authentication server that provides access to web resources.

First Authentication Factor - SSL client certificate

One way to issue a client certificate from our certificate authority is by using the OpenSSL library and the steps below:

1. Generate RSA private key testclient.pem with 2048-bit encryption strength

[root@linusaur certs]# openssl genrsa -des3 -out testclient.pem 2048
Generating RSA private key, 2048 bit long modulus
........................+++
............+++
e is 65537 (0x10001)
Enter pass phrase for testclient.pem:
Verifying - Enter pass phrase for testclient.pem:

2. For self-signed certificate, issue certificate signing request testclient.csr with your details

 
[root@linusaur certs]# openssl req -new -key testclient.pem -out
testclient.csr
Enter pass phrase for testclient.pem:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CA
State or Province Name (full name) []:British Columbia
Locality Name (eg, city) [Default City]:Burnaby
Organization Name (eg, company) [Default Company Ltd]:Test Company
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your servers hostname) []:Test
Email Address []:yourname@gmail.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

3. Issue client certificate testclient.crt against our certificate authority ariCA.crt with 360 days expiry

[root@linusaur certs]# openssl ca -days 360 -in testclient.csr -out testclient.crt
-keyfile arikey.pem -cert ariCA.crt -policy policy_anything
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for arikey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 5 (0x5)
Validity
Not Before: Jan 13 19:15:05 2014 GMT
Not After : Jan 8 19:15:05 2015 GMT
Subject:
countryName = CA
stateOrProvinceName = British Columbia
localityName = Burnaby
organizationName = Test Company
commonName = Test
emailAddress = yourname@gmail.com
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
3D:09:19:13:66:B6:E7:70:04:24:FE:2A:BC:A4:9F:DC:6F:69:FE:38
X509v3 Authority Key Identifier:
keyid:04:3F:2D:FF:71:44:F0:08:E6:CD:71:CD:81:D5:A7:36:EB:70:96:D2
Certificate is to be certified until Jan 8 19:15:05 2015 GMT (360 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

Now, we can give testclient.crt to a user which they will use as the first authentication factor. Every time the user tries to access a web resource on our server, our authentication server should request this client certificate, check it against our certificate authority, and either grant or deny access.

Second authentication factor - username and password

Once a user passes the first authentication step, the server should then validate their username and password. Arguably, the simplest way for a user software to pass username and password to our web service would be using HTTP protocol basic authentication scheme, which uses base-64 encrypted username and password. For instance, user HTTP request header to our authentication server could look like this:

POST /authorize HTTP/1.1
Authorization: Basic QkMwMDAwMEMzNTpTZXZDbGllbnRUZXN0

Where QkMwMDAwMEMzNTpTZXZDbGllbnRUZXN0 would be the output of a client-side function such as string base64encrypt(username + ":" + password).

Upon successful validation of username and password, our authentication server could issue a token which expires after a certain time, with which a client finally could access various resources. Using the token we issued, the authenticated user resource request headers could look like this:

POST /ResourceLocation HTTP/1.1
Authorization: Bearer SN3528Ev0r~lkMTq2jY7

Where SN3528Ev0r~lkMTq2jY7 is a token issued by our server of type Bearer. For more information on Bearer Tokens and Oauth 2.0 authentication, please check The OAuth 2.0 Authorization Framework and The OAuth 2.0 Authorization Framework: Bearer Token Usage.

Both authentication factors working together

System Diagram of Two Factor Authentication System The system diagram demonstrates issuing tokens by a two factor authentication system, where usernames, passwords, and access tokens are stored in MySQL database. The authentication protocol flow is described below:

  1. Web resource client initiates SSL handshake and provides their SSL certificate to the server.
  2. Authentication server verifies client certificate against root certificate authority stored on the server.
  3. Client sends an HTTP(POST) request to authentication server with HTTP basic authorization header (base64-encoded username:password).
  4. Authentication server returns a bearer access token or HTTP error (ie. 401 Unauthorized).
  5. Clients sends an HTTP(POST) request to resource server containing bearer token in authorization header.
  6. Resource server verifies an access token and responds with a requested resource.

comments