示例#1
0
        /// <summary>
        /// Create a deep copy of the given data object, including a clone of the
        /// signature object.
        /// </summary>
        ///
        /// <param name="data">The data object to copy.</param>
        public Data(Data data)
        {
            this.signature_ = new ChangeCounter(
                new Sha256WithRsaSignature());
            this.name_                = new ChangeCounter(new Name());
            this.metaInfo_            = new ChangeCounter(new MetaInfo());
            this.content_             = new Blob();
            this.lpPacket_            = null;
            this.defaultWireEncoding_ = new SignedBlob();
            this.getDefaultWireEncodingChangeCount_ = 0;
            this.changeCount_ = 0;
            try {
                signature_
                .set((data.signature_ == null) ? (net.named_data.jndn.util.ChangeCountable)(new Sha256WithRsaSignature())
                                                                : (net.named_data.jndn.util.ChangeCountable)((Signature)data.getSignature().Clone()));
            } catch (Exception e) {
                // We don't expect this to happen, so just treat it as if we got a null pointer.
                throw new NullReferenceException(
                          "Data.setSignature: unexpected exception in clone(): "
                          + e.Message);
            }

            name_.set(new Name(data.getName()));
            metaInfo_.set(new MetaInfo(data.getMetaInfo()));
            content_ = data.content_;
            setDefaultWireEncoding(data.defaultWireEncoding_, null);
        }
示例#2
0
        private static ArrayList dumpData(Data data)
        {
            ArrayList result = new ArrayList();

            ILOG.J2CsMapping.Collections.Collections.Add(result,dump("name:", data.getName().toUri()));
            if (data.getContent().size() > 0) {
                String raw = "";
                ByteBuffer buf = data.getContent().buf();
                while (buf.remaining() > 0)
                    raw += (char) buf.get();
                ILOG.J2CsMapping.Collections.Collections.Add(result,dump("content (raw):", raw));
                ILOG.J2CsMapping.Collections.Collections.Add(result,dump("content (hex):", data.getContent().toHex()));
            } else
                ILOG.J2CsMapping.Collections.Collections.Add(result,dump("content: <empty>"));
            if (data.getMetaInfo().getType() != net.named_data.jndn.ContentType.BLOB) {
                ILOG.J2CsMapping.Collections.Collections.Add(result,dump(
                                    "metaInfo.type:",
                                    (data.getMetaInfo().getType() == net.named_data.jndn.ContentType.LINK) ? "LINK"
                                            : ((data.getMetaInfo().getType() == net.named_data.jndn.ContentType.KEY) ? "KEY"
                                                    : "unknown")));
            }
            ILOG.J2CsMapping.Collections.Collections.Add(result,dump("metaInfo.freshnessPeriod (milliseconds):", (data
                            .getMetaInfo().getFreshnessPeriod() >= 0) ? ""
                            + (long) data.getMetaInfo().getFreshnessPeriod() : "<none>"));
            ILOG.J2CsMapping.Collections.Collections.Add(result,dump("metaInfo.finalBlockId:", (data.getMetaInfo()
                            .getFinalBlockId().getValue().size() > 0) ? data.getMetaInfo()
                            .getFinalBlockId().toEscapedString() : "<none>"));
            if (data.getSignature()  is  Sha256WithRsaSignature) {
                Sha256WithRsaSignature signature = (Sha256WithRsaSignature) data
                        .getSignature();
                ILOG.J2CsMapping.Collections.Collections.Add(result,dump("signature.signature:", (signature.getSignature()
                                    .size() == 0) ? "<none>" : signature.getSignature().toHex()));
                if (signature.getKeyLocator().getType() != net.named_data.jndn.KeyLocatorType.NONE) {
                    if (signature.getKeyLocator().getType() == net.named_data.jndn.KeyLocatorType.KEY_LOCATOR_DIGEST)
                        ILOG.J2CsMapping.Collections.Collections.Add(result,dump("signature.keyLocator: KeyLocatorDigest:",
                                                    signature.getKeyLocator().getKeyData().toHex()));
                    else if (signature.getKeyLocator().getType() == net.named_data.jndn.KeyLocatorType.KEYNAME)
                        ILOG.J2CsMapping.Collections.Collections.Add(result,dump("signature.keyLocator: KeyName:", signature
                                                    .getKeyLocator().getKeyName().toUri()));
                    else
                        ILOG.J2CsMapping.Collections.Collections.Add(result,dump("signature.keyLocator: <unrecognized KeyLocatorType"));
                } else
                    ILOG.J2CsMapping.Collections.Collections.Add(result,dump("signature.keyLocator: <none>"));
            }

            return result;
        }
