Sunday, April 10, 2016

WeatherClock - Part 4

I need to describe the server-side part of this project in more detail since I've added to my scope. Here is a simple diagram of our entire system. In this post, I'm focused on the non-Arduino portion.

While I have no expectation that anyone else will use the service I've built, every call to the service results in a corresponding call to the Forecast.io API -- and my free account with them only allows 2000 calls a day. If more than 2000 calls happen, I stop getting a response from Forecast.IO, so my clock will have no data. The risk is small, both in it's likelihood of occurrence (nobody will really care about this service if they do find it) and in it's impact - my clock will stop working. While this isn't a big deal, I'd rather it not happen. So, how do I ensure that my public-facing Azure service doesn't get used/abused by anyone other than me?

Web services often use API keys to handle authentication -- you send a request with a valid key, you are authenticated. Forecast.IO does this, in fact. The downside of course is that if your API key is exposed, anyone can pretend to be you. I'm not concerned about this authentication mechanism b/w Azure and Forecast.IO -- that channel is relatively safe. I AM concerned about the channel between my Arduino client and my Azure service.

I could certainly use a static API key to authenticate my Arduino to my Azure service, but that's a bit riskier than a typical setup because I don't have the ability to create an encrypted channel. While Azure makes it free and easy to use SSL/TLS, my Arduino client is incapable of consuming it. So, our traffic will be in the clear over HTTP. How can I authenticate in the clear such that an eavesdropper can't make use of sniffed traffic? Here's what I came up with. Note this does NOTHING to stop a man-in-the-middle, it's just giving the observer of the traffic a harder job to make use of what is seen.

My Azure service exposes a single API: /api/Forecast/{latitude}/{longitude}/ . The header of the request must include two values: id and key. The value of id is essentially an "account identifier". Were I building a service that had multiple accounts/users, this would be the value to identify the account to which we want to associate the call. For me, this is a static, hard-coded value since I am the only account in use. The value of the key is the fun trick I'm using to get a semblance of authentication. The value of key is a calculated one-time-password, such as that used by Google Authenticator or any other 2-factor/OTP system. In fact, the OTP algorithm I'm using is fully compatible with Google Auth. So, here's how it works. My Azure service has a secret key associated with my account (again, this is hard-coded in my setup since I'm the only user), and the exact same key is also embedded in my Arduino. Assuming my service and my Arduino have their clocks in sync (to a reasonable degree), the two sides can calculate an identical 6-digit OTP that changes every 30 seconds. What does this do for us? It means that every 30 seconds, the header value that has to pass to my service to get a successful response will change. Neat - I have a non-static, unpredictable (from the outside) authentication mechanism! Obviously this is not bulletproof. I've done nothing to stop an eavesdropper from re-using a valid OTP within the same 30 second window for which it was calculated (tho' that wouldn't be too hard to stop). I'm sure there are plenty of other vulnerabilities as well. But I think this is a secure-enough solution for what I'm trying to accomplish. And given that I only have 2k of RAM to work with on the Arduino and a ton of other stuff to do in that memory space, I'm pleased with it.

The code for my server component is here: https://github.com/jimnelson2/WeatherClock-Server I put the source there for folks to see/use, but I used visualstudio.com and continue to use that for my development work.

Here's a quick walkthrough of the code. This is a standard .net WebAPI project, I've created only two unique classes - the ForecastController to handle the call/response with the Forecast.IO service, and the ApiKeyHandler to do the OTP/authentication work. The Forecast controller is wired in with the WebApiConfig, which also sets up the ApiKeyHandler. Small bits and pieces are scattered in to try reducing the size of the response back to the Arduino. By default, responses include lots of header data that just doesn't matter for my purposes. I could probably reduce a bit more, but this is good enough.

I use AppSettings to hold several handy values. First and foremost, the Forecast,io API key I use to authenticate my Azure service to the Forecast.io service. In development, this value is in the web.config. In production, this value is set via my Azure configuration so there's never a need to put my key into source control. In addition to the API key, I also use a setting for the OTP key (again, I'm the only user of this sytem - if it were multiuser, the OTP would be in a database along with my account id, etc.)  I use a few other values to help with development/debugging. For example, if I've set app settings for latitude and/or longitude, those values will override anything that comes in a request.

