use of net.i2p.crypto.SigType in project i2p.i2p by i2p.
the class I2PDatagramDissector method loadI2PDatagram.
/**
* Load an I2P repliable datagram into the dissector.
* Does NOT verify the signature.
*
* Format is:
* <ol>
* <li>Destination (387+ bytes)
* <li>Signature (40+ bytes, type and length as implied by signing key type in the Destination)
* <li>Payload
* </ol>
*
* For DSA_SHA1 Destinations, the signature is of the SHA-256 Hash of the payload.
*
* As of 0.9.14, for non-DSA_SHA1 Destinations, the signature is of the payload itself.
*
* @param dgram non-null I2P repliable datagram to be loaded
*
* @throws DataFormatException If there's an error in the datagram format
*/
public void loadI2PDatagram(byte[] dgram) throws DataFormatException {
// set invalid(very important!)
this.valid = false;
if (dgram.length < MIN_DGRAM_SIZE)
throw new DataFormatException("repliable datagram too small: " + dgram.length);
ByteArrayInputStream dgStream = new ByteArrayInputStream(dgram);
try {
// read destination
rxDest = Destination.create(dgStream);
SigType type = rxDest.getSigningPublicKey().getType();
if (type == null)
throw new DataFormatException("unsupported sig type");
rxSign = new Signature(type);
// read signature
rxSign.readBytes(dgStream);
// read payload
rxPayloadLen = dgStream.read(rxPayload);
// calculate the hash of the payload
if (type == SigType.DSA_SHA1) {
if (rxHash == null)
rxHash = new byte[Hash.HASH_LENGTH];
// non-caching
hashGen.calculateHash(rxPayload, 0, rxPayloadLen, rxHash, 0);
// assert this.hashGen.calculateHash(this.extractPayload()).equals(this.rxHash);
} else {
rxHash = null;
}
} catch (IOException e) {
// log.error("Error loading datagram", e);
throw new DataFormatException("Error loading datagram", e);
// } catch(AssertionError e) {
// Log log = I2PAppContext.getGlobalContext().logManager().getLog(I2PDatagramDissector.class);
// log.error("Assertion failed!", e);
}
// _log.debug("Datagram payload size: " + rxPayloadLen + "; content:\n"
// + HexDump.dump(rxPayload, 0, rxPayloadLen));
}
use of net.i2p.crypto.SigType in project i2p.i2p by i2p.
the class I2PDatagramMaker method makeI2PDatagram.
/**
* Make a repliable I2P datagram containing the specified payload.
*
* Format is:
* <ol>
* <li>Destination (387+ bytes)
* <li>Signature (40+ bytes, type and length as implied by signing key type in the Destination)
* <li>Payload
* </ol>
*
* Maximum datagram size is 32768, so maximum payload size is 32341, or less for
* non-DSA_SHA1 destinations. Practical maximum is a few KB less due to
* ElGamal/AES overhead. 10 KB or less is recommended for best results.
*
* For DSA_SHA1 Destinations, the signature is of the SHA-256 Hash of the payload.
*
* As of 0.9.14, for non-DSA_SHA1 Destinations, the signature is of the payload itself.
*
* @param payload non-null Bytes to be contained in the I2P datagram.
* @return null on error
* @throws IllegalArgumentException if payload is too big
* @throws IllegalStateException if Destination signature type unsupported
*/
public byte[] makeI2PDatagram(byte[] payload) {
sxDGram.reset();
try {
sxDGram.write(sxDestBytes);
SigType type = sxPrivKey.getType();
if (type == null)
throw new IllegalStateException("Unsupported sig type");
Signature sig;
if (type == SigType.DSA_SHA1) {
byte[] hash = SimpleByteCache.acquire(Hash.HASH_LENGTH);
// non-caching
hashGen.calculateHash(payload, 0, payload.length, hash, 0);
sig = dsaEng.sign(hash, sxPrivKey);
SimpleByteCache.release(hash);
} else {
sig = dsaEng.sign(payload, sxPrivKey);
}
sig.writeBytes(sxDGram);
sxDGram.write(payload);
if (sxDGram.size() > DGRAM_BUFSIZE)
throw new IllegalArgumentException("Too big");
return sxDGram.toByteArray();
} catch (IOException e) {
Log log = I2PAppContext.getGlobalContext().logManager().getLog(I2PDatagramMaker.class);
log.error("Caught IOException", e);
return null;
} catch (DataFormatException e) {
Log log = I2PAppContext.getGlobalContext().logManager().getLog(I2PDatagramMaker.class);
log.error("Caught DataFormatException", e);
return null;
}
}
use of net.i2p.crypto.SigType in project i2p.i2p by i2p.
the class BlockfileNamingService method addDestination.
/**
* Add a Destination to an existing hostname's entry in the addressbook.
*
* This does not prevent adding b32. Caller must check.
*
* @param options NamingService-specific, may be null
* @return success
* @since 0.9.26
*/
@Override
public boolean addDestination(String hostname, Destination d, Properties options) {
if (!_isVersion4)
return putIfAbsent(hostname, d, options);
List<Properties> storedOptions = new ArrayList<Properties>(4);
synchronized (_bf) {
// We use lookupAll2(), not lookupAll(), because if hostname starts with www.,
// we do not want to read in from the
// non-www hostname and then copy it to a new www hostname.
List<Destination> dests = lookupAll2(hostname, options, storedOptions);
if (dests == null)
return put(hostname, d, options, false);
if (dests.contains(d))
return false;
if (dests.size() >= MAX_DESTS_PER_HOST)
return false;
List<Destination> newDests = new ArrayList<Destination>(dests.size() + 1);
newDests.addAll(dests);
// TODO better sort by sigtype preference.
// For now, non-DSA at the front, DSA at the end
SigType type = d.getSigningPublicKey().getType();
if (type != SigType.DSA_SHA1 && type.isAvailable()) {
newDests.add(0, d);
storedOptions.add(0, options);
} else {
newDests.add(d);
storedOptions.add(options);
}
return put(hostname, newDests, storedOptions, false);
}
}
use of net.i2p.crypto.SigType in project i2p.i2p by i2p.
the class SigningPublicKey method toTypedKey.
/**
* Up-convert this from an untyped (type 0) SPK to a typed SPK based on the Key Cert given.
* The type of the returned key will be null if the kcert sigtype is null.
*
* @throws IllegalArgumentException if this is already typed to a different type
* @since 0.9.12
*/
public SigningPublicKey toTypedKey(KeyCertificate kcert) {
if (_data == null)
throw new IllegalStateException();
SigType newType = kcert.getSigType();
if (_type == newType)
return this;
if (_type != SigType.DSA_SHA1)
throw new IllegalArgumentException("Cannot convert " + _type + " to " + newType);
// unknown type, keep the 128 bytes of data
if (newType == null)
return new SigningPublicKey(null, _data);
int newLen = newType.getPubkeyLen();
int ctype = kcert.getCryptoTypeCode();
if (ctype == 0) {
// prohibit excess key data
// TODO non-zero crypto type if added
int sz = 7;
if (newLen > KEYSIZE_BYTES)
sz += newLen - KEYSIZE_BYTES;
if (kcert.size() != sz)
throw new IllegalArgumentException("Excess data in key certificate");
}
if (newLen == KEYSIZE_BYTES)
return new SigningPublicKey(newType, _data);
byte[] newData = new byte[newLen];
if (newLen < KEYSIZE_BYTES) {
// right-justified
System.arraycopy(_data, _data.length - newLen, newData, 0, newLen);
} else {
// full 128 bytes + fragment in kcert
System.arraycopy(_data, 0, newData, 0, _data.length);
System.arraycopy(kcert.getPayload(), KeyCertificate.HEADER_LENGTH, newData, _data.length, newLen - _data.length);
}
return new SigningPublicKey(newType, newData);
}
use of net.i2p.crypto.SigType in project i2p.i2p by i2p.
the class SigningPublicKey method getPadding.
/**
* Get the portion of this (type 0) SPK that is really padding based on the Key Cert type given,
* if any
*
* @return leading padding length > 0 or null if no padding or type is unknown
* @throws IllegalArgumentException if this is already typed to a different type
* @since 0.9.12
*/
public byte[] getPadding(KeyCertificate kcert) {
if (_data == null)
throw new IllegalStateException();
SigType newType = kcert.getSigType();
if (_type == newType || newType == null)
return null;
if (_type != SigType.DSA_SHA1)
throw new IllegalStateException("Cannot convert " + _type + " to " + newType);
int newLen = newType.getPubkeyLen();
if (newLen >= KEYSIZE_BYTES)
return null;
int padLen = KEYSIZE_BYTES - newLen;
byte[] pad = new byte[padLen];
System.arraycopy(_data, 0, pad, 0, padLen);
return pad;
}
Aggregations