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 { ...@@ -188,24 +188,29 @@ public class StatisticsManager {
if (family != null) { if (family != null) {
stats.setProperty(FamilyKeyCrypto.OPT_NAME, family); stats.setProperty(FamilyKeyCrypto.OPT_NAME, family);
String sig = null; String sig = null;
String key = null;
RouterInfo oldRI = _context.router().getRouterInfo(); RouterInfo oldRI = _context.router().getRouterInfo();
if (oldRI != null) { if (oldRI != null) {
// don't do it if family changed // don't do it if family changed
if (family.equals(oldRI.getOption(FamilyKeyCrypto.OPT_NAME))) { 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); sig = oldRI.getOption(FamilyKeyCrypto.OPT_SIG);
if (sig != null) if (sig != null)
stats.setProperty(FamilyKeyCrypto.OPT_SIG, sig); stats.setProperty(FamilyKeyCrypto.OPT_SIG, sig);
} }
} }
if (sig == null) { if (sig == null || key == null) {
FamilyKeyCrypto fkc = _context.router().getFamilyKeyCrypto(); FamilyKeyCrypto fkc = _context.router().getFamilyKeyCrypto();
if (fkc != null) { if (fkc != null) {
try { try {
sig = fkc.sign(family, h); stats.putAll(fkc.sign(family, h));
stats.setProperty(FamilyKeyCrypto.OPT_SIG, sig);
} catch (GeneralSecurityException gse) { } catch (GeneralSecurityException gse) {
_log.error("Failed to sign router family", 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 { ...@@ -54,7 +54,7 @@ public class FamilyKeyCrypto {
private static final String KEYSTORE_PREFIX = "family-"; private static final String KEYSTORE_PREFIX = "family-";
private static final String KEYSTORE_SUFFIX = ".ks"; private static final String KEYSTORE_SUFFIX = ".ks";
private static final int DEFAULT_KEY_VALID_DAYS = 3652; // 10 years 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 // 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 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; private static final int DEFAULT_KEY_SIZE = SigType.ECDSA_SHA256_P256.isAvailable() ? 256 : 1024;
...@@ -62,6 +62,7 @@ public class FamilyKeyCrypto { ...@@ -62,6 +62,7 @@ public class FamilyKeyCrypto {
private static final String CERT_DIR = "certificates/family"; private static final String CERT_DIR = "certificates/family";
public static final String OPT_NAME = "family"; public static final String OPT_NAME = "family";
public static final String OPT_SIG = "family.sig"; public static final String OPT_SIG = "family.sig";
public static final String OPT_KEY = "family.key";
/** /**
...@@ -109,16 +110,20 @@ public class FamilyKeyCrypto { ...@@ -109,16 +110,20 @@ public class FamilyKeyCrypto {
* *
* @param family non-null, must match that we were initialized with or will throw GSE * @param family non-null, must match that we were initialized with or will throw GSE
* @param h non-null * @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 * @throws GeneralSecurityException on null hash, null or changed family, or signing error
*/ */
public String sign(String family, Hash h) throws GeneralSecurityException { public Map<String, String> sign(String family, Hash h) throws GeneralSecurityException {
if (_privkey == null) if (_privkey == null) {
throw new GeneralSecurityException("family name set, must restart router"); _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) if (h == null)
throw new GeneralSecurityException("null router hash"); throw new GeneralSecurityException("null router hash");
if (!_fname.equals(family)) if (!_fname.equals(family)) {
throw new GeneralSecurityException("family name changed, must restart router"); _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); byte[] nb = DataHelper.getUTF8(_fname);
int len = nb.length + Hash.HASH_LENGTH; int len = nb.length + Hash.HASH_LENGTH;
byte[] b = new byte[len]; byte[] b = new byte[len];
...@@ -127,7 +132,11 @@ public class FamilyKeyCrypto { ...@@ -127,7 +132,11 @@ public class FamilyKeyCrypto {
Signature sig = _context.dsa().sign(b, _privkey); Signature sig = _context.dsa().sign(b, _privkey);
if (sig == null) if (sig == null)
throw new GeneralSecurityException("sig failed"); 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 { ...@@ -162,12 +171,46 @@ public class FamilyKeyCrypto {
return false; return false;
spk = loadCert(name); spk = loadCert(name);
if (spk == null) { if (spk == null) {
_negativeCache.add(h); // look for a b64 key in the RI
if (_log.shouldInfo()) String skey = ri.getOption(OPT_KEY);
_log.info("No cert for " + h + ' ' + name); if (skey != null) {
return false; 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); byte[] bsig = Base64.decode(ssig);
if (bsig == null) { if (bsig == null) {
_negativeCache.add(h); _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