I've also made extensive use of application tracing commands. These are handy for when you need to crank up the logging level of your app. A simple toggle in your Azure panel will start tracing and you can pull the traces back either via the VisualStudio IDE, the web, or Powershell. Search the help docs on Azure for details.

As I've mentioned before, very little of this code is mine. I've documented in the code where I've sourced, primarily the Forecast.IO client and the OTP code.

About the response I send from the service back down to the client. I had initially designed things such that the response would be 60 RGB tuples - this would let me control server-side the exact color of any LED in the ring. e.g. 0,0,255,0,0,255...would set the first two LEDs of the ring to bright blue. After LOTS of frustrating testing I discovered what I should've known instantly - that's a lot of data for the Arduino to handle. So, I redesigned a bit. Instead of 60 RGB tuples (potentially 60 * 3 bytes, comma-separated), I send just 60 single characters. Each character is a hex value from 0 to f. That gives me 16 potential colors to specify, 0 is for an off/dark LED, while the remaining 15 are used to map into an array of 15 RGB tuples set as constants on the Arduino. This shrinks the network payload dramatically at the small expense of flexibility. Should I want to change my colors, I have to jump into the Arduino code. The smaller payload has dramatically improved Arduino stability, but I'll talk about that more in the next post when I go over the client.

Here's a look at the final product as a teaser - it shows a band of medium/heavy rain passing through in the next 15 minutes, followed by light rain wrapping up within the next 45 minutes.



Thursday, March 3, 2016

Calculate the entropy of a string (i.e. a password) with PowerShell

As with my other PowerShell stuff, this was made for fun and might make it's way into something later. The details of what the script is for, and the many assumptions it makes are in the code. Short story, this function will give you the bits of entropy in a provided string. Usually such a thing is interesting when trying to determine the "strength" of a password. The larger the number, the stronger the password (because the amount of space that would need to be explored to find the password via brute force is larger...has more entropy). The code notes a link that discusses the topic in MUCH greater detail.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<#
.SYNOPSIS
    Calculate the entropy (in bits) of the provided string
.DESCRIPTION
    Based primarily upon discussion here, https://technet.microsoft.com/en-us/library/cc512609.aspx
    this function will calculate the entropy of the provided string, returning an integer result
    indicating bits of entropy. Numerous assumptions MUST be made in the calculation of this
    number. This function takes the easiest approach, which you can also read as "lazy" at best
    or misleading at worst.

    We need to figure out the "size" of the space from which the symbols in the string are drawn - after
    all the value we're calculating is not absolute in any way, it's relative to some max/min values. We
    make the following assumptions in this function:
    --if there is a lower case letter in the provided string, assume it's possible any lower case letter could
      have been used. Assume the same for upper, numeric, and special chars.
    --by "special characters" we mean the following: ~`!@#$%^&*()_-+={}[]|\:;"'<,>.?/
    --by "letters", we mean just the letters on a U.S. keyboard.
    --no rules regarding which symbols can appear where, e.g. can't start with a number.
    --no rules disallowing runs, e.g. sequential numbers, sequential characters, etc.
    --no rules considering non-normal distribution of symbols, e.g. "e" just as likley to appear as "#"
    The net impact of these assumptions is we are over-calculating the entropy so the best use of this
    function is probably for comparison between strings, not as some arbiter of absolute entropy.
.PARAMETER s
 The string for which to calculate entropy.
.EXAMPLE
 get-StringEntropy -s "JBSWY3DPEHPK3PXP"
.NOTES  
 FileName: get-StringEntropy
 Author: nelsondev1
#>

function get-StringEntropy {
[CmdletBinding()]
Param(
    [String]$s
)

$specialChars = @"
~`!@#$%^&*()_-+={}[]|\:;"'<,>.?/
"@

    $symbolCount = 0 # running count of our symbol space

    if ($s -cmatch "[a-z]+") {
        $symbolCount += 26
        Write-Verbose "$s contains at least one lower case character. Symbol space now $symbolCount"
    }
    if ($s -cmatch "[A-Z]+") {
        $symbolCount += 26
        Write-Verbose "$s contains at least one upper case character. Symbol space now $symbolCount"
    }
    if ($s -cmatch "[0-9]+") {
        $symbolCount += 10
        Write-Verbose "$s contains at least one numeric character. Symbol space now $symbolCount"
    }

    # In the particular use, I found trying to regex/match...challenging. Instead, just going
    # to iterate and look for containment.
    $hasSpecialChars = $false
    foreach ($c in $specialChars.ToCharArray())
    {
        if ($s.Contains($c))
        {
            $hasSpecialChars = $true
        }
    } 
    if ($hasSpecialChars) {
        $symbolCount += $specialChars.Length
        Write-Verbose "$s contains at least one special character. Symbol space now $symbolCount"
    }

    # in a batch mode, we might want to pre-calculate the possible values since log is slow-ish.
    # there wouldn't be many unique options (eg 26, 26+26, 26+10, 26+16, 26+26+10, etc.)
    # ...though in comparison to performing the above regex matches it may not be a big deal.
    # anyway...

    # Entropy-per-symbol is the base 2 log of the symbol space size
    $entroyPerSymbol = [Math]::Log($symbolCount) / [Math]::Log(2)
    Write-Verbose "Bits of entropy per symbol calculated to be $entroyPerSymbol"

    $passwordEntropy = $entroyPerSymbol * $s.Length

    Write-Verbose "Returning value of $passwordEntropy"
    return $passwordEntropy # this is the bits of entropy in the starting string
}

