1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.springframework.security.oauth2.provider.token.store;
15
16 import java.io.IOException;
17 import java.io.InputStream;
18 import java.security.KeyFactory;
19 import java.security.KeyPair;
20 import java.security.KeyStore;
21 import java.security.PublicKey;
22 import java.security.interfaces.RSAPrivateCrtKey;
23 import java.security.spec.RSAPublicKeySpec;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.springframework.core.io.Resource;
28
29
30
31
32
33
34
35
36 public class KeyStoreKeyFactory {
37
38 private static final Log logger = LogFactory.getLog(KeyStoreKeyFactory.class);
39
40 private Resource resource;
41
42 private char[] password;
43
44 private KeyStore store;
45
46 private Object lock = new Object();
47
48 public KeyStoreKeyFactory(Resource resource, char[] password) {
49 this.resource = resource;
50 this.password = password;
51 }
52
53 public KeyPair getKeyPair(String alias) {
54 return getKeyPair(alias, password);
55 }
56
57 public KeyPair getKeyPair(String alias, char[] password) {
58 InputStream inputStream = null;
59 try {
60 synchronized (lock) {
61 if (store == null) {
62 synchronized (lock) {
63 store = KeyStore.getInstance("jks");
64 inputStream = resource.getInputStream();
65 store.load(inputStream, this.password);
66 }
67 }
68 }
69 RSAPrivateCrtKey key = (RSAPrivateCrtKey) store.getKey(alias, password);
70 RSAPublicKeySpec spec = new RSAPublicKeySpec(key.getModulus(), key.getPublicExponent());
71 PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(spec);
72 return new KeyPair(publicKey, key);
73 }
74 catch (Exception e) {
75 throw new IllegalStateException("Cannot load keys from store: " + resource, e);
76 }
77 finally {
78 try {
79 if (inputStream != null) {
80 inputStream.close();
81 }
82 }
83 catch (IOException e) {
84 logger.warn("Cannot close open stream: ", e);
85 }
86 }
87 }
88 }