Changeset d95d81a for core/java


Ignore:
Timestamp:
Jan 1, 2019 5:14:37 PM (2 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
4ae57f4
Parents:
92ad4d1
Message:

Data: Add support for LS2 multiple encryption keys (proposal 123)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • core/java/src/net/i2p/data/LeaseSet2.java

    r92ad4d1 rd95d81a  
    55import java.io.InputStream;
    66import java.io.OutputStream;
     7import java.util.ArrayList;
     8import java.util.Collections;
     9import java.util.List;
     10import java.util.Map;
    711import java.util.Properties;
    812
     
    3640    // only used for unknown types; else use _encryptionKey.getType()
    3741    private int _encType;
     42    // only used if more than one key, otherwise null
     43    private List<PublicKey> _encryptionKeys;
    3844
    3945    private static final int FLAG_OFFLINE_KEYS = 1;
    4046    private static final int FLAG_UNPUBLISHED = 2;
     47    private static final int MAX_KEYS = 8;
    4148
    4249    public LeaseSet2() {
     
    5865            return null;
    5966        return _options.getProperty(opt);
     67    }
     68
     69    /**
     70     *  Add an encryption key.
     71     */
     72    public void addEncryptionKey(PublicKey key) {
     73        if (_encryptionKey == null) {
     74            setEncryptionKey(key);
     75        } else {
     76            if (_encryptionKeys == null) {
     77                _encryptionKeys = new ArrayList<PublicKey>(4);
     78                _encryptionKeys.add(_encryptionKey);
     79            } else {
     80                if (_encryptionKeys.size() >= MAX_KEYS)
     81                    throw new IllegalStateException();
     82            }
     83            _encryptionKeys.add(key);
     84        }
     85    }
     86
     87    /**
     88     *  This returns all the keys. getEncryptionKey() returns the first one.
     89     *  @return not a copy, do not modify, null if none
     90     */
     91    public List<PublicKey> getEncryptionKeys() {
     92        if (_encryptionKeys != null)
     93            return _encryptionKeys;
     94        if (_encryptionKey != null)
     95            return Collections.singletonList(_encryptionKey);
     96        return null;
    6097    }
    6198
     
    194231        // LS2 part
    195232        _options = DataHelper.readProperties(in);
    196         _encType = (int) DataHelper.readLong(in, 2);
    197         int encLen = (int) DataHelper.readLong(in, 2);
    198         // TODO
    199         if (_encType == 0) {
    200             _encryptionKey = PublicKey.create(in);
    201         } else {
    202             EncType type = EncType.getByCode(_encType);
    203             // type will be null if unknown
    204             byte[] encKey = new byte[encLen];
    205             DataHelper.read(in, encKey);
    206             // this will throw IAE if type is non-null and length is wrong
    207             _encryptionKey = new PublicKey(type, encKey);
     233        int numKeys = in.read();
     234        if (numKeys <= 0 || numKeys > MAX_KEYS)
     235            throw new DataFormatException("Bad key count: " + numKeys);
     236        if (numKeys > 1)
     237            _encryptionKeys = new ArrayList<PublicKey>(numKeys);
     238        for (int i = 0; i < numKeys; i++) {
     239            _encType = (int) DataHelper.readLong(in, 2);
     240            int encLen = (int) DataHelper.readLong(in, 2);
     241            // TODO
     242            if (_encType == 0) {
     243                _encryptionKey = PublicKey.create(in);
     244            } else {
     245                EncType type = EncType.getByCode(_encType);
     246                // type will be null if unknown
     247                byte[] encKey = new byte[encLen];
     248                DataHelper.read(in, encKey);
     249                // this will throw IAE if type is non-null and length is wrong
     250                _encryptionKey = new PublicKey(type, encKey);
     251            }
     252            if (numKeys > 1)
     253                _encryptionKeys.add(_encryptionKey);
    208254        }
    209255        int numLeases = in.read();
     
    247293            DataHelper.writeLong(out, 2, 0);
    248294        }
    249         EncType type = _encryptionKey.getType();
    250         if (type != null) {
    251             DataHelper.writeLong(out, 2, type.getCode());
    252         } else {
    253             DataHelper.writeLong(out, 2, _encType);
    254         }
    255         DataHelper.writeLong(out, 2, _encryptionKey.length());
    256         _encryptionKey.writeBytes(out);
     295        List<PublicKey> keys = getEncryptionKeys();
     296        out.write((byte) keys.size());
     297        for (PublicKey key : keys) {
     298            EncType type = key.getType();
     299            if (type != null) {
     300                DataHelper.writeLong(out, 2, type.getCode());
     301            } else {
     302                DataHelper.writeLong(out, 2, _encType);
     303            }
     304            DataHelper.writeLong(out, 2, key.length());
     305            key.writeBytes(out);
     306        }
    257307        out.write((byte) _leases.size());
    258308        for (Lease lease : _leases) {
     
    434484        buf.append("[LeaseSet2: ");
    435485        buf.append("\n\tDestination: ").append(_destination);
    436         buf.append("\n\tEncryptionKey: ").append(_encryptionKey);
     486        List<PublicKey> keys = getEncryptionKeys();
     487        int sz = keys.size();
     488        buf.append("\n\tEncryption Keys: ").append(sz);
     489        for (int i = 0; i < sz; i++) {
     490            buf.append("\n\tEncryptionKey ").append(i).append(": ").append(keys.get(i));
     491        }
    437492        if (isOffline()) {
    438493            buf.append("\n\tTransient Key: ").append(_transientSigningPublicKey);
     
    441496        }
    442497        buf.append("\n\tOptions: ").append((_options != null) ? _options.size() : 0);
     498        if (_options != null && !_options.isEmpty()) {
     499            for (Map.Entry<Object, Object> e : _options.entrySet()) {
     500                String key = (String) e.getKey();
     501                String val = (String) e.getValue();
     502                buf.append("\n\t\t[").append(key).append("] = [").append(val).append("]");
     503            }
     504        }
    443505        buf.append("\n\tSignature: ").append(_signature);
    444506        buf.append("\n\tPublished: ").append(new java.util.Date(_published));
     
    466528        pkf.createIfAbsent(SigType.EdDSA_SHA512_Ed25519);
    467529        System.out.println("Online test");
    468         java.io.File f2 = new java.io.File("online-leaseset.dat");
     530        java.io.File f2 = new java.io.File("online-ls2.dat");
    469531        test(pkf, f2, false);
    470532        System.out.println("Offline test");
    471         f2 = new java.io.File("offline-leaseset.dat");
     533        f2 = new java.io.File("offline-ls2.dat");
    472534        test(pkf, f2, true);
    473535    }
     
    495557        SimpleDataStructure encKeys[] = net.i2p.crypto.KeyGenerator.getInstance().generatePKIKeys();
    496558        PublicKey pubKey = (PublicKey) encKeys[0];
    497         ls2.setEncryptionKey(pubKey);
     559        ls2.addEncryptionKey(pubKey);
     560        net.i2p.crypto.KeyPair encKeys2 = net.i2p.crypto.KeyGenerator.getInstance().generatePKIKeys(net.i2p.crypto.EncType.ECIES_X25519);
     561        pubKey = encKeys2.getPublic();
     562        ls2.addEncryptionKey(pubKey);
    498563        SigningPrivateKey spk = pkf.getSigningPrivKey();
    499564        if (offline) {
    500             now += 100000;
     565            now += 365*24*60*60*1000L;
    501566            SimpleDataStructure transKeys[] = net.i2p.crypto.KeyGenerator.getInstance().generateSigningKeys(SigType.EdDSA_SHA512_Ed25519);
    502567            SigningPublicKey transientPub = (SigningPublicKey) transKeys[0];
Note: See TracChangeset for help on using the changeset viewer.