Home | History | Annotate | Download | only in jsse
      1 /*
      2  * Copyright (C) 2008 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.MessageDigest;
     20 import java.security.NoSuchAlgorithmException;
     21 
     22 /**
     23  * Implements the JDK MessageDigest interface using OpenSSL's EVP API.
     24  */
     25 public class OpenSSLMessageDigestJDK extends MessageDigest implements Cloneable {
     26 
     27     /**
     28      * Holds a pointer to the native message digest context.
     29      */
     30     private int ctx;
     31 
     32     /**
     33      * The OpenSSL version of the algorithm name for later use by reset.
     34      */
     35     private final String openssl;
     36 
     37     /**
     38      * Holds a dummy buffer for writing single bytes to the digest.
     39      */
     40     private final byte[] singleByte = new byte[1];
     41 
     42     /**
     43      * Creates a new OpenSSLMessageDigest instance for the given algorithm
     44      * name.
     45      *
     46      * @param algorithm The standard name of the algorithm, e.g. "SHA-1".
     47      * @param algorithm The name of the openssl algorithm, e.g. "sha1".
     48      */
     49     private OpenSSLMessageDigestJDK(String algorithm, String openssl)
     50             throws NoSuchAlgorithmException {
     51         super(algorithm);
     52         this.openssl = openssl;
     53 
     54         ctx = NativeCrypto.EVP_MD_CTX_create();
     55         try {
     56             NativeCrypto.EVP_DigestInit(ctx, openssl);
     57         } catch (Exception ex) {
     58             throw new NoSuchAlgorithmException(ex.getMessage() + " (" + algorithm + ")");
     59         }
     60     }
     61 
     62     @Override
     63     protected byte[] engineDigest() {
     64         byte[] result = new byte[NativeCrypto.EVP_MD_CTX_size(ctx)];
     65         NativeCrypto.EVP_DigestFinal(ctx, result, 0);
     66         NativeCrypto.EVP_DigestInit(ctx, openssl);
     67         return result;
     68     }
     69 
     70     @Override
     71     protected void engineReset() {
     72         NativeCrypto.EVP_DigestInit(ctx, openssl);
     73     }
     74 
     75     @Override
     76     protected int engineGetDigestLength() {
     77         return NativeCrypto.EVP_MD_CTX_size(ctx);
     78     }
     79 
     80     @Override
     81     protected void engineUpdate(byte input) {
     82         singleByte[0] = input;
     83         engineUpdate(singleByte, 0, 1);
     84     }
     85 
     86     @Override
     87     protected void engineUpdate(byte[] input, int offset, int len) {
     88         NativeCrypto.EVP_DigestUpdate(ctx, input, offset, len);
     89     }
     90 
     91     public Object clone() throws CloneNotSupportedException {
     92         OpenSSLMessageDigestJDK d = (OpenSSLMessageDigestJDK) super.clone();
     93         d.ctx = NativeCrypto.EVP_MD_CTX_copy(ctx);
     94         return d;
     95     }
     96 
     97     @Override protected void finalize() throws Throwable {
     98         try {
     99             NativeCrypto.EVP_MD_CTX_destroy(ctx);
    100             ctx = 0;
    101         } finally {
    102             super.finalize();
    103         }
    104     }
    105 
    106     public static class MD5 extends OpenSSLMessageDigestJDK {
    107         public MD5() throws NoSuchAlgorithmException {
    108             super("MD5", "md5");
    109         }
    110     }
    111 
    112     public static class SHA1 extends OpenSSLMessageDigestJDK {
    113         public SHA1() throws NoSuchAlgorithmException {
    114             super("SHA-1", "sha1");
    115         }
    116     }
    117 
    118     public static class SHA256 extends OpenSSLMessageDigestJDK {
    119         public SHA256() throws NoSuchAlgorithmException {
    120             super("SHA-256", "sha256");
    121         }
    122     }
    123 
    124     public static class SHA384 extends OpenSSLMessageDigestJDK {
    125         public SHA384() throws NoSuchAlgorithmException {
    126             super("SHA-384", "sha384");
    127         }
    128     }
    129 
    130     public static class SHA512 extends OpenSSLMessageDigestJDK {
    131         public SHA512() throws NoSuchAlgorithmException {
    132             super("SHA-512", "sha512");
    133         }
    134     }
    135 }
    136