From 3946f0d1c42d6da4641e931b41519788340a4b42 Mon Sep 17 00:00:00 2001 From: Emanuel Vecchio Date: Tue, 5 Jul 2016 16:04:42 -0300 Subject: [PATCH 1/4] Widevine Base Aquisition Url + Added FairPlay support --- .../implementation/VersionHeadersFilter.java | 2 +- .../fairplay/FairPlayConfiguration.java | 59 +++++++++++++++++++ .../AssetDeliveryPolicyConfigurationKey.java | 20 ++++++- .../media/models/AssetDeliveryPolicyType.java | 6 +- .../media/models/ContentKeyDeliveryType.java | 6 +- .../services/media/models/ContentKeyType.java | 14 ++++- 6 files changed, 101 insertions(+), 6 deletions(-) create mode 100644 services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/templates/fairplay/FairPlayConfiguration.java diff --git a/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/VersionHeadersFilter.java b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/VersionHeadersFilter.java index e9feb886b431..44009460d744 100644 --- a/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/VersionHeadersFilter.java +++ b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/VersionHeadersFilter.java @@ -40,7 +40,7 @@ public ClientResponse doHandle(ClientRequest cr) { MultivaluedMap headers = cr.getHeaders(); headers.add("DataServiceVersion", "3.0"); headers.add("MaxDataServiceVersion", "3.0"); - headers.add("x-ms-version", "2.11"); + headers.add("x-ms-version", "2.12"); return getNext().handle(cr); } } diff --git a/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/templates/fairplay/FairPlayConfiguration.java b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/templates/fairplay/FairPlayConfiguration.java new file mode 100644 index 000000000000..3c734eb8b91c --- /dev/null +++ b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/templates/fairplay/FairPlayConfiguration.java @@ -0,0 +1,59 @@ +package com.microsoft.windowsazure.services.media.implementation.templates.fairplay; + +import java.io.ByteArrayOutputStream; +import java.security.KeyStore; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.microsoft.windowsazure.core.utils.Base64; + +@JsonInclude(JsonInclude.Include.NON_NULL) +public class FairPlayConfiguration { + + @JsonProperty("ASkId") + public String ASkId; + + @JsonProperty("FairPlayPfxPasswordId") + public String FairPlayPfxPasswordId; + + @JsonProperty("FairPlayPfx") + public String FairPlayPfx; + + @JsonProperty("ContentEncryptionIV") + public String ContentEncryptionIV; + + public static String createSerializedFairPlayOptionConfiguration( + KeyStore keyStore, String pfxPassword, String pfxPasswordKeyId, String askId, + String contentIv) + { + try { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + keyStore.store(outputStream, pfxPassword.toCharArray()); + String certString = Base64.encode(outputStream.toByteArray()); + FairPlayConfiguration config = new FairPlayConfiguration(); + config.ASkId = askId; + config.ContentEncryptionIV = contentIv; + config.FairPlayPfx = certString; + config.FairPlayPfxPasswordId = pfxPasswordKeyId; + ObjectMapper mapper = new ObjectMapper(); + String configuration = mapper.writeValueAsString(config); + + return configuration; + } catch(Throwable t){ + throw new RuntimeException(t); + } + } + + final public static char[] hexArray = "0123456789ABCDEF".toCharArray(); + public static String bytesToHex(byte[] bytes) { + char[] hexChars = new char[bytes.length * 2]; + for ( int j = 0; j < bytes.length; j++ ) { + int v = bytes[j] & 0xFF; + hexChars[j * 2] = hexArray[v >>> 4]; + hexChars[j * 2 + 1] = hexArray[v & 0x0F]; + } + return new String(hexChars); + } + +} diff --git a/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/AssetDeliveryPolicyConfigurationKey.java b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/AssetDeliveryPolicyConfigurationKey.java index 7d33469f8780..9288340e82ed 100644 --- a/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/AssetDeliveryPolicyConfigurationKey.java +++ b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/AssetDeliveryPolicyConfigurationKey.java @@ -37,8 +37,16 @@ public enum AssetDeliveryPolicyConfigurationKey { /** The initialization vector to use for envelope encryption. */ EnvelopeEncryptionIV(6), /** Widevine DRM Acquisition Url to use for common encryption. */ - WidevineLicenseAcquisitionUrl(7); - + WidevineLicenseAcquisitionUrl(7), + /** Base Widevine url that will have KID= appended */ + WidevineBaseLicenseAcquisitionUrl(8), + /** FairPlay license acquisition URL. */ + FairPlayLicenseAcquisitionUrl(9), + /** Base FairPlay license acquisition URL that will have KID= appended. */ + FairPlayBaseLicenseAcquisitionUrl(10), + /** Initialization Vector that will be used for encrypting the content. Must match + IV in the AssetDeliveryPolicy. */ + CommonEncryptionIVForCbcs(11); /** The AssetDeliveryPolicyType code. */ private int assetDeliveryPolicyConfigurationKey; @@ -87,6 +95,14 @@ public static AssetDeliveryPolicyConfigurationKey fromCode(int option) { return AssetDeliveryPolicyConfigurationKey.EnvelopeEncryptionIV; case 7: return AssetDeliveryPolicyConfigurationKey.WidevineLicenseAcquisitionUrl; + case 8: + return AssetDeliveryPolicyConfigurationKey.WidevineBaseLicenseAcquisitionUrl; + case 9: + return AssetDeliveryPolicyConfigurationKey.FairPlayLicenseAcquisitionUrl; + case 10: + return AssetDeliveryPolicyConfigurationKey.FairPlayBaseLicenseAcquisitionUrl; + case 11: + return AssetDeliveryPolicyConfigurationKey.CommonEncryptionIVForCbcs; default: throw new InvalidParameterException("option"); } diff --git a/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/AssetDeliveryPolicyType.java b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/AssetDeliveryPolicyType.java index 1963078a8c1d..b1aab0531623 100644 --- a/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/AssetDeliveryPolicyType.java +++ b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/AssetDeliveryPolicyType.java @@ -31,7 +31,9 @@ public enum AssetDeliveryPolicyType { /** Apply Dynamic Envelope encryption. */ DynamicEnvelopeEncryption(3), /** Apply Dynamic Common encryption. */ - DynamicCommonEncryption(4); + DynamicCommonEncryption(4), + /** Apply Dynamic Common encryption with cbcs */ + DynamicCommonEncryptionCbcs(5); /** The AssetDeliveryPolicyType code. */ @@ -75,6 +77,8 @@ public static AssetDeliveryPolicyType fromCode(int option) { return AssetDeliveryPolicyType.DynamicEnvelopeEncryption; case 4: return AssetDeliveryPolicyType.DynamicCommonEncryption; + case 5: + return AssetDeliveryPolicyType.DynamicCommonEncryptionCbcs; default: throw new InvalidParameterException("option"); } diff --git a/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/ContentKeyDeliveryType.java b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/ContentKeyDeliveryType.java index 155f0d3e3fd3..b547875c8069 100644 --- a/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/ContentKeyDeliveryType.java +++ b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/ContentKeyDeliveryType.java @@ -29,7 +29,9 @@ public enum ContentKeyDeliveryType { /** Use MPEG Baseline HTTP key protocol. */ BaselineHttp(2), /** Use Widevine license acquisition protocol. */ - Widevine(3); + Widevine(3), + /** Send FairPlay SPC to Key Delivery server and get CKC back */ + FairPlay(4); /** The AssetDeliveryPolicyType code. */ private int contentKeyDeliveryType; @@ -70,6 +72,8 @@ public static ContentKeyDeliveryType fromCode(int option) { return ContentKeyDeliveryType.BaselineHttp; case 3: return ContentKeyDeliveryType.Widevine; + case 4: + return ContentKeyDeliveryType.FairPlay; default: throw new InvalidParameterException("option"); } diff --git a/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/ContentKeyType.java b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/ContentKeyType.java index 9c801ad5f94c..fbb6542cbad0 100644 --- a/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/ContentKeyType.java +++ b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/ContentKeyType.java @@ -31,7 +31,13 @@ public enum ContentKeyType { /** The Configuration encryption. */ ConfigurationEncryption(2), /** The Envelope encryption. */ - EnvelopeEncryption(4); + EnvelopeEncryption(4), + /** Specifies a content key for common encryption with CBCS. */ + CommonEncryptionCbcs(6), + /** Application Secret key for FairPlay. */ + FairPlayASk (7), + /** Password for FairPlay application certificate. */ + FairPlayPfxPassword (8); /** The content key type code. */ private int contentKeyTypeCode; @@ -72,6 +78,12 @@ public static ContentKeyType fromCode(int code) { return ContentKeyType.ConfigurationEncryption; case 4: return ContentKeyType.EnvelopeEncryption; + case 6: + return ContentKeyType.CommonEncryptionCbcs; + case 7: + return ContentKeyType.FairPlayASk; + case 8: + return ContentKeyType.FairPlayPfxPassword; default: throw new InvalidParameterException("code"); } From d5f05aae2b261970c069769284dd684dad198656 Mon Sep 17 00:00:00 2001 From: Emanuel Vecchio Date: Wed, 6 Jul 2016 08:50:41 -0300 Subject: [PATCH 2/4] Style fixes --- .../fairplay/FairPlayConfiguration.java | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/templates/fairplay/FairPlayConfiguration.java b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/templates/fairplay/FairPlayConfiguration.java index 3c734eb8b91c..fd9eb6bb2107 100644 --- a/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/templates/fairplay/FairPlayConfiguration.java +++ b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/templates/fairplay/FairPlayConfiguration.java @@ -26,25 +26,25 @@ public class FairPlayConfiguration { public static String createSerializedFairPlayOptionConfiguration( KeyStore keyStore, String pfxPassword, String pfxPasswordKeyId, String askId, String contentIv) - { - try { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - keyStore.store(outputStream, pfxPassword.toCharArray()); - String certString = Base64.encode(outputStream.toByteArray()); - FairPlayConfiguration config = new FairPlayConfiguration(); - config.ASkId = askId; - config.ContentEncryptionIV = contentIv; - config.FairPlayPfx = certString; - config.FairPlayPfxPasswordId = pfxPasswordKeyId; - ObjectMapper mapper = new ObjectMapper(); - String configuration = mapper.writeValueAsString(config); + { + try { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + keyStore.store(outputStream, pfxPassword.toCharArray()); + String certString = Base64.encode(outputStream.toByteArray()); + FairPlayConfiguration config = new FairPlayConfiguration(); + config.ASkId = askId; + config.ContentEncryptionIV = contentIv; + config.FairPlayPfx = certString; + config.FairPlayPfxPasswordId = pfxPasswordKeyId; + ObjectMapper mapper = new ObjectMapper(); + String configuration = mapper.writeValueAsString(config); + + return configuration; + } catch(Throwable t){ + throw new RuntimeException(t); + } + } - return configuration; - } catch(Throwable t){ - throw new RuntimeException(t); - } - } - final public static char[] hexArray = "0123456789ABCDEF".toCharArray(); public static String bytesToHex(byte[] bytes) { char[] hexChars = new char[bytes.length * 2]; From fbd530a175a69b863c6d658990c1c50812c3238e Mon Sep 17 00:00:00 2001 From: Emanuel Vecchio Date: Wed, 6 Jul 2016 08:51:51 -0300 Subject: [PATCH 3/4] Style fixes --- .../templates/fairplay/FairPlayConfiguration.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/templates/fairplay/FairPlayConfiguration.java b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/templates/fairplay/FairPlayConfiguration.java index fd9eb6bb2107..c5032697c590 100644 --- a/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/templates/fairplay/FairPlayConfiguration.java +++ b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/templates/fairplay/FairPlayConfiguration.java @@ -10,18 +10,18 @@ @JsonInclude(JsonInclude.Include.NON_NULL) public class FairPlayConfiguration { - + @JsonProperty("ASkId") - public String ASkId; + public String ASkId; @JsonProperty("FairPlayPfxPasswordId") - public String FairPlayPfxPasswordId; + public String FairPlayPfxPasswordId; @JsonProperty("FairPlayPfx") - public String FairPlayPfx; + public String FairPlayPfx; @JsonProperty("ContentEncryptionIV") - public String ContentEncryptionIV; + public String ContentEncryptionIV; public static String createSerializedFairPlayOptionConfiguration( KeyStore keyStore, String pfxPassword, String pfxPasswordKeyId, String askId, From a66019f7a7d13cca63dc3dc99e7796a6549fdc34 Mon Sep 17 00:00:00 2001 From: Emanuel Vecchio Date: Tue, 12 Jul 2016 15:17:03 -0300 Subject: [PATCH 4/4] Fixed styles --- .../fairplay/FairPlayConfiguration.java | 76 +++++++++++-------- .../templates/fairplay/package-info.java | 1 + .../AssetDeliveryPolicyConfigurationKey.java | 6 +- .../media/models/ContentKeyDeliveryType.java | 2 +- 4 files changed, 50 insertions(+), 35 deletions(-) create mode 100644 services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/templates/fairplay/package-info.java diff --git a/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/templates/fairplay/FairPlayConfiguration.java b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/templates/fairplay/FairPlayConfiguration.java index c5032697c590..9e2ef2c54b9f 100644 --- a/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/templates/fairplay/FairPlayConfiguration.java +++ b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/templates/fairplay/FairPlayConfiguration.java @@ -11,49 +11,63 @@ @JsonInclude(JsonInclude.Include.NON_NULL) public class FairPlayConfiguration { - @JsonProperty("ASkId") - public String ASkId; - - @JsonProperty("FairPlayPfxPasswordId") - public String FairPlayPfxPasswordId; - - @JsonProperty("FairPlayPfx") - public String FairPlayPfx; - - @JsonProperty("ContentEncryptionIV") - public String ContentEncryptionIV; - - public static String createSerializedFairPlayOptionConfiguration( - KeyStore keyStore, String pfxPassword, String pfxPasswordKeyId, String askId, - String contentIv) - { + private String askId; + + private String fairPlayPfxPasswordId; + + private String fairPlayPfx; + + private String contentEncryptionIV; + + public static String createSerializedFairPlayOptionConfiguration( + KeyStore keyStore, String pfxPassword, String pfxPasswordKeyId, String askId, + String contentIv) { try { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); keyStore.store(outputStream, pfxPassword.toCharArray()); String certString = Base64.encode(outputStream.toByteArray()); FairPlayConfiguration config = new FairPlayConfiguration(); - config.ASkId = askId; - config.ContentEncryptionIV = contentIv; - config.FairPlayPfx = certString; - config.FairPlayPfxPasswordId = pfxPasswordKeyId; + config.askId = askId; + config.contentEncryptionIV = contentIv; + config.fairPlayPfx = certString; + config.fairPlayPfxPasswordId = pfxPasswordKeyId; ObjectMapper mapper = new ObjectMapper(); String configuration = mapper.writeValueAsString(config); return configuration; - } catch(Throwable t){ + } catch (Throwable t) { throw new RuntimeException(t); } } - final public static char[] hexArray = "0123456789ABCDEF".toCharArray(); - public static String bytesToHex(byte[] bytes) { - char[] hexChars = new char[bytes.length * 2]; - for ( int j = 0; j < bytes.length; j++ ) { - int v = bytes[j] & 0xFF; - hexChars[j * 2] = hexArray[v >>> 4]; - hexChars[j * 2 + 1] = hexArray[v & 0x0F]; - } - return new String(hexChars); - } + static final char[] HEXARRAY = "0123456789ABCDEF".toCharArray(); + public static String bytesToHex(byte[] bytes) { + char[] hexChars = new char[bytes.length * 2]; + for (int j = 0; j < bytes.length; j++) { + int v = bytes[j] & 0xFF; + hexChars[j * 2] = HEXARRAY[v >>> 4]; + hexChars[j * 2 + 1] = HEXARRAY[v & 0x0F]; + } + return new String(hexChars); + } + + @JsonProperty("ASkId") + public String getASkId() { + return askId; + } + + @JsonProperty("FairPlayPfxPasswordId") + public String getFairPlayPfxPasswordId() { + return fairPlayPfxPasswordId; + } + @JsonProperty("FairPlayPfx") + public String getFairPlayPfx() { + return fairPlayPfx; + } + + @JsonProperty("ContentEncryptionIV") + public String getContentEncryptionIV() { + return contentEncryptionIV; + }; } diff --git a/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/templates/fairplay/package-info.java b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/templates/fairplay/package-info.java new file mode 100644 index 000000000000..345253ed44c1 --- /dev/null +++ b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/implementation/templates/fairplay/package-info.java @@ -0,0 +1 @@ +package com.microsoft.windowsazure.services.media.implementation.templates.fairplay; diff --git a/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/AssetDeliveryPolicyConfigurationKey.java b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/AssetDeliveryPolicyConfigurationKey.java index 9288340e82ed..c32bce8d42f3 100644 --- a/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/AssetDeliveryPolicyConfigurationKey.java +++ b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/AssetDeliveryPolicyConfigurationKey.java @@ -98,11 +98,11 @@ public static AssetDeliveryPolicyConfigurationKey fromCode(int option) { case 8: return AssetDeliveryPolicyConfigurationKey.WidevineBaseLicenseAcquisitionUrl; case 9: - return AssetDeliveryPolicyConfigurationKey.FairPlayLicenseAcquisitionUrl; + return AssetDeliveryPolicyConfigurationKey.FairPlayLicenseAcquisitionUrl; case 10: - return AssetDeliveryPolicyConfigurationKey.FairPlayBaseLicenseAcquisitionUrl; + return AssetDeliveryPolicyConfigurationKey.FairPlayBaseLicenseAcquisitionUrl; case 11: - return AssetDeliveryPolicyConfigurationKey.CommonEncryptionIVForCbcs; + return AssetDeliveryPolicyConfigurationKey.CommonEncryptionIVForCbcs; default: throw new InvalidParameterException("option"); } diff --git a/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/ContentKeyDeliveryType.java b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/ContentKeyDeliveryType.java index b547875c8069..60b00c6f3caa 100644 --- a/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/ContentKeyDeliveryType.java +++ b/services/azure-media/src/main/java/com/microsoft/windowsazure/services/media/models/ContentKeyDeliveryType.java @@ -73,7 +73,7 @@ public static ContentKeyDeliveryType fromCode(int option) { case 3: return ContentKeyDeliveryType.Widevine; case 4: - return ContentKeyDeliveryType.FairPlay; + return ContentKeyDeliveryType.FairPlay; default: throw new InvalidParameterException("option"); }