Wednesday, January 9, 2019

LTI Signature Fails - Carriage Returns, Newlines, and OAuth Signatures

Problem: 

While writing an LTI integration tool, I decided to run a battery of true LTI payloads from various LMS systems and see if I could produce the same signature. While running these payloads via automation, I found that some payloads would fail to produce the same signature. After ensuring that my encoding was using the agreed standard RFC 3986, I looked to narrow in on a specific LMS like Moodle or Blackboard. The signature fails were not confined to a specific LMS, but rather all contained the same single non-visible character.


Solution:

The payloads failing to produce a correct signature happened to contain a carriage return (\r) followed by a new line(\n). The \r\n line termination sequence is commonly used by Microsoft. Suspicious of the carriage return, I removed it from the payloads, then reprocessed the signatures. It was successful. So now understanding what caused the problem, I decided to narrow in to the why.

LTI Process (Simple Version)
The LTI flow originates from the LMS also known as the Tool Consumer (TC), the TC will generate a payload of data consisting of key/value pairs and then sign the data using a shared secret. This signature uses OAuth. Once the data has been created it is generally injected into a user's browser page inside a form element of type POST and an action pointing to the Tool Provider's (TP) endpoint. Once this data is in the form, it will be submitted either automatically or manually. The receipient, which is the TP, takes this payload of data and verifies the data has not been changed by using the shared secret to recreate the signature. If the signature matches the one provided, the data can be trusted.

Dirty Little Microsoft Browser
The problem we see is actually caused by the browser attempting to format the data as it is injected into the form and newlines are preceded by a carriage return. This actually makes sense if the browser is going to display the data to the user, as Windows uses these carriage returns.

At some point, it appears that the issue was corrected for Edge, but current LTI payloads make me suspect that it is still an issue. (See: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/16221536/)

Coding Defensively
Unfortunately, we can't just always remove carriage returns prior to signing our payload. This is because a lot of data in the payload is, in fact, entered by an user who might be using a browser that uses carriage returns. In this case, the data will most likely be signed with the carriage returns in place as few implementations clean up these returns prior to signing.

In order to handle these carriage return injections, we are going to have to check both possibilities. First, we assume that the data provided is correct for signing. The payloads may not contain carriage returns or the possibly no newlines at all. If this fails, we second try to remove only carriage returns that are immediately followed by a newline character.




Friday, February 10, 2017

Android: HAXM hypervisor Error

Problem:

While building my project in Android Studio, I got the following error:

emulator: ERROR: Unfortunately, there's an incompatibility between HAXM hypervisor and VirtualBox 4.3.30+ which doesn't allow multiple hypervisors to co-exist.


Solution:

This turned out to be due to some vagrant instances I was running on my system. After halting my vagrant machines, Android Studio was able to build the project properly.

Friday, December 23, 2016

Adobe Encore CS6 - internal software error: Vobulator\TitlePlanner\CVOBUPlanner.cpp, line 332

Problem:
While working on a DVD for a local commercial I assisted with, I came across a strange error while trying to build the project.

internal software error: Vobulator\TitlePlanner\CVOBUPlanner.cpp, line 332



Solution:
After reading forums and various websites and trying their suggested tips (removing overlapping chapter markers, etc). I decided to determine the problem through the process of elimination. I first determined the issue had to do with some photos that I had Encore using for a Slideshow. I removed them each trying to determine the error and then tried some different settings for the Slideshow component.

It turned out the issue was that my slide duration was less than 6 seconds long and Encore did not like that. Once I changed my slide duration to be 6 seconds, the project built properly.


Monday, September 12, 2016

Salesforce REST API: Unable to read request: No content to map to Object due to end of input

While working on an integration with the Salesforce REST API, I was working with their batch API and ran into this error message:

Unable to read request: No content to map to Object due to end of input

At first I assumed this was because I wasn't passing something I should have been, but it turned out that I was passing something it didn't like. I removed fields from my payload that I wasn't completely sure about and it suddenly started working for me. 

Hope this helps someone else in the same bind.

