1. Project Clover database Sat Feb 2 2019 06:45:20 CET
  2. Package org.xwiki.crypto.store.wiki.internal

File X509KeyWikiStore.java

 

Coverage histogram

../../../../../../img/srcFileCovDistChart9.png
41% of files have more coverage

Code metrics

14
51
7
1
256
142
21
0.41
7.29
7
3

Classes

Class Line # Actions
X509KeyWikiStore 55 51 0% 21 8
0.888888988.9%
 

Contributing tests

This file is covered by 14 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
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    * X509 implementation of {@link org.xwiki.crypto.store.KeyStore} for a wiki store.
48    *
49    * @version $Id: d26fbd43917c653582149d7404ceb622521c3417 $
50    * @since 6.1M2
51    */
52    @Component
53    @Named("X509wiki")
54    @Singleton
 
55    public class X509KeyWikiStore extends AbstractX509WikiStore implements KeyStore
56    {
57    /**
58    * Space where the certificate class is stored.
59    */
60    public static final String PRIVATEKEYCLASS_SPACE = "Crypto";
61   
62    /**
63    * Document name of the certificate class.
64    */
65    public static final String PRIVATEKEYCLASS_NAME = "PrivateKeyClass";
66   
67    /**
68    * Full name of the certificate class.
69    */
70    public static final String PRIVATEKEYCLASS_FULLNAME = PRIVATEKEYCLASS_SPACE + "." + PRIVATEKEYCLASS_NAME;
71   
72    /**
73    * Reference to the signature class.
74    */
75    public static final LocalDocumentReference PRIVATEKEYCLASS =
76    new LocalDocumentReference(PRIVATEKEYCLASS_SPACE, PRIVATEKEYCLASS_NAME);
77   
78    /**
79    * Name of the key field.
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    * The key will be stored in the same document as the certificate. If a document reference is used, this
93    * store could only contain one privateKey since no identifier are associated to a private key. They are linked
94    * to their certificate just by being in the same document as the certificate.
95    *
96    * @param store an {@link org.xwiki.crypto.store.WikiStoreReference} to a document reference or a space reference.
97    */
 
98  5 toggle @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    * The key will be stored in the same document as the certificate. If a document reference is used, this
108    * store could only contain one privateKey since no identifier are associated to a private key. They are linked
109    * to their certificate just by being in the same document as the certificate.
110    *
111    * @param store an {@link org.xwiki.crypto.store.WikiStoreReference} to a document reference or a space reference.
112    */
 
113  1 toggle @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   
 
127  6 toggle 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 store an {@link org.xwiki.crypto.store.WikiStoreReference} to a document reference.
162    */
 
163  3 toggle @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 store an {@link org.xwiki.crypto.store.WikiStoreReference} to a document reference.
173    */
 
174  4 toggle @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 store an {@link org.xwiki.crypto.store.WikiStoreReference} to a space reference.
207    */
 
208  3 toggle @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 store an {@link org.xwiki.crypto.store.WikiStoreReference} to a space reference.
218    */
 
219  4 toggle @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    }