/** * Writes 6 files: router.info (standard RI format), router.keys.dat, and 4 individual key files * under keyBackup/ * * <p>router.keys.dat file format: This is the same "eepPriv.dat" format used by the client code, * as documented in PrivateKeyFile. * * <p>Old router.keys file format: Note that this is NOT the same "eepPriv.dat" format used by the * client code. * * <pre> * - Private key (256 bytes) * - Signing Private key (20 bytes) * - Public key (256 bytes) * - Signing Public key (128 bytes) * Total 660 bytes * </pre> * * Caller must hold Router.routerInfoFileLock. */ RouterInfo createRouterInfo() { SigType type = getSigTypeConfig(getContext()); RouterInfo info = new RouterInfo(); OutputStream fos1 = null; try { info.setAddresses(getContext().commSystem().createAddresses()); // not necessary, in constructor // info.setPeers(new HashSet()); info.setPublished(getCurrentPublishDate(getContext())); Object keypair[] = getContext().keyGenerator().generatePKIKeypair(); PublicKey pubkey = (PublicKey) keypair[0]; PrivateKey privkey = (PrivateKey) keypair[1]; SimpleDataStructure signingKeypair[] = getContext().keyGenerator().generateSigningKeys(type); SigningPublicKey signingPubKey = (SigningPublicKey) signingKeypair[0]; SigningPrivateKey signingPrivKey = (SigningPrivateKey) signingKeypair[1]; RouterIdentity ident = new RouterIdentity(); Certificate cert = createCertificate(getContext(), signingPubKey); ident.setCertificate(cert); ident.setPublicKey(pubkey); ident.setSigningPublicKey(signingPubKey); byte[] padding; int padLen = SigningPublicKey.KEYSIZE_BYTES - signingPubKey.length(); if (padLen > 0) { padding = new byte[padLen]; getContext().random().nextBytes(padding); ident.setPadding(padding); } else { padding = null; } info.setIdentity(ident); Properties stats = getContext().statPublisher().publishStatistics(ident.getHash()); info.setOptions(stats); info.sign(signingPrivKey); if (!info.isValid()) throw new DataFormatException("RouterInfo we just built is invalid: " + info); // remove router.keys (new File(getContext().getRouterDir(), KEYS_FILENAME)).delete(); // write router.info File ifile = new File(getContext().getRouterDir(), INFO_FILENAME); fos1 = new BufferedOutputStream(new SecureFileOutputStream(ifile)); info.writeBytes(fos1); // write router.keys.dat File kfile = new File(getContext().getRouterDir(), KEYS2_FILENAME); PrivateKeyFile pkf = new PrivateKeyFile(kfile, pubkey, signingPubKey, cert, privkey, signingPrivKey, padding); pkf.write(); getContext().keyManager().setKeys(pubkey, privkey, signingPubKey, signingPrivKey); if (_log.shouldLog(Log.INFO)) _log.info( "Router info created and stored at " + ifile.getAbsolutePath() + " with private keys stored at " + kfile.getAbsolutePath() + " [" + info + "]"); getContext().router().eventLog().addEvent(EventLog.REKEYED, ident.calculateHash().toBase64()); } catch (GeneralSecurityException gse) { _log.log(Log.CRIT, "Error building the new router information", gse); } catch (DataFormatException dfe) { _log.log(Log.CRIT, "Error building the new router information", dfe); } catch (IOException ioe) { _log.log(Log.CRIT, "Error writing out the new router information", ioe); } finally { if (fos1 != null) try { fos1.close(); } catch (IOException ioe) { } } return info; }