示例#3
0
        private static Data createFreshData()
        {
            Data freshData = new Data(new Name("/ndn/abc"));
            freshData.setContent(new Blob("SUCCESS!"));
            freshData.getMetaInfo().setFreshnessPeriod(5000);
            freshData.getMetaInfo().setFinalBlockId(new Name("/%00%09").get(0));

            return freshData;
        }
 /// <summary>
 /// Create a new StaleTimeContent to hold data's name and wire encoding
 /// as well as the staleTimeMilliseconds which is now plus
 /// data.getMetaInfo().getFreshnessPeriod().
 /// </summary>
 ///
 /// <param name="data">The Data packet whose name and wire encoding are copied.</param>
 public StaleTimeContent(Data data)
     : base(data)
 {
     // Set up staleTimeMilliseconds_.
     staleTimeMilliseconds_ = net.named_data.jndn.util.Common.getNowMilliseconds()
             + data.getMetaInfo().getFreshnessPeriod();
 }
        /// <summary>
        /// Add the Data packet to the cache so that it is available to use to
        /// answer interests. If data.getMetaInfo().getFreshnessPeriod() is not
        /// negative, set the staleness time to now plus
        /// data.getMetaInfo().getFreshnessPeriod(), which is checked during cleanup to
        /// remove stale content. This also checks if cleanupIntervalMilliseconds
        /// milliseconds have passed and removes stale content from the cache. After
        /// removing stale content, remove timed-out pending interests from
        /// storePendingInterest(), then if the added Data packet satisfies any
        /// interest, send it through the face and remove the interest from the pending
        /// interest table.
        /// </summary>
        ///
        /// <param name="data"></param>
        public void add(Data data)
        {
            doCleanup();

            if (data.getMetaInfo().getFreshnessPeriod() >= 0.0d) {
                // The content will go stale, so use staleTimeCache_.
                MemoryContentCache.StaleTimeContent  content = new MemoryContentCache.StaleTimeContent (data);
                // Insert into staleTimeCache, sorted on content.staleTimeMilliseconds.
                // Search from the back since we expect it to go there.
                int i = staleTimeCache_.Count - 1;
                while (i >= 0) {
                    if (staleTimeCache_[i].getStaleTimeMilliseconds() <= content
                            .getStaleTimeMilliseconds())
                        break;
                    --i;
                }
                // Element i is the greatest less than or equal to
                // content.staleTimeMilliseconds, so insert after it.
                staleTimeCache_.Insert(i + 1, content);
            } else
                // The data does not go stale, so use noStaleTimeCache_.
                ILOG.J2CsMapping.Collections.Collections.Add(noStaleTimeCache_,new MemoryContentCache.Content (data));

            // Remove timed-out interests and check if the data packet matches any
            // pending interest.
            // Go backwards through the list so we can erase entries.
            double nowMilliseconds = net.named_data.jndn.util.Common.getNowMilliseconds();
            for (int i_0 = pendingInterestTable_.Count - 1; i_0 >= 0; --i_0) {
                MemoryContentCache.PendingInterest  pendingInterest = pendingInterestTable_[i_0];
                if (pendingInterest.isTimedOut(nowMilliseconds)) {
                    ILOG.J2CsMapping.Collections.Collections.RemoveAt(pendingInterestTable_,i_0);
                    continue;
                }

                if (pendingInterest.getInterest().matchesName(data.getName())) {
                    try {
                        // Send to the same face from the original call to onInterest.
                        // wireEncode returns the cached encoding if available.
                        pendingInterest.getFace().send(data.wireEncode());
                    } catch (IOException ex) {
                        ILOG.J2CsMapping.Util.Logging.Logger.getLogger(typeof(MemoryContentCache).FullName).log(
                                ILOG.J2CsMapping.Util.Logging.Level.SEVERE, ex.Message);
                        return;
                    }

                    // The pending interest is satisfied, so remove it.
                    ILOG.J2CsMapping.Collections.Collections.RemoveAt(pendingInterestTable_,i_0);
                }
            }
        }
        /**
         * Loop to encode a data packet nIterations times.
         * @param nIterations The number of iterations.
         * @param useComplex If true, use a large name, large content and all fields.
         * If false, use a small name, small content
         * and only required fields.
         * @param useCrypto If true, sign the data packet.  If false, use a blank
         * signature.
         * @param keyType KeyType.RSA or EC, used if useCrypto is true.
         * @param encoding Set encoding[0] to the wire encoding.
         * @return The number of seconds for all iterations.
         */
        private static double benchmarkEncodeDataSeconds(int nIterations, bool useComplex, bool useCrypto, KeyType keyType,
        Blob[] encoding)
        {
            Name name;
              Blob content;
              if (useComplex) {
            // Use a large name and content.
            name = new Name
              ("/ndn/ucla.edu/apps/lwndn-test/numbers.txt/%FD%05%05%E8%0C%CE%1D/%00");

            StringBuilder contentStream = new StringBuilder();
            int count = 1;
            contentStream.append(count++);
            while (contentStream.toString().Length < 1115)
              contentStream.append(" ").append(count++);
            content = new Blob(contentStream.toString());
              }
              else {
            // Use a small name and content.
            name = new Name("/test");
            content = new Blob("abc");
              }
              Name.Component finalBlockId =
            new Name.Component(new Blob(new byte[] { (byte)0 }));

              // Initialize the KeyChain storage in case useCrypto is true.
              MemoryIdentityStorage identityStorage = new MemoryIdentityStorage();
              MemoryPrivateKeyStorage privateKeyStorage = new MemoryPrivateKeyStorage();
              KeyChain keyChain = new KeyChain
            (new IdentityManager(identityStorage, privateKeyStorage),
              new SelfVerifyPolicyManager(identityStorage));
              Name keyName = new Name("/testname/DSK-123");
              Name certificateName = keyName.getSubName(0, keyName.size() - 1).append
            ("KEY").append(keyName.get(-1)).append("ID-CERT").append("0");
              privateKeyStorage.setKeyPairForKeyName
              (keyName, KeyType.RSA, new ByteBuffer(DEFAULT_RSA_PUBLIC_KEY_DER),
            new ByteBuffer(DEFAULT_RSA_PRIVATE_KEY_DER));

              Blob signatureBits = new Blob(new byte[256]);
              Blob emptyBlob = new Blob(new byte[0]);

              double start = getNowSeconds();
              for (int i = 0; i < nIterations; ++i) {
            Data data = new Data(name);
            data.setContent(content);
            if (useComplex) {
              data.getMetaInfo().setFreshnessPeriod(30000);
              data.getMetaInfo().setFinalBlockId(finalBlockId);
            }

            if (useCrypto)
              // This sets the signature fields.
              keyChain.sign(data, certificateName);
            else {
              // Imitate IdentityManager.signByCertificate to set up the signature
              //   fields, but don't sign.
              KeyLocator keyLocator = new KeyLocator();
              keyLocator.setType(KeyLocatorType.KEYNAME);
              keyLocator.setKeyName(certificateName);
              Sha256WithRsaSignature sha256Signature =
            (Sha256WithRsaSignature)data.getSignature();
              sha256Signature.setKeyLocator(keyLocator);
              sha256Signature.setSignature(signatureBits);
            }

            encoding[0] = data.wireEncode();
              }
              double finish = getNowSeconds();

              return finish - start;
        }
