/// <summary> /// Create an IdentityCertificate from the content in the data packet. /// </summary> /// /// <param name="data">The data packet with the content to decode.</param> public IdentityCertificate(Data data) : base(data) { this.publicKeyName_ = new Name(); if (!isCorrectName(data.getName())) throw new SecurityException("Wrong Identity Certificate Name!"); setPublicKeyName(); }
/// <summary> /// Prepare an encrypted data packet by encrypting the payload using the key /// according to the params. In addition, this prepares the encoded /// EncryptedContent with the encryption result using keyName and params. The /// encoding is set as the content of the data packet. If params defines an /// asymmetric encryption algorithm and the payload is larger than the maximum /// plaintext size, this encrypts the payload with a symmetric key that is /// asymmetrically encrypted and provided as a nonce in the content of the data /// packet. The packet's /{dataName}/ is updated to be /// /{dataName}/FOR/{keyName} /// </summary> /// /// <param name="data">The data packet which is updated.</param> /// <param name="payload">The payload to encrypt.</param> /// <param name="keyName">The key name for the EncryptedContent.</param> /// <param name="key">The encryption key value.</param> /// <param name="params">The parameters for encryption.</param> public static void encryptData(Data data, Blob payload, Name keyName, Blob key, EncryptParams paras) { data.getName().append(NAME_COMPONENT_FOR).append(keyName); EncryptAlgorithmType algorithmType = paras.getAlgorithmType(); if (algorithmType == net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.AesCbc || algorithmType == net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.AesEcb) { EncryptedContent content = encryptSymmetric(payload, key, keyName, paras); data.setContent(content.wireEncode(net.named_data.jndn.encoding.TlvWireFormat.get())); } else if (algorithmType == net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.RsaPkcs || algorithmType == net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.RsaOaep) { // Java doesn't have a direct way to get the maximum plain text size, so // try to encrypt the payload first and catch the error if it is too big. try { EncryptedContent content_0 = encryptAsymmetric(payload, key, keyName, paras); data.setContent(content_0.wireEncode(net.named_data.jndn.encoding.TlvWireFormat.get())); return; } catch (IllegalBlockSizeException ex) { // The payload is larger than the maximum plaintext size. Continue. } // 128-bit nonce. ByteBuffer nonceKeyBuffer = ILOG.J2CsMapping.NIO.ByteBuffer.allocate(16); net.named_data.jndn.util.Common.getRandom().nextBytes(nonceKeyBuffer.array()); Blob nonceKey = new Blob(nonceKeyBuffer, false); Name nonceKeyName = new Name(keyName); nonceKeyName.append("nonce"); EncryptParams symmetricParams = new EncryptParams( net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.AesCbc, net.named_data.jndn.encrypt.algo.AesAlgorithm.BLOCK_SIZE); EncryptedContent nonceContent = encryptSymmetric(payload, nonceKey, nonceKeyName, symmetricParams); EncryptedContent payloadContent = encryptAsymmetric(nonceKey, key, keyName, paras); Blob nonceContentEncoding = nonceContent.wireEncode(); Blob payloadContentEncoding = payloadContent.wireEncode(); ByteBuffer content_1 = ILOG.J2CsMapping.NIO.ByteBuffer.allocate(nonceContentEncoding .size() + payloadContentEncoding.size()); content_1.put(payloadContentEncoding.buf()); content_1.put(nonceContentEncoding.buf()); content_1.flip(); data.setContent(new Blob(content_1, false)); } else throw new Exception("Unsupported encryption method"); }
/// <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> /// Check if the given Data packet can satisfy this Interest. This method /// considers the Name, MinSuffixComponents, MaxSuffixComponents, /// PublisherPublicKeyLocator, and Exclude. It does not consider the /// ChildSelector or MustBeFresh. This uses the given wireFormat to get the /// Data packet encoding for the full Name. /// </summary> /// /// <param name="data">The Data packet to check.</param> /// <param name="wireFormat"></param> /// <returns>True if the given Data packet can satisfy this Interest.</returns> public bool matchesData(Data data, WireFormat wireFormat) { // Imitate ndn-cxx Interest::matchesData. int interestNameLength = getName().size(); Name dataName = data.getName(); int fullNameLength = dataName.size() + 1; // Check MinSuffixComponents. bool hasMinSuffixComponents = getMinSuffixComponents() >= 0; int minSuffixComponents = (hasMinSuffixComponents) ? getMinSuffixComponents() : 0; if (!(interestNameLength + minSuffixComponents <= fullNameLength)) return false; // Check MaxSuffixComponents. bool hasMaxSuffixComponents = getMaxSuffixComponents() >= 0; if (hasMaxSuffixComponents && !(interestNameLength + getMaxSuffixComponents() >= fullNameLength)) return false; // Check the prefix. if (interestNameLength == fullNameLength) { if (getName().get(-1).isImplicitSha256Digest()) { if (!getName().equals(data.getFullName(wireFormat))) return false; } else // The Interest Name is the same length as the Data full Name, but the // last component isn't a digest so there's no possibility of matching. return false; } else { // The Interest Name should be a strict prefix of the Data full Name, if (!getName().isPrefixOf(dataName)) return false; } // Check the Exclude. // The Exclude won't be violated if the Interest Name is the same as the // Data full Name. if (getExclude().size() > 0 && fullNameLength > interestNameLength) { if (interestNameLength == fullNameLength - 1) { // The component to exclude is the digest. if (getExclude().matches( data.getFullName(wireFormat).get(interestNameLength))) return false; } else { // The component to exclude is not the digest. if (getExclude().matches(dataName.get(interestNameLength))) return false; } } // Check the KeyLocator. KeyLocator publisherPublicKeyLocator = getKeyLocator(); if (publisherPublicKeyLocator.getType() != net.named_data.jndn.KeyLocatorType.NONE) { Signature signature = data.getSignature(); if (!net.named_data.jndn.KeyLocator.canGetFromSignature(signature)) // No KeyLocator in the Data packet. return false; if (!publisherPublicKeyLocator.equals(net.named_data.jndn.KeyLocator .getFromSignature(signature))) return false; } return true; }
static void Main(string[] args) { var data = new Data(); data.wireDecode(new Blob(TlvData)); // Use a hard-wired secret for testing. In a real application the signer // ensures that the verifier knows the shared key and its keyName. var key = new Blob(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }); if (KeyChain.verifyDataWithHmacWithSha256(data, key)) Console.Out.WriteLine("Hard-coded data signature verification: VERIFIED"); else Console.Out.WriteLine("Hard-coded data signature verification: FAILED"); var freshData = new Data(new Name("/ndn/abc")); var signature = new HmacWithSha256Signature(); signature.getKeyLocator().setType(KeyLocatorType.KEYNAME); signature.getKeyLocator().setKeyName(new Name("key1")); freshData.setSignature(signature); freshData.setContent(new Blob("SUCCESS!")); Console.Out.WriteLine("Signing fresh data packet " + freshData.getName().toUri()); KeyChain.signWithHmacWithSha256(freshData, key); if (KeyChain.verifyDataWithHmacWithSha256(freshData, key)) Console.Out.WriteLine("Freshly-signed data signature verification: VERIFIED"); else Console.Out.WriteLine("Freshly-signed data signature verification: FAILED"); }
/// <summary> /// This is called from an expressInterest OnData to check that the encryption /// key contained in data fits the timeSlot. This sends a refined interest if /// required. /// </summary> /// /// <param name="interest">The interest given to expressInterest.</param> /// <param name="data">The fetched Data packet.</param> /// <param name="timeSlot_0">The time slot as milliseconds since Jan 1, 1970 UTC.</param> /// <param name="onEncryptedKeys_1">encrypted content key Data packets. If onEncryptedKeys is null, this does not use it.</param> internal void handleCoveringKey(Interest interest, Data data, double timeSlot_0, Producer.OnEncryptedKeys onEncryptedKeys_1, net.named_data.jndn.encrypt.EncryptError.OnError onError_2) { double timeCount = Math.Round(timeSlot_0,MidpointRounding.AwayFromZero); Producer.KeyRequest keyRequest = (Producer.KeyRequest ) ILOG.J2CsMapping.Collections.Collections.Get(keyRequests_,timeCount); Name interestName = interest.getName(); Name keyName = data.getName(); double begin = net.named_data.jndn.encrypt.Schedule.fromIsoString(keyName .get(START_TIME_STAMP_INDEX).getValue().toString()); double end = net.named_data.jndn.encrypt.Schedule.fromIsoString(keyName.get(END_TIME_STAMP_INDEX) .getValue().toString()); if (timeSlot_0 >= end) { // If the received E-KEY covers some earlier period, try to retrieve an // E-KEY covering a later one. Exclude timeRange = new Exclude(interest.getExclude()); excludeBefore(timeRange, keyName.get(START_TIME_STAMP_INDEX)); ILOG.J2CsMapping.Collections.Collections.Put(keyRequest.repeatAttempts,interestName,0); sendKeyInterest(new Interest(interestName).setExclude(timeRange) .setChildSelector(1), timeSlot_0, onEncryptedKeys_1, onError_2); } else { // If the received E-KEY covers the content key, encrypt the content. Blob encryptionKey = data.getContent(); // If everything is correct, save the E-KEY as the current key. if (encryptContentKey(encryptionKey, keyName, timeSlot_0, onEncryptedKeys_1, onError_2)) { Producer.KeyInfo keyInfo = (Producer.KeyInfo ) ILOG.J2CsMapping.Collections.Collections.Get(eKeyInfo_,interestName); keyInfo.beginTimeSlot = begin; keyInfo.endTimeSlot = end; keyInfo.keyBits = encryptionKey; } } }
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; }
/// <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(); }
/// <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> /// 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> /// 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; } }
public void onVerified(Data data) { IdentityCertificate certificate; try { certificate = new IdentityCertificate(data); } catch (DerDecodingException ex) { try { onValidationFailed_.onInterestValidationFailed( originalInterest_, "Cannot decode certificate " + data.getName().toUri()); } catch (Exception exception) { net.named_data.jndn.security.policy.ConfigPolicyManager.logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onInterestValidationFailed", exception); } return; } outer_ConfigPolicyManager.certificateCache_.insertCertificate(certificate); try { // Now that we stored the needed certificate, increment stepCount and try again // to verify the originalInterest. outer_ConfigPolicyManager.checkVerificationPolicy(originalInterest_, stepCount_ + 1, onVerified_, onValidationFailed_, wireFormat_); } catch (SecurityException ex_0) { try { onValidationFailed_.onInterestValidationFailed( originalInterest_, "Error in checkVerificationPolicy: " + ex_0); } catch (Exception exception_1) { net.named_data.jndn.security.policy.ConfigPolicyManager.logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onInterestValidationFailed", exception_1); } } }
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); } } }
public virtual void onDataValidationFailed(Data data, String reason) { try { onError_.onError(net.named_data.jndn.util.SegmentFetcher.ErrorCode.SEGMENT_VERIFICATION_FAILED, "Segment verification failed for " + data.getName().toUri() + " . Reason: " + reason); } catch (Exception ex) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in onError", ex); } }
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>"); } }
/// <summary> /// Wire encode the Data object, sign it and set its signature. /// </summary> /// /// <param name="data"></param> /// <param name="identityName"></param> /// <param name="wireFormat">A WireFormat object used to encode the input. If omitted, use WireFormat getDefaultWireFormat().</param> public void signByIdentity(Data data, Name identityName, WireFormat wireFormat) { Name signingCertificateName; if (identityName.size() == 0) { Name inferredIdentity = policyManager_.inferSigningIdentity(data .getName()); if (inferredIdentity.size() == 0) signingCertificateName = identityManager_ .getDefaultCertificateName(); else signingCertificateName = identityManager_ .getDefaultCertificateNameForIdentity(inferredIdentity); } else signingCertificateName = identityManager_ .getDefaultCertificateNameForIdentity(identityName); if (signingCertificateName.size() == 0) throw new SecurityException("No qualified certificate name found!"); if (!policyManager_.checkSigningPolicy(data.getName(), signingCertificateName)) throw new SecurityException( "Signing Cert name does not comply with signing policy"); identityManager_.signByCertificate(data, signingCertificateName, wireFormat); }
/// <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); } } }
public void testContentAsymmetricEncryptSmall() { /* foreach */ foreach (TestEncryptor.AsymmetricEncryptInput input in encryptorRsaTestInputs) { Blob rawContent = new Blob(toBuffer(new int[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73 }), false); Data data = new Data(); RsaKeyParams rsaParams = new RsaKeyParams(1024); Name keyName = new Name("test"); DecryptKey decryptKey = net.named_data.jndn.encrypt.algo.RsaAlgorithm.generateKey(rsaParams); EncryptKey encryptKey = net.named_data.jndn.encrypt.algo.RsaAlgorithm.deriveEncryptKey(decryptKey .getKeyBits()); Blob eKey = encryptKey.getKeyBits(); Blob dKey = decryptKey.getKeyBits(); EncryptParams encryptParams = new EncryptParams(input.type()); net.named_data.jndn.encrypt.algo.Encryptor.encryptData(data, rawContent, keyName, eKey, encryptParams); Assert.AssertEquals(input.testName(), new Name("/FOR").append(keyName), data.getName()); EncryptedContent extractContent = new EncryptedContent(); extractContent.wireDecode(data.getContent()); Assert.AssertEquals(input.testName(), keyName, extractContent .getKeyLocator().getKeyName()); Assert.AssertEquals(input.testName(), 0, extractContent.getInitialVector() .size()); Assert.AssertEquals(input.testName(), input.type(), extractContent.getAlgorithmType()); Blob recovered = extractContent.getPayload(); Blob decrypted = net.named_data.jndn.encrypt.algo.RsaAlgorithm.decrypt(dKey, recovered, encryptParams); Assert.AssertTrue(input.testName(), rawContent.equals(decrypted)); } }
public void testFullName() { Data data = new Data(); try { data.wireDecode(codedData); } catch (EncodingException ex) { Assert.Fail("Can't decode codedData"); } // Check the full name format. Assert.AssertEquals(data.getName().size() + 1, data.getFullName().size()); Assert.AssertEquals(data.getName(), data.getFullName().getPrefix(-1)); Assert.AssertEquals(32, data.getFullName().get(-1).getValue().size()); // Check the independent digest calculation. Blob newDigest = new Blob(net.named_data.jndn.util.Common.digestSha256(codedData)); Assert.AssertTrue(newDigest.equals(data.getFullName().get(-1).getValue())); // Check the expected URI. Assert.AssertEquals( "/ndn/abc/sha256digest=" + "96556d685dcb1af04be4ae57f0e7223457d4055ea9b3d07c0d337bef4a8b3ee9", data.getFullName().toUri()); // Changing the Data packet should change the full name. Name saveFullName = new Name(data.getFullName()); data.setContent(new Blob()); Assert.AssertFalse(data.getFullName().get(-1).equals(saveFullName.get(-1))); }
public void testContentSymmetricEncrypt() { /* foreach */ foreach (TestEncryptor.SymmetricEncryptInput input in encryptorAesTestInputs) { Data data = new Data(); net.named_data.jndn.encrypt.algo.Encryptor.encryptData(data, input.plainText(), input.keyName(), input.key(), input.encryptParams()); Assert.AssertEquals(input.testName(), new Name("/FOR").append(input.keyName()), data.getName()); Assert.AssertTrue(input.testName(), input.encryptedContent().equals(data.getContent())); EncryptedContent content = new EncryptedContent(); content.wireDecode(data.getContent()); Blob decryptedOutput = net.named_data.jndn.encrypt.algo.AesAlgorithm.decrypt(input.key(), content.getPayload(), input.encryptParams()); Assert.AssertTrue(input.testName(), input.plainText().equals(decryptedOutput)); } }
public void testContentAsymmetricEncryptLarge() { /* foreach */ foreach (TestEncryptor.AsymmetricEncryptInput input in encryptorRsaTestInputs) { Blob largeContent = new Blob(toBuffer(new int[] { 0x73, 0x5a, 0xbd, 0x47, 0x0c, 0xfe, 0xf8, 0x7d, 0x2e, 0x17, 0xaa, 0x11, 0x6f, 0x23, 0xc5, 0x10, 0x23, 0x36, 0x88, 0xc4, 0x2a, 0x0f, 0x9a, 0x72, 0x54, 0x31, 0xa8, 0xb3, 0x51, 0x18, 0x9f, 0x0e, 0x1b, 0x93, 0x62, 0xd9, 0xc4, 0xf5, 0xf4, 0x3d, 0x61, 0x9a, 0xca, 0x05, 0x65, 0x6b, 0xc6, 0x41, 0xf9, 0xd5, 0x1c, 0x67, 0xc1, 0xd0, 0xd5, 0x6f, 0x7b, 0x70, 0xb8, 0x8f, 0xdb, 0x19, 0x68, 0x7c, 0xe0, 0x2d, 0x04, 0x49, 0xa9, 0xa2, 0x77, 0x4e, 0xfc, 0x60, 0x0d, 0x7c, 0x1b, 0x93, 0x6c, 0xd2, 0x61, 0xc4, 0x6b, 0x01, 0xe9, 0x12, 0x28, 0x6d, 0xf5, 0x78, 0xe9, 0x99, 0x0b, 0x9c, 0x4f, 0x90, 0x34, 0x3e, 0x06, 0x92, 0x57, 0xe3, 0x7a, 0x8f, 0x13, 0xc7, 0xf3, 0xfe, 0xf0, 0xe2, 0x59, 0x48, 0x15, 0xb9, 0xdb, 0x77, 0x07, 0x1d, 0x6d, 0xb5, 0x65, 0x17, 0xdf, 0x76, 0x6f, 0xb5, 0x43, 0xde, 0x71, 0xac, 0xf1, 0x22, 0xbf, 0xb2, 0xe5, 0xd9, 0x22, 0xf1, 0x67, 0x76, 0x71, 0x0c, 0xff, 0x99, 0x7b, 0x94, 0x9b, 0x24, 0x20, 0x80, 0xe3, 0xcc, 0x06, 0x4a, 0xed, 0xdf, 0xec, 0x50, 0xd5, 0x87, 0x3d, 0xa0, 0x7d, 0x9c, 0xe5, 0x13, 0x10, 0x98, 0x14, 0xc3, 0x90, 0x10, 0xd9, 0x25, 0x9a, 0x59, 0xe9, 0x37, 0x26, 0xfd, 0x87, 0xd7, 0xf4, 0xf9, 0x11, 0x91, 0xad, 0x5c, 0x00, 0x95, 0xf5, 0x2b, 0x37, 0xf7, 0x4e, 0xb4, 0x4b, 0x42, 0x7c, 0xb3, 0xad, 0xd6, 0x33, 0x5f, 0x0b, 0x84, 0x57, 0x7f, 0xa7, 0x07, 0x73, 0x37, 0x4b, 0xab, 0x2e, 0xfb, 0xfe, 0x1e, 0xcb, 0xb6, 0x4a, 0xc1, 0x21, 0x5f, 0xec, 0x92, 0xb7, 0xac, 0x97, 0x75, 0x20, 0xc9, 0xd8, 0x9e, 0x93, 0xd5, 0x12, 0x7a, 0x64, 0xb9, 0x4c, 0xed, 0x49, 0x87, 0x44, 0x5b, 0x4f, 0x90, 0x34, 0x3e, 0x06, 0x92, 0x57, 0xe3, 0x7a, 0x8f, 0x13, 0xc7, 0xf3, 0xfe, 0xf0, 0xe2, 0x59, 0x48, 0x15, 0xb9, 0xdb, 0x77, 0x07, 0x1d, 0x6d, 0xb5, 0x65, 0x17, 0xdf, 0x76, 0x6f, 0xb5, 0x43, 0xde, 0x71, 0xac, 0xf1, 0x22, 0xbf, 0xb2, 0xe5, 0xd9 }), false); Data data = new Data(); RsaKeyParams rsaParams = new RsaKeyParams(1024); Name keyName = new Name("test"); DecryptKey decryptKey = net.named_data.jndn.encrypt.algo.RsaAlgorithm.generateKey(rsaParams); EncryptKey encryptKey = net.named_data.jndn.encrypt.algo.RsaAlgorithm.deriveEncryptKey(decryptKey .getKeyBits()); Blob eKey = encryptKey.getKeyBits(); Blob dKey = decryptKey.getKeyBits(); EncryptParams encryptParams = new EncryptParams(input.type()); net.named_data.jndn.encrypt.algo.Encryptor.encryptData(data, largeContent, keyName, eKey, encryptParams); Assert.AssertEquals(input.testName(), new Name("/FOR").append(keyName), data.getName()); Blob largeDataContent = data.getContent(); // largeDataContent is a sequence of the two EncryptedContent. EncryptedContent encryptedNonce = new EncryptedContent(); encryptedNonce.wireDecode(largeDataContent); Assert.AssertEquals(input.testName(), keyName, encryptedNonce .getKeyLocator().getKeyName()); Assert.AssertEquals(input.testName(), 0, encryptedNonce.getInitialVector() .size()); Assert.AssertEquals(input.testName(), input.type(), encryptedNonce.getAlgorithmType()); // Use the size of encryptedNonce to find the start of encryptedPayload. ByteBuffer payloadContent = largeDataContent.buf().duplicate(); payloadContent.position(encryptedNonce.wireEncode().size()); EncryptedContent encryptedPayload = new EncryptedContent(); encryptedPayload.wireDecode(payloadContent); Name nonceKeyName = new Name(keyName); nonceKeyName.append("nonce"); Assert.AssertEquals(input.testName(), nonceKeyName, encryptedPayload .getKeyLocator().getKeyName()); Assert.AssertEquals(input.testName(), 16, encryptedPayload .getInitialVector().size()); Assert.AssertEquals(input.testName(), net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.AesCbc, encryptedPayload.getAlgorithmType()); Assert.AssertTrue(input.testName(), encryptedNonce.wireEncode().size() + encryptedPayload.wireEncode().size() == largeDataContent .size()); Blob blobNonce = encryptedNonce.getPayload(); Blob nonce = net.named_data.jndn.encrypt.algo.RsaAlgorithm.decrypt(dKey, blobNonce, encryptParams); encryptParams.setAlgorithmType(net.named_data.jndn.encrypt.algo.EncryptAlgorithmType.AesCbc); encryptParams.setInitialVector(encryptedPayload.getInitialVector()); Blob bufferPayload = encryptedPayload.getPayload(); Blob largePayload = net.named_data.jndn.encrypt.algo.AesAlgorithm.decrypt(nonce, bufferPayload, encryptParams); Assert.AssertTrue(input.testName(), largeContent.equals(largePayload)); } }
/// <summary> /// Check if the given Data packet can satisfy this Interest. This method /// considers the Name, MinSuffixComponents, MaxSuffixComponents, /// PublisherPublicKeyLocator, and Exclude. It does not consider the /// ChildSelector or MustBeFresh. This uses the given wireFormat to get the /// Data packet encoding for the full Name. /// </summary> /// /// <param name="data">The Data packet to check.</param> /// <param name="wireFormat"></param> /// <returns>True if the given Data packet can satisfy this Interest.</returns> public bool matchesData(Data data, WireFormat wireFormat) { // Imitate ndn-cxx Interest::matchesData. int interestNameLength = getName().size(); Name dataName = data.getName(); int fullNameLength = dataName.size() + 1; // Check MinSuffixComponents. bool hasMinSuffixComponents = getMinSuffixComponents() >= 0; int minSuffixComponents = (hasMinSuffixComponents) ? getMinSuffixComponents() : 0; if (!(interestNameLength + minSuffixComponents <= fullNameLength)) { return(false); } // Check MaxSuffixComponents. bool hasMaxSuffixComponents = getMaxSuffixComponents() >= 0; if (hasMaxSuffixComponents && !(interestNameLength + getMaxSuffixComponents() >= fullNameLength)) { return(false); } // Check the prefix. if (interestNameLength == fullNameLength) { if (getName().get(-1).isImplicitSha256Digest()) { if (!getName().equals(data.getFullName(wireFormat))) { return(false); } } else { // The Interest Name is the same length as the Data full Name, but the // last component isn't a digest so there's no possibility of matching. return(false); } } else { // The Interest Name should be a strict prefix of the Data full Name, if (!getName().isPrefixOf(dataName)) { return(false); } } // Check the Exclude. // The Exclude won't be violated if the Interest Name is the same as the // Data full Name. if (getExclude().size() > 0 && fullNameLength > interestNameLength) { if (interestNameLength == fullNameLength - 1) { // The component to exclude is the digest. if (getExclude().matches( data.getFullName(wireFormat).get(interestNameLength))) { return(false); } } else { // The component to exclude is not the digest. if (getExclude().matches(dataName.get(interestNameLength))) { return(false); } } } // Check the KeyLocator. KeyLocator publisherPublicKeyLocator = getKeyLocator(); if (publisherPublicKeyLocator.getType() != net.named_data.jndn.KeyLocatorType.NONE) { Signature signature = data.getSignature(); if (!net.named_data.jndn.KeyLocator.canGetFromSignature(signature)) { // No KeyLocator in the Data packet. return(false); } if (!publisherPublicKeyLocator.equals(net.named_data.jndn.KeyLocator .getFromSignature(signature))) { return(false); } } return(true); }