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