示例#7
0
        /// <summary>
        /// Create a deep copy of the given data object, including a clone of the
        /// signature object.
        /// </summary>
        ///
        /// <param name="data">The data object to copy.</param>
        public Data(Data data)
        {
            this.signature_ = new ChangeCounter(
                    new Sha256WithRsaSignature());
            this.name_ = new ChangeCounter(new Name());
            this.metaInfo_ = new ChangeCounter(new MetaInfo());
            this.content_ = new Blob();
            this.lpPacket_ = null;
            this.defaultWireEncoding_ = new SignedBlob();
            this.defaultFullName_ = new Name();
            this.getDefaultWireEncodingChangeCount_ = 0;
            this.changeCount_ = 0;
            try {
                signature_
                        .set((data.signature_ == null) ? (net.named_data.jndn.util.ChangeCountable) (new Sha256WithRsaSignature())
                                : (net.named_data.jndn.util.ChangeCountable) ((Signature) data.getSignature().Clone()));
            } catch (Exception e) {
                // We don't expect this to happen, so just treat it as if we got a null pointer.
                throw new NullReferenceException(
                        "Data.setSignature: unexpected exception in clone(): "
                                + e.Message);
            }

            name_.set(new Name(data.getName()));
            metaInfo_.set(new MetaInfo(data.getMetaInfo()));
            content_ = data.content_;
            setDefaultWireEncoding(data.defaultWireEncoding_, null);
        }
        /// <summary>
        /// Decode input as a data packet in NDN-TLV and set the fields in the data
        /// object.
        /// </summary>
        ///
        /// <param name="data">The Data object whose fields are updated.</param>
        /// <param name="input"></param>
        /// <param name="signedPortionBeginOffset">If you are not decoding in order to verify, you can call decodeData(data, input) to ignore this returned value.</param>
        /// <param name="signedPortionEndOffset">not decoding in order to verify, you can call decodeData(data, input) to ignore this returned value.</param>
        /// <param name="copy">unchanged while the Blob values are used.</param>
        /// <exception cref="EncodingException">For invalid encoding.</exception>
        public override void decodeData(Data data, ByteBuffer input,
				int[] signedPortionBeginOffset, int[] signedPortionEndOffset,
				bool copy)
        {
            TlvDecoder decoder = new TlvDecoder(input);

            int endOffset = decoder.readNestedTlvsStart(net.named_data.jndn.encoding.tlv.Tlv.Data);
            signedPortionBeginOffset[0] = decoder.getOffset();

            decodeName(data.getName(), new int[1], new int[1], decoder, copy);
            decodeMetaInfo(data.getMetaInfo(), decoder, copy);
            data.setContent(new Blob(decoder.readBlobTlv(net.named_data.jndn.encoding.tlv.Tlv.Content), copy));
            decodeSignatureInfo(data, decoder, copy);

            signedPortionEndOffset[0] = decoder.getOffset();
            data.getSignature().setSignature(
                    new Blob(decoder.readBlobTlv(net.named_data.jndn.encoding.tlv.Tlv.SignatureValue), copy));

            decoder.finishNestedTlvs(endOffset);
        }
        /// <summary>
        /// Encode data in NDN-TLV and return the encoding.
        /// </summary>
        ///
        /// <param name="data">The Data object to encode.</param>
        /// <param name="signedPortionBeginOffset">If you are not encoding in order to sign, you can call encodeData(data) to ignore this returned value.</param>
        /// <param name="signedPortionEndOffset">If you are not encoding in order to sign, you can call encodeData(data) to ignore this returned value.</param>
        /// <returns>A Blob containing the encoding.</returns>
        public override Blob encodeData(Data data, int[] signedPortionBeginOffset,
				int[] signedPortionEndOffset)
        {
            TlvEncoder encoder = new TlvEncoder(1500);
            int saveLength = encoder.getLength();

            // Encode backwards.
            encoder.writeBlobTlv(net.named_data.jndn.encoding.tlv.Tlv.SignatureValue, (data.getSignature())
                    .getSignature().buf());
            int signedPortionEndOffsetFromBack = encoder.getLength();

            encodeSignatureInfo(data.getSignature(), encoder);
            encoder.writeBlobTlv(net.named_data.jndn.encoding.tlv.Tlv.Content, data.getContent().buf());
            encodeMetaInfo(data.getMetaInfo(), encoder);
            encodeName(data.getName(), new int[1], new int[1], encoder);
            int signedPortionBeginOffsetFromBack = encoder.getLength();

            encoder.writeTypeAndLength(net.named_data.jndn.encoding.tlv.Tlv.Data, encoder.getLength() - saveLength);

            signedPortionBeginOffset[0] = encoder.getLength()
                    - signedPortionBeginOffsetFromBack;
            signedPortionEndOffset[0] = encoder.getLength()
                    - signedPortionEndOffsetFromBack;
            return new Blob(encoder.getOutput(), false);
        }
