1e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker/* 2e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * Copyright (C) 2013 The Android Open Source Project 3e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * 4e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * Licensed under the Apache License, Version 2.0 (the "License"); 5e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * you may not use this file except in compliance with the License. 6e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * You may obtain a copy of the License at 7e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * 8e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * http://www.apache.org/licenses/LICENSE-2.0 9e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * 10e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * Unless required by applicable law or agreed to in writing, software 11e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * distributed under the License is distributed on an "AS IS" BASIS, 12e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * See the License for the specific language governing permissions and 14e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * limitations under the License. 15e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker */ 16e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker 17e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinkerpackage com.android.mediadrm.signer; 18e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker 19e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinkerimport android.media.MediaDrm; 20e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinkerimport android.media.DeniedByServerException; 21e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker 22e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker/** 23e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * Provides certificate request generation, response handling and 24e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * signing APIs 25e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker */ 26e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinkerpublic final class MediaDrmSigner { 27e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker private MediaDrmSigner() {} 28e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker 29e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker /** 30e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * Specify X.509 certificate type 31e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker */ 32e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker public static final int CERTIFICATE_TYPE_X509 = MediaDrm.CERTIFICATE_TYPE_X509; 33e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker 34e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker /** 35e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * Contains the opaque data an app uses to request a certificate from a provisioning 36e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * server 37e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker */ 38e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker public final static class CertificateRequest { 399de8c1d82b6bf2b70e854a3349c9f1da60a23e83Jeff Tinker private final MediaDrm.CertificateRequest mCertRequest; 40e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker 41e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker CertificateRequest(MediaDrm.CertificateRequest certRequest) { 42e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker mCertRequest = certRequest; 43e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker } 44e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker 45e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker /** 46e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * Get the opaque message data 47e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker */ 48e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker public byte[] getData() { 49e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker return mCertRequest.getData(); 50e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker } 51e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker 52e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker /** 53e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * Get the default URL to use when sending the certificate request 54e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * message to a server, if known. The app may prefer to use a different 55e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * certificate server URL obtained from other sources. 56e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker */ 57e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker public String getDefaultUrl() { 58e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker return mCertRequest.getDefaultUrl(); 59e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker } 60e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker } 61e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker 62e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker /** 63e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * Contains the wrapped private key and public certificate data associated 64e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * with a certificate. 65e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker */ 66e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker public final static class Certificate { 679de8c1d82b6bf2b70e854a3349c9f1da60a23e83Jeff Tinker private final MediaDrm.Certificate mCertificate; 68e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker 69e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker Certificate(MediaDrm.Certificate certificate) { 70e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker mCertificate = certificate; 71e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker } 72e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker 73e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker /** 74e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * Get the wrapped private key data 75e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker */ 76e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker public byte[] getWrappedPrivateKey() { 77e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker return mCertificate.getWrappedPrivateKey(); 78e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker } 79e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker 80e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker /** 81e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * Get the PEM-encoded public certificate chain 82e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker */ 83e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker public byte[] getContent() { 84e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker return mCertificate.getContent(); 85e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker } 86e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker } 87e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker 88e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker /** 89e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * Generate a certificate request, specifying the certificate type 90e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * and authority. The response received should be passed to 91e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * provideCertificateResponse. 92e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * 93e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * @param drm the MediaDrm object 94e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * @param certType Specifies the certificate type. 95e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * @param certAuthority is passed to the certificate server to specify 96e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * the chain of authority. 97e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker */ 98e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker public static CertificateRequest getCertificateRequest(MediaDrm drm, int certType, 999de8c1d82b6bf2b70e854a3349c9f1da60a23e83Jeff Tinker String certAuthority) { 100e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker return new CertificateRequest(drm.getCertificateRequest(certType, certAuthority)); 101e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker } 102e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker 103e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker /** 104e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * Process a response from the provisioning server. The response 105e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * is obtained from an HTTP Post to the url provided by getCertificateRequest. 106e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * 107e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * The public X509 certificate chain and wrapped private key are returned 108e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * in the returned Certificate objec. The certificate chain is in BIO serialized 109e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * PEM format. The wrapped private key should be stored in application private 110e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * storage, and used when invoking the signRSA method. 111e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * 112e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * @param drm the MediaDrm object 113e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * @param response the opaque certificate response byte array to provide to the 114e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * DRM engine plugin. 115e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * @throws android.media.DeniedByServerException if the response indicates that the 116e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * server rejected the request 117e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker */ 118e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker public static Certificate provideCertificateResponse(MediaDrm drm, byte[] response) 1199de8c1d82b6bf2b70e854a3349c9f1da60a23e83Jeff Tinker throws DeniedByServerException { 120e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker return new Certificate(drm.provideCertificateResponse(response)); 121e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker } 122e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker 123e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker /** 124e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * Sign data using an RSA key 125e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * 126e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * @param drm the MediaDrm object 127e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * @param sessionId a sessionId obtained from openSession on the MediaDrm object 128e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * @param algorithm the signing algorithm to use, e.g. "PKCS1-BlockType1" 129e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * @param wrappedKey - the wrapped (encrypted) RSA private key obtained 130e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * from provideCertificateResponse 131e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker * @param message the data for which a signature is to be computed 132e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker */ 1339de8c1d82b6bf2b70e854a3349c9f1da60a23e83Jeff Tinker public static byte[] signRSA(MediaDrm drm, byte[] sessionId, 1349de8c1d82b6bf2b70e854a3349c9f1da60a23e83Jeff Tinker String algorithm, byte[] wrappedKey, byte[] message) { 1359de8c1d82b6bf2b70e854a3349c9f1da60a23e83Jeff Tinker return drm.signRSA(sessionId, algorithm, wrappedKey, message); 136e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker } 137e4095a80b674642e0e0e8f0883dee3b22f32f19aJeff Tinker} 138