Saturday, February 20, 2016

WeatherClock - Part 3

Let's look at the server-side portions first. We'll do this in two parts and this initial one is trivial. We're going to be using the Forecast.IO API at https://developer.forecast.io/ to source our weather data. I'm going to be writing my server portion of this app in .net b/c I like it and I love Azure. It's just super quick and simple. Rather than writing my own wrapper to consume the Forecast.IO service, I'm going to use some lovely code found here: https://github.com/f0xy/forecast.io-csharp . This wrapper is PERFECT for what I need, and only needed two small enhancements.

First, the wrapper as-is does not include Precipitation Type for the minute-by-minute forecast. Easy enough to add, we just PrecipType to MinuteForecast in https://github.com/f0xy/forecast.io-csharp/blob/master/forecast.io/Entities/ForecastIOResponse.cs

Second, the wrapper needs an API key when it calls Forecast.IO. Rather than embedding the key in code, I made the trivial change to have the code pull the API key from my Azure app settings. This is a better solution as it keeps secrets completely removed from the code base.

Ok, that's a description of half our server side. Next post will wrap up the server-side code and provide reference to the full source.

Monday, January 4, 2016

WeatherClock - Part 2


First, the hardware. I got EVERYTHING from Adafruit.com. We have three primary components: An Arduino, a Wifi shield, and 4 1/4-ring Neopixels. I also got all my bits of wire and solder and sundry components from Adafruit as well.

Let's look at the hardware first. Here's what we're building. Note in this diagram the LED ring depicted is NOT the 60 element ring, but I think the idea is pretty clear.

Following the instructions from Adafruit, solder together the 4 Neopixel 1/4-ring pieces into a single ring. http://www.adafruit.com/products/1768. I'll just re-emphasize some of the more salient parts of this. While you DO want all four joints of your ring to have the 5V and ground connections soldered, make sure you DON'T solder together the data pads of the final joint -- you only want that data signal going in one side. I chose to have my power, ground, and data wires all leading off the same joint. I don't think it's necessary, but it looks cleaner to me.

