Changeset 3a4e82f


Ignore:
Timestamp:
Dec 12, 2015 12:14:51 PM (4 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
89bdbed
Parents:
c8aca62d
Message:

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

Location:
router/java/src/net/i2p/router
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • router/java/src/net/i2p/router/StatisticsManager.java

    rc8aca62d r3a4e82f  
    189189            stats.setProperty(FamilyKeyCrypto.OPT_NAME, family);
    190190            String sig = null;
     191            String key = null;
    191192            RouterInfo oldRI = _context.router().getRouterInfo();
    192193            if (oldRI != null) {
    193194                // don't do it if family changed
    194195                if (family.equals(oldRI.getOption(FamilyKeyCrypto.OPT_NAME))) {
    195                     // copy over the signature
     196                    // copy over the pubkey and signature
     197                    key = oldRI.getOption(FamilyKeyCrypto.OPT_KEY);
     198                    if (key != null)
     199                        stats.setProperty(FamilyKeyCrypto.OPT_KEY, key);
    196200                    sig = oldRI.getOption(FamilyKeyCrypto.OPT_SIG);
    197201                    if (sig != null)
     
    199203                }
    200204            }
    201             if (sig == null) {
     205            if (sig == null || key == null) {
    202206                FamilyKeyCrypto fkc = _context.router().getFamilyKeyCrypto();
    203207                if (fkc != null) {
    204208                    try {
    205                         sig = fkc.sign(family, h);
    206                         stats.setProperty(FamilyKeyCrypto.OPT_SIG, sig);
     209                        stats.putAll(fkc.sign(family, h));
    207210                    } catch (GeneralSecurityException gse) {
    208211                        _log.error("Failed to sign router family", gse);
     212                        stats.remove(FamilyKeyCrypto.OPT_KEY);
     213                        stats.remove(FamilyKeyCrypto.OPT_SIG);
    209214                    }
    210215                }
  • router/java/src/net/i2p/router/crypto/FamilyKeyCrypto.java

    rc8aca62d r3a4e82f  
    5555    private static final String KEYSTORE_SUFFIX = ".ks";
    5656    private static final int DEFAULT_KEY_VALID_DAYS = 3652;  // 10 years
    57     // Note that we can't use RSA here, as the b64 sig would exceed the 256 char limit for a Mapping
     57    // Note that we can't use RSA here, as the b64 sig would exceed the 255 char limit for a Mapping
    5858    // Note that we can't use EdDSA here, as keystore doesn't know how, and encoding/decoding is unimplemented
    5959    private static final String DEFAULT_KEY_ALGORITHM = SigType.ECDSA_SHA256_P256.isAvailable() ? "EC" : "DSA";
     
    6363    public static final String OPT_NAME = "family";
    6464    public static final String OPT_SIG = "family.sig";
     65    public static final String OPT_KEY = "family.key";
    6566
    6667
     
    110111     *  @param family non-null, must match that we were initialized with or will throw GSE
    111112     *  @param h non-null
    112      *  @return non-null base 64 signature string to be added to the RI
     113     *  @return non-null options to be added to the RI
    113114     *  @throws GeneralSecurityException on null hash, null or changed family, or signing error
    114115     */
    115     public String sign(String family, Hash h) throws GeneralSecurityException {
    116         if (_privkey == null)
    117             throw new GeneralSecurityException("family name set, must restart router");
     116    public Map<String, String> sign(String family, Hash h) throws GeneralSecurityException {
     117        if (_privkey == null) {
     118            _log.logAlways(Log.WARN, "family name now set, must restart router to generate or load keys");
     119            throw new GeneralSecurityException("family name now set, must restart router to generate or load keys");
     120        }
    118121        if (h == null)
    119122            throw new GeneralSecurityException("null router hash");
    120         if (!_fname.equals(family))
    121             throw new GeneralSecurityException("family name changed, must restart router");
     123        if (!_fname.equals(family)) {
     124            _log.logAlways(Log.WARN, "family name changed, must restart router to generate or load new keys");
     125            throw new GeneralSecurityException("family name changed, must restart router to generate or load new keys");
     126        }
    122127        byte[] nb = DataHelper.getUTF8(_fname);
    123128        int len = nb.length + Hash.HASH_LENGTH;
     
    128133        if (sig == null)
    129134            throw new GeneralSecurityException("sig failed");
    130         return sig.toBase64();
     135        Map<String, String> rv = new HashMap<String, String>(3);
     136        rv.put(OPT_NAME, family);
     137        rv.put(OPT_KEY, _pubkey.getType().getCode() + ";" + _pubkey.toBase64());
     138        rv.put(OPT_SIG, sig.toBase64());
     139        return rv;
    131140    }
    132141
     
    163172            spk = loadCert(name);
    164173            if (spk == null) {
    165                 _negativeCache.add(h);
    166                 if (_log.shouldInfo())
    167                     _log.info("No cert for " + h + ' ' + name);
    168                 return false;
    169             }
     174                // look for a b64 key in the RI
     175                String skey = ri.getOption(OPT_KEY);
     176                if (skey != null) {
     177                    int semi = skey.indexOf(";");
     178                    if (semi > 0) {
     179                        try {
     180                            int code = Integer.parseInt(skey.substring(0, semi));
     181                            SigType type = SigType.getByCode(code);
     182                            if (type != null) {
     183                                byte[] bkey = Base64.decode(skey.substring(semi + 1));
     184                                if (bkey != null) {
     185                                    spk = new SigningPublicKey(type, bkey);
     186                                }
     187                            }
     188                        } catch (NumberFormatException e) {
     189                            if (_log.shouldInfo())
     190                                _log.info("Bad b64 family key: " + ri, e);
     191                        } catch (IllegalArgumentException e) {
     192                            if (_log.shouldInfo())
     193                                _log.info("Bad b64 family key: " + ri, e);
     194                        } catch (ArrayIndexOutOfBoundsException e) {
     195                            if (_log.shouldInfo())
     196                                _log.info("Bad b64 family key: " + ri, e);
     197                        }
     198                    }
     199                }
     200                if (spk == null) {
     201                    _negativeCache.add(h);
     202                    if (_log.shouldInfo())
     203                        _log.info("No cert or valid key for " + h + ' ' + name);
     204                    return false;
     205                }
     206            }
     207        }
     208        if (!spk.getType().isAvailable()) {
     209            _negativeCache.add(h);
     210            if (_log.shouldInfo())
     211                _log.info("Unsupported crypto for sig for " + h);
     212            return false;
    170213        }
    171214        byte[] bsig = Base64.decode(ssig);
Note: See TracChangeset for help on using the changeset viewer.