s243a

CHKBlock.java (freenet.keys)

Oct 22nd, 2014
307
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.30 KB | None | 0 0
  1. //s243a pearltree node: http://www.pearltrees.com/s243a/chkblock-freenet-client/id12827851
  2. /* This code is part of Freenet. It is distributed under the GNU General
  3.  * Public License, version 2 (or at your option any later version). See
  4.  * http://www.gnu.org/ for further details of the GPL. */
  5. package freenet.keys;
  6.  
  7. import java.security.MessageDigest;
  8. import java.util.Arrays;
  9.  
  10. import com.db4o.ObjectContainer;
  11.  
  12. import freenet.crypt.SHA256;
  13. import freenet.support.Fields;
  14.  
  15. /**
  16.  * @author amphibian
  17.  *
  18.  * CHK plus data. When fed a ClientCHK, can decode into the original
  19.  * data for a client.
  20.  */
  21. public class CHKBlock implements KeyBlock {
  22.  
  23.     final byte[] data;
  24.     final byte[] headers;
  25.     final short hashIdentifier;
  26.     final NodeCHK chk;
  27.     final int hashCode;
  28.     public static final int MAX_LENGTH_BEFORE_COMPRESSION = Integer.MAX_VALUE;
  29.     public static final int TOTAL_HEADERS_LENGTH = 36;
  30.     public static final int DATA_LENGTH = 32768;
  31.     /* Maximum length of compressed payload */
  32.     public static final int MAX_COMPRESSED_DATA_LENGTH = DATA_LENGTH - 4;
  33.    
  34.     @Override
  35.     public String toString() {
  36.         return super.toString()+": chk="+chk;
  37.     }
  38.    
  39.     /**
  40.      * @return The header for this key. DO NOT MODIFY THIS DATA!
  41.      */
  42.     public byte[] getHeaders() {
  43.         return headers;
  44.     }
  45.  
  46.     /**
  47.      * @return The actual data for this key. DO NOT MODIFY THIS DATA!
  48.      */
  49.     public byte[] getData() {
  50.         return data;
  51.     }
  52.    
  53.     public static CHKBlock construct(byte[] data, byte[] header, byte cryptoAlgorithm) throws CHKVerifyException {
  54.         return new CHKBlock(data, header, null, true, cryptoAlgorithm);
  55.      }
  56.    
  57.     public CHKBlock(byte[] data2, byte[] header2, NodeCHK key) throws CHKVerifyException {
  58.         this(data2, header2, key, key.cryptoAlgorithm);
  59.     }
  60.  
  61.     public CHKBlock(byte[] data2, byte[] header2, NodeCHK key, byte cryptoAlgorithm) throws CHKVerifyException {
  62.         this(data2, header2, key, true, cryptoAlgorithm);
  63.     }
  64.    
  65.     public CHKBlock(byte[] data2, byte[] header2, NodeCHK key, boolean verify, byte cryptoAlgorithm) throws CHKVerifyException {
  66.         data = data2;
  67.         headers = header2;
  68.         if(headers.length != TOTAL_HEADERS_LENGTH)
  69.             throw new IllegalArgumentException("Wrong length: "+headers.length+" should be "+TOTAL_HEADERS_LENGTH);
  70.         hashIdentifier = (short)(((headers[0] & 0xff) << 8) + (headers[1] & 0xff));
  71. //        Logger.debug(CHKBlock.class, "Data length: "+data.length+", header length: "+header.length);
  72.         if((key != null) && !verify) {
  73.             this.chk = key;
  74.             hashCode = key.hashCode() ^ Fields.hashCode(data) ^ Fields.hashCode(headers) ^ cryptoAlgorithm;
  75.             return;
  76.         }
  77.        
  78.         // Minimal verification
  79.         // Check the hash
  80.         if(hashIdentifier != HASH_SHA256)
  81.             throw new CHKVerifyException("Hash not SHA-256");
  82.         MessageDigest md = SHA256.getMessageDigest();
  83.        
  84.         md.update(headers);
  85.         md.update(data);
  86.         byte[] hash = md.digest();
  87.         SHA256.returnMessageDigest(md);
  88.         if(key == null) {
  89.             chk = new NodeCHK(hash, cryptoAlgorithm);
  90.         } else {
  91.             chk = key;
  92.             byte[] check = chk.routingKey;
  93.             if(!java.util.Arrays.equals(hash, check)) {
  94.                 throw new CHKVerifyException("Hash does not verify");
  95.             }
  96.             // Otherwise it checks out
  97.         }
  98.         hashCode = chk.hashCode() ^ Fields.hashCode(data) ^ Fields.hashCode(headers) ^ cryptoAlgorithm;
  99.     }
  100.  
  101.     @Override
  102.     public NodeCHK getKey() {
  103.         return chk;
  104.     }
  105.  
  106.     @Override
  107.     public byte[] getRawHeaders() {
  108.         return headers;
  109.     }
  110.  
  111.     @Override
  112.     public byte[] getRawData() {
  113.         return data;
  114.     }
  115.  
  116.     @Override
  117.     public byte[] getPubkeyBytes() {
  118.         return null;
  119.     }
  120.  
  121.     @Override
  122.     public byte[] getFullKey() {
  123.         return getKey().getFullKey();
  124.     }
  125.  
  126.     @Override
  127.     public byte[] getRoutingKey() {
  128.         return getKey().getRoutingKey();
  129.     }
  130.    
  131.     @Override
  132.     public int hashCode() {
  133.         return hashCode;
  134.     }
  135.    
  136.     @Override
  137.     public boolean equals(Object o) {
  138.         if(!(o instanceof CHKBlock)) return false;
  139.         CHKBlock block = (CHKBlock) o;
  140.         if(!chk.equals(block.chk)) return false;
  141.         if(!Arrays.equals(data, block.data)) return false;
  142.         if(!Arrays.equals(headers, block.headers)) return false;
  143.         if(hashIdentifier != block.hashIdentifier) return false;
  144.         return true;
  145.     }
  146.    
  147.     public boolean objectCanNew(ObjectContainer container) {
  148.         /* Storing an SSKBlock is not supported. There are some complications, so lets
  149.          * not implement this since we don't actually use the functionality atm.
  150.          *
  151.          * The major problems are:
  152.          * - In both CHKBlock and SSKBlock, who is responsible for deleting the node keys? We
  153.          *   have to have them in the objects.
  154.          * - In SSKBlock, who is responsible for deleting the DSAPublicKey? And the DSAGroup?
  155.          *   A group might be unique or might be shared between very many SSKs...
  156.          *
  157.          * Especially in the second case, we don't want to just copy every time even for
  158.          * transient uses ... the best solution may be to copy in objectCanNew(), but even
  159.          * then callers to the relevant getter methods may be a worry.
  160.          */
  161.         throw new UnsupportedOperationException("Block set storage in database not supported");
  162.     }
  163.  
  164. }
Add Comment
Please, Sign In to add comment