OpenSSLEngine.java revision 5b7f91c1e6e208187cef57ab8a5de0a7f35e817f
1/*
2 * Copyright (C) 2012 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 org.apache.harmony.xnet.provider.jsse;
18
19import java.security.InvalidKeyException;
20import java.security.PrivateKey;
21
22public class OpenSSLEngine {
23    static {
24        NativeCrypto.ENGINE_load_dynamic();
25    }
26
27    /** The ENGINE's native handle. */
28    private final int ctx;
29
30    public static OpenSSLEngine getInstance(String engine) throws IllegalArgumentException {
31        if (engine == null) {
32            throw new NullPointerException("engine == null");
33        }
34
35        final int engineCtx = NativeCrypto.ENGINE_by_id(engine);
36
37        if (engineCtx == 0) {
38            throw new IllegalArgumentException("Unknown ENGINE id: " + engine);
39        }
40
41        return new OpenSSLEngine(engineCtx);
42    }
43
44    private OpenSSLEngine(int engineCtx) {
45        ctx = engineCtx;
46
47        if (NativeCrypto.ENGINE_init(engineCtx) == 0) {
48            throw new IllegalArgumentException("Could not initialize engine");
49        }
50    }
51
52    public PrivateKey getPrivateKeyById(String id) throws InvalidKeyException {
53        if (id == null) {
54            throw new NullPointerException("id == null");
55        }
56
57        final int keyRef = NativeCrypto.ENGINE_load_private_key(ctx, id);
58        if (keyRef == 0) {
59            return null;
60        }
61
62        final int keyType = NativeCrypto.EVP_PKEY_type(keyRef);
63        switch (keyType) {
64            case NativeCrypto.EVP_PKEY_RSA:
65                return OpenSSLRSAPrivateKey.getInstance(new OpenSSLKey(keyRef, this));
66            case NativeCrypto.EVP_PKEY_DSA:
67                return new OpenSSLDSAPrivateKey(new OpenSSLKey(keyRef, this));
68            default:
69                throw new InvalidKeyException("Unknown key type: " + keyType);
70        }
71    }
72
73    int getEngineContext() {
74        return ctx;
75    }
76
77    @Override
78    protected void finalize() throws Throwable {
79        try {
80            NativeCrypto.ENGINE_finish(ctx);
81            NativeCrypto.ENGINE_free(ctx);
82        } finally {
83            super.finalize();
84        }
85    }
86
87    @Override
88    public boolean equals(Object o) {
89        if (o == this) {
90            return true;
91        }
92
93        if (!(o instanceof OpenSSLEngine)) {
94            return false;
95        }
96
97        OpenSSLEngine other = (OpenSSLEngine) o;
98
99        return other.getEngineContext() == ctx;
100    }
101
102    @Override
103    public int hashCode() {
104        return ctx;
105    }
106}
107