After assembling the ring, it's a good idea to connect your ring to the Arduino and fire up a sketch to exercise the ring. You want to be sure that all the LEDs light as expected, otherwise when stuff doesn't work later you won't know if it's your hardware or your software. That's no fun. Your pre-requisite task for this is to have downloaded and installed the Arduino IDE and downloaded the Neopixel libraries from Adafruit, available on GitHub. There are plenty of tutorials available to walk you through how to use this software, so I won't bother here.  I discovered when I first ran the example sketches that only half my ring lit up, with a couple of odd LEDs here and there turned on for the remainder of the ring. Turns out I had a cold solder joint on the data pads between the second and third rings, so signal wasn't making it through. Better to find these problems now than later!

Some additional notes: I also followed the precautions noted by Adafruit to place a large capacitor across the power supply and put a small resistor inline with the data connection. They know more than me about electronics, so I did it. It works.

Your next step is assemble the WiFi shield, which is nothing more than soldering on the headers so you can attach the shield to the Arduino. As with the ring, I fired up example sketches to be sure that the WiFi shield was working properly. Below is a pic showing the wired up hardware with a trivial Aruduino sketch lighting up the ring with simple colors.



At this point, we have hardware. At the end of this series of posts, I'll provide a complete parts list for what's been built. Now we're ready to write some code to make the hardware do something...

WeatherClock - Part 1

This is first in a series of posts detailing the build and programming for what I'm calling a "Weather Clock." The folks at AccuWeather have nice mobile app that includes a real-time, minute-by-minute forecast of precipitation for the next two hours. What's neat about this is the visualization. They present a ring, with "right now" at the top and the minutes flowing along clockwise, just a like a -- well -- a clock. Each minute on the clock face is colored to represent the type and intensity of precipitation expected for the next two hours. Here's a picture, showing light rain starting in about 26 minutes, heavier rain around 90.



I always liked this visual, and thought it would be fun to build one of these weather clocks and hang it on a wall. You could certainly do this mostly/entirely in software by building an app to run on a tablet, then hang the tablet on the wall. But in this case I wanted to tinker around with actually building dedicated hardware. Like many people drawn to building internet-connected devices, my background is in software -- not hardware -- so I approached this project with a little trepidation. Turns out there wasn't much to fear, this came together pretty well (I think). By the end of this series of posts, I'll have provided links to everything -- the hardware components, the code, etc. I welcome any and all comments about how this could've been done better, or differently, or whatever.
 

Friday, December 4, 2015

Mapping Java WebSphere Cipher Suite Names to IBM Host Cipher Suites

We recently went through an issue at work that required digging into the cipher suite negotiation between a WebSphere client and a web service exposed via CICS. The trickiness of this was based on how these two side expose their cipher suites to admins. On the Host side, the cipher suites are presented as a string of hex codes identifying the unique cipher IDs. On the WebSphere side, the suites are listed by name -- but the WebSphere cipher suite names do not match up with the cipher suite names in host documentation. I tried for a bit to find a cross reference somewhere on web but gave up. So I made my own which I present below. I did this by looking at openJDK's CipherSuite.java which maps the java cipher suite names to cipher IDs. Then I matched those cipher IDs to the Host cipher suite names. Trival. This is not a complete list of all available ciphers on these platforms -- it was what we needed for our current problem.
 
As a final bit of fun with names, note that depending on the particular Java you are using, the JAVA names may interchange the three-letter acronyms TLS and SSL. For example, the IBMJSSE2 suite does this. Refer to documentation here: https://www-01.ibm.com/support/knowledgecenter/SSYKE2_7.0.0/com.ibm.java.security.component.71.doc/security-component/jsse2Docs/ciphersuites.html

Hope this helps someone.


