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