/// <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); }
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; }
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; }
/// <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); }
/// <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; }
/// <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; }
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>"); } }