Monday, July 21, 2014

Gnocchi Research: Week 10

At the end of Week 9, I found that the Mongoose library (in C) was too difficult for me to work with. As a result, I searched for alternatives. Python-as a language-seemed like a good choice. This was because it had high level operations. Furthermore, Python had better documented APIs than C.

Olga suggested I run with Flask or Cherrypy. Both seemed quite similar and fulfilled the same purpose- providing the API for a web server.

Choosing the Flask API, I started implementing several server-side operations at a functional level. I used the server's file system to do storage.

  • PUBLISHER_REGISTER and SUBSCRIBER REGISTER
    • A POST that registers the publisher/subscriber by storing their public key. 
  • CREDENTIAL_QUERY
    • A GET operation that tells a publisher/subscriber information about a target entity. 
  • ADD_MEMBER
    • A POST that allows publishers to add subscribers. 
  • JOIN_GROUP
    • A POST that lets subscribers request to join a group
  • RETRIEVE_MEMBERSHIP_REQUESTS
    • Publishers GET membership requests from the previous JOIN_GROUP for a particular group
  • SUBSCRIBER_UNREGISTER
    • Deletes a subscriber from all of its groups, freeing up space in the server
  • DELETE_MEMBER
    • Publisher POST that removes a member from a group
    • New encrypted group keys must be uploaded eventually via UPDATE_GROUP_KEY
  • GET_GROUP_KEY
    • Subscriber GET request that retrieves his/her encrypted group key for a particular group
  • RETRIEVE_MEMBERSHIP
    • Publisher GET command that retrieves the members of a group he/she created
  • UPDATE_GROUP_KEY
    • Follow-up to DELETE_MEMBER
    • Publisher POST that uploads new encrypted group keys to everyone who wasn't deleted
  • CREATE_GROUP
    • A GET request by publishers to get a unique Group ID for the keyserver.
    • Also registers that group for the publisher
  • SUBSCRIBER_GROUP_LIST
    • GET request by subscribers that shows what groups he/she is a part of
  • PUBLISHER_GROUP_LIST
    • GET request by subscribers that shows what groups a certain publisher is in charge of
All of these are done on some level aside from UPDATE_GROUP_KEY: That function probably needs some thought first. Perhaps we should use a special file structure that contains users and encrypted keys, which could be parsed by the file server

Additionally, verification will have to be implemented: We don't want the key server to allow a non-creator publisher to delete members of a group :)


Wednesday, July 9, 2014

Gnocchi Research: Week 9

This week started with looking for a protocol or framework that could make implementing the key server simple. We wanted something that supported HTTP because the Chrome extension spoke the language of browsers, HTTP. We had a couple of options:
  1. Open Source HTTP web servers in C/C++
  2. Python's resources for HTTP web servers
  3. Less academically used frameworks with good APIs such as Nodejs 
Pros and Cons
In C/C++, I found two seemingly well-maintained libraries: Mongoose (C) and Pion Network Library (C++). One desired characteristic of the key server is that it is lightweight. At the very least, the Pion library seemed to take much longer to compile and had many more files involved. Mongoose, however, was just a pair of .h and .c files. Pion, using boost and possibly other C++ features, may have performance advantages over Mongoose, but for simplicity sake, I chose Mongoose over Pion.
(Additionally, Pion seems incredibly difficult to compile. On Ubuntu 12.04, I got furthest with compilation by installing boost 1.55, recompiling openssl with ./config shared, modifying makefiles to include -fPIC, and moving libssl.a to the directory Pion looked in. Even after copying all the boost files to where the old v1.48 ones were, there were still linking issues with boost when trying to compile a sample program)

Libraries in Python might be more developed than possible web server libraries in C/C++. For now, I chose Mongoose (C) because I didn't want to be slowed down by my lack of Python knowledge. Perhaps I will go back and use Python instead.

Something like Nodejs or Ruby on Rails seemed useful for developing a key server. However, we wouldn't have much control over the way certain protocols are implemented, and there could be hidden security issues or bugs. Working in C/C++/Python gives us control over implementation but opens doors up for our own bugs. Additionally, people in academia might frown upon the use of these newer, more "hip" technologies over languages everyone knows.

To be continued....


Thursday, July 3, 2014

Gnocchi Research: Week 8

This week I started to work on implementing the key server.

The Key Server must be able to do the following:
1. Register a client or publisher
2. Allow users to upload/download keys
3. Allow publishers to manage groups
4. Allow users to query the database

By "keys," the key server should serve encrypted group keys to users and public keys of clients to publishers. The primary purpose is to serve encrypted group keys to users so that users can decrypt and find the group key with their private key.

At first, I thought this could be done in a standalone web application separate from the publisher side and the client side. On the development side, I think it would have been simple. However, for end users, they would have to interact with another program (the web application that interacts with the key server), which could easily confuse people. There might have been operations that would not be intuitive to the average person.

We concluded that the key server, at least on the publisher side, should work in conjunction with the publisher app. Right now, the publisher app is a command line utility. When publishers want to upload their group information and keys to the key server, they can use the upload utility on the publisher app, and then data would be sent to the key server, which would process it.

I know a little bit about how server programs can send and receive data. A program can make a connection to another entity on the web through a port, and then once the connection is made and bound, the web server can listen and receive data through a sent byte stream. The web server can also send data back to the client through a byte stream as well, who would receive data through the same connection.

For the client side, we don't know if work should be done cooperatively. It might be easier for users to go to a website and receive their encrypted keys through a website application. Perhaps users will use the website, which will show their keys in plaintext, or perhaps they can download a file containing their encrypted key.

For security, we have not yet put much thought in. We are trying to be flexible so that changes can be made easily. As of now, we are thinking of using Kerberos to secure authenticity between users and the key server. Perhaps SSL could be used instead. Even though part of Gnocchi is to show that SSL could be weak, there has to be some first level of trust.

One design alternative thought up was to use a web development framework to implement the key server. In particular, I wanted to try this in Ruby on Rails. It's hip, new, and reportedly easy to get stuff started. I'd be learning something pretty interesting. However, my intuition tells me academia probably wants to use technologies that are well known. As a result, I'm working on writing the key server in C++ in a manner that makes it easy for the publisher app to interact with it.

Another design alternative was to work with HTTP GETs and POSTs for sending and receiving content (as in, keys). This may actually have to be done, as GETs and POSTs are the language of internet browsers, and we do have a Chrome extension for the client app.

Gnocchi Research: Weeks 6-7

I missed week 6's blog post, so this post will comprise both weeks 6 and 7.

Contrary to what I said in a previous post, OpenSSL's verify application actually does verify signatures. It turns out the proper way to run the verify command is:
openssl verify -CAfile <file with only trusted certs but can be multiple> <singular cert to verify>
As a result, running
openssl verify -CAfile adtrust_and_incom.crt fake.crt
where fake.crt was a certificate with modified entries, the verify command failed. The reason for this is simple. Openssl's verify utility only cares about the first entry of the file it's checking. So for the <singular cert to verify> spot, I was concatenating 3 certs of a certificate chain (adtrust-incommon-fake) with adtrust.crt on top, making openssl's verify utility only check the validity of adtrust.crt (which would always return true because the optarg of -CAfile would be adtrust.crt). As expected, the error message generated was error 7: invalid signature.

As for other vulnerabilities to black-box test, there could be problems with how CA signing interprets the data read from the csr (certificate request). Are there bad/missed bounds checking, or does OpenSSL properly read in various data entries? Even though we know CA request generation doesn't output files with super long entries (over 1024 bytes), what if requests were modified to include those super long entries- perhaps buffers could be overflowed.