CIPHER ID
CICS NAME
JAVA Name
35
TLS1_RSA_WITH_AES_256_SHA
TLS_RSA_WITH_AES_256_CBC_SHA
36
TLS1_DH_DSS_WITH_AES_256_SHA
N/A WEBSPHERE
37
TLS1_DH_RSA_WITH_AES_256_SHA
N/A WEBSPHERE
38
TLS1_DHE_DSS_WITH_AES_256_SHA
TLS_DHE_DSS_WITH_AES_256_CBC_SHA
39
TLS1_DHE_RSA_WITH_AES_256_SHA
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
2F
TLS1_RSA_WITH_AES_128_SHA
TLS_RSA_WITH_AES_128_CBC_SHA
30
TLS1_DH_DSS_WITH_AES_128_SHA
N/A WEBSPHERE
31
TLS1_DH_RSA_WITH_AES_128_SHA
N/A WEBSPHERE
32
TLS1_DHE_DSS_WITH_AES_128_SHA
TLS_DHE_DSS_WITH_AES_128_CBC_SHA
33
TLS1_DHE_RSA_WITH_AES_128_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
0A
SSL3_RSA_DES_192_CBC3_SHA
SSL_RSA_WITH_3DES_EDE_CBC_SHA
16
SSL3_EDH_RSA_DES_192_CBC3_SHA
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
13
SSL3_EDH_DSS_DES_192_CBC3_SHA
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
10
SSL3_DH_RSA_DES_192_CBC3_SHA
SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA
0D
SSL3_DH_DSS_DES_192_CBC3_SHA
SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA
09
SSL3_RSA_DES_64_CBC_SHA
SSL_RSA_WITH_DES_CBC_SHA
15
SSL3_EDH_RSA_DES_64_CBC_SHA
SSL_DHE_RSA_WITH_DES_CBC_SHA
12
SSL3_EDH_DSS_DES_64_CBC_SHA
SSL_DHE_DSS_WITH_DES_CBC_SHA
0F
SSL3_DH_RSA_DES_64_CBC_SHA
SSL_DH_RSA_WITH_DES_CBC_SHA
0C
SSL3_DH_DSS_DES_64_CBC_SHA
SSL_DH_DSS_WITH_DES_CBC_SHA

Friday, November 20, 2015

When read-only is too much -- how to obtain programmatic access to EMC RSA Data Protection Manager crypto keys.

The audience for this post is quite limited - not many folks (relatively) use EMC's RSA DPM product. I'm gonna make NO effort to really describe how the RSA DPM system works. If you know the system, this will all make sense. If you do not, it probably won't though the general color and ideas should resonate. In addition, what I'm about to show is a known behavior -- the developer guides for the RSA DPM (at least for java) recommend the steps necessary to mitigate what I'm showing here. The c# and c++ guides make no mention of this that I could find, but the same behavior exists on those frameworks as well. What's not really called out clearly is what the risk entails.

The RSA DPM is a cryptography and key management solution for enterprises. The server-side manages cryptography keys, and clients obtain the keys when needed to perform crypto operations locally on the client. The clients do this by importing the necessary library files, and "registering" themselves with the server. The registration process essentially sets up a certificate-based authentication mechanism between client and server. Once registration is completed, a certificate and some "fingerprint" files are generated. At run-time, the client requests keys from the server over the authenticated channel using the certificate. The "fingerprint" files do some magic to ensure that the client system has not been changed in some way that might indicate compromise or movement of the client.

Here's the "weakness". If the "bad-guy" has read-only access to these registration files, it is a TRIVIAL matter to copy the files to another location on the same system and use the files to make perfectly valid calls to the RSA DPM server via a small custom application, accessing all the crypto keys that should (by intent) only be accessible to the orignal client application.

The example below is in java. You can do the same for c# or c++. The idea/approach is equally valid there. Our outline of activity:
1) Copy RSA DPM registration files to a new location on the original client that is write-able by the user.
2) Use a custom application making reference to these copied registration files to pull crypto keys from the RSA DPM server. This is NOT hard -- the RSA DPM client modules come pre-packaged with sample applications to help developers learn how to use the client. We'll just use one of these sample programs.
3) ??? Well, you now have crypto keys. That's not good for whoever the keys belong to. How you approach mitigating this is up to you and probably depends on how your business operates. It should be NO surprise that the "fix" for this problem is:
4) Lock down read access to the original client registration files. Only the application using these files needs access to them, so nothing/no one else should be able to read them. Basic security principles here. Lock. Down. Access.