示例#10
0
        /// <summary>
        /// Create an E-KEY Data packet for the given public key.
        /// </summary>
        ///
        /// <param name="startTimeStamp">The start time stamp string to put in the name.</param>
        /// <param name="endTimeStamp">The end time stamp string to put in the name.</param>
        /// <param name="publicKeyBlob">A Blob of the public key DER.</param>
        /// <returns>The Data packet.</returns>
        /// <exception cref="System.Security.SecurityException">for an error using the security KeyChain.</exception>
        private Data createEKeyData(String startTimeStamp, String endTimeStamp,
				Blob publicKeyBlob)
        {
            Name name = new Name(namespace_);
            name.append(net.named_data.jndn.encrypt.algo.Encryptor.NAME_COMPONENT_E_KEY).append(startTimeStamp)
                    .append(endTimeStamp);

            Data data = new Data(name);
            data.getMetaInfo().setFreshnessPeriod(
                    freshnessHours_ * MILLISECONDS_IN_HOUR);
            data.setContent(publicKeyBlob);
            keyChain_.sign(data);
            return data;
        }
示例#11
0
        /// <summary>
        /// Create a D-KEY Data packet with an EncryptedContent for the given private
        /// key, encrypted with the certificate key.
        /// </summary>
        ///
        /// <param name="startTimeStamp">The start time stamp string to put in the name.</param>
        /// <param name="endTimeStamp">The end time stamp string to put in the name.</param>
        /// <param name="keyName"></param>
        /// <param name="privateKeyBlob">A Blob of the encoded private key.</param>
        /// <param name="certificateKey"></param>
        /// <returns>The Data packet.</returns>
        /// <exception cref="System.Security.SecurityException">for an error using the security KeyChain.</exception>
        private Data createDKeyData(String startTimeStamp, String endTimeStamp,
				Name keyName, Blob privateKeyBlob, Blob certificateKey)
        {
            Name name = new Name(namespace_);
            name.append(net.named_data.jndn.encrypt.algo.Encryptor.NAME_COMPONENT_D_KEY);
            name.append(startTimeStamp).append(endTimeStamp);
            Data data = new Data(name);
            data.getMetaInfo().setFreshnessPeriod(
                    freshnessHours_ * MILLISECONDS_IN_HOUR);
            EncryptParams encryptParams = new EncryptParams(
                    net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.RsaOaep);
            try {
                net.named_data.jndn.encrypt.algo.Encryptor.encryptData(data, privateKeyBlob, keyName,
                        certificateKey, encryptParams);
            } catch (Exception ex) {
                // Consolidate errors such as InvalidKeyException.
                throw new SecurityException(
                        "createDKeyData: Error in encryptData: " + ex.Message);
            }

            keyChain_.sign(data);
            return data;
        }
