1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
|
17 |
|
|
18 |
|
|
19 |
|
|
20 |
|
package org.xwiki.crypto.store.wiki.internal; |
21 |
|
|
22 |
|
import java.io.IOException; |
23 |
|
|
24 |
|
import javax.inject.Inject; |
25 |
|
import javax.inject.Named; |
26 |
|
import javax.inject.Singleton; |
27 |
|
|
28 |
|
import org.xwiki.component.annotation.Component; |
29 |
|
import org.xwiki.crypto.AsymmetricKeyFactory; |
30 |
|
import org.xwiki.crypto.password.PrivateKeyPasswordBasedEncryptor; |
31 |
|
import org.xwiki.crypto.pkix.params.CertifiedKeyPair; |
32 |
|
import org.xwiki.crypto.pkix.params.CertifiedPublicKey; |
33 |
|
import org.xwiki.crypto.pkix.params.x509certificate.X509CertifiedPublicKey; |
34 |
|
import org.xwiki.crypto.store.CertificateStoreException; |
35 |
|
import org.xwiki.crypto.store.KeyStore; |
36 |
|
import org.xwiki.crypto.store.KeyStoreException; |
37 |
|
import org.xwiki.crypto.store.StoreReference; |
38 |
|
import org.xwiki.crypto.store.wiki.internal.query.CertificateObjectReference; |
39 |
|
import org.xwiki.model.reference.LocalDocumentReference; |
40 |
|
|
41 |
|
import com.xpn.xwiki.XWikiContext; |
42 |
|
import com.xpn.xwiki.XWikiException; |
43 |
|
import com.xpn.xwiki.doc.XWikiDocument; |
44 |
|
import com.xpn.xwiki.objects.BaseObject; |
45 |
|
|
46 |
|
|
47 |
|
@link |
48 |
|
|
49 |
|
@version |
50 |
|
@since |
51 |
|
|
52 |
|
@Component |
53 |
|
@Named("X509wiki") |
54 |
|
@Singleton |
|
|
| 88.9% |
Uncovered Elements: 8 (72) |
Complexity: 21 |
Complexity Density: 0.41 |
|
55 |
|
public class X509KeyWikiStore extends AbstractX509WikiStore implements KeyStore |
56 |
|
{ |
57 |
|
|
58 |
|
|
59 |
|
|
60 |
|
public static final String PRIVATEKEYCLASS_SPACE = "Crypto"; |
61 |
|
|
62 |
|
|
63 |
|
|
64 |
|
|
65 |
|
public static final String PRIVATEKEYCLASS_NAME = "PrivateKeyClass"; |
66 |
|
|
67 |
|
|
68 |
|
|
69 |
|
|
70 |
|
public static final String PRIVATEKEYCLASS_FULLNAME = PRIVATEKEYCLASS_SPACE + "." + PRIVATEKEYCLASS_NAME; |
71 |
|
|
72 |
|
|
73 |
|
|
74 |
|
|
75 |
|
public static final LocalDocumentReference PRIVATEKEYCLASS = |
76 |
|
new LocalDocumentReference(PRIVATEKEYCLASS_SPACE, PRIVATEKEYCLASS_NAME); |
77 |
|
|
78 |
|
|
79 |
|
|
80 |
|
|
81 |
|
public static final String PRIVATEKEYCLASS_PROP_KEY = "key"; |
82 |
|
|
83 |
|
@Inject |
84 |
|
private PrivateKeyPasswordBasedEncryptor encryptor; |
85 |
|
|
86 |
|
@Inject |
87 |
|
private AsymmetricKeyFactory keyFactory; |
88 |
|
|
89 |
|
|
90 |
|
@inheritDoc |
91 |
|
|
92 |
|
|
93 |
|
|
94 |
|
|
95 |
|
|
96 |
|
@param@link |
97 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
98 |
5 |
@Override... |
99 |
|
public void store(StoreReference store, CertifiedKeyPair keyPair) throws KeyStoreException |
100 |
|
{ |
101 |
5 |
storeKeyPair(store, keyPair.getCertificate(), keyPair.getPrivateKey().getEncoded()); |
102 |
|
} |
103 |
|
|
104 |
|
|
105 |
|
@inheritDoc |
106 |
|
|
107 |
|
|
108 |
|
|
109 |
|
|
110 |
|
|
111 |
|
@param@link |
112 |
|
|
|
|
| 80% |
Uncovered Elements: 1 (5) |
Complexity: 2 |
Complexity Density: 0.4 |
|
113 |
1 |
@Override... |
114 |
|
public void store(StoreReference store, CertifiedKeyPair keyPair, byte[] password) throws KeyStoreException |
115 |
|
{ |
116 |
1 |
byte[] key; |
117 |
|
|
118 |
1 |
try { |
119 |
1 |
key = this.encryptor.encrypt(password, keyPair.getPrivateKey()); |
120 |
|
} catch (Exception e) { |
121 |
0 |
throw new KeyStoreException("Error while encrypting private key to store a key pair in [" + store + "]", e); |
122 |
|
} |
123 |
|
|
124 |
1 |
storeKeyPair(store, keyPair.getCertificate(), key); |
125 |
|
} |
126 |
|
|
|
|
| 80% |
Uncovered Elements: 3 (15) |
Complexity: 5 |
Complexity Density: 0.38 |
|
127 |
6 |
private void storeKeyPair(StoreReference store, CertifiedPublicKey certificate, byte[] privateKey)... |
128 |
|
throws KeyStoreException |
129 |
|
{ |
130 |
6 |
XWikiContext context = getXWikiContext(); |
131 |
6 |
XWikiDocument document; |
132 |
|
|
133 |
6 |
try { |
134 |
6 |
document = storeCertificate(store, certificate, context); |
135 |
|
} catch (CertificateStoreException e) { |
136 |
0 |
throw new KeyStoreException("Error while preparing certificate to store a key pair in [" + store + "]", e); |
137 |
|
} |
138 |
|
|
139 |
6 |
try { |
140 |
6 |
BaseObject obj = document.getXObject(PRIVATEKEYCLASS); |
141 |
|
|
142 |
6 |
if (obj == null) { |
143 |
5 |
obj = document.newXObject(PRIVATEKEYCLASS, context); |
144 |
|
} |
145 |
|
|
146 |
6 |
obj.setLargeStringValue(PRIVATEKEYCLASS_PROP_KEY, getEncoder().encode(privateKey, 64)); |
147 |
|
|
148 |
6 |
context.getWiki().saveDocument(document, context); |
149 |
|
} catch (IOException e) { |
150 |
0 |
throw new KeyStoreException("Error while preparing private key for [" |
151 |
|
+ document.getDocumentReference() + "]", e); |
152 |
|
} catch (XWikiException e) { |
153 |
0 |
throw new KeyStoreException("Error while saving key pair for [" |
154 |
|
+ document.getDocumentReference() + "]", e); |
155 |
|
} |
156 |
|
} |
157 |
|
|
158 |
|
|
159 |
|
@inheritDoc |
160 |
|
|
161 |
|
@param@link |
162 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
163 |
3 |
@Override... |
164 |
|
public CertifiedKeyPair retrieve(StoreReference store) throws KeyStoreException |
165 |
|
{ |
166 |
3 |
return retrieve(store, (byte[]) null); |
167 |
|
} |
168 |
|
|
169 |
|
|
170 |
|
@inheritDoc |
171 |
|
|
172 |
|
@param@link |
173 |
|
|
|
|
| 94.1% |
Uncovered Elements: 1 (17) |
Complexity: 5 |
Complexity Density: 0.38 |
|
174 |
4 |
@Override... |
175 |
|
public CertifiedKeyPair retrieve(StoreReference store, byte[] password) throws KeyStoreException |
176 |
|
{ |
177 |
4 |
XWikiContext context = getXWikiContext(); |
178 |
|
|
179 |
4 |
try { |
180 |
4 |
XWikiDocument document = context.getWiki().getDocument(getDocumentReference(store), context); |
181 |
4 |
BaseObject certObj = document.getXObject(X509CertificateWikiStore.CERTIFICATECLASS); |
182 |
4 |
BaseObject pkObj = document.getXObject(PRIVATEKEYCLASS); |
183 |
|
|
184 |
4 |
if (pkObj == null || certObj == null) { |
185 |
2 |
return null; |
186 |
|
} |
187 |
|
|
188 |
2 |
byte[] cert = getEncoder().decode( |
189 |
|
certObj.getLargeStringValue(X509CertificateWikiStore.CERTIFICATECLASS_PROP_CERTIFICATE)); |
190 |
2 |
byte[] key = getEncoder().decode(pkObj.getLargeStringValue(PRIVATEKEYCLASS_PROP_KEY)); |
191 |
|
|
192 |
2 |
if (password != null) { |
193 |
1 |
return new CertifiedKeyPair( |
194 |
|
this.encryptor.decrypt(password, key), getCertificateFactory().decode(cert)); |
195 |
|
} else { |
196 |
1 |
return new CertifiedKeyPair(this.keyFactory.fromPKCS8(key), getCertificateFactory().decode(cert)); |
197 |
|
} |
198 |
|
} catch (Exception e) { |
199 |
0 |
throw new KeyStoreException("Failed to retrieved private key from [" + store + "]"); |
200 |
|
} |
201 |
|
} |
202 |
|
|
203 |
|
|
204 |
|
@inheritDoc |
205 |
|
|
206 |
|
@param@link |
207 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
208 |
3 |
@Override... |
209 |
|
public CertifiedKeyPair retrieve(StoreReference store, CertifiedPublicKey publicKey) throws KeyStoreException |
210 |
|
{ |
211 |
3 |
return retrieve(store, publicKey, null); |
212 |
|
} |
213 |
|
|
214 |
|
|
215 |
|
@inheritDoc |
216 |
|
|
217 |
|
@param@link |
218 |
|
|
|
|
| 88% |
Uncovered Elements: 3 (25) |
Complexity: 6 |
Complexity Density: 0.35 |
|
219 |
4 |
@Override... |
220 |
|
public CertifiedKeyPair retrieve(StoreReference store, CertifiedPublicKey certificate, byte[] password) |
221 |
|
throws KeyStoreException |
222 |
|
{ |
223 |
4 |
if (!(certificate instanceof X509CertifiedPublicKey)) { |
224 |
0 |
throw new IllegalArgumentException("Certificate should be X509 certificates."); |
225 |
|
} |
226 |
|
|
227 |
4 |
X509CertifiedPublicKey publicKey = (X509CertifiedPublicKey) certificate; |
228 |
4 |
XWikiContext context = getXWikiContext(); |
229 |
|
|
230 |
4 |
try { |
231 |
4 |
CertificateObjectReference certRef = findCertificate(store, publicKey); |
232 |
|
|
233 |
4 |
if (certRef == null) { |
234 |
1 |
return null; |
235 |
|
} |
236 |
|
|
237 |
3 |
XWikiDocument document = getDocument(store, certRef, context); |
238 |
3 |
BaseObject pkObj = document.getXObject(PRIVATEKEYCLASS); |
239 |
|
|
240 |
3 |
if (pkObj == null) { |
241 |
1 |
return null; |
242 |
|
} |
243 |
|
|
244 |
2 |
byte[] key = getEncoder().decode(pkObj.getLargeStringValue(PRIVATEKEYCLASS_PROP_KEY)); |
245 |
|
|
246 |
2 |
if (password != null) { |
247 |
1 |
return new CertifiedKeyPair(this.encryptor.decrypt(password, key), certificate); |
248 |
|
} else { |
249 |
1 |
return new CertifiedKeyPair(this.keyFactory.fromPKCS8(key), certificate); |
250 |
|
} |
251 |
|
} catch (Exception e) { |
252 |
0 |
throw new KeyStoreException("Failed to retrieved private key for certificate [" |
253 |
|
+ publicKey.getSubject().getName() + "]"); |
254 |
|
} |
255 |
|
} |
256 |
|
} |