Package freenet.crypt

Examples of freenet.crypt.BlockCipher


        Logger.minor(this, error);
      } else {
        Logger.error(this, error);
      }
    }
    BlockCipher c = null;
    try { c = new Rijndael(256, 256); } catch (UnsupportedCipherException e) { throw new RuntimeException(e); }

    final int expectedLength =
      HASH_LENGTH + // HMAC of the cyphertext
      (c.getBlockSize() >> 3) + // IV
      signLength + // the signature
      9 + // ID of packet tracker, plus boolean byte
      8+ // bootID
      1; // znoderefR

    if(payload.length - inputOffset < expectedLength + 3) {
      Logger.error(this, "Packet too short from "+pn.getPeer()+": "+payload.length+" after decryption in JFK(4), should be "+(expectedLength + 3));
      return false;
    }
    byte[] jfkBuffer = pn.getJFKBuffer();
    if(jfkBuffer == null) {
      Logger.normal(this, "We have already handled this message... might be a replay or a bug - "+pn);
      return false;
    }

    byte[] hmac = Arrays.copyOfRange(payload, inputOffset, inputOffset+HASH_LENGTH);
    inputOffset += HASH_LENGTH;

    c.initialize(pn.jfkKe);
    int ivLength = PCFBMode.lengthIV(c);
    int decypheredPayloadOffset = 0;
    // We compute the HMAC of ("R"+cyphertext) : the cyphertext includes the IV!
    byte[] decypheredPayload = Arrays.copyOf(JFK_PREFIX_RESPONDER, JFK_PREFIX_RESPONDER.length + payload.length - inputOffset);
    decypheredPayloadOffset += JFK_PREFIX_RESPONDER.length;
    System.arraycopy(payload, inputOffset, decypheredPayload, decypheredPayloadOffset, payload.length-inputOffset);
    if(!HMAC.verifyWithSHA256(pn.jfkKa, decypheredPayload, hmac)) {
      Logger.normal(this, "The digest-HMAC doesn't match; let's discard the packet - "+pn.getPeer());
      return false;
    }

    // Try to find the HMAC in the cache:
    // If it is already present it indicates duplicate/replayed message4 and we can discard
    // If it's not, we can add it with a timestamp
    byte[] message4Timestamp = null;
    synchronized (authenticatorCache) {
      ByteArrayWrapper hmacBAW = new ByteArrayWrapper(hmac);
      message4Timestamp = authenticatorCache.get(hmacBAW);
      if(message4Timestamp == null) { // normal behaviour
        authenticatorCache.put(hmacBAW, Fields.longToBytes(t1));
      }
    }
    if(message4Timestamp != null) {
      Logger.normal(this, "We got a replayed message4 (first handled at "+TimeUtil.formatTime(t1-Fields.bytesToLong(message4Timestamp))+") from - "+pn);
      return true;
    }

    // Get the IV
    final PCFBMode pk = PCFBMode.create(c, decypheredPayload, decypheredPayloadOffset);
    decypheredPayloadOffset += ivLength;
    // Decrypt the payload
    pk.blockDecipher(decypheredPayload, decypheredPayloadOffset, decypheredPayload.length - decypheredPayloadOffset);
    /*
     * DecipheredData Format:
     * Signature-r,s
     * bootID, znoderef
     */
        byte[] sig = new byte[signLength];
        System.arraycopy(decypheredPayload, decypheredPayloadOffset, sig, 0, signLength);
        decypheredPayloadOffset += signLength;
    byte[] data = new byte[decypheredPayload.length - decypheredPayloadOffset];
    System.arraycopy(decypheredPayload, decypheredPayloadOffset, data, 0, decypheredPayload.length - decypheredPayloadOffset);
    int ptr = 0;
    long trackerID;
    boolean reusedTracker;
    trackerID = Fields.bytesToLong(data, ptr);
    ptr += 8;
    reusedTracker = data[ptr++] != 0;
    long bootID = Fields.bytesToLong(data, ptr);
    ptr += 8;
    byte[] hisRef = Arrays.copyOfRange(data, ptr, data.length);

    // verify the signature
    int dataLen = hisRef.length + 8 + 9;
    int nonceSize = getNonceSize(negType);
    int nonceSizeHashed = (negType > 8 ? HASH_LENGTH : nonceSize);
      byte[] identity = crypto.getIdentity(negType, unknownInitiator);
    byte[] locallyGeneratedText = new byte[nonceSizeHashed + nonceSize + modulusLength * 2 + identity.length + dataLen + pn.jfkMyRef.length];
    int bufferOffset = nonceSizeHashed + nonceSize + modulusLength*2;
    System.arraycopy(jfkBuffer, 0, locallyGeneratedText, 0, bufferOffset);
    System.arraycopy(identity, 0, locallyGeneratedText, bufferOffset, identity.length);
    bufferOffset += identity.length;
    // bootID
    System.arraycopy(data, 0, locallyGeneratedText, bufferOffset, dataLen);
    bufferOffset += dataLen;
    System.arraycopy(pn.jfkMyRef, 0, locallyGeneratedText, bufferOffset, pn.jfkMyRef.length);
      if(negType < 9) { // DSA sig    
          byte[] r = new byte[Node.SIGNATURE_PARAMETER_LENGTH];
          System.arraycopy(sig, 0, r, 0, Node.SIGNATURE_PARAMETER_LENGTH);
          byte[] s = new byte[Node.SIGNATURE_PARAMETER_LENGTH];
          System.arraycopy(sig, Node.SIGNATURE_PARAMETER_LENGTH, s, 0, Node.SIGNATURE_PARAMETER_LENGTH);
          DSASignature remoteSignature = new DSASignature(new NativeBigInteger(1,r), new NativeBigInteger(1,s));
          byte[] messageHash = SHA256.digest(locallyGeneratedText);
          if(!DSA.verify(pn.peerPubKey, remoteSignature, new NativeBigInteger(1, messageHash), false)) {
              String error = "The signature verification has failed!! JFK(4) -"+pn.getPeer()+" message hash "+HexUtil.bytesToHex(messageHash)+" length "+locallyGeneratedText.length+" hisRef "+hisRef.length+" hash "+Fields.hashCode(hisRef)+" myRef "+pn.jfkMyRef.length+" hash "+Fields.hashCode(pn.jfkMyRef)+" boot ID "+bootID;
              Logger.error(this, error);
              return true;
          }
      } else { // ECDSA sig
          if(!ECDSA.verify(Curves.P256, pn.peerECDSAPubKey(), sig, locallyGeneratedText)) {
              Logger.error(this, "The ECDSA signature verification has failed!! JFK(4) - "+pn.getPeer()+" length "+locallyGeneratedText.length+" hisRef "+hisRef.length+" hash "+Fields.hashCode(hisRef)+" myRef "+pn.jfkMyRef.length+" hash "+Fields.hashCode(pn.jfkMyRef)+" boot ID "+bootID);
              return true;
          }
      }

    // Received a packet
    pn.receivedPacket(true, false);

    // Promote if necessary
    boolean dontWant = false;
    if(oldOpennetPeer && pn instanceof OpennetPeerNode /* true */) {
        OpennetPeerNode opn = (OpennetPeerNode) pn;
      OpennetManager opennet = node.getOpennet();
      if(opennet == null) {
        Logger.normal(this, "Dumping incoming old-opennet peer as opennet just turned off: "+pn+".");
        return true;
      }
      /* When an old-opennet-peer connects, add it at the top of the LRU, so that it isn't
       * immediately dropped when there is no droppable peer to drop. If it was dropped
       * from the bottom of the LRU list, we would not have added it to the LRU; so it was
       * somewhere in the middle. */
      if(!opennet.wantPeer(opn, false, false, true, ConnectionType.RECONNECT)) {
        Logger.normal(this, "No longer want peer "+pn+" - dumping it after connecting");
        dontWant = true;
        opennet.purgeOldOpennetPeer(opn);
      }
      // wantPeer will call node.peers.addPeer(), we don't have to.
    }
    if((!dontWant) && !crypto.allowConnection(pn, replyTo.getFreenetAddress())) {
      Logger.normal(this, "Rejecting connection because already have something with the same IP");
      dontWant = true;
    }
    // Set acknowledging method acording to negType
    pn.setAcknowledgeType(negType);

    // We change the key
    BlockCipher ivCipher = null;
    BlockCipher outgoingCipher = null;
    BlockCipher incommingCipher = null;
    try {
      ivCipher = new Rijndael(256, 256);
      outgoingCipher = new Rijndael(256, 256);
      incommingCipher = new Rijndael(256, 256);
    } catch (UnsupportedCipherException e) {
      throw new RuntimeException(e);
    }

    outgoingCipher.initialize(pn.outgoingKey);
    incommingCipher.initialize(pn.incommingKey);
    ivCipher.initialize(pn.ivKey);

    long newTrackerID = pn.completedHandshake(
        bootID, hisRef, 0, hisRef.length, outgoingCipher, pn.outgoingKey, incommingCipher,
        pn.incommingKey, replyTo, false, negType, trackerID, true, reusedTracker, pn.hmacKey,
View Full Code Here


    int nonceSize = getNonceSize(negType);
        // Pre negtype 9 we were sending Ni as opposed to Ni'
        byte[] nonceInitiatorHashed = (negType > 8 ? SHA256.digest(nonceInitiator) : nonceInitiator);
       
    long t1=System.currentTimeMillis();
    BlockCipher c = null;
    try { c = new Rijndael(256, 256); } catch (UnsupportedCipherException e) { throw new RuntimeException(e); }
    KeyAgreementSchemeContext ctx = pn.getKeyAgreementSchemeContext();
    if(ctx == null) return;
    byte[] ourExponential = ctx.getPublicKeyNetworkFormat();
    pn.jfkMyRef = unknownInitiator ? crypto.myCompressedHeavySetupRef() : crypto.myCompressedSetupRef();
    byte[] data = new byte[8 + 8 + pn.jfkMyRef.length];
    int ptr = 0;
    long trackerID;
    trackerID = pn.getReusableTrackerID();
    System.arraycopy(Fields.longToBytes(trackerID), 0, data, ptr, 8);
    ptr += 8;
    if(logMINOR) Logger.minor(this, "Sending tracker ID "+trackerID+" in JFK(3)");
    System.arraycopy(Fields.longToBytes(pn.getOutgoingBootID()), 0, data, ptr, 8);
    ptr += 8;
    System.arraycopy(pn.jfkMyRef, 0, data, ptr, pn.jfkMyRef.length);
    final byte[] message3 = new byte[nonceSize*2 + // nI, nR
                               modulusLength*2 + // g^i, g^r
                               HASH_LENGTH + // authenticator
                               HASH_LENGTH + // HMAC(cyphertext)
                               (c.getBlockSize() >> 3) + // IV
                               signLength + // Signature
                               data.length]; // The bootid+noderef
    int offset = 0;
    // Ni
    System.arraycopy(nonceInitiator, 0, message3, offset, nonceSize);
    offset += nonceSize;
    if(logDEBUG) Logger.debug(this, "We are sending Ni : " + HexUtil.bytesToHex(nonceInitiator));
    // Nr
    System.arraycopy(nonceResponder, 0, message3, offset, nonceSize);
    offset += nonceSize;
    // g^i
    System.arraycopy(ourExponential, 0,message3, offset, ourExponential.length);
    offset += ourExponential.length;
    // g^r
    System.arraycopy(hisExponential, 0,message3, offset, hisExponential.length);
    offset += hisExponential.length;

    // Authenticator
    System.arraycopy(authenticator, 0, message3, offset, HASH_LENGTH);
    offset += HASH_LENGTH;
    /*
     * Digital Signature of the message with the private key belonging to the initiator/responder
     * It is assumed to be non-message recovering
     */
    // save parameters so that we can verify message4
    byte[] toSign = assembleDHParams(nonceInitiatorHashed, nonceResponder, ourExponential, hisExponential, pn.getIdentity(negType), data);
    pn.setJFKBuffer(toSign);
    byte[] sig = (negType < 9 ? crypto.sign(SHA256.digest(toSign)) : crypto.ecdsaSign(toSign));

    byte[] computedExponential;
    if (negType < 8 ) { // Legacy DH
        NativeBigInteger _hisExponential = new NativeBigInteger(1,hisExponential);
        computedExponential= ((DiffieHellmanLightContext)ctx).getHMACKey(_hisExponential);
    }else {
        computedExponential = ((ECDHLightContext)ctx).getHMACKey(ECDH.getPublicKey(hisExponential, ecdhCurveToUse));
    }
    if(logDEBUG) Logger.debug(this, "The shared Master secret is : "+HexUtil.bytesToHex(computedExponential)+ " for " + pn);
    /* 0 is the outgoing key for the initiator, 7 for the responder */
    pn.outgoingKey = computeJFKSharedKey(computedExponential, nonceInitiatorHashed, nonceResponder, "0");
    pn.incommingKey = computeJFKSharedKey(computedExponential, nonceInitiatorHashed, nonceResponder, "7");
    pn.jfkKe = computeJFKSharedKey(computedExponential, nonceInitiatorHashed, nonceResponder, "1");
    pn.jfkKa = computeJFKSharedKey(computedExponential, nonceInitiatorHashed, nonceResponder, "2");

    pn.hmacKey = computeJFKSharedKey(computedExponential, nonceInitiatorHashed, nonceResponder, "3");
    pn.ivKey = computeJFKSharedKey(computedExponential, nonceInitiatorHashed, nonceResponder, "4");
    pn.ivNonce = computeJFKSharedKey(computedExponential, nonceInitiatorHashed, nonceResponder, "5");

    /* Bytes  1-4:  Initial sequence number for the initiator
     * Bytes  5-8:  Initial sequence number for the responder
     * Bytes  9-12: Initial message id for the initiator
     * Bytes 13-16: Initial message id for the responder
     * Note that we are the initiator */
    byte[] sharedData = computeJFKSharedKey(computedExponential, nonceInitiatorHashed, nonceResponder, "6");
      Arrays.fill(computedExponential, (byte)0);
    pn.ourInitialSeqNum = ((sharedData[0] & 0xFF) << 24)
        | ((sharedData[1] & 0xFF) << 16)
        | ((sharedData[2] & 0xFF) << 8)
        | (sharedData[3] & 0xFF);
    pn.theirInitialSeqNum = ((sharedData[4] & 0xFF) << 24)
        | ((sharedData[5] & 0xFF) << 16)
        | ((sharedData[6] & 0xFF) << 8)
        | (sharedData[7] & 0xFF);
    if(negType >= 7) {
      pn.theirInitialMsgID =
        unknownInitiator ? getInitialMessageID(pn.identity) :
          getInitialMessageID(pn.identity, crypto.myIdentity);
      pn.ourInitialMsgID =
        unknownInitiator ? getInitialMessageID(pn.identity) :
          getInitialMessageID(crypto.myIdentity, pn.identity);
    } else {
      pn.ourInitialMsgID= ((sharedData[8] & 0xFF) << 24)
        | ((sharedData[9] & 0xFF) << 16)
        | ((sharedData[10] & 0xFF) << 8)
        | (sharedData[11] & 0xFF);
      pn.theirInitialMsgID= ((sharedData[12] & 0xFF) << 24)
        | ((sharedData[13] & 0xFF) << 16)
        | ((sharedData[14] & 0xFF) << 8)
        | (sharedData[15] & 0xFF);
    }
     
    if(logMINOR)
      Logger.minor(this, "Their initial message ID: "+pn.theirInitialMsgID+" ours "+pn.ourInitialMsgID);


    c.initialize(pn.jfkKe);
    int ivLength = PCFBMode.lengthIV(c);
    byte[] iv = new byte[ivLength];
    node.random.nextBytes(iv);
    PCFBMode pcfb = PCFBMode.create(c, iv);
    int cleartextOffset = 0;
View Full Code Here

  }
 
  /* This checks the output of the sequence number encryption function to
   * make sure it doesn't change accidentally. */
  public void testSequenceNumberEncryption() {
    BlockCipher ivCipher = new Rijndael();
    ivCipher.initialize(new byte[] {
        0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00
    });

    byte[] ivNonce = new byte[16];

    BlockCipher incommingCipher = new Rijndael();
    incommingCipher.initialize(new byte[] {
        0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00
    });
View Full Code Here

    @SuppressWarnings("deprecation") // FIXME Back compatibility, using dubious ciphers; remove eventually.
    public Bucket decodeOld(BucketFactory bf, int maxLength, boolean dontCompress) throws CHKDecodeException, IOException {
        // Overall hash already verified, so first job is to decrypt.
    if(key.cryptoAlgorithm != Key.ALGO_AES_PCFB_256_SHA256)
            throw new UnsupportedOperationException();
        BlockCipher cipher;
        try {
            cipher = new Rijndael(256, 256);
        } catch (UnsupportedCipherException e) {
            // FIXME - log this properly
            throw new Error(e);
        }
        byte[] cryptoKey = key.cryptoKey;
        if(cryptoKey.length < Node.SYMMETRIC_KEY_LENGTH)
            throw new CHKDecodeException("Crypto key too short");
        cipher.initialize(key.cryptoKey);
        PCFBMode pcfb = PCFBMode.create(cipher);
        byte[] headers = block.headers;
        byte[] data = block.data;
    byte[] hbuf = Arrays.copyOfRange(headers, 2, headers.length);
        byte[] dbuf = Arrays.copyOf(data, data.length);
View Full Code Here

        header[plainIV.length+3] = (byte)(dataLength & 0xff);
        // GRRR, java 1.4 does not have any symmetric crypto
        // despite exposing asymmetric and hashes!
       
        // Now encrypt the header, then the data, using the same PCFB instance
        BlockCipher cipher;
        try {
            cipher = new Rijndael(256, 256);
        } catch (UnsupportedCipherException e) {
          Logger.error(ClientCHKBlock.class, "Impossible: "+e, e);
            throw new Error(e);
        }
        cipher.initialize(encKey);
       
        // FIXME CRYPTO plainIV, the hash of the crypto key, is encrypted with a null IV.
        // In other words, it is XORed with E(0).
        // For splitfiles we reuse the same decryption key for multiple blocks; it is derived from the overall hash,
        // or it is set randomly.
View Full Code Here

    System.arraycopy(salt, 0, iv2, 0, 0x10);
    System.arraycopy(iv, 0, iv2, 0x10, 0x10);

    try {
      BlockCipher aes = new Rijndael(256, 256);
      aes.initialize(key);

      return PCFBMode.create(aes, iv2);
    } catch (UnsupportedCipherException e) {
      Logger.error(this, "Rijndael not supported!", e);
      throw new Error("Rijndael not supported!", e);
View Full Code Here

      // create new
      byte[] newsalt = new byte[0x10];
      random.nextBytes(newsalt);
      byte[] diskSalt = newsalt;
      if(masterKey != null) {
        BlockCipher cipher;
        try {
          cipher = new Rijndael(256, 128);
        } catch (UnsupportedCipherException e) {
          throw new Error("Impossible: no Rijndael(256,128): "+e, e);
        }
        cipher.initialize(masterKey);
        diskSalt = new byte[0x10];
        cipher.encipher(newsalt, diskSalt);
        if(logDEBUG)
          Logger.debug(this, "Encrypting with "+HexUtil.bytesToHex(newsalt)+" from "+HexUtil.bytesToHex(diskSalt));
      }
      cipherManager = new CipherManager(newsalt, diskSalt);

      writeConfigFile();
      return true;
    } else {
      try {
        // try to load
        RandomAccessFile raf = new RandomAccessFile(configFile, "r");
        try {
          byte[] salt = new byte[0x10];
          raf.readFully(salt);

          byte[] diskSalt = salt;
          if(masterKey != null) {
            BlockCipher cipher;
            try {
              cipher = new Rijndael(256, 128);
            } catch (UnsupportedCipherException e) {
              throw new Error("Impossible: no Rijndael(256,128): "+e, e);
            }
            cipher.initialize(masterKey);
            salt = new byte[0x10];
            cipher.decipher(diskSalt, salt);
            if(logDEBUG)
              Logger.debug(this, "Encrypting (new) with "+HexUtil.bytesToHex(salt)+" from "+HexUtil.bytesToHex(diskSalt));
          }

          cipherManager = new CipherManager(salt, diskSalt);
View Full Code Here

TOP

Related Classes of freenet.crypt.BlockCipher

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.