Roku Developer Program

Developers and content creators—a complete solution for growing an audience directly.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Level 9

SSL Mutual Authentication of Video Streams

One possible security model for video stream access is to use the same SSL mutual authentication technique that we recommend for accessing feeds. (Other models might be randomized expiring URLs with just server side SSL encryption, or some sort of DRM). This post will cover the SSL mutual authentication technique using Apache along with the details of using openssl to generate some test certificates and use them to configure apache on the server side where your video may be stored. Finally, we will modify the simplevideoplayer example to play this secure video.

1) Create a Self-Signed CA (Certificate Authority) root Certificate
a) Create the CA private key (remember the password chosen):
sudo openssl genrsa -out /opt/openssl/testCA/CA/testCA.KEY
b) Create CA Certificate Request:
sudo openssl req -new -key /opt/openssl/testCA/CA/testCA.KEY -out /opt/openssl/testCA/CA/testCA.CSR
c) Self-sign the CA certificate:
sudo openssl x509 -req -days 3650 -in /opt/openssl/testCA/CA/testCA.CSR -out /opt/openssl/testCA/CA/testCA.CRT -signkey /opt/openssl/testCA/CA/testCA.KEY

2) OpenSSL Server Cert
a) Create the Web Server's key (remember the password chosen):
sudo openssl genrsa -des3 -out /opt/openssl/testCA/server/keys/testWEB.KEY
b) Create the Web Server's Cert Req:
sudo openssl req -new -key /opt/openssl/testCA/server/keys/testWEB.KEY -out /opt/openssl/testCA/server/requests/testWEB.CSR
c) Sign the Web Server's Cert Req with the CA Cert:
sudo openssl ca -in /opt/openssl/testCA/server/requests/testWEB.CSR -cert /opt/openssl/testCA/CA/testCA.CRT -keyfile /opt/openssl/testCA/CA/testCA.KEY \
-out /opt/openssl/testCA/server/certificates/testWEB.CRT

3) Install Cert in Apache
a) sudo mkdir /etc/httpd/certs
b) sudo cp /opt/openssl/testCA/server/certificates/testWEB.CRT /etc/httpd/certs
c) sudo cp /opt/openssl/testCA/server/keys/testWEB.KEY /etc/httpd/certs
d) sudo cp sudo cp /opt/openssl/testCA/CA/testCA.CRT /etc/httpd/certs
e) If you don't want to enter the passwd for testWEB every time Apache starts,
you can remove the passwd from the keyfile:
sudo cp /etc/httpd/certs/testWEB.KEY /etc/httpd/certs/testWEB.KEY.orig
sudo openssl rsa -in /etc/httpd/certs/testWEB.KEY.orig -out /etc/httpd/certs/testWEB.KEY
f) Edit /etc/httpd/conf.d/ssl.conf
# Configure your server cert:
SSLCertificateFile /etc/httpd/certs/testWEB.CRT
SSLCertificateKeyFile /etc/httpd/certs/testWEB.KEY

# Configure client cert authentication:
SSLCACertificateFile /etc/httpd/certs/cacert.pem # from roku sdk
SSLVerifyClient require
SSLVerifyDepth 1

g) Edit /etc/httpd/conf/httpd.conf:
# In <Directory> </Directory> tags where your video resides:
#
# Checking the x-roku-reserved-dev-id header value assures that it is
# your package trying to connect to this directory.
#
# You can find the dev-id of your brightscript package by going to the
# developer page on your Roku box, and selecting "Utilities".
# On the "Utilities" page, select "Choose File", enter the passwd for that pkg, and hit "Inspect"
# Copy the value for the "Dev ID:" parameter and paste it here:
SetEnvIf x-roku-reserved-dev-id 6bb22ba64125f6da56fa4b7d6f2199a970d06672 let_roku_in
SSLRequireSSL
Order Deny,Allow
Deny from all
Allow from env=let_roku_in

h) Restart Apache:
sudo service httpd restart

4) Place your video in your Apache directory configured in step 3.g) above.

5) Modify the simplevideoplayer application to access the secure video:
a) Add the testCA.CRT (The Certificate Authority cert) file to the
implevideoplayer/source directory.
b) In the appMain.brs:displyVideo() function, change the URL and video meta-data
to match the video you put on your server in step 4).
c) Right before the "video.SetContent(videoclip)" line, add the following calls:
video.Addheader("x-roku-reserved-dev-id","")
video.SetCertificatesFile("pkg:/source/testCA.CRT")
video.InitClientCertificates()

6) Test the authentication with and without the code in 5.c) above. If any of the three authentication methods above are ommitted you should get access denied. Note that you cannot successfully access the video until you've built a package, uploaded it to the channel store, and are running that channel via a channel code. A side-loaded developer app does not properly negotiate client certs or send the enforced dev-id value for the x-roku-reserved-dev-id header.

--Kevin
0 Kudos
20 Replies
Level 7

Re: SSL Mutual Authentication of Video Streams

