use of net.i2p.crypto.SigType in project i2p.i2p by i2p.
the class I2PSocketManagerFull method getSigType.
/**
* @param opts may be null
* @since 0.9.21 copied from I2PSocketManagerFactory
*/
private SigType getSigType(Properties opts) {
if (opts != null) {
String st = opts.getProperty(I2PClient.PROP_SIGTYPE);
if (st != null) {
SigType rv = SigType.parseSigType(st);
if (rv != null && rv.isAvailable())
return rv;
if (rv != null)
st = rv.toString();
_log.logAlways(Log.WARN, "Unsupported sig type " + st + ", reverting to " + I2PClient.DEFAULT_SIGTYPE);
// TODO throw instead?
}
}
return I2PClient.DEFAULT_SIGTYPE;
}
use of net.i2p.crypto.SigType in project i2p.i2p by i2p.
the class I2PSocketManagerFull method addSubsession.
/**
* For a server, you must call connect() on the returned object.
* Connecting the primary session does NOT connect any subsessions.
* If the primary session is not connected, connecting a subsession will connect the primary session first.
*
* @return a new subsession, non-null
* @param privateKeyStream null for transient, if non-null must have same encryption keys as primary session
* and different signing keys
* @param opts subsession options if any, may be null
* @since 0.9.21
*/
public I2PSession addSubsession(InputStream privateKeyStream, Properties opts) throws I2PSessionException {
if (privateKeyStream == null) {
// We don't actually need the same pubkey in the dest, just in the LS.
// The dest one is unused. But this is how we find the LS keys
// to reuse in RequestLeaseSetMessageHandler.
ByteArrayOutputStream keyStream = new ByteArrayOutputStream(1024);
try {
SigType type = getSigType(opts);
if (type != SigType.DSA_SHA1) {
// hassle, have to set up the padding and cert, see I2PClientImpl
throw new I2PSessionException("type " + type + " unsupported");
}
PublicKey pub = _session.getMyDestination().getPublicKey();
PrivateKey priv = _session.getDecryptionKey();
SimpleDataStructure[] keys = _context.keyGenerator().generateSigningKeys(type);
pub.writeBytes(keyStream);
// signing pub
keys[0].writeBytes(keyStream);
Certificate.NULL_CERT.writeBytes(keyStream);
priv.writeBytes(keyStream);
// signing priv
keys[1].writeBytes(keyStream);
} catch (GeneralSecurityException e) {
throw new I2PSessionException("Error creating keys", e);
} catch (I2PException e) {
throw new I2PSessionException("Error creating keys", e);
} catch (IOException e) {
throw new I2PSessionException("Error creating keys", e);
} catch (RuntimeException e) {
throw new I2PSessionException("Error creating keys", e);
}
privateKeyStream = new ByteArrayInputStream(keyStream.toByteArray());
}
I2PSession rv = _session.addSubsession(privateKeyStream, opts);
boolean added = _subsessions.add(rv);
if (!added) {
// shouldn't happen
_session.removeSubsession(rv);
throw new I2PSessionException("dup");
}
ConnectionOptions defaultOptions = new ConnectionOptions(opts);
int protocol = defaultOptions.getEnforceProtocol() ? I2PSession.PROTO_STREAMING : I2PSession.PROTO_ANY;
rv.addMuxedSessionListener(_connectionManager.getMessageHandler(), protocol, defaultOptions.getLocalPort());
if (_log.shouldLog(Log.WARN))
_log.warn("Added subsession " + rv);
return rv;
}
use of net.i2p.crypto.SigType in project i2p.i2p by i2p.
the class Packet method readPacket.
/**
* Read the packet from the buffer (starting at the offset) and return
* the number of bytes read.
*
* @param buffer packet buffer containing the data
* @param offset index into the buffer to start readign
* @param length how many bytes within the buffer past the offset are
* part of the packet?
*
* @throws IllegalArgumentException if the data is b0rked
*/
public void readPacket(byte[] buffer, int offset, int length) throws IllegalArgumentException {
if (buffer.length - offset < length)
throw new IllegalArgumentException("len=" + buffer.length + " off=" + offset + " length=" + length);
if (// min header size
length < 22)
throw new IllegalArgumentException("Too small: len=" + buffer.length);
int cur = offset;
setSendStreamId(DataHelper.fromLong(buffer, cur, 4));
cur += 4;
setReceiveStreamId(DataHelper.fromLong(buffer, cur, 4));
cur += 4;
setSequenceNum(DataHelper.fromLong(buffer, cur, 4));
cur += 4;
setAckThrough(DataHelper.fromLong(buffer, cur, 4));
cur += 4;
int numNacks = buffer[cur] & 0xff;
cur++;
if (length < 22 + numNacks * 4)
throw new IllegalArgumentException("Too small with " + numNacks + " nacks: " + length);
if (numNacks > 0) {
long[] nacks = new long[numNacks];
for (int i = 0; i < numNacks; i++) {
nacks[i] = DataHelper.fromLong(buffer, cur, 4);
cur += 4;
}
setNacks(nacks);
} else {
setNacks(null);
}
setResendDelay(buffer[cur] & 0xff);
cur++;
setFlags((int) DataHelper.fromLong(buffer, cur, 2));
cur += 2;
int optionSize = (int) DataHelper.fromLong(buffer, cur, 2);
cur += 2;
if (length < 22 + numNacks * 4 + optionSize)
throw new IllegalArgumentException("Too small with " + numNacks + " nacks and " + optionSize + " options: " + length);
int payloadBegin = cur + optionSize;
int payloadSize = length - payloadBegin;
if ((payloadSize < 0) || (payloadSize > MAX_PAYLOAD_SIZE))
throw new IllegalArgumentException("length: " + length + " offset: " + offset + " begin: " + payloadBegin);
// skip ahead to the payload
// _payload = new ByteArray(new byte[payloadSize]);
_payload = new ByteArray(buffer, payloadBegin, payloadSize);
// ok now lets go back and deal with the options
if (isFlagSet(FLAG_DELAY_REQUESTED)) {
setOptionalDelay((int) DataHelper.fromLong(buffer, cur, 2));
cur += 2;
}
if (isFlagSet(FLAG_FROM_INCLUDED)) {
ByteArrayInputStream bais = new ByteArrayInputStream(buffer, cur, length - cur);
try {
Destination optionFrom = Destination.create(bais);
cur += optionFrom.size();
_optionFrom = optionFrom;
} catch (IOException ioe) {
throw new IllegalArgumentException("Bad from field", ioe);
} catch (DataFormatException dfe) {
throw new IllegalArgumentException("Bad from field", dfe);
}
}
if (isFlagSet(FLAG_MAX_PACKET_SIZE_INCLUDED)) {
setOptionalMaxSize((int) DataHelper.fromLong(buffer, cur, 2));
cur += 2;
}
if (isFlagSet(FLAG_SIGNATURE_INCLUDED)) {
Signature optionSignature;
Destination from = getOptionalFrom();
if (from != null) {
optionSignature = new Signature(from.getSigningPublicKey().getType());
} else {
// super cheat for now, look for correct type,
// assume no more options. If we add to the options
// we will have to ask the manager.
// We will get this wrong for Ed25519, same length as P256...
// See verifySignature() below where we will recast the signature to
// the correct type if necessary
int siglen = payloadBegin - cur;
SigType type = null;
for (SigType t : SigType.values()) {
if (t.getSigLen() == siglen) {
type = t;
break;
}
}
if (type == null) {
if (siglen < Signature.SIGNATURE_BYTES)
throw new IllegalArgumentException("unknown sig type len=" + siglen);
// Hope it's the default type with some unknown options following;
// if not the sig will fail later
type = SigType.DSA_SHA1;
siglen = Signature.SIGNATURE_BYTES;
}
optionSignature = new Signature(type);
}
byte[] buf = new byte[optionSignature.length()];
System.arraycopy(buffer, cur, buf, 0, buf.length);
optionSignature.setData(buf);
setOptionalSignature(optionSignature);
cur += buf.length;
}
}
use of net.i2p.crypto.SigType in project i2p.i2p by i2p.
the class TunnelController method createPrivateKey.
/**
* @return success
*/
private boolean createPrivateKey() {
I2PClient client = I2PClientFactory.createClient();
File keyFile = getPrivateKeyFile();
if (keyFile == null) {
log("No filename specified for the private key");
return false;
}
if (keyFile.exists()) {
// log("Not overwriting existing private keys in " + keyFile.getAbsolutePath());
return true;
} else {
File parent = keyFile.getParentFile();
if ((parent != null) && (!parent.exists()))
parent.mkdirs();
}
FileOutputStream fos = null;
try {
fos = new SecureFileOutputStream(keyFile);
SigType stype = PREFERRED_SIGTYPE;
String st = _config.getProperty(OPT_SIG_TYPE);
if (st != null) {
SigType type = SigType.parseSigType(st);
if (type != null && type.isAvailable())
stype = type;
else
log("Unsupported sig type " + st + ", reverting to " + stype);
}
Destination dest = client.createDestination(fos, stype);
String destStr = dest.toBase64();
log("Private key created and saved in " + keyFile.getAbsolutePath());
log("You should backup this file in a secure place.");
log("New destination: " + destStr);
String b32 = dest.toBase32();
log("Base32: " + b32);
File backupDir = new SecureFile(I2PAppContext.getGlobalContext().getConfigDir(), KEY_BACKUP_DIR);
if (backupDir.isDirectory() || backupDir.mkdir()) {
String name = b32 + '-' + I2PAppContext.getGlobalContext().clock().now() + ".dat";
File backup = new File(backupDir, name);
if (FileUtil.copy(keyFile, backup, false, true)) {
SecureFileOutputStream.setPerms(backup);
log("Private key backup saved to " + backup.getAbsolutePath());
}
}
} catch (I2PException ie) {
if (_log.shouldLog(Log.ERROR))
_log.error("Error creating new destination", ie);
log("Error creating new destination: " + ie.getMessage());
return false;
} catch (IOException ioe) {
if (_log.shouldLog(Log.ERROR))
_log.error("Error creating writing the destination to " + keyFile.getAbsolutePath(), ioe);
log("Error writing the keys to " + keyFile.getAbsolutePath());
return false;
} finally {
if (fos != null)
try {
fos.close();
} catch (IOException ioe) {
}
}
return true;
}
use of net.i2p.crypto.SigType in project i2p.i2p by i2p.
the class BlocklistEntries method main.
/**
* BlocklistEntries [-p keystorepw] input.txt keystore.ks you@mail.i2p
* File format: One entry per line, # starts a comment, ! starts an unblock entry.
* Single IPv4 or IPv6 address only (no mask allowed), or 44-char base 64 router hash.
* See MAX_ENTRIES above.
*/
public static void main(String[] args) {
if (args.length < 3) {
System.err.println("Usage: BlocklistEntries [-p keystorepw] input.txt keystore.ks you@mail.i2p");
System.exit(1);
}
int st;
String kspass;
if (args[0].equals("-p")) {
kspass = args[1];
st = 2;
} else {
kspass = KeyStoreUtil.DEFAULT_KEYSTORE_PASSWORD;
st = 0;
}
String inputFile = args[st++];
String privateKeyFile = args[st++];
String signerName = args[st];
I2PAppContext ctx = new I2PAppContext();
List<String> elist = new ArrayList<String>(16);
List<String> rlist = new ArrayList<String>(4);
StringBuilder buf = new StringBuilder();
long now = System.currentTimeMillis();
String date = RFC3339Date.to3339Date(now);
buf.append(date).append('\n');
;
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(inputFile), "UTF-8"));
String s = null;
while ((s = br.readLine()) != null) {
int index = s.indexOf('#');
if (index == 0)
// comment
continue;
if (index > 0)
s = s.substring(0, index);
s = s.trim();
if (s.length() < 7) {
if (s.length() > 0)
System.err.println("Bad line: " + s);
continue;
}
if (s.startsWith("!")) {
rlist.add(s.substring(1));
} else {
elist.add(s);
buf.append(s).append('\n');
;
}
}
} catch (IOException ioe) {
System.err.println("load error from " + args[0]);
ioe.printStackTrace();
System.exit(1);
} finally {
if (br != null)
try {
br.close();
} catch (IOException ioe) {
}
}
if (elist.isEmpty() && rlist.isEmpty()) {
System.err.println("nothing to sign");
System.exit(1);
}
if (elist.size() > MAX_ENTRIES) {
System.err.println("too many blocks, max is " + MAX_ENTRIES);
System.exit(1);
}
for (String s : rlist) {
buf.append('!').append(s).append('\n');
}
SigningPrivateKey spk = null;
try {
String keypw = "";
while (keypw.length() < 6) {
System.err.print("Enter password for key \"" + signerName + "\": ");
keypw = DataHelper.readLine(System.in);
if (keypw == null) {
System.out.println("\nEOF reading password");
System.exit(1);
}
keypw = keypw.trim();
if (keypw.length() > 0 && keypw.length() < 6)
System.out.println("Key password must be at least 6 characters");
}
File pkfile = new File(privateKeyFile);
PrivateKey pk = KeyStoreUtil.getPrivateKey(pkfile, kspass, signerName, keypw);
if (pk == null) {
System.out.println("Private key for " + signerName + " not found in keystore " + privateKeyFile);
System.exit(1);
}
spk = SigUtil.fromJavaKey(pk);
} catch (GeneralSecurityException gse) {
System.out.println("Error signing input file '" + inputFile + "'");
gse.printStackTrace();
System.exit(1);
} catch (IOException ioe) {
System.out.println("Error signing input file '" + inputFile + "'");
ioe.printStackTrace();
System.exit(1);
}
SigType type = spk.getType();
byte[] data = DataHelper.getUTF8(buf.toString());
Signature ssig = ctx.dsa().sign(data, spk);
if (ssig == null) {
System.err.println("sign failed");
System.exit(1);
}
String bsig = Base64.encode(ssig.getData());
// verify
BlocklistEntries ble = new BlocklistEntries(elist.size());
ble.entries.addAll(elist);
ble.removes.addAll(rlist);
ble.supdated = date;
ble.signer = signerName;
ble.sig = type.getCode() + ":" + bsig;
boolean ok = ble.verify(ctx);
if (!ok) {
System.err.println("verify failed");
System.exit(1);
}
System.out.println(" <i2p:blocklist signer=\"" + signerName + "\" sig=\"" + type.getCode() + ':' + bsig + "\">");
System.out.println(" <updated>" + date + "</updated>");
for (String e : elist) {
System.out.println(" <i2p:block>" + e + "</i2p:block>");
}
for (String e : rlist) {
System.out.println(" <i2p:unblock>" + e + "</i2p:unblock>");
}
System.out.println(" </i2p:blocklist>");
}
Aggregations