Changeset 3ba0fcf


Ignore:
Timestamp:
Feb 7, 2019 8:27:42 PM (18 months ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
5b78b53f
Parents:
7544d0a
Message:

SAM: Support offline keys

Location:
apps/sam/java/src/net/i2p/sam
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • apps/sam/java/src/net/i2p/sam/SAMMessageSession.java

    r7544d0a r3ba0fcf  
    4646     * Initialize a new SAM message-based session.
    4747     *
    48      * @param dest Base64-encoded destination and private keys (same format as PrivateKeyFile)
     48     * @param dest Base64-encoded destination and private keys,
     49     *             and optional offline signature section (same format as PrivateKeyFile)
    4950     * @param props Properties to setup the I2P session
    5051     * @throws IOException
     
    5960     * Initialize a new SAM message-based session.
    6061     *
    61      * @param destStream Input stream containing the destination and private keys (same format as PrivateKeyFile)
     62     * @param destStream Input stream containing the binary destination and private keys,
     63     *                   and optional offline signature section (same format as PrivateKeyFile)
    6264     * @param props Properties to setup the I2P session
    6365     * @throws IOException
  • apps/sam/java/src/net/i2p/sam/SAMStreamSession.java

    r7544d0a r3ba0fcf  
    8686     * Caller MUST call start().
    8787     *
    88      * @param dest Base64-encoded destination and private keys (same format as PrivateKeyFile)
     88     * @param dest Base64-encoded destination and private keys,
     89     *             and optional offline signature section (same format as PrivateKeyFile)
    8990     * @param dir Session direction ("RECEIVE", "CREATE" or "BOTH") or "__v3__" if extended by SAMv3StreamSession
    9091     * @param props Properties to setup the I2P session
     
    102103     * Create a new SAM STREAM session.
    103104     *
    104      * @param destStream Input stream containing the destination and private keys (same format as PrivateKeyFile)
     105     * Caller MUST call start().
     106     *
     107     * @param destStream Input stream containing the binary destination and private keys,
     108     *                   and optional offline signature section (same format as PrivateKeyFile)
    105109     * @param dir Session direction ("RECEIVE", "CREATE" or "BOTH") or "__v3__" if extended by SAMv3StreamSession
    106110     * @param props Properties to setup the I2P session
  • apps/sam/java/src/net/i2p/sam/SAMUtils.java

    r7544d0a r3ba0fcf  
    2424import net.i2p.data.Base64;
    2525import net.i2p.data.DataFormatException;
     26import net.i2p.data.DataHelper;
    2627import net.i2p.data.Destination;
    2728import net.i2p.data.PrivateKey;
     29import net.i2p.data.Signature;
    2830import net.i2p.data.SigningPrivateKey;
     31import net.i2p.data.SigningPublicKey;
    2932
    3033/**
     
    9699
    97100    /**
    98      * Check whether a base64-encoded {dest,privkey,signingprivkey} is valid
     101     * Check whether a base64-encoded {dest,privkey,signingprivkey[,offlinesig]} is valid
     102     *
     103     * This only checks that the length is correct. It does not validate
     104     * for pubkey/privkey match, or check the signatures.
    99105     *
    100106     * @param dest The base64-encoded destination and keys to be checked (same format as PrivateKeyFile)
     
    107113        ByteArrayInputStream destKeyStream = new ByteArrayInputStream(b);
    108114        try {
    109                 Destination d = Destination.create(destKeyStream);
    110                 new PrivateKey().readBytes(destKeyStream);
    111                 SigningPrivateKey spk = new SigningPrivateKey(d.getSigningPublicKey().getType());
    112                 spk.readBytes(destKeyStream);
    113         } catch (DataFormatException e) {
     115            Destination d = Destination.create(destKeyStream);
     116            new PrivateKey().readBytes(destKeyStream);
     117            SigType dtype = d.getSigningPublicKey().getType();
     118            SigningPrivateKey spk = new SigningPrivateKey(dtype);
     119            spk.readBytes(destKeyStream);
     120            if (isOffline(spk)) {
     121                // offlineExpiration
     122                DataHelper.readLong(destKeyStream, 4);
     123                int itype = (int) DataHelper.readLong(destKeyStream, 2);
     124                SigType type = SigType.getByCode(itype);
     125                if (type == null)
     126                    return false;
     127                SigningPublicKey transientSigningPublicKey = new SigningPublicKey(type);
     128                transientSigningPublicKey.readBytes(destKeyStream);
     129                Signature offlineSignature = new Signature(dtype);
     130                offlineSignature.readBytes(destKeyStream);
     131                // replace spk
     132                spk = new SigningPrivateKey(type);
     133                spk.readBytes(destKeyStream);
     134            }
     135        } catch (DataFormatException e) {
    114136                return false;
    115         } catch (IOException e) {
     137        } catch (IOException e) {
    116138                return false;
    117         }
     139        }
    118140        return destKeyStream.available() == 0;
     141    }
     142
     143    /**
     144     *  @since 0.9.39
     145     */
     146    private static boolean isOffline(SigningPrivateKey spk) {
     147        byte[] data = spk.getData();
     148        for (int i = 0; i < data.length; i++) {
     149            if (data[i] != 0)
     150                return false;
     151        }
     152        return true;
    119153    }
    120154
Note: See TracChangeset for help on using the changeset viewer.