I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Commit 3a4e82f0 authored by zzz's avatar zzz
Browse files

Family: Publish pubkey in RI; use it to verify if no cert available

parent c8aca62d
No related branches found
No related tags found
No related merge requests found
......@@ -188,24 +188,29 @@ public class StatisticsManager {
if (family != null) {
stats.setProperty(FamilyKeyCrypto.OPT_NAME, family);
String sig = null;
String key = null;
RouterInfo oldRI = _context.router().getRouterInfo();
if (oldRI != null) {
// don't do it if family changed
if (family.equals(oldRI.getOption(FamilyKeyCrypto.OPT_NAME))) {
// copy over the signature
// copy over the pubkey and signature
key = oldRI.getOption(FamilyKeyCrypto.OPT_KEY);
if (key != null)
stats.setProperty(FamilyKeyCrypto.OPT_KEY, key);
sig = oldRI.getOption(FamilyKeyCrypto.OPT_SIG);
if (sig != null)
stats.setProperty(FamilyKeyCrypto.OPT_SIG, sig);
}
}
if (sig == null) {
if (sig == null || key == null) {
FamilyKeyCrypto fkc = _context.router().getFamilyKeyCrypto();
if (fkc != null) {
try {
sig = fkc.sign(family, h);
stats.setProperty(FamilyKeyCrypto.OPT_SIG, sig);
stats.putAll(fkc.sign(family, h));
} catch (GeneralSecurityException gse) {
_log.error("Failed to sign router family", gse);
stats.remove(FamilyKeyCrypto.OPT_KEY);
stats.remove(FamilyKeyCrypto.OPT_SIG);
}
}
}
......
......@@ -54,7 +54,7 @@ public class FamilyKeyCrypto {
private static final String KEYSTORE_PREFIX = "family-";
private static final String KEYSTORE_SUFFIX = ".ks";
private static final int DEFAULT_KEY_VALID_DAYS = 3652; // 10 years
// Note that we can't use RSA here, as the b64 sig would exceed the 256 char limit for a Mapping
// Note that we can't use RSA here, as the b64 sig would exceed the 255 char limit for a Mapping
// Note that we can't use EdDSA here, as keystore doesn't know how, and encoding/decoding is unimplemented
private static final String DEFAULT_KEY_ALGORITHM = SigType.ECDSA_SHA256_P256.isAvailable() ? "EC" : "DSA";
private static final int DEFAULT_KEY_SIZE = SigType.ECDSA_SHA256_P256.isAvailable() ? 256 : 1024;
......@@ -62,6 +62,7 @@ public class FamilyKeyCrypto {
private static final String CERT_DIR = "certificates/family";
public static final String OPT_NAME = "family";
public static final String OPT_SIG = "family.sig";
public static final String OPT_KEY = "family.key";
/**
......@@ -109,16 +110,20 @@ public class FamilyKeyCrypto {
*
* @param family non-null, must match that we were initialized with or will throw GSE
* @param h non-null
* @return non-null base 64 signature string to be added to the RI
* @return non-null options to be added to the RI
* @throws GeneralSecurityException on null hash, null or changed family, or signing error
*/
public String sign(String family, Hash h) throws GeneralSecurityException {
if (_privkey == null)
throw new GeneralSecurityException("family name set, must restart router");
public Map<String, String> sign(String family, Hash h) throws GeneralSecurityException {
if (_privkey == null) {
_log.logAlways(Log.WARN, "family name now set, must restart router to generate or load keys");
throw new GeneralSecurityException("family name now set, must restart router to generate or load keys");
}
if (h == null)
throw new GeneralSecurityException("null router hash");
if (!_fname.equals(family))
throw new GeneralSecurityException("family name changed, must restart router");
if (!_fname.equals(family)) {
_log.logAlways(Log.WARN, "family name changed, must restart router to generate or load new keys");
throw new GeneralSecurityException("family name changed, must restart router to generate or load new keys");
}
byte[] nb = DataHelper.getUTF8(_fname);
int len = nb.length + Hash.HASH_LENGTH;
byte[] b = new byte[len];
......@@ -127,7 +132,11 @@ public class FamilyKeyCrypto {
Signature sig = _context.dsa().sign(b, _privkey);
if (sig == null)
throw new GeneralSecurityException("sig failed");
return sig.toBase64();
Map<String, String> rv = new HashMap<String, String>(3);
rv.put(OPT_NAME, family);
rv.put(OPT_KEY, _pubkey.getType().getCode() + ";" + _pubkey.toBase64());
rv.put(OPT_SIG, sig.toBase64());
return rv;
}
/**
......@@ -162,12 +171,46 @@ public class FamilyKeyCrypto {
return false;
spk = loadCert(name);
if (spk == null) {
_negativeCache.add(h);
if (_log.shouldInfo())
_log.info("No cert for " + h + ' ' + name);
return false;
// look for a b64 key in the RI
String skey = ri.getOption(OPT_KEY);
if (skey != null) {
int semi = skey.indexOf(";");
if (semi > 0) {
try {
int code = Integer.parseInt(skey.substring(0, semi));
SigType type = SigType.getByCode(code);
if (type != null) {
byte[] bkey = Base64.decode(skey.substring(semi + 1));
if (bkey != null) {
spk = new SigningPublicKey(type, bkey);
}
}
} catch (NumberFormatException e) {
if (_log.shouldInfo())
_log.info("Bad b64 family key: " + ri, e);
} catch (IllegalArgumentException e) {
if (_log.shouldInfo())
_log.info("Bad b64 family key: " + ri, e);
} catch (ArrayIndexOutOfBoundsException e) {
if (_log.shouldInfo())
_log.info("Bad b64 family key: " + ri, e);
}
}
}
if (spk == null) {
_negativeCache.add(h);
if (_log.shouldInfo())
_log.info("No cert or valid key for " + h + ' ' + name);
return false;
}
}
}
if (!spk.getType().isAvailable()) {
_negativeCache.add(h);
if (_log.shouldInfo())
_log.info("Unsupported crypto for sig for " + h);
return false;
}
byte[] bsig = Base64.decode(ssig);
if (bsig == null) {
_negativeCache.add(h);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment