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 17 package org.apache.harmony.xnet.provider.jsse; 18 19 import java.security.InvalidKeyException; 20 import java.security.PrivateKey; 21 22 public 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