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