Thanks for the very detailed writeup Kevin; much appreciated.
Greg
0 Kudos
Highlighted
Level 8

Re: SSL Mutual Authentication of Video Streams

Excellent post!

Any plans of adding DRM support? Or a piracy protection mechanism that is widely approved by film distributors so we can create a distribution channel for our clients?
0 Kudos
Highlighted
Level 10

Re: SSL Mutual Authentication of Video Streams

Trying to follow this example but I can't get the streams to play over https even without requiring authentication.
The video plays in a browser just fine (albeit with an untrusted cert warning)
But when I try to connect to the https stream from the roku, it just goes back to the detail screen & nothing appears in the web server logs at all.
This is the debug output from roku:

Button pressed:  1  0
Displaying video:
srt = <UNINITIALIZED>
play failed: An unexpected problem (but not server timeout or HTTP error) has been detected.
Closing video screen


Should the video be able to play over https; does the cert need to be signed by a trusted authority?
thank you in advance,
joe
aspiring
0 Kudos
Highlighted
Level 9

Re: SSL Mutual Authentication of Video Streams

Your script needs to call SetCertificatesFile() and passed in PEM file needs to include the CA cert that signed the web server cert.

--Kevin
0 Kudos
Highlighted
Level 10

Re: SSL Mutual Authentication of Video Streams

Thanks Kevin, I tried that again, with the same result.

here's what i have in simplevideoplayer now:

video.Addheader("x-roku-reserved-dev-id","")
video.SetCertificatesFile("pkg:/source/cacert.pem")
video.InitClientCertificates()
video.SetContent(videoclip)

For cacert.pem I tried using just my ca.crt and also tried adding my ca.crt to the pre-existing cacert.pem that came with SDK. Both gave the same result: no video and debug says "play failed: An unexpected problem (but not server timeout or HTTP error) has been detected."

I've tried publishing as a private channel and sideloading to see if i can get a video to play over https (in another thread you said it was possible to play sideloaded channels over https, but maybe i'm confused, because I can't get it to work). no luck.
aspiring
0 Kudos
Highlighted
Level 9

Re: SSL Mutual Authentication of Video Streams

I suggest testing each authentication piece individually. Starting with just the server cert.

To debug, check the cert is installed properly on your server by accessing in a browser and get more detail via:


openssl s_client -showcerts -connect 'yourServer.com:443'


