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;
24cc1fc6b6adc1edc2acaa42205b4ec5ca00bfd353Kenny Rootimport org.apache.harmony.xnet.provider.jsse.OpenSSLKey;
25cc1fc6b6adc1edc2acaa42205b4ec5ca00bfd353Kenny Rootimport org.apache.harmony.xnet.provider.jsse.OpenSSLKeyHolder;
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
59cc1fc6b6adc1edc2acaa42205b4ec5ca00bfd353Kenny Root            if (privateKey instanceof OpenSSLKeyHolder) {
60cc1fc6b6adc1edc2acaa42205b4ec5ca00bfd353Kenny Root                OpenSSLKey pkey = ((OpenSSLKeyHolder) privateKey).getOpenSSLKey();
61cc1fc6b6adc1edc2acaa42205b4ec5ca00bfd353Kenny Root                setSslClientCertFromCtx(pkey.getPkeyContext(), chainBytes);
62275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun            } else {
63cc1fc6b6adc1edc2acaa42205b4ec5ca00bfd353Kenny Root                setSslClientCertFromPKCS8(privateKey.getEncoded(), chainBytes);
64275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun            }
65a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom        } catch (CertificateEncodingException e) {
6638f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun            post(new Runnable() {
6738f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun                    public void run() {
68275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun                        mBrowserFrame.nativeSslClientCert(mHandle, 0, null);
6938f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun                        return;
7038f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun                    }
7138f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun                });
72a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom        }
73a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom    }
74a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom
75a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom    /**
76275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun     * Proceed with the specified private key bytes and client certificate chain.
77275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun     */
786bae82a2ae174670c97843af225d112907fce89fBrian Carlstrom    private void setSslClientCertFromCtx(final long ctx, final byte[][] chainBytes) {
79275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun        post(new Runnable() {
80275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun                public void run() {
81275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun                    mBrowserFrame.nativeSslClientCert(mHandle, ctx, chainBytes);
82275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun                }
83275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun            });
84275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun    }
85275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun
86275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun    /**
87275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun     * Proceed with the specified private key context and client certificate chain.
88275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun     */
89275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun    private void setSslClientCertFromPKCS8(final byte[] key, final byte[][] chainBytes) {
90275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun        post(new Runnable() {
91275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun                public void run() {
92275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun                    mBrowserFrame.nativeSslClientCert(mHandle, key, chainBytes);
93275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun                }
94275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun            });
95275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun    }
96275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun
97275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun    /**
98a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom     * Igore the request for now, the user may be prompted again.
99a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom     */
100a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom    public void ignore() {
10138f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun        post(new Runnable() {
10238f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun                public void run() {
103275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun                    mBrowserFrame.nativeSslClientCert(mHandle, 0, null);
10438f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun                }
10538f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun            });
106a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom    }
107a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom
108a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom    /**
109a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom     * Cancel this request, remember the users negative choice.
110a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom     */
111a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom    public void cancel() {
112a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom        mTable.Deny(mHostAndPort);
11338f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun        post(new Runnable() {
11438f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun                public void run() {
115275fce8a2ca45e640abf451552dd1bdbbc0cb54cSelim Gurun                    mBrowserFrame.nativeSslClientCert(mHandle, 0, null);
11638f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun                }
11738f3610a29c75c3bb16408a911e3365a71b6524cSelim Gurun            });
118a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom    }
119a14775949c97a616196f5293209b092ee3d4e9a9Brian Carlstrom}
120