Here is the process and minimal code samples that walk through the steps to access crypto keys. Whatever system you are on will almost certainly differ in the details, primarily paths and file names. But this should be enough to get the idea across. We're going to be demonstrating this on a *nix system running WebSphere that has an app incorporating the EMC RSA DPM. This assumes (as I've described above) that the bad guy has read access to the application files, and write/execute access to some path, somewhere, on the same server.

1) Copy all the "registration files" to a new writeable location. These files are (assuming the app developers follow the nomenclature of the RSA DPM examples).
*.p12
*.bin
*.cache
Optionally, copy the RSA DPM client jar files, too. You can always just reference them in their existing location when you run your app later to extract keys.

2) Do some environment setup. Nothing fancy here, we're essentially just setting ourselves up for running java
export Java_Home=/apps/websphere/java/jre
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/apps/websphere/java/jre/bin:/apps/websphere/java/jre/bin/classic:/apps/websphere/java/jre/bin
export CLASSPATH=/home/usr/me/rsadpm/*.*

3) Execute one of the sample RSA DPM client apps, specifying the copied registration files.  Note that I'm being a little obtuse here and NOT showing the small modifications made to the demo EncryptAndDecryptData code -- the changes from how this file is delivered from EMC are minor. Just change the path references, and update the the config file to reference the files you copied in step 1.
/apps/websphere/java/jre/bin/java -cp /home/usr/me/rsadpm:/home/usr/me/rsadpm/certj.jar:/home/usr/me/rsadpm/cryptoj.jar:/home/usr/me/rsadpm/cryptojFIPS.jar:/home/usr/me/rsadpm/kmsclient.jar:/home/usr/me/rsadpm/LB.jar:/home/usr/me/rsadpm/LBImpl.jar:/home/usr/me/rsadpm/log4j-1.2.15.jar:/home/usr/me/rsadpm/sslj.jar rkmjc.simpleapi.EncryptAndDecryptData

 4) Here's what output looks like. In this, I'm simply encrypting/decrypting a hard-coded value using a key obtained from the server. It'd be just as easy to export the key to file or do whatever else you wanted.

Running Sample EncryptAndDecryptData
Plain Text:
  0000: 31 32 33 34 31 32 33 34 31 32 33 34 31 32 33 34 [1234123412341234]

Cipher Text:
  0000: 52 4b 4d 43 32 31 30 00 ff ff ff ff 00 00 00 05 [RKMC210.........]
  0010: 75 75 69 64 00 00 00 00 10 16 68 f2 8c 96 ca 4a [uuid......h....J]
  0020: 86 9c f4 f0 83 30 f6 9a db ff ff ff ff 00 00 00 [.....0..........]
  0030: 05 6f 72 69 64 00 00 00 00 20 0b 76 58 dc 76 07 [.orid.... .vX.v.]
  0040: 59 7e c5 9d f3 ba 66 cd f9 20 a2 fb 82 8f fd 2b [Y~....f.. .....+]
  0050: 88 fe 1b 05 2e a8 a2 6c 63 2b ff ff ff ff 00 00 [.......lc+......]
  0060: 00 05 63 73 75 6d 00 00 00 00 20 9f e4 86 dd 57 [..csum.... ....W]
  0070: 2a 72 fa 9f cb 08 e6 d5 e8 79 14 89 3d a9 05 17 [*r.......y..=...]
  0080: bd 03 94 b7 ea 9d 73 8a 07 3e f8 ce d8 18 71 e8 [......s..>....q.]
  0090: 69 c3 02 16 90 65 56 ff 28 8f 29 d8 c3 63 85 6c [i....eV.(.)..c.l]
  00a0: 30 1a c9 72 7a b3 15 d8 fe c6 5c                [0..rz.....\     ]

Recovered Plain Text:
  0000: 31 32 33 34 31 32 33 34 31 32 33 34 31 32 33 34 [1234123412341234]

Successful Ending EncryptAndDecryptData


So, what's the takeaway here? If you are using the EMC RSA DPM client, please be sure to lock down access to the DPM files -- NOTHING should be able to get to them that doesn't absolutely need them. Otherwise you open yourself to exfiltration of keys.