The output would be something like this (example done for http://www.google.com):

CONNECTED(00000003)
depth=2 /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
verify return:1
depth=1 /C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
verify return:1
depth=0 /C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com
verify return:1
---
Certificate chain
0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com
i:/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
-----BEGIN CERTIFICATE-----
MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBM
MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg
THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0x
MTEyMTgyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh
MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw
FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC
gYEA6PmGD5D6htffvXImttdEAoN4c9kCKO+IRTn7EOh8rqk41XXGOOsKFQebg+jN
gtXj9xVoRaELGYW84u+E593y17iYwqG7tcFR39SDAqc9BkJb4SLD3muFXxzW2k6L
05vuuWciKh0R73mkszeK9P4Y/bz5RiNQl/Os/CRGK1w7t0UCAwEAAaOB5zCB5DAM
BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl
LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF
BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw
Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0
ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF
AAOBgQCfQ89bxFApsb/isJr/aiEdLRLDLE5a+RLizrmCUi3nHX4adpaQedEkUjh5
u2ONgJd8IyAPkU0Wueru9G2Jysa9zCRo1kNbzipYvzwY4OA8Ys+WAi0oR1A04Se6
z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqAibAxWEEHXw==
-----END CERTIFICATE-----
1 s:/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
-----BEGIN CERTIFICATE-----
MIIDIzCCAoygAwIBAgIEMAAAAjANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJV
UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDMgUHVi
bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNTEzMDAw
MDAwWhcNMTQwNTEyMjM1OTU5WjBMMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhh
d3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBD
QTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1NNn0I0Vf67NMf59HZGhPwtx
PKzMyGT7Y/wySweUvW+Aui/hBJPAM/wJMyPpC3QrccQDxtLN4i/1CWPN/0ilAL/g
5/OIty0y3pg25gqtAHvEZEo7hHUD8nCSfQ5i9SGraTaEMXWQ+L/HbIgbBpV8yeWo
3nWhLHpo39XKHIdYYBkCAwEAAaOB/jCB+zASBgNVHRMBAf8ECDAGAQH/AgEAMAsG
A1UdDwQEAwIBBjARBglghkgBhvhCAQEEBAMCAQYwKAYDVR0RBCEwH6QdMBsxGTAX
BgNVBAMTEFByaXZhdGVMYWJlbDMtMTUwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDov
L2NybC52ZXJpc2lnbi5jb20vcGNhMy5jcmwwMgYIKwYBBQUHAQEEJjAkMCIGCCsG
AQUFBzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMDQGA1UdJQQtMCsGCCsGAQUF
BwMBBggrBgEFBQcDAgYJYIZIAYb4QgQBBgpghkgBhvhFAQgBMA0GCSqGSIb3DQEB
BQUAA4GBAFWsY+reod3SkF+fC852vhNRj5PZBSvIG3dLrWlQoe7e3P3bB+noOZTc
q3J5Lwa/q4FwxKjt6lM07e8eU9kGx1Yr0Vz00YqOtCuxN5BICEIlxT6Ky3/rbwTR
bcV0oveifHtgPHfNDs5IAn8BL7abN+AqKjbc1YXWrOU/VG+WHgWv
-----END CERTIFICATE-----
---
Server certificate
subject=/C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com
issuer=/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
---
No client certificate CA names sent
---
SSL handshake has read 1772 bytes and written 334 bytes
---
New, TLSv1/SSLv3, Cipher is RC4-SHA
Server public key is 1024 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : RC4-SHA
Session-ID: 859C071E4A7412890B39B2F1F93B424D52F2E7CD31F360654BC7B2A352AB162F
Session-ID-ctx:
Master-Key: 0FAA0A8BBC2D155A390DA881139230CCA3720A86A4B80062C38C4050A6DA22C46BD93E764252B83A37E675C725456C71
Key-Arg : None
Krb5 Principal: None
Start Time: 1304440052
Timeout : 300 (sec)
Verify return code: 0 (ok)



If you cut and past the CA certs (all text between and including "BEGIN CERTIFICATE" and "END CERTIFICATE") into the PEM file that you included in you package and called with SetCertificatesFile(), you configuration should be good.

In this example, the PEM file would include:

-----BEGIN CERTIFICATE-----
MIIDIzCCAoygAwIBAgIEMAAAAjANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJV
UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDMgUHVi
bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNTEzMDAw
MDAwWhcNMTQwNTEyMjM1OTU5WjBMMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhh
d3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBD
QTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1NNn0I0Vf67NMf59HZGhPwtx
PKzMyGT7Y/wySweUvW+Aui/hBJPAM/wJMyPpC3QrccQDxtLN4i/1CWPN/0ilAL/g
5/OIty0y3pg25gqtAHvEZEo7hHUD8nCSfQ5i9SGraTaEMXWQ+L/HbIgbBpV8yeWo
3nWhLHpo39XKHIdYYBkCAwEAAaOB/jCB+zASBgNVHRMBAf8ECDAGAQH/AgEAMAsG
A1UdDwQEAwIBBjARBglghkgBhvhCAQEEBAMCAQYwKAYDVR0RBCEwH6QdMBsxGTAX
BgNVBAMTEFByaXZhdGVMYWJlbDMtMTUwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDov
L2NybC52ZXJpc2lnbi5jb20vcGNhMy5jcmwwMgYIKwYBBQUHAQEEJjAkMCIGCCsG
AQUFBzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMDQGA1UdJQQtMCsGCCsGAQUF
BwMBBggrBgEFBQcDAgYJYIZIAYb4QgQBBgpghkgBhvhFAQgBMA0GCSqGSIb3DQEB
BQUAA4GBAFWsY+reod3SkF+fC852vhNRj5PZBSvIG3dLrWlQoe7e3P3bB+noOZTc
q3J5Lwa/q4FwxKjt6lM07e8eU9kGx1Yr0Vz00YqOtCuxN5BICEIlxT6Ky3/rbwTR
bcV0oveifHtgPHfNDs5IAn8BL7abN+AqKjbc1YXWrOU/VG+WHgWv
-----END CERTIFICATE-----
0 Kudos
Highlighted
Level 10

Re: SSL Mutual Authentication of Video Streams

Thanks very much Kevin.
When I issue the command:
openssl s_client -showcerts -connect 'yourServer.com:443'


I see in the response:
CONNECTED(00000003)
depth=1 /C=US/ST=California/L=MyCity/O=MyCo/CN=roku.mydomain.com
verify error:num=19:self signed certificate in certificate chain
verify return:0
-snip-
Verify return code: 19 (self signed certificate in certificate chain)


Would this be the problem? I believe I followed the instructions in the original post... Is there something I've done wrong?
aspiring
0 Kudos
Highlighted
Level 9

Re: SSL Mutual Authentication of Video Streams

Self signed certs are OK with Roku, as long as they are in your PEM file registered with SetCertificatesFile() . After clicking through the warning about "unrecognized CA Cert" of similar warning, are you able to make an SSL connection with your browser?
0 Kudos
Highlighted
Level 10

Re: SSL Mutual Authentication of Video Streams

After clicking through the warning about "unrecognized CA Cert" of similar warning, are you able to make an SSL connection with your browser?


yes, the video plays in a browser just fine (albeit with an untrusted cert warning - ie, in chrome i see "https" with a red line through it and when i click on the lock i see that "Your connection is encrypted with 256-bit encryption" and "The identity of this website has not been verified")

For roku to connect to https, does the common name need to match? in other words my cert might have the CN as 'secure.mydomain.com' but then I access for testing via https://192.168.1.20 In the browser there is a warning but it still allows the connection.
aspiring
0 Kudos