示例#12
0
        public void onVerified(Data data, Interest originalInterest_0)
        {
            if (!endsWithSegmentNumber(data.getName())) {
                // We don't expect a name without a segment number.  Treat it as a bad packet.
                try {
                    onError_.onError(net.named_data.jndn.util.SegmentFetcher.ErrorCode.DATA_HAS_NO_SEGMENT,
                            "Got an unexpected packet without a segment number: "
                                    + data.getName().toUri());
                } catch (Exception ex) {
                    logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onError", ex);
                }
            } else {
                long currentSegment;
                try {
                    currentSegment = data.getName().get(-1).toSegment();
                } catch (EncodingException ex_1) {
                    try {
                        onError_.onError(net.named_data.jndn.util.SegmentFetcher.ErrorCode.DATA_HAS_NO_SEGMENT,
                                "Error decoding the name segment number "
                                        + data.getName().get(-1).toEscapedString()
                                        + ": " + ex_1);
                    } catch (Exception exception) {
                        logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onError", exception);
                    }
                    return;
                }

                long expectedSegmentNumber = contentParts_.Count;
                if (currentSegment != expectedSegmentNumber) {
                    // Try again to get the expected segment.  This also includes the case
                    //   where the first segment is not segment 0.
                    fetchNextSegment(originalInterest_0, data.getName(),
                            expectedSegmentNumber);
                } else {
                    // Save the content and check if we are finished.
                    ILOG.J2CsMapping.Collections.Collections.Add(contentParts_,data.getContent());

                    if (data.getMetaInfo().getFinalBlockId().getValue().size() > 0) {
                        long finalSegmentNumber;
                        try {
                            finalSegmentNumber = data.getMetaInfo()
                                    .getFinalBlockId().toSegment();
                        } catch (EncodingException ex_2) {
                            try {
                                onError_.onError(net.named_data.jndn.util.SegmentFetcher.ErrorCode.DATA_HAS_NO_SEGMENT,
                                        "Error decoding the FinalBlockId segment number "
                                                + data.getMetaInfo()
                                                        .getFinalBlockId()
                                                        .toEscapedString() + ": "
                                                + ex_2);
                            } catch (Exception exception_3) {
                                logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onError",
                                        exception_3);
                            }
                            return;
                        }

                        if (currentSegment == finalSegmentNumber) {
                            // We are finished.

                            // Get the total size and concatenate to get content.
                            int totalSize = 0;
                            for (int i = 0; i < contentParts_.Count; ++i)
                                totalSize += ((Blob) contentParts_[i]).size();
                            ByteBuffer content = ILOG.J2CsMapping.NIO.ByteBuffer.allocate(totalSize);
                            for (int i_4 = 0; i_4 < contentParts_.Count; ++i_4)
                                content.put(((Blob) contentParts_[i_4]).buf());
                            content.flip();

                            try {
                                onComplete_.onComplete(new Blob(content, false));
                            } catch (Exception ex_5) {
                                logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onComplete", ex_5);
                            }
                            return;
                        }
                    }

                    // Fetch the next segment.
                    fetchNextSegment(originalInterest_0, data.getName(),
                            expectedSegmentNumber + 1);
                }
            }
        }
        static void Main(string[] args)
        {
            var data = new Data();
              data.wireDecode(new Blob(TlvData));
              Console.Out.WriteLine("Decoded Data:");
              dumpData(data);

              // Set the content again to clear the cached encoding so we encode again.
              data.setContent(data.getContent());
              var encoding = data.wireEncode();

              var reDecodedData = new Data();
              reDecodedData.wireDecode(encoding);
              Console.Out.WriteLine("");
              Console.Out.WriteLine("Re-decoded Data:");
              dumpData(reDecodedData);

              var identityStorage = new MemoryIdentityStorage();
              var privateKeyStorage = new MemoryPrivateKeyStorage();
              var keyChain = new KeyChain
            (new IdentityManager(identityStorage, privateKeyStorage),
              new SelfVerifyPolicyManager(identityStorage));

              // Initialize the storage.
              var keyName = new Name("/testname/DSK-123");
              var certificateName = keyName.getSubName(0, keyName.size() - 1).append
            ("KEY").append(keyName.get(-1)).append("ID-CERT").append("0");
              identityStorage.addKey(keyName, KeyType.RSA, new Blob(DEFAULT_RSA_PUBLIC_KEY_DER));
              privateKeyStorage.setKeyPairForKeyName
            (keyName, KeyType.RSA, new ByteBuffer(DEFAULT_RSA_PUBLIC_KEY_DER),
              new ByteBuffer(DEFAULT_RSA_PRIVATE_KEY_DER));

              VerifyCallbacks callbacks = new VerifyCallbacks("Re-decoded Data");
              keyChain.verifyData(reDecodedData, callbacks, callbacks);

              var freshData = new Data(new Name("/ndn/abc"));
              freshData.setContent(new Blob("SUCCESS!"));
              freshData.getMetaInfo().setFreshnessPeriod(5000);
              freshData.getMetaInfo().setFinalBlockId(new Name("/%00%09").get(0));
              keyChain.sign(freshData, certificateName);
              Console.Out.WriteLine("");
              Console.Out.WriteLine("Freshly-signed Data:");
              dumpData(freshData);

              callbacks = new VerifyCallbacks("Freshly-signed Data");
              keyChain.verifyData(freshData, callbacks, callbacks);
        }
        static void dumpData(Data data)
        {
            Console.Out.WriteLine("name: " + data.getName().toUri());
              if (data.getContent().size() > 0) {
            Console.Out.Write("content (raw): ");
            var buf = data.getContent().buf();
            while(buf.remaining() > 0)
              Console.Out.Write((char)buf.get());
            Console.Out.WriteLine("");
            Console.Out.WriteLine("content (hex): " + data.getContent().toHex());
              }
              else
            Console.Out.WriteLine("content: <empty>");

              if (!(data.getMetaInfo().getType() == ContentType.BLOB)) {
            Console.Out.Write("metaInfo.type: ");
            if (data.getMetaInfo().getType() == ContentType.KEY)
              Console.Out.WriteLine("KEY");
            else if (data.getMetaInfo().getType() == ContentType.LINK)
              Console.Out.WriteLine("LINK");
            else if (data.getMetaInfo().getType() == ContentType.NACK)
              Console.Out.WriteLine("NACK");
            else if (data.getMetaInfo().getType() == ContentType.OTHER_CODE)
              Console.Out.WriteLine("other code " + data.getMetaInfo().getOtherTypeCode());
              }
              Console.Out.WriteLine("metaInfo.freshnessPeriod (milliseconds): " +
            (data.getMetaInfo().getFreshnessPeriod() >= 0 ?
              "" + data.getMetaInfo().getFreshnessPeriod() : "<none>"));
              Console.Out.WriteLine("metaInfo.finalBlockId: " +
            (data.getMetaInfo().getFinalBlockId().getValue().size() > 0 ?
              data.getMetaInfo().getFinalBlockId().getValue().toHex() : "<none>"));

              KeyLocator keyLocator = null;
              if (data.getSignature() is Sha256WithRsaSignature) {
            var signature = (Sha256WithRsaSignature)data.getSignature();
            Console.Out.WriteLine("Sha256WithRsa signature.signature: " +
              (signature.getSignature().size() > 0 ?
            signature.getSignature().toHex() : "<none>"));
            keyLocator = signature.getKeyLocator();
              }
              else if (data.getSignature() is Sha256WithEcdsaSignature) {
            var signature = (Sha256WithEcdsaSignature)data.getSignature();
            Console.Out.WriteLine("Sha256WithEcdsa signature.signature: " +
              (signature.getSignature().size() > 0 ?
            signature.getSignature().toHex() : "<none>"));
            keyLocator = signature.getKeyLocator();
              }
              else if (data.getSignature() is HmacWithSha256Signature) {
            var signature = (HmacWithSha256Signature)data.getSignature();
            Console.Out.WriteLine("HmacWithSha256 signature.signature: " +
              (signature.getSignature().size() > 0 ?
            signature.getSignature().toHex() : "<none>"));
            keyLocator = signature.getKeyLocator();
              }
              else if (data.getSignature() is DigestSha256Signature) {
            var signature = (DigestSha256Signature)data.getSignature();
            Console.Out.WriteLine("DigestSha256 signature.signature: " +
              (signature.getSignature().size() > 0 ?
            signature.getSignature().toHex() : "<none>"));
              }
              else if (data.getSignature() is GenericSignature) {
            var signature = (GenericSignature)data.getSignature();
            Console.Out.WriteLine("Generic signature.signature: " +
              (signature.getSignature().size() > 0 ?
            signature.getSignature().toHex() : "<none>"));
            Console.Out.WriteLine("  Type code: " + signature.getTypeCode() + " signatureInfo: " +
              (signature.getSignatureInfoEncoding().size() > 0 ?
            signature.getSignatureInfoEncoding().toHex() : "<none>"));
              }
              if (keyLocator != null) {
            Console.Out.Write("signature.keyLocator: ");
            if (keyLocator.getType() == KeyLocatorType.NONE)
              Console.Out.WriteLine("<none>");
            else if (keyLocator.getType() ==KeyLocatorType.KEY_LOCATOR_DIGEST)
              Console.Out.WriteLine("KeyLocatorDigest: " + keyLocator.getKeyData().toHex());
            else if (keyLocator.getType() == KeyLocatorType.KEYNAME)
              Console.Out.WriteLine("KeyName: " + keyLocator.getKeyName().toUri());
            else
              Console.Out.WriteLine("<unrecognized ndn_KeyLocatorType>");
              }
        }