/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSignature.java

https://bitbucket.org/aways/android_libcore · Java · 303 lines · 212 code · 40 blank · 51 comment · 53 complexity · fc9cb82ab238c986fc295f9835318e84 MD5 · raw file

  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. package org.apache.harmony.xnet.provider.jsse;
  17. import java.security.InvalidKeyException;
  18. import java.security.InvalidParameterException;
  19. import java.security.NoSuchAlgorithmException;
  20. import java.security.PrivateKey;
  21. import java.security.PublicKey;
  22. import java.security.Signature;
  23. import java.security.SignatureException;
  24. import java.security.interfaces.DSAPrivateKey;
  25. import java.security.interfaces.DSAPublicKey;
  26. import java.security.interfaces.RSAPrivateCrtKey;
  27. import java.security.interfaces.RSAPrivateKey;
  28. import java.security.interfaces.RSAPublicKey;
  29. /**
  30. * Implements the subset of the JDK Signature interface needed for
  31. * signature verification using OpenSSL.
  32. */
  33. public class OpenSSLSignature extends Signature {
  34. private static enum EngineType {
  35. RSA, DSA,
  36. };
  37. /**
  38. * Holds a pointer to the native message digest context.
  39. */
  40. private int ctx;
  41. /**
  42. * The current OpenSSL key we're operating on.
  43. */
  44. private OpenSSLKey key;
  45. /**
  46. * Holds the type of the Java algorithm.
  47. */
  48. private final EngineType engineType;
  49. /**
  50. * Holds the OpenSSL name of the algorithm (lower case, no dashes).
  51. */
  52. private final String evpAlgorithm;
  53. /**
  54. * Holds a dummy buffer for writing single bytes to the digest.
  55. */
  56. private final byte[] singleByte = new byte[1];
  57. /**
  58. * Creates a new OpenSSLSignature instance for the given algorithm name.
  59. *
  60. * @param algorithm OpenSSL name of the algorithm, e.g. "RSA-SHA1".
  61. */
  62. private OpenSSLSignature(String algorithm, EngineType engineType)
  63. throws NoSuchAlgorithmException {
  64. super(algorithm);
  65. // We don't support MD2
  66. if ("RSA-MD2".equals(algorithm)) {
  67. throw new NoSuchAlgorithmException(algorithm);
  68. }
  69. this.engineType = engineType;
  70. this.evpAlgorithm = algorithm;
  71. }
  72. @Override
  73. protected void engineUpdate(byte input) {
  74. singleByte[0] = input;
  75. engineUpdate(singleByte, 0, 1);
  76. }
  77. @Override
  78. protected void engineUpdate(byte[] input, int offset, int len) {
  79. if (state == SIGN) {
  80. if (ctx == 0) {
  81. try {
  82. ctx = NativeCrypto.EVP_SignInit(evpAlgorithm);
  83. } catch (Exception ex) {
  84. throw new RuntimeException(ex);
  85. }
  86. }
  87. NativeCrypto.EVP_SignUpdate(ctx, input, offset, len);
  88. } else {
  89. if (ctx == 0) {
  90. try {
  91. ctx = NativeCrypto.EVP_VerifyInit(evpAlgorithm);
  92. } catch (Exception ex) {
  93. throw new RuntimeException(ex);
  94. }
  95. }
  96. NativeCrypto.EVP_VerifyUpdate(ctx, input, offset, len);
  97. }
  98. }
  99. @Override
  100. protected Object engineGetParameter(String param) throws InvalidParameterException {
  101. return null;
  102. }
  103. @Override
  104. protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {
  105. destroyContextIfExists();
  106. if (privateKey instanceof OpenSSLDSAPrivateKey) {
  107. if (engineType != EngineType.DSA) {
  108. throw new InvalidKeyException("Signature not initialized as DSA");
  109. }
  110. OpenSSLDSAPrivateKey dsaPrivateKey = (OpenSSLDSAPrivateKey) privateKey;
  111. key = dsaPrivateKey.getOpenSSLKey();
  112. } else if (privateKey instanceof DSAPrivateKey) {
  113. if (engineType != EngineType.DSA) {
  114. throw new InvalidKeyException("Signature not initialized as DSA");
  115. }
  116. DSAPrivateKey dsaPrivateKey = (DSAPrivateKey) privateKey;
  117. key = OpenSSLDSAPrivateKey.getInstance(dsaPrivateKey);
  118. } else if (privateKey instanceof OpenSSLRSAPrivateKey) {
  119. if (engineType != EngineType.RSA) {
  120. throw new InvalidKeyException("Signature not initialized as RSA");
  121. }
  122. OpenSSLRSAPrivateKey rsaPrivateKey = (OpenSSLRSAPrivateKey) privateKey;
  123. key = rsaPrivateKey.getOpenSSLKey();
  124. } else if (privateKey instanceof RSAPrivateCrtKey) {
  125. if (engineType != EngineType.RSA) {
  126. throw new InvalidKeyException("Signature not initialized as RSA");
  127. }
  128. RSAPrivateCrtKey rsaPrivateKey = (RSAPrivateCrtKey) privateKey;
  129. key = OpenSSLRSAPrivateCrtKey.getInstance(rsaPrivateKey);
  130. } else if (privateKey instanceof RSAPrivateKey) {
  131. if (engineType != EngineType.RSA) {
  132. throw new InvalidKeyException("Signature not initialized as RSA");
  133. }
  134. RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey;
  135. key = OpenSSLRSAPrivateKey.getInstance(rsaPrivateKey);
  136. } else {
  137. throw new InvalidKeyException("Need DSA or RSA private key");
  138. }
  139. }
  140. @Override
  141. protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
  142. // If we had an existing context, destroy it first.
  143. destroyContextIfExists();
  144. if (publicKey instanceof OpenSSLDSAPublicKey) {
  145. if (engineType != EngineType.DSA) {
  146. throw new InvalidKeyException("Signature not initialized as DSA");
  147. }
  148. OpenSSLDSAPublicKey dsaPublicKey = (OpenSSLDSAPublicKey) publicKey;
  149. key = dsaPublicKey.getOpenSSLKey();
  150. } else if (publicKey instanceof DSAPublicKey) {
  151. if (engineType != EngineType.DSA) {
  152. throw new InvalidKeyException("Signature not initialized as DSA");
  153. }
  154. DSAPublicKey dsaPublicKey = (DSAPublicKey) publicKey;
  155. key = OpenSSLDSAPublicKey.getInstance(dsaPublicKey);
  156. } else if (publicKey instanceof OpenSSLRSAPublicKey) {
  157. if (engineType != EngineType.RSA) {
  158. throw new InvalidKeyException("Signature not initialized as RSA");
  159. }
  160. OpenSSLRSAPublicKey rsaPublicKey = (OpenSSLRSAPublicKey) publicKey;
  161. key = rsaPublicKey.getOpenSSLKey();
  162. } else if (publicKey instanceof RSAPublicKey) {
  163. if (engineType != EngineType.RSA) {
  164. throw new InvalidKeyException("Signature not initialized as RSA");
  165. }
  166. RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;
  167. key = OpenSSLRSAPublicKey.getInstance(rsaPublicKey);
  168. } else {
  169. throw new InvalidKeyException("Need DSA or RSA public key");
  170. }
  171. }
  172. @Override
  173. protected void engineSetParameter(String param, Object value) throws InvalidParameterException {
  174. }
  175. @Override
  176. protected byte[] engineSign() throws SignatureException {
  177. if (key == null) {
  178. // This can't actually happen, but you never know...
  179. throw new SignatureException("Need DSA or RSA private key");
  180. }
  181. try {
  182. byte[] buffer = new byte[NativeCrypto.EVP_PKEY_size(key.getPkeyContext())];
  183. int bytesWritten = NativeCrypto.EVP_SignFinal(ctx, buffer, 0, key.getPkeyContext());
  184. byte[] signature = new byte[bytesWritten];
  185. System.arraycopy(buffer, 0, signature, 0, bytesWritten);
  186. return signature;
  187. } catch (Exception ex) {
  188. throw new SignatureException(ex);
  189. } finally {
  190. /*
  191. * Java expects the digest context to be reset completely after sign
  192. * calls.
  193. */
  194. destroyContextIfExists();
  195. }
  196. }
  197. @Override
  198. protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
  199. if (key == null) {
  200. // This can't actually happen, but you never know...
  201. throw new SignatureException("Need DSA or RSA public key");
  202. }
  203. try {
  204. int result = NativeCrypto.EVP_VerifyFinal(ctx, sigBytes, 0, sigBytes.length,
  205. key.getPkeyContext());
  206. return result == 1;
  207. } catch (Exception ex) {
  208. return false;
  209. } finally {
  210. /*
  211. * Java expects the digest context to be reset completely after
  212. * verify calls.
  213. */
  214. destroyContextIfExists();
  215. }
  216. }
  217. private void destroyContextIfExists() {
  218. if (ctx != 0) {
  219. NativeCrypto.EVP_MD_CTX_destroy(ctx);
  220. ctx = 0;
  221. }
  222. }
  223. @Override
  224. protected void finalize() throws Throwable {
  225. try {
  226. if (ctx != 0) {
  227. NativeCrypto.EVP_MD_CTX_destroy(ctx);
  228. }
  229. } finally {
  230. super.finalize();
  231. }
  232. }
  233. public static final class MD5RSA extends OpenSSLSignature {
  234. public MD5RSA() throws NoSuchAlgorithmException {
  235. super("RSA-MD5", EngineType.RSA);
  236. }
  237. }
  238. public static final class SHA1RSA extends OpenSSLSignature {
  239. public SHA1RSA() throws NoSuchAlgorithmException {
  240. super("RSA-SHA1", EngineType.RSA);
  241. }
  242. }
  243. public static final class SHA256RSA extends OpenSSLSignature {
  244. public SHA256RSA() throws NoSuchAlgorithmException {
  245. super("RSA-SHA256", EngineType.RSA);
  246. }
  247. }
  248. public static final class SHA384RSA extends OpenSSLSignature {
  249. public SHA384RSA() throws NoSuchAlgorithmException {
  250. super("RSA-SHA384", EngineType.RSA);
  251. }
  252. }
  253. public static final class SHA512RSA extends OpenSSLSignature {
  254. public SHA512RSA() throws NoSuchAlgorithmException {
  255. super("RSA-SHA512", EngineType.RSA);
  256. }
  257. }
  258. public static final class SHA1DSA extends OpenSSLSignature {
  259. public SHA1DSA() throws NoSuchAlgorithmException {
  260. super("DSA-SHA1", EngineType.DSA);
  261. }
  262. }
  263. }