Compare commits
1 Commits
i2p-2.8.2-
...
ri-dest-pa
Author | SHA1 | Date | |
---|---|---|---|
![]() |
cfa994cb73 |
@@ -41,6 +41,8 @@ import net.i2p.util.RandomSource;
|
||||
*/
|
||||
public class I2PClientImpl implements I2PClient {
|
||||
|
||||
private static final int PADDING_ENTROPY = 32;
|
||||
|
||||
/**
|
||||
* Create a destination with a DSA 1024/160 signature type and a null certificate.
|
||||
* This is not bound to the I2PClient, you must supply the data back again
|
||||
@@ -93,9 +95,23 @@ public class I2PClientImpl implements I2PClient {
|
||||
*/
|
||||
public Destination createDestination(OutputStream destKeyStream, Certificate cert) throws I2PException, IOException {
|
||||
Destination d = new Destination();
|
||||
Object keypair[] = KeyGenerator.getInstance().generatePKIKeypair();
|
||||
PublicKey publicKey = (PublicKey) keypair[0];
|
||||
PrivateKey privateKey = (PrivateKey) keypair[1];
|
||||
// Don't generate ElGamal keys anymore, they are unused since release 0.6 2005
|
||||
//Object keypair[] = KeyGenerator.getInstance().generatePKIKeypair();
|
||||
//PublicKey publicKey = (PublicKey) keypair[0];
|
||||
//PrivateKey privateKey = (PrivateKey) keypair[1];
|
||||
// repeating pattern to be used in pubkey and padding, so the
|
||||
// destination will be compressible
|
||||
byte[] rand = new byte[PADDING_ENTROPY];
|
||||
RandomSource.getInstance().nextBytes(rand);
|
||||
byte[] pk = new byte[PublicKey.KEYSIZE_BYTES];
|
||||
for (int i = 0; i < pk.length; i += PADDING_ENTROPY) {
|
||||
System.arraycopy(rand, 0, pk, i, Math.min(PADDING_ENTROPY, pk.length - i));
|
||||
}
|
||||
PublicKey publicKey = new PublicKey(pk);
|
||||
// private key all zeros, just for I2CP
|
||||
byte[] prk = new byte[PrivateKey.KEYSIZE_BYTES];
|
||||
PrivateKey privateKey = new PrivateKey(prk);
|
||||
|
||||
SimpleDataStructure signingKeys[];
|
||||
if (cert.getCertificateType() == Certificate.CERTIFICATE_TYPE_KEY) {
|
||||
KeyCertificate kcert = cert.toKeyCertificate();
|
||||
@@ -118,8 +134,12 @@ public class I2PClientImpl implements I2PClient {
|
||||
SigType type = kcert.getSigType();
|
||||
int len = type.getPubkeyLen();
|
||||
if (len < 128) {
|
||||
byte[] pad = new byte[128 - len];
|
||||
RandomSource.getInstance().nextBytes(pad);
|
||||
int padLen = 128 - len;
|
||||
byte[] pad = new byte[padLen];
|
||||
// pad with the same pattern as in the public key
|
||||
for (int i = 0; i < padLen; i += PADDING_ENTROPY) {
|
||||
System.arraycopy(rand, 0, pad, i, Math.min(PADDING_ENTROPY, padLen - i));
|
||||
}
|
||||
d.setPadding(pad);
|
||||
} else if (len > 128) {
|
||||
System.arraycopy(signingPubKey.getData(), 128, kcert.getPayload(), KeyCertificate.HEADER_LENGTH, len - 128);
|
||||
|
@@ -67,6 +67,13 @@ import net.i2p.util.SecureFileOutputStream;
|
||||
* Total: 663 or more bytes for ElGamal, may be smaller for other enc. types
|
||||
*</pre>
|
||||
*
|
||||
* Destination encryption keys have been unused since 0.6 (2005).
|
||||
* As of 0.9.57, new Destination encryption public keys are simply random data.
|
||||
* Encryption private keys are all zeros.
|
||||
*
|
||||
* This class is extended by net.i2p.data.router.RouterPrivateKeyFile.
|
||||
* RouterIdentity encryption keys ARE used and must be valid.
|
||||
*
|
||||
* @author welterde, zzz
|
||||
*/
|
||||
|
||||
@@ -84,6 +91,8 @@ public class PrivateKeyFile {
|
||||
private SigningPrivateKey _transientSigningPrivKey;
|
||||
private SigningPublicKey _transientSigningPubKey;
|
||||
|
||||
private static final int PADDING_ENTROPY = 32;
|
||||
|
||||
/**
|
||||
* Create a new PrivateKeyFile, or modify an existing one, with various
|
||||
* types of Certificates.
|
||||
@@ -591,9 +600,25 @@ public class PrivateKeyFile {
|
||||
// no support for this in I2PClient,
|
||||
// so we modify code from CreateRouterInfoJob.createRouterInfo()
|
||||
I2PAppContext ctx = I2PAppContext.getGlobalContext();
|
||||
KeyPair keypair = ctx.keyGenerator().generatePKIKeys(ptype);
|
||||
PublicKey pub = keypair.getPublic();
|
||||
PrivateKey priv = keypair.getPrivate();
|
||||
byte[] rand = new byte[PADDING_ENTROPY];
|
||||
ctx.random().nextBytes(rand);
|
||||
PublicKey pub;
|
||||
PrivateKey priv;
|
||||
if (getClass().equals(PrivateKeyFile.class)) {
|
||||
// destinations don't use the encryption key
|
||||
byte[] bpub = new byte[ptype.getPubkeyLen()];
|
||||
for (int i = 0; i < bpub.length; i += PADDING_ENTROPY) {
|
||||
System.arraycopy(rand, 0, bpub, i, Math.min(PADDING_ENTROPY, bpub.length - i));
|
||||
}
|
||||
pub = new PublicKey(ptype, bpub);
|
||||
byte[] bpriv = new byte[ptype.getPrivkeyLen()];
|
||||
priv = new PrivateKey(ptype, bpriv);
|
||||
} else {
|
||||
// routers use the encryption key
|
||||
KeyPair keypair = ctx.keyGenerator().generatePKIKeys(ptype);
|
||||
pub = keypair.getPublic();
|
||||
priv = keypair.getPrivate();
|
||||
}
|
||||
SimpleDataStructure signingKeypair[] = ctx.keyGenerator().generateSigningKeys(type);
|
||||
SigningPublicKey spub = (SigningPublicKey)signingKeypair[0];
|
||||
SigningPrivateKey spriv = (SigningPrivateKey)signingKeypair[1];
|
||||
@@ -611,7 +636,9 @@ public class PrivateKeyFile {
|
||||
(PublicKey.KEYSIZE_BYTES - pub.length());
|
||||
if (padLen > 0) {
|
||||
padding = new byte[padLen];
|
||||
ctx.random().nextBytes(padding);
|
||||
for (int i = 0; i < padLen; i += PADDING_ENTROPY) {
|
||||
System.arraycopy(rand, 0, padding, i, Math.min(PADDING_ENTROPY, padLen - i));
|
||||
}
|
||||
} else {
|
||||
padding = null;
|
||||
}
|
||||
@@ -793,6 +820,8 @@ public class PrivateKeyFile {
|
||||
}
|
||||
|
||||
/**
|
||||
* Private key may be all zeros for Destinations as of 0.9.57
|
||||
*
|
||||
* @return null on error or if not initialized
|
||||
*/
|
||||
public PrivateKey getPrivKey() {
|
||||
@@ -941,6 +970,8 @@ public class PrivateKeyFile {
|
||||
* Verify that the PublicKey matches the PrivateKey, and
|
||||
* the SigningPublicKey matches the SigningPrivateKey.
|
||||
*
|
||||
* NOTE this will fail for Destinations containing random padding for the enc. key
|
||||
*
|
||||
* @return success
|
||||
* @since 0.9.16
|
||||
*/
|
||||
|
@@ -64,6 +64,7 @@ public class CreateRouterInfoJob extends JobImpl {
|
||||
private static final EncType DEFAULT_ENCTYPE = (VersionComparator.comp(CoreVersion.VERSION, "0.9.49") >= 0) ?
|
||||
EncType.ECIES_X25519 :
|
||||
EncType.ELGAMAL_2048;
|
||||
private static final int PADDING_ENTROPY = 32;
|
||||
|
||||
CreateRouterInfoJob(RouterContext ctx, Job next) {
|
||||
super(ctx);
|
||||
@@ -129,7 +130,14 @@ public class CreateRouterInfoJob extends JobImpl {
|
||||
(PublicKey.KEYSIZE_BYTES - pubkey.length());
|
||||
if (padLen > 0) {
|
||||
padding = new byte[padLen];
|
||||
ctx.random().nextBytes(padding);
|
||||
if (padLen <= PADDING_ENTROPY) {
|
||||
ctx.random().nextBytes(padding);
|
||||
} else {
|
||||
ctx.random().nextBytes(padding, 0, PADDING_ENTROPY);
|
||||
for (int i = PADDING_ENTROPY; i < padLen; i += PADDING_ENTROPY) {
|
||||
System.arraycopy(padding, 0, padding, i, Math.min(PADDING_ENTROPY, padLen - i));
|
||||
}
|
||||
}
|
||||
ident.setPadding(padding);
|
||||
} else {
|
||||
padding = null;
|
||||
|
Reference in New Issue
Block a user