public void testMaxNdnPacketSize() { // Construct an interest whose encoding is one byte larger than getMaxNdnPacketSize. int targetSize = net.named_data.jndn.Face.getMaxNdnPacketSize() + 1; // Start with an interest which is almost the right size. Interest interest = new Interest(); interest.getName().append(new byte[targetSize]); int initialSize = interest.wireEncode().size(); // Now replace the component with the desired size which trims off the extra encoding. interest.setName(new Name().append(new byte[targetSize - (initialSize - targetSize)])); int interestSize = interest.wireEncode().size(); AssertEquals("Wrong interest size for MaxNdnPacketSize", targetSize, interestSize); CallbackCounter counter = new CallbackCounter(); bool gotError = true; try { face.expressInterest(interest, counter, counter); gotError = false; } catch (Exception ex) { } if (!gotError) Fail("expressInterest didn't throw an exception when the interest size exceeds getMaxNdnPacketSize()"); }
/// <summary> /// Do the work of expressInterest once we know we are connected. Add the entry /// to the PIT, encode and send the interest. /// </summary> /// /// <param name="pendingInterestId"></param> /// <param name="interestCopy"></param> /// <param name="onData"></param> /// <param name="onTimeout"></param> /// <param name="onNetworkNack"></param> /// <param name="wireFormat">A WireFormat object used to encode the message.</param> /// <param name="face"></param> /// <exception cref="IOException">For I/O error in sending the interest.</exception> /// <exception cref="System.Exception">If the encoded interest size exceeds getMaxNdnPacketSize().</exception> internal void expressInterestHelper(long pendingInterestId, Interest interestCopy, OnData onData, OnTimeout onTimeout, OnNetworkNack onNetworkNack, WireFormat wireFormat, Face face) { PendingInterestTable.Entry pendingInterest = pendingInterestTable_ .add(pendingInterestId, interestCopy, onData, onTimeout, onNetworkNack); if (pendingInterest == null) { // removePendingInterest was already called with the pendingInterestId. return; } if (onTimeout != null || interestCopy.getInterestLifetimeMilliseconds() >= 0.0d) { // Set up the timeout. double delayMilliseconds = interestCopy .getInterestLifetimeMilliseconds(); if (delayMilliseconds < 0.0d) { // Use a default timeout delay. delayMilliseconds = 4000.0d; } face.callLater(delayMilliseconds, new Node.Anonymous_C0(this, pendingInterest)); } // Special case: For timeoutPrefix_ we don't actually send the interest. if (!timeoutPrefix_.match(interestCopy.getName())) { Blob encoding = interestCopy.wireEncode(wireFormat); if (encoding.size() > getMaxNdnPacketSize()) { throw new Exception( "The encoded interest size exceeds the maximum limit getMaxNdnPacketSize()"); } transport_.send(encoding.buf()); } }
/// <summary> /// Use wireFormat.decodeSignatureInfoAndValue to decode the last two name /// components of the signed interest. Look in the IdentityStorage for the /// public key with the name in the KeyLocator (if available) and use it to /// verify the interest. If the public key can't be found, call onVerifyFailed. /// </summary> /// /// <param name="interest">The interest 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">onValidationFailed.onInterestValidationFailed(interest, reason). 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(Interest interest, int stepCount, OnVerifiedInterest onVerified, OnInterestValidationFailed onValidationFailed, WireFormat wireFormat) { if (interest.getName().size() < 2) { try { onValidationFailed.onInterestValidationFailed(interest, "The signed interest has less than 2 components: " + interest.getName().toUri()); } catch (Exception exception) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onInterestValidationFailed", exception); } return null; } // Decode the last two name components of the signed interest Signature signature; try { signature = wireFormat.decodeSignatureInfoAndValue(interest .getName().get(-2).getValue().buf(), interest.getName() .get(-1).getValue().buf(), false); } catch (EncodingException ex) { logger_.log( ILOG.J2CsMapping.Util.Logging.Level.INFO, "Cannot decode the signed interest SignatureInfo and value", ex); try { onValidationFailed.onInterestValidationFailed(interest, "Error decoding the signed interest signature: " + ex); } catch (Exception exception_0) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onInterestValidationFailed", exception_0); } return null; } String[] failureReason = new String[] { "unknown" }; // wireEncode returns the cached encoding if available. if (verify(signature, interest.wireEncode(wireFormat), failureReason)) { try { onVerified.onVerifiedInterest(interest); } catch (Exception ex_1) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onVerifiedInterest", ex_1); } } else { try { onValidationFailed.onInterestValidationFailed(interest, failureReason[0]); } catch (Exception ex_2) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onInterestValidationFailed", ex_2); } } // No more steps, so return a null ValidationRequest. return null; }
static void Main(string[] args) { var interest = new Interest(); interest.wireDecode(new Blob(TlvInterest)); Console.Out.WriteLine("Interest:"); dumpInterest(interest); // Set the name again to clear the cached encoding so we encode again. interest.setName(interest.getName()); var encoding = interest.wireEncode(); Console.Out.WriteLine(""); Console.Out.WriteLine("Re-encoded interest " + encoding.toHex()); var reDecodedInterest = new Interest(); reDecodedInterest.wireDecode(encoding); Console.Out.WriteLine(""); Console.Out.WriteLine("Re-decoded Interest:"); dumpInterest(reDecodedInterest); var freshInterest = new Interest(new Name("/ndn/abc")); freshInterest.setMinSuffixComponents(4); freshInterest.setMaxSuffixComponents(6); freshInterest.setInterestLifetimeMilliseconds(30000); freshInterest.setChildSelector(1); freshInterest.setMustBeFresh(true); freshInterest.getKeyLocator().setType(KeyLocatorType.KEY_LOCATOR_DIGEST); freshInterest.getKeyLocator().setKeyData (new Blob(new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F })); freshInterest.getExclude().appendComponent(new Name("abc").get(0)).appendAny(); 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)); // Make a Face just so that we can sign the interest. var face = new Face("localhost"); face.setCommandSigningInfo(keyChain, certificateName); face.makeCommandInterest(freshInterest); Interest reDecodedFreshInterest = new Interest(); reDecodedFreshInterest.wireDecode(freshInterest.wireEncode()); Console.Out.WriteLine(""); Console.Out.WriteLine("Re-decoded fresh Interest:"); dumpInterest(reDecodedFreshInterest); VerifyCallbacks callbacks = new VerifyCallbacks("Freshly-signed Interest"); keyChain.verifyInterest(reDecodedFreshInterest, callbacks, callbacks); }
/// <summary> /// Append a SignatureInfo to the Interest name, sign the name components and /// append a final name component with the signature bits. /// </summary> /// /// <param name="interest"></param> /// <param name="certificateName">The certificate name of the key to use for signing.</param> /// <param name="wireFormat">A WireFormat object used to encode the input.</param> public void signInterestByCertificate(Interest interest, Name certificateName, WireFormat wireFormat) { DigestAlgorithm[] digestAlgorithm = new DigestAlgorithm[1]; Signature signature = makeSignatureByCertificate(certificateName, digestAlgorithm); // Append the encoded SignatureInfo. interest.getName().append(wireFormat.encodeSignatureInfo(signature)); // Append an empty signature so that the "signedPortion" is correct. interest.getName().append(new Name.Component()); // Encode once to get the signed portion, and sign. SignedBlob encoding = interest.wireEncode(wireFormat); signature.setSignature(privateKeyStorage_.sign(encoding.signedBuf(), net.named_data.jndn.security.certificate.IdentityCertificate .certificateNameToPublicKeyName(certificateName), digestAlgorithm[0])); // Remove the empty signature and append the real one. interest.setName(interest.getName().getPrefix(-1) .append(wireFormat.encodeSignatureValue(signature))); }
public void testEncodeDecodeInterestWithLink() { Link link1 = new Link(); link1.setName(new Name("test")); link1.addDelegation(10, new Name("/test1")); link1.addDelegation(20, new Name("/test2")); link1.addDelegation(100, new Name("/test3")); try { keyChain.sign(link1, certificateName); } catch (SecurityException ex) { Assert.Fail(ex.Message); } Interest interestA = new Interest(); interestA.setName(new Name("/Test/Encode/Decode/With/Link")); interestA.setChildSelector(1); interestA.setInterestLifetimeMilliseconds(10000); interestA.setLinkWireEncoding(link1.wireEncode()); Blob interestEncoding = interestA.wireEncode(); Interest interestB = new Interest(); try { interestB.wireDecode(interestEncoding); } catch (EncodingException ex_0) { Assert.Fail(ex_0.Message); } Assert.AssertEquals(interestA.getName(), interestB.getName()); Link link2 = null; try { link2 = interestB.getLink(); } catch (Exception ex_1) { Assert.Fail("interestB.getLink(): " + ex_1.Message); } Assert.AssertTrue("Interest link object not specified", link2 != null); DelegationSet delegations = link2.getDelegations(); for (int i = 0; i < delegations.size(); ++i) { if (i == 0) { Assert.AssertEquals(10, delegations.get(i).getPreference()); Assert.AssertEquals(new Name("/test1"), delegations.get(i).getName()); } if (i == 1) { Assert.AssertEquals(20, delegations.get(i).getPreference()); Assert.AssertEquals(new Name("/test2"), delegations.get(i).getName()); } if (i == 2) { Assert.AssertEquals(100, delegations.get(i).getPreference()); Assert.AssertEquals(new Name("/test3"), delegations.get(i).getName()); } } }
/// <summary> /// Append a SignatureInfo for DigestSha256 to the Interest name, digest the /// name components and append a final name component with the signature bits /// (which is the digest). /// </summary> /// /// <param name="interest"></param> /// <param name="wireFormat">A WireFormat object used to encode the input.</param> public void signInterestWithSha256(Interest interest, WireFormat wireFormat) { DigestSha256Signature signature = new DigestSha256Signature(); // Append the encoded SignatureInfo. interest.getName().append(wireFormat.encodeSignatureInfo(signature)); // Append an empty signature so that the "signedPortion" is correct. interest.getName().append(new Name.Component()); // Encode once to get the signed portion. SignedBlob encoding = interest.wireEncode(wireFormat); // Digest and set the signature. byte[] signedPortionDigest = net.named_data.jndn.util.Common.digestSha256(encoding.signedBuf()); signature.setSignature(new Blob(signedPortionDigest, false)); // Remove the empty signature and append the real one. interest.setName(interest.getName().getPrefix(-1) .append(wireFormat.encodeSignatureValue(signature))); }
/// <summary> /// Do the work of expressInterest once we know we are connected. Add the entry /// to the PIT, encode and send the interest. /// </summary> /// /// <param name="pendingInterestId"></param> /// <param name="interestCopy"></param> /// <param name="onData"></param> /// <param name="onTimeout"></param> /// <param name="onNetworkNack"></param> /// <param name="wireFormat">A WireFormat object used to encode the message.</param> /// <param name="face"></param> /// <exception cref="IOException">For I/O error in sending the interest.</exception> /// <exception cref="System.Exception">If the encoded interest size exceeds getMaxNdnPacketSize().</exception> internal void expressInterestHelper(long pendingInterestId, Interest interestCopy, OnData onData, OnTimeout onTimeout, OnNetworkNack onNetworkNack, WireFormat wireFormat, Face face) { PendingInterestTable.Entry pendingInterest = pendingInterestTable_ .add(pendingInterestId, interestCopy, onData, onTimeout, onNetworkNack); if (pendingInterest == null) // removePendingInterest was already called with the pendingInterestId. return; if (onTimeout != null || interestCopy.getInterestLifetimeMilliseconds() >= 0.0d) { // Set up the timeout. double delayMilliseconds = interestCopy .getInterestLifetimeMilliseconds(); if (delayMilliseconds < 0.0d) // Use a default timeout delay. delayMilliseconds = 4000.0d; face.callLater(delayMilliseconds, new Node.Anonymous_C0 (this, pendingInterest)); } // Special case: For timeoutPrefix_ we don't actually send the interest. if (!timeoutPrefix_.match(interestCopy.getName())) { Blob encoding = interestCopy.wireEncode(wireFormat); if (encoding.size() > getMaxNdnPacketSize()) throw new Exception( "The encoded interest size exceeds the maximum limit getMaxNdnPacketSize()"); transport_.send(encoding.buf()); } }
/// <summary> /// Check whether the received signed interest complies with the verification /// policy, and get the indication of the next verification step. /// </summary> /// /// <param name="interest">The interest 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>the indication of next verification step, null if there is no /// further step.</returns> public override sealed ValidationRequest checkVerificationPolicy(Interest interest, int stepCount, OnVerifiedInterest onVerified, OnInterestValidationFailed onValidationFailed, WireFormat wireFormat) { String[] failureReason = new String[] { "unknown" }; Signature signature = extractSignature(interest, wireFormat, failureReason); if (signature == null) { // Can't get the signature from the interest name. try { onValidationFailed.onInterestValidationFailed(interest, failureReason[0]); } catch (Exception ex) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onInterestValidationFailed", ex); } return null; } // For command interests, we need to ignore the last 4 components when // matching the name. Interest certificateInterest = getCertificateInterest(stepCount, "interest", interest.getName().getPrefix(-4), signature, failureReason); if (certificateInterest == null) { try { onValidationFailed.onInterestValidationFailed(interest, failureReason[0]); } catch (Exception ex_0) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onInterestValidationFailed", ex_0); } return null; } if (certificateInterest.getName().size() > 0) return new ValidationRequest(certificateInterest, new ConfigPolicyManager.OnCertificateDownloadCompleteForInterest (this, interest, stepCount, onVerified, onValidationFailed, wireFormat), new ConfigPolicyManager.OnVerifyInterestFailedWrapper ( onValidationFailed, interest), 2, stepCount + 1); else { // For interests, we must check that the timestamp is fresh enough. // This is done after (possibly) downloading the certificate to avoid filling // the cache with bad keys. Name signatureName = net.named_data.jndn.KeyLocator.getFromSignature(signature) .getKeyName(); Name keyName = net.named_data.jndn.security.certificate.IdentityCertificate .certificateNameToPublicKeyName(signatureName); double timestamp = interest.getName().get(-4).toNumber(); if (!interestTimestampIsFresh(keyName, timestamp, failureReason)) { try { onValidationFailed.onInterestValidationFailed(interest, failureReason[0]); } catch (Exception ex_1) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onInterestValidationFailed", ex_1); } return null; } // Certificate is known. Verify the signature. // wireEncode returns the cached encoding if available. if (verify(signature, interest.wireEncode(), failureReason)) { try { onVerified.onVerifiedInterest(interest); } catch (Exception ex_2) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onVerifiedInterest", ex_2); } updateTimestampForKey(keyName, timestamp); } else { try { onValidationFailed.onInterestValidationFailed(interest, failureReason[0]); } catch (Exception ex_3) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onInterestValidationFailed", ex_3); } } return null; } }
public void extractEntriesForNackInterest( Interest interest, ArrayList<Entry> entries) { SignedBlob encoding = interest.wireEncode(); // Go backwards through the list so we can remove entries. for (int i = table_.Count - 1; i >= 0; --i) { PendingInterestTable.Entry pendingInterest = table_[i]; if (pendingInterest.getOnNetworkNack() == null) continue; // wireEncode returns the encoding cached when the interest was sent (if // it was the default wire encoding). if (pendingInterest.getInterest().wireEncode().equals(encoding)) { ILOG.J2CsMapping.Collections.Collections.Add(entries,table_[i]); // We let the callback from callLater call _processInterestTimeout, but // for efficiency, mark this as removed so that it returns right away. ILOG.J2CsMapping.Collections.Collections.RemoveAt(table_,i); pendingInterest.setIsRemoved(); } } }
public void testRedecodeImplicitDigestExclude() { // Check that we encode and decode correctly with an implicit digest exclude. Interest interest = new Interest(new Name("/A")); interest.getExclude() .appendComponent( new Name( "/sha256digest=" + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f") .get(0)); ArrayList dump = dumpInterest(interest); Blob encoding = interest.wireEncode(); Interest reDecodedInterest = new Interest(); try { reDecodedInterest.wireDecode(encoding); } catch (EncodingException ex) { Assert.Fail("Can't decode reDecodedInterest"); } ArrayList redecodedDump = dumpInterest(reDecodedInterest); Assert.AssertTrue("Re-decoded interest does not match original", interestDumpsEqual(dump, redecodedDump)); }