Home | History | Annotate | Download | only in jsse
      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.NoSuchAlgorithmException;
     21 import java.security.PrivateKey;
     22 
     23 import javax.crypto.SecretKey;
     24 
     25 public class OpenSSLEngine {
     26     static {
     27         NativeCrypto.ENGINE_load_dynamic();
     28     }
     29 
     30     private static final Object mLoadingLock = new Object();
     31 
     32     /** The ENGINE's native handle. */
     33     private final long ctx;
     34 
     35     public static OpenSSLEngine getInstance(String engine) throws IllegalArgumentException {
     36         if (engine == null) {
     37             throw new NullPointerException("engine == null");
     38         }
     39 
     40         final long engineCtx;
     41         synchronized (mLoadingLock) {
     42             engineCtx = NativeCrypto.ENGINE_by_id(engine);
     43             if (engineCtx == 0) {
     44                 throw new IllegalArgumentException("Unknown ENGINE id: " + engine);
     45             }
     46 
     47             NativeCrypto.ENGINE_add(engineCtx);
     48         }
     49 
     50         return new OpenSSLEngine(engineCtx);
     51     }
     52 
     53     private OpenSSLEngine(long engineCtx) {
     54         ctx = engineCtx;
     55 
     56         if (NativeCrypto.ENGINE_init(engineCtx) == 0) {
     57             NativeCrypto.ENGINE_free(engineCtx);
     58             throw new IllegalArgumentException("Could not initialize engine");
     59         }
     60     }
     61 
     62     public PrivateKey getPrivateKeyById(String id) throws InvalidKeyException {
     63         if (id == null) {
     64             throw new NullPointerException("id == null");
     65         }
     66 
     67         final long keyRef = NativeCrypto.ENGINE_load_private_key(ctx, id);
     68         if (keyRef == 0) {
     69             return null;
     70         }
     71 
     72         OpenSSLKey pkey = new OpenSSLKey(keyRef, this, id);
     73         try {
     74             return pkey.getPrivateKey();
     75         } catch (NoSuchAlgorithmException e) {
     76             throw new InvalidKeyException(e);
     77         }
     78     }
     79 
     80     public SecretKey getSecretKeyById(String id, String algorithm) throws InvalidKeyException {
     81         if (id == null) {
     82             throw new NullPointerException("id == null");
     83         }
     84 
     85         final long keyRef = NativeCrypto.ENGINE_load_private_key(ctx, id);
     86         if (keyRef == 0) {
     87             return null;
     88         }
     89 
     90         OpenSSLKey pkey = new OpenSSLKey(keyRef, this, id);
     91         try {
     92             return pkey.getSecretKey(algorithm);
     93         } catch (NoSuchAlgorithmException e) {
     94             throw new InvalidKeyException(e);
     95         }
     96     }
     97 
     98     long getEngineContext() {
     99         return ctx;
    100     }
    101 
    102     @Override
    103     protected void finalize() throws Throwable {
    104         try {
    105             NativeCrypto.ENGINE_finish(ctx);
    106             NativeCrypto.ENGINE_free(ctx);
    107         } finally {
    108             super.finalize();
    109         }
    110     }
    111 
    112     @Override
    113     public boolean equals(Object o) {
    114         if (o == this) {
    115             return true;
    116         }
    117 
    118         if (!(o instanceof OpenSSLEngine)) {
    119             return false;
    120         }
    121 
    122         OpenSSLEngine other = (OpenSSLEngine) o;
    123 
    124         if (other.getEngineContext() == ctx) {
    125             return true;
    126         }
    127 
    128         final String id = NativeCrypto.ENGINE_get_id(ctx);
    129         if (id == null) {
    130             return false;
    131         }
    132 
    133         return id.equals(NativeCrypto.ENGINE_get_id(other.getEngineContext()));
    134     }
    135 
    136     @Override
    137     public int hashCode() {
    138       return (int) ctx;
    139     }
    140 }
    141