Home | History | Annotate | Download | only in jsse
      1 /*
      2  * Copyright (C) 2013 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.io.IOException;
     20 import java.io.NotSerializableException;
     21 import java.io.ObjectInputStream;
     22 import java.io.ObjectOutputStream;
     23 import java.security.InvalidKeyException;
     24 import java.util.Arrays;
     25 
     26 import javax.crypto.SecretKey;
     27 
     28 public class OpenSSLSecretKey implements SecretKey, OpenSSLKeyHolder {
     29     private static final long serialVersionUID = 1831053062911514589L;
     30 
     31     private final String algorithm;
     32     private final int type;
     33     private final byte[] encoded;
     34 
     35     private transient OpenSSLKey key;
     36 
     37     public OpenSSLSecretKey(String algorithm, byte[] encoded) {
     38         this.algorithm = algorithm;
     39         this.encoded = encoded;
     40 
     41         type = NativeCrypto.EVP_PKEY_HMAC;
     42         key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_mac_key(type, encoded));
     43     }
     44 
     45     public OpenSSLSecretKey(String algorithm, OpenSSLKey key) {
     46         this.algorithm = algorithm;
     47         this.key = key;
     48 
     49         type = NativeCrypto.EVP_PKEY_type(key.getPkeyContext());
     50         encoded = null;
     51     }
     52 
     53     public static OpenSSLKey getInstance(SecretKey key) throws InvalidKeyException {
     54         try {
     55             return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_mac_key(NativeCrypto.EVP_PKEY_HMAC,
     56                     key.getEncoded()));
     57         } catch (Exception e) {
     58             throw new InvalidKeyException(e);
     59         }
     60     }
     61 
     62     @Override
     63     public String getAlgorithm() {
     64         return algorithm;
     65     }
     66 
     67     @Override
     68     public String getFormat() {
     69         if (key.isEngineBased()) {
     70             return null;
     71         }
     72 
     73         return "RAW";
     74     }
     75 
     76     @Override
     77     public byte[] getEncoded() {
     78         if (key.isEngineBased()) {
     79             return null;
     80         }
     81 
     82         return encoded;
     83     }
     84 
     85     @Override
     86     public OpenSSLKey getOpenSSLKey() {
     87         return key;
     88     }
     89 
     90     @Override
     91     public boolean equals(Object o) {
     92         if (o == this) {
     93             return true;
     94         }
     95 
     96         if (!(o instanceof SecretKey)) {
     97             return false;
     98         }
     99 
    100         SecretKey other = (SecretKey) o;
    101         if (!algorithm.equals(other.getAlgorithm())) {
    102             return false;
    103         }
    104 
    105         if (o instanceof OpenSSLSecretKey) {
    106             OpenSSLSecretKey otherOpenSSL = (OpenSSLSecretKey) o;
    107             return key.equals(otherOpenSSL.getOpenSSLKey());
    108         } else if (key.isEngineBased()) {
    109             return false;
    110         }
    111 
    112         if (!getFormat().equals(other.getFormat())) {
    113             return false;
    114         }
    115 
    116         return Arrays.equals(encoded, other.getEncoded());
    117     }
    118 
    119     @Override
    120     public int hashCode() {
    121         return key.hashCode();
    122     }
    123 
    124     private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
    125         stream.defaultReadObject();
    126 
    127         key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_mac_key(type, encoded));
    128     }
    129 
    130     private void writeObject(ObjectOutputStream stream) throws IOException {
    131         if (getOpenSSLKey().isEngineBased()) {
    132             throw new NotSerializableException("engine-based keys can not be serialized");
    133         }
    134 
    135         stream.defaultWriteObject();
    136     }
    137 }
    138