1 18 package org.apache.geronimo.security.ca; 19 20 import java.io.File ; 21 import java.io.FileInputStream ; 22 import java.io.FileOutputStream ; 23 import java.io.IOException ; 24 import java.math.BigInteger ; 25 import java.net.URI ; 26 import java.security.cert.Certificate ; 27 import java.security.cert.CertificateFactory ; 28 import java.security.cert.X509Certificate ; 29 import java.util.Properties ; 30 31 import org.apache.commons.logging.Log; 32 import org.apache.commons.logging.LogFactory; 33 import org.apache.geronimo.gbean.AbstractName; 34 import org.apache.geronimo.gbean.GBeanInfo; 35 import org.apache.geronimo.gbean.GBeanInfoBuilder; 36 import org.apache.geronimo.gbean.GBeanLifecycle; 37 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; 38 import org.apache.geronimo.kernel.Kernel; 39 import org.apache.geronimo.management.geronimo.CertificateStore; 40 import org.apache.geronimo.management.geronimo.CertificateStoreException; 41 import org.apache.geronimo.system.serverinfo.ServerInfo; 42 import org.apache.geronimo.util.CaUtils; 43 44 49 50 public class FileCertificateStore implements CertificateStore, GBeanLifecycle { 51 private static final Log log = LogFactory.getLog(FileCertificateStore.class); 52 53 private ServerInfo serverInfo; 54 private Kernel kernel; 55 private AbstractName abstractName; 56 private URI directoryPath; 57 58 private static final String SERIAL_NUMBER_FILE = "highest-serial-number.txt"; 60 private static final String CERT_FILE_SUFFIX = ".txt"; 62 private static final String CA_CERT_FILE = "ca-cert.txt"; 64 private static final String CHALLENGE_FILENAME = "challenge.properties"; 66 private static final String CHALLENGE_FILE_HEADER = "Challenge File"; 67 68 private File storeDir = null; 70 71 private File highestSerialFile = null; 73 private BigInteger highestSerialNumber = null; 75 private Properties challenges = null; 77 78 82 public FileCertificateStore(ServerInfo serverInfo, URI directoryPath, Kernel kernel, AbstractName abstractName) { 83 this.serverInfo = serverInfo; 84 this.kernel = kernel; 85 this.abstractName = abstractName; 86 this.directoryPath = directoryPath; 87 } 88 93 public void storeCertificate(Certificate cert) throws CertificateStoreException { 94 BigInteger sNo = ((X509Certificate )cert).getSerialNumber(); 95 File certFile = new File (storeDir, sNo+CERT_FILE_SUFFIX); 96 try { 97 if(sNo.compareTo(getHighestSerialNumber()) == 1) { 99 setHighestSerialNumber(sNo); 102 } 103 104 FileOutputStream fout = new FileOutputStream (certFile); 106 CaUtils.storeInBase64(fout, cert.getEncoded(), CaUtils.CERT_HEADER, CaUtils.CERT_FOOTER, CaUtils.B64_LINE_SIZE); 107 fout.close(); 108 } catch (Exception e) { 109 throw new CertificateStoreException("Error while storing certificate.", e); 110 } 111 } 112 113 118 public Certificate getCertificate(BigInteger sNo) throws CertificateStoreException { 119 File certFile = new File (storeDir, sNo+CERT_FILE_SUFFIX); 120 if(!certFile.exists()) { 121 throw new CertificateStoreException("No certificate with serial number "+sNo+" found."); 123 } 124 125 try { 127 FileInputStream fin = new FileInputStream (certFile); 128 CertificateFactory certFac = CertificateFactory.getInstance("X.509"); 129 Certificate cert = certFac.generateCertificate(fin); 130 fin.close(); 131 return cert; 132 } catch (Exception e) { 133 throw new CertificateStoreException("Error while retrieving certificate.", e); 134 } 135 } 136 137 142 public String getCertificateBase64Text(BigInteger sNo) throws CertificateStoreException { 143 File certFile = new File (storeDir, sNo+CERT_FILE_SUFFIX); 144 if(!certFile.exists()) { 145 throw new CertificateStoreException("No certificate with serial number "+sNo+" found."); 146 } 147 FileInputStream fin; 148 try { 149 fin = new FileInputStream (certFile); 150 byte[] data = new byte[fin.available()]; 151 fin.read(data); 152 fin.close(); 153 return new String (data); 154 } catch (Exception e) { 155 throw new CertificateStoreException("Error while retrieving certificate.", e); 156 } 157 } 158 159 162 public BigInteger getHighestSerialNumber() throws CertificateStoreException{ 163 if(highestSerialNumber == null) { 164 try { 166 FileInputStream finp = new FileInputStream (highestSerialFile); 167 byte[] data = new byte[finp.available()]; 168 finp.read(data); 169 finp.close(); 170 highestSerialNumber = new BigInteger (new String (data).trim()); 171 } catch (Exception e) { 172 throw new CertificateStoreException("Error while getting serial number.", e); 173 } 174 } 175 return highestSerialNumber; 176 } 177 178 182 public BigInteger getNextSerialNumber() throws CertificateStoreException{ 183 setHighestSerialNumber(getHighestSerialNumber().add(BigInteger.ONE)); 184 return highestSerialNumber; 185 } 186 187 192 public boolean containsCertificate(BigInteger sNo) { 193 File certFile = new File (storeDir, sNo+CERT_FILE_SUFFIX); 194 return certFile.exists(); 195 } 196 197 201 private void setHighestSerialNumber(BigInteger sNo) throws CertificateStoreException{ 202 try { 203 highestSerialNumber = sNo; 204 FileOutputStream fout = new FileOutputStream (highestSerialFile); 205 fout.write(highestSerialNumber.toString().getBytes()); 206 fout.close(); 207 } catch (Exception e) { 208 throw new CertificateStoreException("Error while setting highest serial number.", e); 209 } 210 } 211 212 216 public boolean storeCACertificate(Certificate cert) throws CertificateStoreException{ 217 FileOutputStream fout = null; 218 try { 219 fout = new FileOutputStream (new File (storeDir, CA_CERT_FILE)); 220 CaUtils.storeInBase64(fout, cert.getEncoded(), CaUtils.CERT_HEADER, CaUtils.CERT_FOOTER, CaUtils.B64_LINE_SIZE); 221 fout.close(); 222 return true; 223 } catch (Exception e) { 224 throw new CertificateStoreException("Exception in storing CA certificate", e); 225 } 226 } 227 228 231 public Certificate getCACertificate() throws CertificateStoreException { 232 FileInputStream fin = null; 233 try { 234 fin = new FileInputStream (new File (storeDir, CA_CERT_FILE)); 235 CertificateFactory certFac = CertificateFactory.getInstance("X.509"); 236 Certificate cert = certFac.generateCertificate(fin); 237 fin.close(); 238 return cert; 239 } catch (Exception e) { 240 throw new CertificateStoreException("Exception in getting CA certificate", e); 241 } 242 } 243 244 249 public boolean setCertificateChallenge(BigInteger sNo, String challenge) { 250 if(challenges == null) { 251 loadChallenges(); 252 } 253 if(!challenges.containsKey(sNo.toString())) { 254 challenges.setProperty(sNo.toString(), challenge); 255 storeChallenges(); 256 return true; 257 } 258 return false; 259 } 260 261 264 private void storeChallenges() { 265 if(challenges == null) loadChallenges(); 266 File chFile = new File (storeDir, CHALLENGE_FILENAME); 267 FileOutputStream fout = null; 268 try { 269 fout = new FileOutputStream (chFile); 270 challenges.store(fout, CHALLENGE_FILE_HEADER); 271 fout.close(); 272 } catch (Exception e) { 273 log.error("Exceptions while storing challenges file. File = "+chFile.getAbsolutePath(), e); 274 } 275 276 } 277 278 281 private void loadChallenges() { 282 File chFile = new File (storeDir, CHALLENGE_FILENAME); 283 FileInputStream fin = null; 284 try { 285 if(!chFile.exists()) 286 chFile.createNewFile(); 287 fin = new FileInputStream (chFile); 288 challenges = new Properties (); 289 challenges.load(fin); 290 fin.close(); 291 } catch (IOException e) { 292 log.error("Exceptions while loading challenges file. File = "+chFile.getAbsolutePath(), e); 293 } 294 } 295 296 public void doFail() { 297 } 298 299 public void doStart() throws Exception { 300 serverInfo.resolveServer(directoryPath); 301 URI dirURI; 302 if (serverInfo != null) { 303 dirURI = serverInfo.resolve(directoryPath); 304 } else { 305 dirURI = directoryPath; 306 } 307 if (!dirURI.getScheme().equals("file")) { 308 throw new IllegalStateException ("FileCertificateStore must have a root that's a local directory (not " + dirURI + ")"); 309 } 310 storeDir = new File (dirURI); 311 if(!storeDir.exists()) { 312 storeDir.mkdirs(); 313 log.debug("Created directory "+storeDir.getAbsolutePath()); 314 } else if(!storeDir.isDirectory() || !storeDir.canRead()) { 315 throw new IllegalStateException ("FileCertificateStore must have a root that's a valid readable directory (not " + storeDir.getAbsolutePath() + ")"); 316 } 317 log.debug("CertificateStore directory is " + storeDir.getAbsolutePath()); 318 highestSerialFile = new File (storeDir, SERIAL_NUMBER_FILE); 319 if(!highestSerialFile.exists()) { 320 try { 323 setHighestSerialNumber(BigInteger.ZERO); 324 } catch(CertificateStoreException e) { 325 log.error("Error initializing certificate store. storeDir="+storeDir, e); 326 } 327 } 328 loadChallenges(); 329 } 330 331 public void doStop() throws Exception { 332 } 333 334 public static final GBeanInfo GBEAN_INFO; 335 336 static { 337 GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(FileCertificateStore.class, "CertificateStore"); 338 infoFactory.addAttribute("directoryPath", URI .class, true, false); 339 infoFactory.addAttribute("kernel", Kernel.class, false); 340 infoFactory.addAttribute("abstractName", AbstractName.class, false); 341 infoFactory.addReference("ServerInfo", ServerInfo.class, NameFactory.GERONIMO_SERVICE); 342 infoFactory.addInterface(CertificateStore.class); 343 infoFactory.setConstructor(new String []{"ServerInfo", "directoryPath", "kernel", "abstractName"}); 344 345 GBEAN_INFO = infoFactory.getBeanInfo(); 346 } 347 348 public static GBeanInfo getGBeanInfo() { 349 return GBEAN_INFO; 350 } 351 } 352 | Popular Tags |