/// <summary> /// Encode interest using NDN-TLV and return the encoding. /// </summary> /// /// <param name="interest">The Interest object to encode.</param> /// <param name="signedPortionBeginOffset">name component and ends just before the final name component (which is assumed to be a signature for a signed interest).</param> /// <param name="signedPortionEndOffset">name component and ends just before the final name component (which is assumed to be a signature for a signed interest).</param> /// <returns>A Blob containing the encoding.</returns> public override Blob encodeInterest(Interest interest, int[] signedPortionBeginOffset, int[] signedPortionEndOffset) { TlvEncoder encoder = new TlvEncoder(); int saveLength = encoder.getLength(); // Encode backwards. encoder.writeOptionalNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.SelectedDelegation, interest.getSelectedDelegationIndex()); try { Blob linkWireEncoding = interest.getLinkWireEncoding(this); if (!linkWireEncoding.isNull()) // Encode the entire link as is. encoder.writeBuffer(linkWireEncoding.buf()); } catch (EncodingException ex) { throw new Exception(ex.Message); } encoder.writeOptionalNonNegativeIntegerTlvFromDouble( net.named_data.jndn.encoding.tlv.Tlv.InterestLifetime, interest.getInterestLifetimeMilliseconds()); // Encode the Nonce as 4 bytes. if (interest.getNonce().size() == 0) { // This is the most common case. Generate a nonce. ByteBuffer nonce = ILOG.J2CsMapping.NIO.ByteBuffer.allocate(4); random_.nextBytes(nonce.array()); encoder.writeBlobTlv(net.named_data.jndn.encoding.tlv.Tlv.Nonce, nonce); } else if (interest.getNonce().size() < 4) { ByteBuffer nonce_0 = ILOG.J2CsMapping.NIO.ByteBuffer.allocate(4); // Copy existing nonce bytes. nonce_0.put(interest.getNonce().buf()); // Generate random bytes for remaining bytes in the nonce. for (int i = 0; i < 4 - interest.getNonce().size(); ++i) nonce_0.put((byte) random_.Next()); nonce_0.flip(); encoder.writeBlobTlv(net.named_data.jndn.encoding.tlv.Tlv.Nonce, nonce_0); } else if (interest.getNonce().size() == 4) // Use the nonce as-is. encoder.writeBlobTlv(net.named_data.jndn.encoding.tlv.Tlv.Nonce, interest.getNonce().buf()); else { // Truncate. ByteBuffer nonce_1 = interest.getNonce().buf(); // buf() returns a new ByteBuffer, so we can change its limit. nonce_1.limit(nonce_1.position() + 4); encoder.writeBlobTlv(net.named_data.jndn.encoding.tlv.Tlv.Nonce, nonce_1); } encodeSelectors(interest, encoder); int[] tempSignedPortionBeginOffset = new int[1]; int[] tempSignedPortionEndOffset = new int[1]; encodeName(interest.getName(), tempSignedPortionBeginOffset, tempSignedPortionEndOffset, encoder); int signedPortionBeginOffsetFromBack = encoder.getLength() - tempSignedPortionBeginOffset[0]; int signedPortionEndOffsetFromBack = encoder.getLength() - tempSignedPortionEndOffset[0]; encoder.writeTypeAndLength(net.named_data.jndn.encoding.tlv.Tlv.Interest, encoder.getLength() - saveLength); signedPortionBeginOffset[0] = encoder.getLength() - signedPortionBeginOffsetFromBack; signedPortionEndOffset[0] = encoder.getLength() - signedPortionEndOffsetFromBack; return new Blob(encoder.getOutput(), false); }
/// <summary> /// An internal method to encode signature as the appropriate form of /// SignatureInfo in NDN-TLV. /// </summary> /// /// <param name="signature">An object of a subclass of Signature to encode.</param> /// <param name="encoder">The TlvEncoder to receive the encoding.</param> private void encodeSignatureInfo(Signature signature, TlvEncoder encoder) { if (signature is GenericSignature) { // Handle GenericSignature separately since it has the entire encoding. Blob encoding = ((GenericSignature) signature) .getSignatureInfoEncoding(); // Do a test decoding to sanity check that it is valid TLV. try { TlvDecoder decoder = new TlvDecoder(encoding.buf()); int endOffset = decoder.readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.SignatureInfo); decoder.readNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.SignatureType); decoder.finishNestedTlvs(endOffset); } catch (EncodingException ex) { throw new Exception( "The GenericSignature encoding is not a valid NDN-TLV SignatureInfo: " + ex.Message); } encoder.writeBuffer(encoding.buf()); return; } int saveLength = encoder.getLength(); // Encode backwards. if (signature is Sha256WithRsaSignature) { if (((Sha256WithRsaSignature) signature).getValidityPeriod() .hasPeriod()) encodeValidityPeriod( ((Sha256WithRsaSignature) signature) .getValidityPeriod(), encoder); encodeKeyLocator(net.named_data.jndn.encoding.tlv.Tlv.KeyLocator, ((Sha256WithRsaSignature) signature).getKeyLocator(), encoder); encoder.writeNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.SignatureType, net.named_data.jndn.encoding.tlv.Tlv.SignatureType_SignatureSha256WithRsa); } else if (signature is Sha256WithEcdsaSignature) { if (((Sha256WithEcdsaSignature) signature).getValidityPeriod() .hasPeriod()) encodeValidityPeriod( ((Sha256WithEcdsaSignature) signature) .getValidityPeriod(), encoder); encodeKeyLocator(net.named_data.jndn.encoding.tlv.Tlv.KeyLocator, ((Sha256WithEcdsaSignature) signature).getKeyLocator(), encoder); encoder.writeNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.SignatureType, net.named_data.jndn.encoding.tlv.Tlv.SignatureType_SignatureSha256WithEcdsa); } else if (signature is HmacWithSha256Signature) { encodeKeyLocator(net.named_data.jndn.encoding.tlv.Tlv.KeyLocator, ((HmacWithSha256Signature) signature).getKeyLocator(), encoder); encoder.writeNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.SignatureType, net.named_data.jndn.encoding.tlv.Tlv.SignatureType_SignatureHmacWithSha256); } else if (signature is DigestSha256Signature) encoder.writeNonNegativeIntegerTlv(net.named_data.jndn.encoding.tlv.Tlv.SignatureType, net.named_data.jndn.encoding.tlv.Tlv.SignatureType_DigestSha256); else throw new Exception( "encodeSignatureInfo: Unrecognized Signature object type"); encoder.writeTypeAndLength(net.named_data.jndn.encoding.tlv.Tlv.SignatureInfo, encoder.getLength() - saveLength); }