private static byte[] adjustRequestData(UUID uuid, byte[] requestData) { if (C.CLEARKEY_UUID.equals(uuid)) { return ClearKeyUtil.adjustRequestData(requestData); } return requestData; }
@Override public byte[] provideKeyResponse(byte[] scope, byte[] response) throws NotProvisionedException, DeniedByServerException { if (C.CLEARKEY_UUID.equals(uuid)) { response = ClearKeyUtil.adjustResponseData(response); } return mediaDrm.provideKeyResponse(scope, response); }
adjustedResponseBuilder.append(base64UrlToBase64(key.getString("k"))); adjustedResponseBuilder.append("\",\"kid\":\""); adjustedResponseBuilder.append(base64UrlToBase64(key.getString("kid"))); adjustedResponseBuilder.append("\",\"kty\":\""); adjustedResponseBuilder.append(key.getString("kty"));
/** * Adjusts ClearKey request data obtained from the Android ClearKey CDM to be spec compliant. * * @param request The request data. * @return The adjusted request data. */ public static byte[] adjustRequestData(byte[] request) { if (Util.SDK_INT >= 27) { return request; } // Prior to O-MR1 the ClearKey CDM encoded the values in the "kids" array using Base64 encoding // rather than Base64Url encoding. See [Internal: b/64388098]. We know the exact request format // from the platform's InitDataParser.cpp. Since there aren't any "+" or "/" symbols elsewhere // in the request, it's safe to fix the encoding by replacement through the whole request. String requestString = Util.fromUtf8Bytes(request); return Util.getUtf8Bytes(base64ToBase64Url(requestString)); }
@Config(sdk = 27) @Test public void testAdjustResponseDataV27() { // Response should be unchanged. assertThat(ClearKeyUtil.adjustResponseData(SINGLE_KEY_RESPONSE)).isEqualTo(SINGLE_KEY_RESPONSE); }
@Config(sdk = 27) @Test public void testAdjustRequestDataV27() { // Request should be unchanged. assertThat(ClearKeyUtil.adjustRequestData(KEY_REQUEST)).isEqualTo(KEY_REQUEST); }
@Config(sdk = 26) @Test public void testAdjustMultiKeyResponseDataV26() { // Everything but the keys should be removed. Within each key only the k, kid and kty parameters // should remain. Any "-" and "_" characters in the k and kid values should be replaced with "+" // and "/". byte[] expected = Util.getUtf8Bytes( "{" + "\"keys\":[" + "{" + "\"k\":\"abc/def+\",\"kid\":\"ab/cde+f\",\"kty\":\"oct\"" + "},{" + "\"k\":\"ghi/jkl+\",\"kid\":\"gh/ijk+l\",\"kty\":\"oct\"" + "}" + "]" + "}"); assertThat(ClearKeyUtil.adjustResponseData(MULTI_KEY_RESPONSE)).isEqualTo(expected); }
@Config(sdk = 26) @Test public void testAdjustRequestDataV26() { // We expect "+" and "/" to be replaced with "-" and "_" respectively, for "kids". byte[] expected = Util.getUtf8Bytes( "{" + "\"kids\":[" + "\"abc-def_\"," + "\"ab-cde_f\"" + "]," + "\"type\":\"temporary\"" + "}"); assertThat(ClearKeyUtil.adjustRequestData(KEY_REQUEST)).isEqualTo(expected); }
@Config(sdk = 26) @Test public void testAdjustSingleKeyResponseDataV26() { // Everything but the keys should be removed. Within each key only the k, kid and kty parameters // should remain. Any "-" and "_" characters in the k and kid values should be replaced with "+" // and "/". byte[] expected = Util.getUtf8Bytes( "{" + "\"keys\":[" + "{" + "\"k\":\"abc/def+\",\"kid\":\"ab/cde+f\",\"kty\":\"o_c-t\"" + "}" + "]" + "}"); assertThat(ClearKeyUtil.adjustResponseData(SINGLE_KEY_RESPONSE)).isEqualTo(expected); }