7/25/2011

Protect KML / KMZ Files from Unauthorized Access Using Cryptography

In this blog post, I want to detail out the way we can protect KML files from unauthorized access in an Enterprise environment. In this approach, we can use the simple cryptography principles to make sure that the access to the KML files is granted only to authorized users, who are already authenticated in an enterprise context. But the problem here is that the KML files are accessed by Google server directly and there is no way for the Google server to send any authentication/authorization information on its own.

To understand this, we need to understand the basic flow of the request when a user accesses the KML from the browser. In the following diagram, I tried to capture this basic flow.
In an enterprise environment, before any of this request, we assume the user is already logged into the server and access the application.  

Google Accessing KML resource without any protection

  1. User accesses the maps application, which will have overlays mentioned as KML Url(which is located in the web server).
  2. The maps applications return the maps related HTML, JavaScript with the KML Url in the JavaScript.
  3. The JavaScript sends a request to the Google Maps server to access and parse the KML file with the KML Url in the request.
  4. Google Maps server accesses the KML Url directly from the server (not via the browser)
  5. The KML request reaches our own server and the server returns the KML content. This is the reason why the KML should be accessible from the Internet directly.
  6. Google Maps server parses the request and sends the parsed response to the JavaScript back and the Maps JavaScript draws the overlays necessary.
With these basic steps in view, let’s see how we can authenticate and authorize the user when the KML request reaches our server from the Google Maps server (Step 4 and 5). The main aim of this method is to establish a token and pass it as part of the KML Url. This token will be used when a KML request reaches the web server to verify the originator of the message, user who really requested the KML file, so that the server can do the verification, validation of the token and also the authorization, access-control for the KML resource (some group or role check). For this description, I am going to use the symmetric key encryption but it’s quite feasible to use the PKI based digital signatures too.

Google accessing the KML resource with cryptography based protection

  1. User accesses the maps application, which will have overlays mentioned as KML Url.
  2. The web/app server upon request for the map application, forms the crypto token to be included as part of the KML Url. This token is just a representation of the user identity (loginId of the user), valid from and valid to timestamps.  The reason for including these two timestamps is to establish a unique token for every request and also to introduce the expiry of the token, so that the same request cannot be replayed after the token is expired. The web server has to establish some secret key for the symmetric encryption.
    An example of the token:
    tokenBuffer = concat(userId, “:”, validFrom, “:”, validTo)  //”:” is used as a delimiter
    token = base64encoding(AESCipher(tokenBuffer, symmetricKey))  //using AES for this example


    This token will be appended as a query string to the KML url. Instead directly accessing the KML file, here we use a component (a servlet, PHP script or similar) for KML request processing. If the KML Url is http://:/test.kml then this Url will become http://:/webapp/KMLController?token=&kmlFile=test.kml
  3. The maps application responds to the browser with the maps HTML+JavaScirpt along with the KML Url containing the token.
  4. Google Maps “google.maps.KmlLayer” JavaScript object requests the Google maps server to fetch and process the KML as indicated by the Url. Please note that the Url contains the token we just formed as part of step 2.
  5. Upon request, the Google maps server sends a request to our web server’s KML Controller component to process a request for the KML file. The KML file name is passed as part of the query string.
  6. When KML controller receives the request for KML file content, it performs the following steps:
    1. It first extracts the token, which is available as part of the query string.
    2. This token is decrypted using the same symmetric key to get the clear text of the token.
    3. Extract the token values using the delimiter. In this step we get the user id, valid from and valid to values.
    4. Do the access control checks and validate the timestamps.
    5. If everything is fine send the KML content in the response with proper mimetype, i.e. application/vnd.google-earth.kml+xml for KML files and application/vnd.google-earth.kmz for KMZ files. (KML file name is available as part of the query string).
    6. If any of the steps failed, send proper response code (401, 403, 400 etc).
  7. Send the response back to the Google server’s HTTP request.
  8. Google server parses the KML if the KML is sent properly. Otherwise, it ignores the errors.
This way, we can protect the KML resource access from an unauthorized access.

References

  1. Book "Beginning Cryptography with Java" by David Hook
  2. Icons used in the above drawings are taken from the following site:
  3. Browser icon: http://www.iconfinder.com/icondetails/17856/128/browser_icon Maps icon: http://lab.iirojappinen.com/idroid/

7/13/2011

Protecting KML Files from general public access in Google Maps

Google provides a way to include the geospatial data in KML (Keyhole Markup Language) format and show that data in the maps (Google maps and earth). For Google to display the KML files in maps applications, those files have to be publicly accessible to the Google server. From an Enterprise perspective, often times, there is a requirement to protect these KML files from unauthorized access. This may be an issue as Enterprises do not want to expose the KML files in the public domains without any authentication.

So, till the time Google comes up with a solution (not sure if it already has any solution), following are my views about the options that can be considered.
  1. Allow access to KML files only from specific IPs or IP ranges. This means we need to get the IP range of the Google map servers and allow access to the KML files only from this IPs.
  2. Instead of using Google APIs to parse the KML files, we can use the client side processing libraries or implement our own KML parsing libraries (client side or server side) and use Google Map APIs to plot the places. As KML files are XMLs in the end, any XML parsing technique can be used. Two of the client side libraries:
    1. http://www.dyasdesigns.com/geoxml
    2. http://econym.org.uk/gmap/egeoxml.htm
  3. I recently found out about the usage of OpenLayers. Following are two examples which are of interest regarding this post.
    1. Usage of OpenLayers to display Google layer http://openlayers.org/dev/examples/google.html
    2. Usage of OpenLayers to display the KML overlays http://openlayers.org/dev/examples/kml-layer.html
  4. May be we can combine both options to display the KML overlays on top of Google Maps. From the view source of the KML OpenLayers example (http://openlayers.org/dev/examples/kml-layer.html), it does not look like the request is being sent to Google for KML parsing. So, all the authentication and authorization can be performed by server side scripts and this server side script will be the URL for the KML file.
  5. Use of digital signatures to protect the KMLs. In this option, we can use the simple public/private key pair to include the digital signature as part of the KML URL and this signature will be verified before providing the access to the KML file. This way, all the unauthorized access to the KMLs can be protected, as we can make sure that the originator is same as our own server with establishing a unique signature for every KML URL. I will detail out this option in the next blog post.
References
  1. KML tutorial from Google: http://code.google.com/apis/kml/documentation/kml_tut.html
  2. http://openlayers.org/
  3. Usage of different map providers using OpenLayers API http://openlayers.org/gallery/multiple.html
  4. Two client side libraries for displaying KML files:
    1. http://www.dyasdesigns.com/geoxml
    2. http://econym.org.uk/gmap/egeoxml.htm