PageRenderTime 60ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/Oauth/java/jmeter/core/commons/src/main/java/net/oauth/signature/RSA_SHA1.java

https://github.com/levelcap/isohealth
Java | 337 lines | 210 code | 34 blank | 93 comment | 36 complexity | b6206d0da22b4c1a1fd95e3b68e508e9 MD5 | raw file
  1. /*
  2. * Copyright 2007 Google, Inc.
  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 net.oauth.signature;
  17. import java.io.ByteArrayInputStream;
  18. import java.io.IOException;
  19. import java.io.InputStream;
  20. import java.io.UnsupportedEncodingException;
  21. import java.security.GeneralSecurityException;
  22. import java.security.KeyFactory;
  23. import java.security.PrivateKey;
  24. import java.security.PublicKey;
  25. import java.security.Signature;
  26. import java.security.cert.CertificateFactory;
  27. import java.security.cert.X509Certificate;
  28. import java.security.spec.EncodedKeySpec;
  29. import java.security.spec.KeySpec;
  30. import java.security.spec.PKCS8EncodedKeySpec;
  31. import java.security.spec.X509EncodedKeySpec;
  32. import net.oauth.OAuth;
  33. import net.oauth.OAuthAccessor;
  34. import net.oauth.OAuthException;
  35. import net.oauth.signature.pem.PEMReader;
  36. import net.oauth.signature.pem.PKCS1EncodedKeySpec;
  37. /**
  38. * The RSA-SHA1 signature method. A consumer
  39. * that wishes to use public-key signatures on messages does not need
  40. * a shared secret with the service provider, but it needs a private
  41. * RSA signing key. You create it like this:
  42. *
  43. * OAuthConsumer c = new OAuthConsumer(callback_url, consumer_key,
  44. * null, provider);
  45. * c.setProperty(RSA_SHA1.PRIVATE_KEY, consumer_privateRSAKey);
  46. *
  47. * consumer_privateRSAKey must be an RSA signing key and
  48. * of type java.security.PrivateKey, String, byte[] or InputStream.
  49. * The key must either PKCS#1 or PKCS#8 encoded.
  50. *
  51. * A service provider that wishes to verify signatures made by such a
  52. * consumer does not need a shared secret with the consumer, but it needs
  53. * to know the consumer's public key. You create the necessary
  54. * OAuthConsumer object (on the service provider's side) like this:
  55. *
  56. * OAuthConsumer c = new OAuthConsumer(callback_url, consumer_key,
  57. * null, provider);
  58. * c.setProperty(RSA_SHA1.PUBLIC_KEY, consumer_publicRSAKey);
  59. *
  60. * consumer_publicRSAKey must be the consumer's public RSAkey and
  61. * of type java.security.PublicKey, String, or byte[]. In the latter two
  62. * cases, the key must be X509-encoded (byte[]) or X509-encoded and
  63. * then Base64-encoded (String).
  64. *
  65. * Alternatively, a service provider that wishes to verify signatures made
  66. * by such a consumer can use a X509 certificate containing the consumer's
  67. * public key. You create the necessary OAuthConsumer object (on the service
  68. * provider's side) like this:
  69. *
  70. * OAuthConsumer c = new OAuthConsumer(callback_url, consumer_key,
  71. * null, provider);
  72. * c.setProperty(RSA_SHA1.X509_CERTIFICATE, consumer_cert);
  73. *
  74. * consumer_cert must be a X509 Certificate containing the consumer's public
  75. * key and be of type java.security.cert.X509Certificate, String,
  76. * or byte[]. In the latter two cases, the certificate must be DER-encoded
  77. * (byte[]) or PEM-encoded (String).
  78. *
  79. * @author Dirk Balfanz
  80. *
  81. */
  82. public class RSA_SHA1 extends OAuthSignatureMethod {
  83. final static public String PRIVATE_KEY = "RSA-SHA1.PrivateKey";
  84. final static public String PUBLIC_KEY = "RSA-SHA1.PublicKey";
  85. final static public String X509_CERTIFICATE = "RSA-SHA1.X509Certificate";
  86. private PrivateKey privateKey = null;
  87. private PublicKey publicKey = null;
  88. @Override
  89. protected void initialize(String name, OAuthAccessor accessor)
  90. throws OAuthException {
  91. super.initialize(name, accessor);
  92. // Due to the support of PEM input stream, the keys must be cached.
  93. // The stream may not be markable so it can't be read again.
  94. try {
  95. Object privateKeyObject = accessor.consumer.getProperty(PRIVATE_KEY);
  96. if (privateKeyObject != null) {
  97. privateKey = loadPrivateKey(privateKeyObject);
  98. }
  99. Object publicKeyObject = accessor.consumer.getProperty(PUBLIC_KEY);
  100. if (publicKeyObject != null) {
  101. publicKey = loadPublicKey(publicKeyObject, false);
  102. } else { // public key was null. perhaps they gave us a X509 cert.
  103. Object certObject = accessor.consumer.getProperty(X509_CERTIFICATE);
  104. if (certObject != null) {
  105. publicKey = loadPublicKey(certObject, true);
  106. }
  107. }
  108. } catch (GeneralSecurityException e) {
  109. throw new OAuthException(e);
  110. } catch (IOException e) {
  111. throw new OAuthException(e);
  112. }
  113. }
  114. private PublicKey getPublicKeyFromDerCert(byte[] certObject)
  115. throws GeneralSecurityException {
  116. CertificateFactory fac = CertificateFactory.getInstance("X509");
  117. ByteArrayInputStream in = new ByteArrayInputStream(certObject);
  118. X509Certificate cert = (X509Certificate)fac.generateCertificate(in);
  119. return cert.getPublicKey();
  120. }
  121. private PublicKey getPublicKeyFromDer(byte[] publicKeyObject)
  122. throws GeneralSecurityException {
  123. KeyFactory fac = KeyFactory.getInstance("RSA");
  124. EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(publicKeyObject);
  125. return fac.generatePublic(pubKeySpec);
  126. }
  127. private PublicKey getPublicKeyFromPem(String pem)
  128. throws GeneralSecurityException, IOException {
  129. InputStream stream = new ByteArrayInputStream(
  130. pem.getBytes("UTF-8"));
  131. PEMReader reader = new PEMReader(stream);
  132. byte[] bytes = reader.getDerBytes();
  133. PublicKey pubKey;
  134. if (PEMReader.PUBLIC_X509_MARKER.equals(reader.getBeginMarker())) {
  135. KeySpec keySpec = new X509EncodedKeySpec(bytes);
  136. KeyFactory fac = KeyFactory.getInstance("RSA");
  137. pubKey = fac.generatePublic(keySpec);
  138. } else if (PEMReader.CERTIFICATE_X509_MARKER.equals(reader.getBeginMarker())) {
  139. pubKey = getPublicKeyFromDerCert(bytes);
  140. } else {
  141. throw new IOException("Invalid PEM fileL: Unknown marker for " +
  142. " public key or cert " + reader.getBeginMarker());
  143. }
  144. return pubKey;
  145. }
  146. private PrivateKey getPrivateKeyFromDer(byte[] privateKeyObject)
  147. throws GeneralSecurityException {
  148. KeyFactory fac = KeyFactory.getInstance("RSA");
  149. EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(privateKeyObject);
  150. return fac.generatePrivate(privKeySpec);
  151. }
  152. private PrivateKey getPrivateKeyFromPem(String pem)
  153. throws GeneralSecurityException, IOException {
  154. InputStream stream = new ByteArrayInputStream(
  155. pem.getBytes("UTF-8"));
  156. PEMReader reader = new PEMReader(stream);
  157. byte[] bytes = reader.getDerBytes();
  158. KeySpec keySpec;
  159. if (PEMReader.PRIVATE_PKCS1_MARKER.equals(reader.getBeginMarker())) {
  160. keySpec = (new PKCS1EncodedKeySpec(bytes)).getKeySpec();
  161. } else if (PEMReader.PRIVATE_PKCS8_MARKER.equals(reader.getBeginMarker())) {
  162. keySpec = new PKCS8EncodedKeySpec(bytes);
  163. } else {
  164. throw new IOException("Invalid PEM file: Unknown marker " +
  165. "for private key " + reader.getBeginMarker());
  166. }
  167. KeyFactory fac = KeyFactory.getInstance("RSA");
  168. return fac.generatePrivate(keySpec);
  169. }
  170. @Override
  171. protected String getSignature(String baseString) throws OAuthException {
  172. try {
  173. byte[] signature = sign(baseString.getBytes(OAuth.ENCODING));
  174. return base64Encode(signature);
  175. } catch (UnsupportedEncodingException e) {
  176. throw new OAuthException(e);
  177. } catch (GeneralSecurityException e) {
  178. throw new OAuthException(e);
  179. }
  180. }
  181. @Override
  182. protected boolean isValid(String signature, String baseString)
  183. throws OAuthException {
  184. try {
  185. return verify(decodeBase64(signature),
  186. baseString.getBytes(OAuth.ENCODING));
  187. } catch (UnsupportedEncodingException e) {
  188. throw new OAuthException(e);
  189. } catch (GeneralSecurityException e) {
  190. throw new OAuthException(e);
  191. }
  192. }
  193. private byte[] sign(byte[] message) throws GeneralSecurityException {
  194. if (privateKey == null) {
  195. throw new IllegalStateException("need to set private key with " +
  196. "OAuthConsumer.setProperty when " +
  197. "generating RSA-SHA1 signatures.");
  198. }
  199. Signature signer = Signature.getInstance("SHA1withRSA");
  200. signer.initSign(privateKey);
  201. signer.update(message);
  202. return signer.sign();
  203. }
  204. private boolean verify(byte[] signature, byte[] message)
  205. throws GeneralSecurityException {
  206. if (publicKey == null) {
  207. throw new IllegalStateException("need to set public key with " +
  208. " OAuthConsumer.setProperty when " +
  209. "verifying RSA-SHA1 signatures.");
  210. }
  211. Signature verifier = Signature.getInstance("SHA1withRSA");
  212. verifier.initVerify(publicKey);
  213. verifier.update(message);
  214. return verifier.verify(signature);
  215. }
  216. /**
  217. * Load private key from various sources, including
  218. * <ul>
  219. * <li>A PrivateKey object
  220. * <li>A string buffer for PEM
  221. * <li>A byte array with PKCS#8 encoded key
  222. * </ul>
  223. * @param privateKeyObject
  224. * @return The private key
  225. * @throws IOException
  226. * @throws GeneralSecurityException
  227. */
  228. private PrivateKey loadPrivateKey(Object privateKeyObject)
  229. throws IOException, GeneralSecurityException {
  230. PrivateKey privateKey;
  231. if (privateKeyObject instanceof PrivateKey) {
  232. privateKey = (PrivateKey)privateKeyObject;
  233. } else if (privateKeyObject instanceof String) {
  234. try {
  235. // PEM Reader's native string constructor is for filename.
  236. privateKey = getPrivateKeyFromPem((String)privateKeyObject);
  237. } catch (IOException e) {
  238. // Check if it's PEM with markers stripped
  239. privateKey = getPrivateKeyFromDer(
  240. decodeBase64((String)privateKeyObject));
  241. }
  242. } else if (privateKeyObject instanceof byte[]) {
  243. privateKey = getPrivateKeyFromDer((byte[])privateKeyObject);
  244. } else {
  245. throw new IllegalArgumentException(
  246. "Private key set through RSA_SHA1.PRIVATE_KEY must be of " +
  247. "type PrivateKey, String or byte[] and not " +
  248. privateKeyObject.getClass().getName());
  249. }
  250. return privateKey;
  251. }
  252. /**
  253. * Load a public key from key file or certificate. It can load from
  254. * different sources depending on the type of the input,
  255. * <ul>
  256. * <li>A PublicKey object
  257. * <li>A X509Certificate object
  258. * <li>A string buffer for PEM
  259. * <li>A byte array with X509 encoded key or certificate
  260. * </ul>
  261. *
  262. * @param publicKeyObject The object for public key or certificate
  263. * @param isCert True if this object is provided as Certificate
  264. * @return The public key
  265. * @throws IOException
  266. * @throws GeneralSecurityException
  267. */
  268. private PublicKey loadPublicKey(Object publicKeyObject, boolean isCert)
  269. throws IOException, GeneralSecurityException {
  270. PublicKey publicKey;
  271. if (publicKeyObject instanceof PublicKey) {
  272. publicKey = (PublicKey)publicKeyObject;
  273. } else if (publicKeyObject instanceof X509Certificate) {
  274. publicKey = ((X509Certificate) publicKeyObject).getPublicKey();
  275. } else if (publicKeyObject instanceof String) {
  276. try {
  277. publicKey = getPublicKeyFromPem((String)publicKeyObject);
  278. } catch (IOException e) {
  279. // Check if it's marker-stripped PEM for public key
  280. if (isCert)
  281. throw e;
  282. publicKey = getPublicKeyFromDer(
  283. decodeBase64((String)publicKeyObject));
  284. }
  285. } else if (publicKeyObject instanceof byte[]) {
  286. if (isCert)
  287. publicKey = getPublicKeyFromDerCert((byte[])publicKeyObject);
  288. else
  289. publicKey = getPublicKeyFromDer((byte[])publicKeyObject);
  290. } else {
  291. String source;
  292. if (isCert)
  293. source = "RSA_SHA1.X509_CERTIFICATE";
  294. else
  295. source = "RSA_SHA1.PUBLIC_KEY";
  296. throw new IllegalArgumentException(
  297. "Public key or certificate set through " + source + " must be of " +
  298. "type PublicKey, String or byte[], and not " +
  299. publicKeyObject.getClass().getName());
  300. }
  301. return publicKey;
  302. }
  303. }