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
17package com.android.mediadrm.signer;
18
19import android.media.MediaDrm;
20import android.media.DeniedByServerException;
21
22/**
23 * Provides certificate request generation, response handling and
24 * signing APIs
25 */
26public final class 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
41        CertificateRequest(MediaDrm.CertificateRequest certRequest) {
42            mCertRequest = certRequest;
43        }
44
45        /**
46         * Get the opaque message data
47         */
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         */
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
69        Certificate(MediaDrm.Certificate certificate) {
70            mCertificate = certificate;
71        }
72
73        /**
74         * Get the wrapped private key data
75         */
76        public byte[] getWrappedPrivateKey() {
77            return mCertificate.getWrappedPrivateKey();
78        }
79
80        /**
81         * Get the PEM-encoded public certificate chain
82         */
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     */
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     */
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     */
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