/// <summary> /// The OnInterestCallback calls this to put a Data packet which /// satisfies an Interest. /// </summary> /// /// <param name="data">The Data packet which satisfies the interest.</param> /// <param name="wireFormat">A WireFormat object used to encode the Data packet.</param> /// <exception cref="System.Exception">If the encoded Data packet size exceeds getMaxNdnPacketSize().</exception> public void putData(Data data, WireFormat wireFormat) { Blob encoding = data.wireEncode(wireFormat); if (encoding.size() > getMaxNdnPacketSize()) { throw new Exception( "The encoded Data packet size exceeds the maximum limit getMaxNdnPacketSize()"); } transport_.send(encoding.buf()); }
/// <summary> /// Look in the IdentityStorage for the public key with the name in the /// KeyLocator (if available) and use it to verify the data packet. If the /// public key can't be found, call onVerifyFailed. /// </summary> /// /// <param name="data">The Data object with the signature to check.</param> /// <param name="stepCount"></param> /// <param name="onVerified">better error handling the callback should catch and properly handle any exceptions.</param> /// <param name="onValidationFailed">NOTE: The library will log any exceptions thrown by this callback, but for better error handling the callback should catch and properly handle any exceptions.</param> /// <returns>null for no further step for looking up a certificate chain.</returns> public override ValidationRequest checkVerificationPolicy(Data data, int stepCount, OnVerified onVerified, OnDataValidationFailed onValidationFailed) { String[] failureReason = new String[] { "unknown" }; // wireEncode returns the cached encoding if available. if (verify(data.getSignature(), data.wireEncode(), failureReason)) { try { onVerified.onVerified(data); } catch (Exception ex) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onVerified", ex); } } else { try { onValidationFailed.onDataValidationFailed(data, failureReason[0]); } catch (Exception ex_0) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onDataValidationFailed", ex_0); } } // No more steps, so return a null ValidationRequest. return null; }
/// <summary> /// Create a new Content entry to hold data's name and wire encoding. /// </summary> /// /// <param name="data">The Data packet whose name and wire encoding are copied.</param> public Content(Data data) { // wireEncode returns the cached encoding if available. name_ = data.getName(); dataEncoding_ = data.wireEncode(); }
public void testEncodeDecode() { Data data = new Data(); try { data.wireDecode(codedData); } catch (EncodingException ex) { Assert.Fail("Can't decode codedData"); } // Set the content again to clear the cached encoding so we encode again. data.setContent(data.getContent()); Blob encoding = data.wireEncode(); Data reDecodedData = new Data(); try { reDecodedData.wireDecode(encoding); } catch (EncodingException ex_0) { Assert.Fail("Can't decode reDecodedData"); } Assert.AssertArrayEquals("Re-decoded data does not match original dump", ILOG.J2CsMapping.Collections.Collections.ToArray(initialDump), ILOG.J2CsMapping.Collections.Collections.ToArray(dumpData(reDecodedData))); }
/// <summary> /// Compute a new HmacWithSha256 for the data packet and verify it against the /// signature value. /// </summary> /// /// @note This method is an experimental feature. The API may change. /// <param name="data">The Data packet to verify.</param> /// <param name="key">The key for the HmacWithSha256.</param> /// <param name="wireFormat">A WireFormat object used to encode the data packet.</param> /// <returns>True if the signature verifies, otherwise false.</returns> public static bool verifyDataWithHmacWithSha256(Data data, Blob key, WireFormat wireFormat) { // wireEncode returns the cached encoding if available. SignedBlob encoding = data.wireEncode(wireFormat); byte[] newSignatureBytes = net.named_data.jndn.util.Common.computeHmacWithSha256( key.getImmutableArray(), encoding.signedBuf()); return ILOG.J2CsMapping.NIO.ByteBuffer.wrap(newSignatureBytes).equals( data.getSignature().getSignature().buf()); }
/// <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> /// Wire encode the data packet, compute an HmacWithSha256 and update the /// signature value. /// </summary> /// /// @note This method is an experimental feature. The API may change. /// <param name="data">The Data object to be signed. This updates its signature.</param> /// <param name="key">The key for the HmacWithSha256.</param> /// <param name="wireFormat">A WireFormat object used to encode the data packet.</param> public static void signWithHmacWithSha256(Data data, Blob key, WireFormat wireFormat) { // Encode once to get the signed portion. SignedBlob encoding = data.wireEncode(wireFormat); byte[] signatureBytes = net.named_data.jndn.util.Common.computeHmacWithSha256( key.getImmutableArray(), encoding.signedBuf()); data.getSignature().setSignature(new Blob(signatureBytes, false)); }
/// <summary> /// Sign data packet based on the certificate name. /// </summary> /// /// <param name="data">The Data object to sign and update its signature.</param> /// <param name="certificateName"></param> /// <param name="wireFormat">The WireFormat for calling encodeData.</param> public void signByCertificate(Data data, Name certificateName, WireFormat wireFormat) { DigestAlgorithm[] digestAlgorithm = new DigestAlgorithm[1]; Signature signature = makeSignatureByCertificate(certificateName, digestAlgorithm); data.setSignature(signature); // Encode once to get the signed portion. SignedBlob encoding = data.wireEncode(wireFormat); data.getSignature() .setSignature( privateKeyStorage_.sign( encoding.signedBuf(), net.named_data.jndn.security.certificate.IdentityCertificate .certificateNameToPublicKeyName(certificateName), digestAlgorithm[0])); // Encode again to include the signature. data.wireEncode(wireFormat); }
/// <summary> /// Wire encode the Data object, digest it and set its SignatureInfo to /// a DigestSha256. /// </summary> /// /// <param name="data"></param> /// <param name="wireFormat">The WireFormat for calling encodeData.</param> public void signWithSha256(Data data, WireFormat wireFormat) { data.setSignature(new DigestSha256Signature()); // Encode once to get the signed portion. SignedBlob encoding = data.wireEncode(wireFormat); // Digest and set the signature. byte[] signedPortionDigest = net.named_data.jndn.util.Common.digestSha256(encoding.signedBuf()); data.getSignature().setSignature(new Blob(signedPortionDigest, false)); // Encode again to include the signature. data.wireEncode(wireFormat); }
/// <summary> /// The OnInterestCallback calls this to put a Data packet which /// satisfies an Interest. /// </summary> /// /// <param name="data">The Data packet which satisfies the interest.</param> /// <param name="wireFormat">A WireFormat object used to encode the Data packet.</param> /// <exception cref="System.Exception">If the encoded Data packet size exceeds getMaxNdnPacketSize().</exception> public void putData(Data data, WireFormat wireFormat) { Blob encoding = data.wireEncode(wireFormat); if (encoding.size() > getMaxNdnPacketSize()) throw new Exception( "The encoded Data packet size exceeds the maximum limit getMaxNdnPacketSize()"); transport_.send(encoding.buf()); }
/// <summary> /// Check whether the received data packet complies with the verification policy, /// and get the indication of the next verification step. /// </summary> /// /// <param name="data">The Data object with the signature to check.</param> /// <param name="stepCount"></param> /// <param name="onVerified">NOTE: The library will log any exceptions thrown by this callback, but for better error handling the callback should catch and properly handle any exceptions.</param> /// <param name="onValidationFailed">NOTE: The library will log any exceptions thrown by this callback, but for better error handling the callback should catch and properly handle any exceptions.</param> /// <returns>the indication of next verification step, null if there is no /// further step.</returns> public override sealed ValidationRequest checkVerificationPolicy(Data data, int stepCount, OnVerified onVerified, OnDataValidationFailed onValidationFailed) { String[] failureReason = new String[] { "unknown" }; Interest certificateInterest = getCertificateInterest(stepCount, "data", data.getName(), data.getSignature(), failureReason); if (certificateInterest == null) { try { onValidationFailed.onDataValidationFailed(data, failureReason[0]); } catch (Exception ex) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onDataValidationFailed", ex); } return null; } if (certificateInterest.getName().size() > 0) return new ValidationRequest(certificateInterest, new ConfigPolicyManager.OnCertificateDownloadComplete (this, data, stepCount, onVerified, onValidationFailed), onValidationFailed, 2, stepCount + 1); else { // Certificate is known. Verify the signature. // wireEncode returns the cached encoding if available. if (verify(data.getSignature(), data.wireEncode(), failureReason)) { try { onVerified.onVerified(data); } catch (Exception ex_0) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onVerified", ex_0); } } else { try { onValidationFailed.onDataValidationFailed(data, failureReason[0]); } catch (Exception ex_1) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onDataValidationFailed", ex_1); } } return null; } }
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); }