Saturday, April 9, 2016

Composer Update Failed on Dreamhost - killed for excessive resource usage

Problem:
While working on a pet project, I decided to use Laravel 5 on my Dreamhost shared server (where most of my prototype/hobbies go). I was able to get composer running fine with the exception of when I would try to run composer update. Composer can sometimes take a bit of resources, and unfortunately Dreamhost shared servers are pretty slim. I kept getting the following message.

Loading composer repositories with package information
Updating dependencies (including require-dev)

Yikes! One of your processes (php, pid 3726) was just killed for excessive resource usage.
Please contact DreamHost Support for details.

Killed

Solution:
It turns out that one of the heaviest parts of running composer update is the point as which the composer.lock file is updated and PHP tries to determine new packages, etc. If we generate the composer.lock file outside of Dreamhost (like on your local machine) and then move the file over, we can bypass this by running composer install.  For this pet project, I just add the composer.lock to my source version control to make things simpler when moving the file back and forth.

Good luck!

Friday, February 26, 2016

Ionic V2 - Could not find any version that matches com.android.support:support-v4

Problem: 
Lately I've been playing around with mobile app development using Ionic V2 (with Cordova). While testing it on my older mobile device (Galaxy S4) I noticed that the native web view (Android browser) seems to be slow and didn't play any of the Material Design animations. I found CrossWalk and started trying to add it to my project:

> ionic browser add crosswalk

I was able to get older versions working (14, 15), but when trying to use CrossWalk 16, I ran into an error:

ANDROID_HOME=/home/me/android-sdk-linux
JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
embedded
org.xwalk:xwalk_core_library:16+

FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring root project 'android'.
> Could not resolve all dependencies for configuration ':_armv7DebugCompile'.
   > Could not find any version that matches com.android.support:support-v4:[13.0.0,).
     Searched in the following locations:
         https://repo1.maven.org/maven2/com/android/support/support-v4/maven-metadata.xml
         https://repo1.maven.org/maven2/com/android/support/support-v4/
         https://download.01.org/crosswalk/releases/crosswalk/android/maven2/com/android/support/support-v4/maven-metadata.xml
         https://download.01.org/crosswalk/releases/crosswalk/android/maven2/com/android/support/support-v4/
         file:/home/me/android-sdk-linux/extras/google/m2repository/com/android/support/support-v4/maven-metadata.xml
         file:/home/me/android-sdk-linux/extras/google/m2repository/com/android/support/support-v4/
     Required by:
         :android:unspecified > org.xwalk:xwalk_core_library:16.45.421.19

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Solution:
It turned out I didn't have everything I needed installed from the Android SDK Manager. I found that I needed to have from Extra:

  • Android Support Library
  • Google Repository
  • Local Maven repository for Support Library

 Once I had these installed, my build was able to succeed and the app feels slightly more responsive but I still do not get Material Design animations.

Tuesday, May 19, 2015

cURL on Windows: cURL error 60: SSL certificate problem: unable to get local issuer certificate

Problem:

While running some unit tests on a managed project, I ran across an issue from the Guzzle library.

cURL error 60: SSL certificate problem: unable to get local issuer certificate


Solution:

The latest version of cURL does not ship with a bundle of root certificates. This is due to security concerns in the past. Instead, they have you provide the root certificates that should be valid as certificate authorities. Most of us are really only concerned with the main ones likes Equifax, GlobalSign, and Verisign.

There are several ways to solve this problem, but what I decided to do was allow PHP on my system to always reference the same PEM file instead of other methods (like telling cURL not validate the peer certificate - please note this is a bad idea!).

In order to solve this problem, we need to obtain a version of this cacert.pem file that has not been corrupted. I found mine from the cURL web site which links to Mozilla.orgs CAs.

Once I had downloaded the pem file, I placed it in a common development directory on my Windows machine.

Last, we just need to tell PHP where to look for this file. Open your php.ini file and set the following property*:

openssl.cafile="C:\dev\cacert.pem"


Hope this solves some head scratching.



*This may change if you use something other than OpenSSL.