1a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom/*
2a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom * Copyright (C) 2011 The Android Open Source Project
3a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom *
4a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License");
5a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom * you may not use this file except in compliance with the License.
6a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom * You may obtain a copy of the License at
7a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom *
8a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom *      http://www.apache.org/licenses/LICENSE-2.0
9a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom *
10a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom * Unless required by applicable law or agreed to in writing, software
11a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS,
12a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom * See the License for the specific language governing permissions and
14a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom * limitations under the License.
15a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom */
16a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom
17a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrompackage android.webkit;
18a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom
1938f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurunimport android.os.Handler;
20a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstromimport java.security.PrivateKey;
21a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstromimport java.security.cert.CertificateEncodingException;
22a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstromimport java.security.cert.X509Certificate;
23a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstromimport org.apache.harmony.xnet.provider.jsse.NativeCrypto;
24275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurunimport org.apache.harmony.xnet.provider.jsse.OpenSSLDSAPrivateKey;
25275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurunimport org.apache.harmony.xnet.provider.jsse.OpenSSLRSAPrivateKey;
26a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom
27a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom/**
28a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom * ClientCertRequestHandler: class responsible for handling client
29a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom * certificate requests.  This class is passed as a parameter to
30a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom * BrowserCallback.displayClientCertRequestDialog and is meant to
31a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom * receive the user's response.
32a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom *
33a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom * @hide
34a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom */
3538f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurunpublic final class ClientCertRequestHandler extends Handler {
36a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom
37a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom    private final BrowserFrame mBrowserFrame;
38a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom    private final int mHandle;
39a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom    private final String mHostAndPort;
40a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom    private final SslClientCertLookupTable mTable;
41a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom    ClientCertRequestHandler(BrowserFrame browserFrame,
42a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom                             int handle,
43a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom                             String host_and_port,
44a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom                             SslClientCertLookupTable table) {
45a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom        mBrowserFrame = browserFrame;
46a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom        mHandle = handle;
47a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom        mHostAndPort = host_and_port;
48a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom        mTable = table;
49a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom    }
50a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom
51a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom    /**
52a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom     * Proceed with the specified private key and client certificate chain.
53a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom     */
54a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom    public void proceed(PrivateKey privateKey, X509Certificate[] chain) {
55a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom        try {
56275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun            byte[][] chainBytes = NativeCrypto.encodeCertificates(chain);
57275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun            mTable.Allow(mHostAndPort, privateKey, chainBytes);
58275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun
59275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun            if (privateKey instanceof OpenSSLRSAPrivateKey) {
60275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun                setSslClientCertFromCtx(((OpenSSLRSAPrivateKey)privateKey).getPkeyContext(),
61275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun                           chainBytes);
62275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun            } else if (privateKey instanceof OpenSSLDSAPrivateKey) {
63275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun                setSslClientCertFromCtx(((OpenSSLDSAPrivateKey)privateKey).getPkeyContext(),
64275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun                           chainBytes);
65275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun            } else {
66275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun                setSslClientCertFromPKCS8(privateKey.getEncoded(),chainBytes);
67275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun            }
68a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom        } catch (CertificateEncodingException e) {
6938f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun            post(new Runnable() {
7038f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun                    public void run() {
71275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun                        mBrowserFrame.nativeSslClientCert(mHandle, 0, null);
7238f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun                        return;
7338f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun                    }
7438f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun                });
75a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom        }
76a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom    }
77a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom
78a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom    /**
79275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun     * Proceed with the specified private key bytes and client certificate chain.
80275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun     */
81275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun    private void setSslClientCertFromCtx(final int ctx, final byte[][] chainBytes) {
82275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun        post(new Runnable() {
83275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun                public void run() {
84275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun                    mBrowserFrame.nativeSslClientCert(mHandle, ctx, chainBytes);
85275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun                }
86275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun            });
87275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun    }
88275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun
89275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun    /**
90275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun     * Proceed with the specified private key context and client certificate chain.
91275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun     */
92275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun    private void setSslClientCertFromPKCS8(final byte[] key, final byte[][] chainBytes) {
93275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun        post(new Runnable() {
94275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun                public void run() {
95275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun                    mBrowserFrame.nativeSslClientCert(mHandle, key, chainBytes);
96275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun                }
97275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun            });
98275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun    }
99275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun
100275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun    /**
101a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom     * Igore the request for now, the user may be prompted again.
102a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom     */
103a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom    public void ignore() {
10438f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun        post(new Runnable() {
10538f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun                public void run() {
106275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun                    mBrowserFrame.nativeSslClientCert(mHandle, 0, null);
10738f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun                }
10838f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun            });
109a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom    }
110a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom
111a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom    /**
112a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom     * Cancel this request, remember the users negative choice.
113a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom     */
114a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom    public void cancel() {
115a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom        mTable.Deny(mHostAndPort);
11638f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun        post(new Runnable() {
11738f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun                public void run() {
118275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun                    mBrowserFrame.nativeSslClientCert(mHandle, 0, null);
11938f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun                }
12038f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun            });
121a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom    }
122a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom}
123