Creating the companion app

Learn how to create the ios companion app for authentication with Alexa Voice Services.

Advertisements

This post is a continuation of my series of posts concerning the authentication of the AVS Java client.  See here for the prior post.

In our current configuration we need a so called “Companion App” to take care of the initial authentication with the LWA (Login with Amazon) service.  This companion app will should allow us to log on to amazon and tell the Amazon service that a certain product (our raspberry Pi) is allowed to make calls on my behalf, with my credentials.  To do that, the companion app needs to know a few things about my device.  It should call the Java Client on my Pi to get more information.  After that It should request an Authorization Code from the LWA Service and send it back to the Raspberry Pi.  It can use it to get a refresh token.

Luckily Amazon provides a sample application for a companion app as well.  Both for Android and for iOS.  That’s great.  I own a Mac, so can easily compile iOS version using XCode.  The companion app is written in Objective-C.  A language that’s not new to me, but it’s been a while since I did something with it.  Let’s dive in to what it does exactly.

I opened the project in XCode, but what I see is that it’s missing a file.  A certificate.

Schermafbeelding 2017-01-13 om 17.41.02.png

This certificate is used to encrypt all of the traffic to and from the companion app.  Where do we get such a certificate?  The answer is simple.  You generate it yourself.  That’s called a self signed certificate.  You can find the details here, but I’ll walk you through what I did.

First, I opened a terminal on my Mac (these steps apply to a Mac, so for the exact steps on windows, please see the details on the GitHub site.) and navigated to the JavaClient directory of the Alexa sample app.  Open the file ssl.cnf :

sudo nano ssl.cnf

Next, I entered the values as in the screenshot below.  A few important things :

  • The country name has to be 2 letters
  • I entered the exact same information as in the ssl.cnf on the Raspberry Pi
  • I entered an extra IP address as I was going to address the Raspberry Pi using another IP address that the first two.

Schermafbeelding 2017-01-13 om 20.15.51.png

Ctrl-x y enter to get out of nano.

In the same directory you can also see a script called “generate.sh”.  If you check out the contents you can see something like this :

Schermafbeelding 2017-01-13 om 17.42.23.png

See how it generates the certificate using all kinds of exotic commands and finally copies the certificate in the right place.

Before you can execute the script, you have to make it executable :

chmod 777 generate.sh

Next, execute it :

sudo ./generate.sh

When all is done, and you return to Xcode, the file should no longer be highlighted red.

Schermafbeelding 2017-01-13 om 18.24.04.png

The next thing to do is tell Amazon that I’m going to connect using a Companion App.  There’s two things to do : first I need to tell amazon how my app is called, and second I need to tell my app to log on with a certain key.

Go into Xcode, and in the properties of the application target, on the General tab, copy the Bundle Identifier to the clipboard.

Schermafbeelding 2017-01-13 om 18.26.00.png

Go to the Amazon Developer Portal en navigate to your device’s security profile.  On the “iOS Settings” tab, enter a API Key Name (an identifier for the API Key), and paste in the Bundle Identifier.  Click Add.

Schermafbeelding 2017-01-13 om 18.26.58.png

After everything is refreshed, you will find a key here:

Schermafbeelding 2017-01-13 om 18.32.54.png

You need to paste this key in the AlexaCompanionAppSample-Info property list.  Locate it in Xcode, and add an extra key to it called “APIKey” (exactly, mind the capitals).  Edit the value, and paste in the key.

Schermafbeelding 2017-01-13 om 18.34.18.png

We’re all ready to build.  Click the “Play” button to start the device simulator and start the application.  Next, the application will run, and it will prompt you for a device address.  Type the static ip, followed by the 8433 port.  This port is also used by the JavaClient op the Pi.

Important : Make sure the Javaclient is running on the Pi!

Schermafbeelding 2017-01-13 om 19.04.59.png

Click connect.

If you’re lucky a screen will appear letting you sign into amazon. I wasn’t so lucky. I got this error :

The operation couldn’t be completed. (nsurlerrordomain error – 1012.)

I can tell you this : there’s not much usable info on this on the entire bloody internet.  But hey.  There’s code debugging.  After some debugging I stumbled on the piece of code below.  It checks a “result” variable for 2 specific values : kSecTrustResultProceed or kSecTrusResultUnspecified.  Only in those 2 cases it continues.  The result in my case was kSecTrustResultRecoverableTrustFailure.

Well, it says “recoverable”, so that might still work, I figured.  So I adjusted the code accordingly

Schermafbeelding 2017-01-13 om 20.03.40.png

Rebuild and run.

And what do you know.  It worked.  Logged in with amazon on the iPhone simulator, and the following appears :

Schermafbeelding 2017-01-13 om 20.03.31.png

That’s cool.  Looking at the JavaClient on the Pi: The bearer token is filled in!

Schermafbeelding 2017-01-13 om 20.04.09.png

Looking at the config.json file : the refreshToken is saved!

Schermafbeelding 2017-01-13 om 20.06.09.png

Missing accomplished.  After some hours of painstaking search, I finally got it working with automatic authentication.  The road is open for all kinds of great things!

 

3 thoughts on “Creating the companion app”

  1. Thanks for such detailed tutorial! I too am trying to authenticate Alexa running on Raspberry pi with the mobile companion app running on my emulator (tried both iOS & Android). But unfortunately, the companion app is erroring with ‘request timed out’.
    I have confirmed the ip of the pi and ports and successfully able to do telnet with 8443 from my mac. However the apps fail to connect. FYI, I have updated the ssl.cnf with the raspberry’s ip before generating the certificates and copied the same ca.der file to my ios sample project.
    Please share your thoughts /suggestions on this. You have mentioned about static ip too, does it mean that I need to attach a static ip for the raspberry?

    Like

    1. Hi My3,

      Thank you for reading my blog. I hope it helps you in your journey.
      Regarding your question…
      I did indeed specify a static IP for my Raspberry Pi. I explained it in one of my first posts.
      The reason why in particular is because I wouldn’t have to check the DHCP server for the correct IP every single time. It also comes in very handy using this certificate. I suggest the following things :

      * double check the ssl.cnf file and see if everything is typed correctly. It’s all case sensitive you know.
      * did you update the bundle identifier on Amazon?
      * The updating of the key in the pList is very case sensitive. Maybe check this again?
      * have tried shutting down the firewall on the mac?
      * Did the generation of the certificate give any errors or remarks?
      * Is the .der file no longer red in xcode? (in other words, is it detected)
      * In ssl.cnf all of the entries (not only the ip) are important. Please all entries them entirely.

      I do suggest you use a static IP. I also did it for my mac . It makes things more easy.

      Let me know how it goes

      kind regards

      Bart

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s