Storables.java :  » Net » frost-14 » freenet » Java Open Source

Java Open Source » Net » frost 14 
frost 14 » freenet » Storables.java
package freenet;

import java.math.BigInteger;
import java.util.Random;

import freenet.crypt.*;
import freenet.support.Fields;

/** A simple wrapper around a FieldSet for dealing with the Storable.*
  * fields in a Freenet message.
  */
public class Storables extends FieldSet {

    public static final String PREFIX = "Storable";

    public Storables() {
        super();
    }

    private Storables(FieldSet sto) {
        super(sto);
    }

    public static Storables readFrom(FieldSet fs) {
        FieldSet sto = fs.getSet(PREFIX);
        return sto == null ? null : new Storables(sto);
    }

    public void addTo(FieldSet fs) {
        fs.put(PREFIX, this);
    }
    
    /** Checks whether the Storables are legal for a CHK.
      * The following fields, and no others, must be present:
      *     Part-size
      *     Initial-digest
      *     Symmetric-cipher
      *     Document-header
      * Part-size must be greater than zero.
      */
    public boolean isLegalForCHK() {
        return size()               == 4
            && getPartSize()         > 0
            && getInitialDigest()   != null
            && getSymmetricCipher() != null
            && getDocumentHeader()  != null;
    }

    /** Checks whether the Storables are legal for a SVK or derivative.
      * The following fields, and no others, must be present:
      *     Part-size
      *     Initial-digest
      *     Symmetric-cipher
      *     Document-header
      *     Public-key
      *     Document-name (optional)
      *     Signature
      * Part-size must be greater than zero.
      */
    public boolean isLegalForSVK() {
        if (size() == 6)
            {}
        else if (size() != 7 || getDocumentName() == null)
            return false;
        return getPartSize()         > 0
            && getInitialDigest()   != null
            && getSymmetricCipher() != null
            && getDocumentHeader()  != null
            && getPublicKey()       != null
            && getSignature()       != null;
    }
    
    /** Calculates and stores the Public-key and Signature
      * fields in the Storables.
      */
    public void sign(Random r, DSAPrivateKey sk, DSAGroup g) {
        setPublicKey(new DSAPublicKey(g, sk));
        Digest ctx = SHA1.getInstance();
        hashUpdate(ctx, new String[] {"Signature"});
        BigInteger k = Util.generateLargeRandom(80, 160, r);
        BigInteger m = Util.byteArrayToMPI(ctx.digest());
        setSignature(DSA.sign(g, sk, k, m));
    }

    /** Checks the Signature using the Public-key.
      * This may throw NPEs if you haven't checked isLegalSVK() first.
      */
    public boolean verifies() {
        Digest ctx = SHA1.getInstance();
        hashUpdate(ctx, new String[] {"Signature"});
        BigInteger m = Util.byteArrayToMPI(ctx.digest());
        return DSA.verify(getPublicKey(), getSignature(), m);
    }
    
    
    //=======================================================================//
    // the remainder of these methods are tailored get()/set()               //
    // pairs for the various fields                                          //
    //=======================================================================//

    /** @return the part size, or zero
      */
    public long getPartSize() {
        try {
            return Math.max(0, Long.parseLong(get("Part-size"), 16));
        }
        catch (NumberFormatException e) {}
        return 0;
    }

    /** Store the part size, or zero.
      */
    public void setPartSize(long partSize) {
        put("Part-size", Long.toHexString(Math.max(0, partSize)));
    }
    
    /** @return the digest of the first part as a byte array
      */
    public byte[] getInitialDigest() {
        String s = get("Initial-digest");
        return s == null ? null : Fields.hexToBytes(s);
    }

    /** Store the digest of the first part.
      */
    public void setInitialDigest(byte[] digest) {
        put("Initial-digest", Fields.bytesToHex(digest));
    }

    /** @return the string name of the symmetric cipher used for the document
      */
    public String getSymmetricCipher() {
        return get("Symmetric-cipher");
    }

    /** Store the string name of the symmetric cipher used for the document.
      */
    public void setSymmetricCipher(String cipher) {
        put("Symmetric-cipher", cipher);
    }

    /** @return the encrypted header data as a byte array
      */
    public byte[] getDocumentHeader() {
        String s = get("Document-header");
        return s == null ? null : Fields.hexToBytes(s);
    }

    /** Store the encrypted document header.
      */
    public void setDocumentHeader(byte[] header) {
        put("Document-header", Fields.bytesToHex(header));
    }

    private static final String[] ypqgS = {"y","p","q","g"};
    /** @return the signing public key
      */
    public DSAPublicKey getPublicKey() {
        FieldSet fs = getSet("Public-key");
        if (fs == null) return null;
        BigInteger[] ypqg = new BigInteger[4];
        for (int i = 0 ; i < 4 ; i++) {
            String n = fs.get(ypqgS[i]);
            if (n == null)
                return null;
            ypqg[i] = new BigInteger(n, 16);
        }

        return new DSAPublicKey(new DSAGroup(ypqg[1], ypqg[2],
                                             ypqg[3]), ypqg[0]);
    }

    /** Store the signing public key.
      */
    public void setPublicKey(DSAPublicKey pk) {
        FieldSet fs = new FieldSet();
        fs.put("y", pk.getY().toString(16));
        fs.put("p", pk.getP().toString(16));
        fs.put("q", pk.getQ().toString(16));
        fs.put("g", pk.getG().toString(16));
        put("Public-key", fs);
    }

    /** @return the hash of the document name as a byte array.
      */
    public byte[] getDocumentName() {
        String s = get("Document-name");
        return s == null ? null : Fields.hexToBytes(s);
    }

    /** Store the hash of the document's name.
      */
    public void setDocumentName(byte[] hash) {
        put("Document-name", Fields.bytesToHex(hash));
    }

    /** @return the DSA signature
      */
    public DSASignature getSignature() {
        String s = get("Signature");
        return s == null ? null : new DSASignature(s);
    }

    /** Store the DSA signature.
      */
    public void setSignature(DSASignature sig) {
        put("Signature", sig.toString());
    }

}



java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.