/// <summary> /// Asynchronously fetch a certificate. setCertificateStorage must have been /// called first. /// If the requested certificate exists in the storage, then this method will /// immediately call continueValidation with the certificate. If certificate is /// not available, then the implementation-specific doFetch will be called to /// asynchronously fetch the certificate. The successfully-retrieved /// certificate will be automatically added to the unverified cache of the /// certificate storage. /// When the requested certificate is retrieved, continueValidation is called. /// Otherwise, the fetcher implementation calls state.failed() with the /// appropriate error code and diagnostic message. /// </summary> /// /// <param name="certificateRequest"></param> /// <param name="state">The validation state.</param> /// <param name="continueValidation">is the fetched certificate and state is the ValidationState.</param> public void fetch(CertificateRequest certificateRequest, ValidationState state, CertificateFetcher.ValidationContinuation continueValidation) { if (certificateStorage_ == null) { throw new Exception( "CertificateFetcher.fetch: You must first call setCertificateStorage"); } CertificateV2 certificate = certificateStorage_ .getUnverifiedCertificateCache().find( certificateRequest.interest_); if (certificate != null) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.FINE, "Found certificate in **un**verified key cache {0}", certificate.getName().toUri()); continueValidation.continueValidation(certificate, state); return; } // Rename continueValidation to avoid a loop. CertificateFetcher.ValidationContinuation outerContinueValidation_0 = continueValidation; // Fetch asynchronously. doFetch(certificateRequest, state, new CertificateFetcher.Anonymous_C0(this, outerContinueValidation_0)); }
/// <summary> /// Read a base-64-encoded certificate from a file. /// </summary> /// /// <param name="filePath">The certificate file path.</param> /// <returns>The decoded certificate, or null if there is an error.</returns> public static CertificateV2 readCertificate(String filePath) { StringBuilder encodedData = new StringBuilder(); try { TextReader certificateFile = new FileReader( filePath); // Use "try/finally instead of "try-with-resources" or "using" // which are not supported before Java 7. try { String line; while ((line = certificateFile.readLine()) != null) { encodedData.append(line); } } finally { certificateFile.close(); } } catch (FileNotFoundException ex) { return(null); } catch (IOException ex_0) { return(null); } byte[] decodedData = net.named_data.jndn.util.Common.base64Decode(encodedData.toString()); CertificateV2 result = new CertificateV2(); try { result.wireDecode(new Blob(decodedData, false)); return(result); } catch (Exception ex_1) { return(null); } }
public void onData(Interest interest, Data data) { net.named_data.jndn.security.v2.CertificateFetcherFromNetwork.logger_.log(ILOG.J2CsMapping.Util.Logging.Level.FINE, "Fetched certificate from network {0}", data .getName().toUri()); CertificateV2 certificate; try { certificate = new CertificateV2(data); } catch (Exception ex) { state.fail(new ValidationError( net.named_data.jndn.security.v2.ValidationError.MALFORMED_CERTIFICATE, "Fetched a malformed certificate `" + data.getName().toUri() + "` (" + ex + ")")); return; } try { continueValidation.continueValidation(certificate, state); } catch (Exception ex_0) { state.fail(new ValidationError( net.named_data.jndn.security.v2.ValidationError.CANNOT_RETRIEVE_CERTIFICATE, "Error in continueValidation: " + ex_0)); } }
public override void verifyOriginalPacket_(CertificateV2 trustedCertificate) { if (net.named_data.jndn.security.VerificationHelpers.verifyInterestSignature(interest_, trustedCertificate)) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.FINE, "OK signature for interest `{0}`", interest_.getName().toUri()); for (int i = 0; i < successCallbacks_.Count; ++i) { try { successCallbacks_[i].successCallback(interest_); } catch (Exception exception) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in successCallback", exception); } } setOutcome(true); } else { fail(new ValidationError(net.named_data.jndn.security.v2.ValidationError.INVALID_SIGNATURE, "Invalid signature of interest `" + interest_.getName().toUri() + "`")); } }
/// <summary> /// Verify signatures of certificates in the certificate chain. On return, the /// certificate chain contains a list of certificates successfully verified by /// trustedCertificate. /// When the certificate chain cannot be verified, this method will call /// fail() with the INVALID_SIGNATURE error code and the appropriate message. /// This is only called by the Validator class. /// </summary> /// /// <returns>The certificate to validate the original data packet, either the /// last entry in the certificate chain or trustedCertificate if the /// certificate chain is empty. However, return null if the signature of at /// least one certificate in the chain is invalid, in which case all unverified /// certificates have been removed from the certificate chain.</returns> public CertificateV2 verifyCertificateChain_( CertificateV2 trustedCertificate) { CertificateV2 validatedCertificate = trustedCertificate; for (int i = 0; i < certificateChain_.Count; ++i) { CertificateV2 certificateToValidate = certificateChain_[i]; if (!net.named_data.jndn.security.VerificationHelpers.verifyDataSignature(certificateToValidate, validatedCertificate)) { fail(new ValidationError(net.named_data.jndn.security.v2.ValidationError.INVALID_SIGNATURE, "Invalid signature of certificate `" + certificateToValidate.getName().toUri() + "`")); // Remove this and remaining certificates in the chain. while (certificateChain_.Count > i) { ILOG.J2CsMapping.Collections.Collections.RemoveAt(certificateChain_, i); } return(null); } else { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.FINE, "OK signature for certificate `{0}`", certificateToValidate.getName().toUri()); validatedCertificate = certificateToValidate; } } return(validatedCertificate); }
/// <summary> /// Find the certificate by the given key name. /// </summary> /// /// <param name="certificatePrefix"></param> /// <returns>The found certificate, or null if not found. You must not modify /// the returned object. If you need to modify it, then make a copy.</returns> public CertificateV2 find(Name certificatePrefix) { if (certificatePrefix.size() > 0 && certificatePrefix.get(-1).isImplicitSha256Digest()) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.FINE, "Certificate search using a name with an implicit digest is not yet supported"); } refresh(); Name entryKey = (Name)certificatesByName_ .ceilingKey(certificatePrefix); if (entryKey == null) { return(null); } CertificateV2 certificate = ((CertificateCacheV2.Entry)certificatesByName_[entryKey]).certificate_; if (!certificatePrefix.isPrefixOf(certificate.getName())) { return(null); } return(certificate); }
/// <summary> /// Find a certificate for the given interest. /// </summary> /// /// <param name="interest">The input interest packet.</param> /// <returns>The found certificate, or null if not found.</returns> /// @note Interest with implicit digest is not supported. /// @note ChildSelector is not supported. public CertificateV2 find(Interest interest) { refresh(); Name firstKey = (Name)anchors_.anchorsByName_.ceilingKey(interest .getName()); if (firstKey == null) { return(null); } /* foreach */ foreach (Object key in anchors_.anchorsByName_.navigableKeySet().tailSet( firstKey)) { CertificateV2 certificate = (CertificateV2)anchors_.anchorsByName_[(Name)key]; if (!interest.getName().isPrefixOf(certificate.getName())) { break; } try { if (interest.matchesData(certificate)) { return(certificate); } } catch (EncodingException ex) { // We don't expect this to happen. throw new Exception("Error in matchesData: " + ex); } } return(null); }
/// <summary> /// Insert the certificate into the cache. The inserted certificate will be /// removed no later than its NotAfter time, or maxLifetimeMilliseconds given /// to the constructor. /// </summary> /// /// <param name="certificate">The certificate object, which is copied.</param> public void insert(CertificateV2 certificate) { double notAfterTime = certificate.getValidityPeriod().getNotAfter(); // nowOffsetMilliseconds_ is only used for testing. double now = net.named_data.jndn.util.Common.getNowMilliseconds() + nowOffsetMilliseconds_; if (notAfterTime < now) { logger_.log( ILOG.J2CsMapping.Util.Logging.Level.FINE, "Not adding {0}: already expired at {1}", new Object[] { certificate.getName().toUri(), net.named_data.jndn.encrypt.Schedule.toIsoString(notAfterTime) }); return; } double removalTime = Math.Min(notAfterTime, now + maxLifetimeMilliseconds_); if (removalTime < nextRefreshTime_) { // We need to run refresh() sooner.) nextRefreshTime_ = removalTime; } double removalHours = (removalTime - now) / (3600 * 1000.0d); logger_.log(ILOG.J2CsMapping.Util.Logging.Level.FINE, "Adding {0}, will remove in {1} hours", new Object[] { certificate.getName().toUri(), removalHours }); CertificateV2 certificateCopy = new CertificateV2(certificate); ILOG.J2CsMapping.Collections.Collections.Put(certificatesByName_, certificateCopy.getName(), new CertificateCacheV2.Entry( certificateCopy, removalTime)); }
/// <summary> /// Load the static anchor certificate. If a certificate with the name is /// already added, do nothing. /// </summary> /// /// <param name="certificate">The certificate to add, which is copied.</param> public void add(CertificateV2 certificate) { if (ILOG.J2CsMapping.Collections.Collections.Contains(certificate.getName(), anchorNames_)) { return; } // Copy the certificate name. ILOG.J2CsMapping.Collections.Collections.Add(anchorNames_, new Name(certificate.getName())); // This copies the certificate. certificates_.add(certificate); }
/// <summary> /// Find a trusted certificate in the trust anchor container or in the /// verified cache. /// </summary> /// /// <param name="interestForCertificate">The Interest for the certificate.</param> /// <returns>The found certificate, or null if not found.</returns> public CertificateV2 findTrustedCertificate( Interest interestForCertificate) { CertificateV2 certificate = trustAnchors_.find(interestForCertificate); if (certificate != null) { return(certificate); } certificate = verifiedCertificateCache_.find(interestForCertificate); return(certificate); }
/// <summary> /// Add the certificate to the container. /// </summary> /// /// <param name="certificate">The certificate to add, which is copied.</param> public override void add(CertificateV2 certificate) { CertificateV2 certificateCopy; try { certificateCopy = new CertificateV2(certificate); } catch (CertificateV2.Error ex) { // We don't expect this from the copy constructor. throw new Exception( "Error in CertificateV2 copy constructor: " + ex); } ILOG.J2CsMapping.Collections.Collections.Put(anchorsByName_, certificateCopy.getName(), certificateCopy); }
/// <summary> /// Find the certificate by the given interest. /// </summary> /// /// <param name="interest">The input interest object.</param> /// <returns>The found certificate which matches the interest, or null if not /// found. You must not modify the returned object. If you need to modify it, /// then make a copy.</returns> /// @note ChildSelector is not supported. public CertificateV2 find(Interest interest) { if (interest.getChildSelector() >= 0) { logger_.log( ILOG.J2CsMapping.Util.Logging.Level.FINE, "Certificate search using a ChildSelector is not supported. Searching as if this selector not specified"); } if (interest.getName().size() > 0 && interest.getName().get(-1).isImplicitSha256Digest()) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.FINE, "Certificate search using a name with an implicit digest is not yet supported"); } refresh(); Name firstKey = (Name)certificatesByName_.ceilingKey(interest .getName()); if (firstKey == null) { return(null); } /* foreach */ foreach (Object key in certificatesByName_.navigableKeySet().tailSet( firstKey)) { CertificateV2 certificate = ((CertificateCacheV2.Entry)certificatesByName_[(Name)key]).certificate_; if (!interest.getName().isPrefixOf(certificate.getName())) { break; } try { if (interest.matchesData(certificate)) { return(certificate); } } catch (EncodingException ex) { // We don't expect this. Promote to Error. throw new Exception("Error in Interest.matchesData: " + ex); } } return(null); }
/// <summary> /// Request a certificate for further validation. /// </summary> /// /// <param name="certificateRequest">The certificate request.</param> /// <param name="state">The current validation state.</param> internal void requestCertificate(CertificateRequest certificateRequest, ValidationState state) { if (state.getDepth() >= maxDepth_) { state.fail(new ValidationError( net.named_data.jndn.security.v2.ValidationError.EXCEEDED_DEPTH_LIMIT, "Exceeded validation depth limit")); return; } if (state .hasSeenCertificateName(certificateRequest.interest_.getName())) { state.fail(new ValidationError(net.named_data.jndn.security.v2.ValidationError.LOOP_DETECTED, "Validation loop detected for certificate `" + certificateRequest.interest_.getName().toUri() + "`")); return; } logger_.log(ILOG.J2CsMapping.Util.Logging.Level.FINE, "Retrieving {0}", certificateRequest.interest_ .getName().toUri()); CertificateV2 certificate_0 = findTrustedCertificate(certificateRequest.interest_); if (certificate_0 != null) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.FINE, "Found trusted certificate {0}", certificate_0.getName().toUri()); certificate_0 = state.verifyCertificateChain_(certificate_0); if (certificate_0 != null) { state.verifyOriginalPacket_(certificate_0); } for (int i = 0; i < state.getCertificateChain_().Count; ++i) { cacheVerifiedCertificate(state.getCertificateChain_()[i]); } return; } certificateFetcher_.fetch(certificateRequest, state, new Validator.Anonymous_C0(this)); }
private void loadCertificate(String file, HashedSet <Name> oldAnchorNames) { CertificateV2 certificate = net.named_data.jndn.security.v2.TrustAnchorGroup.readCertificate(file); if (certificate != null) { if (!ILOG.J2CsMapping.Collections.Collections.Contains(certificate.getName(), anchorNames_)) { ILOG.J2CsMapping.Collections.Collections.Add(anchorNames_, certificate.getName()); certificates_.add(certificate); } else { ILOG.J2CsMapping.Collections.Collections.Remove(oldAnchorNames, certificate.getName()); } } }
/// <summary> /// Recursively validate the certificates in the certification chain. /// </summary> /// /// <param name="certificate_0">The certificate to check.</param> /// <param name="state">The current validation state.</param> internal void validateCertificate(CertificateV2 certificate_0, ValidationState state) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.FINE, "Start validating certificate {0}", certificate_0 .getName().toUri()); if (!certificate_0.isValid()) { state.fail(new ValidationError(net.named_data.jndn.security.v2.ValidationError.EXPIRED_CERTIFICATE, "Retrieved certificate is not yet valid or expired `" + certificate_0.getName().toUri() + "`")); return; } policy_.checkCertificatePolicy(certificate_0, state, new Validator.Anonymous_C1(this, certificate_0)); }
/// <summary> /// Search for a certificate across all groups (longest prefix match). /// </summary> /// /// <param name="keyName">The key name prefix for searching for the certificate.</param> /// <returns>The found certificate, or null if not found.</returns> public CertificateV2 find(Name keyName) { refresh(); Name nameKey = (Name)anchors_.anchorsByName_.ceilingKey(keyName); if (nameKey == null) { return(null); } CertificateV2 certificate = (CertificateV2)anchors_.anchorsByName_[nameKey]; if (!keyName.isPrefixOf(certificate.getName())) { return(null); } return(certificate); }
/// <summary> /// Insert a static trust anchor. If the certificate (having the same name /// without considering implicit digest) already exists in the group with /// groupId, then do nothing. /// </summary> /// /// <param name="groupId">The certificate group id.</param> /// <param name="certificate">The certificate to insert, which is copied.</param> /// <exception cref="TrustAnchorContainer.Error">If groupId is a dynamic anchor group .</exception> public void insert(String groupId, CertificateV2 certificate) { TrustAnchorGroup group = ILOG.J2CsMapping.Collections.Collections.Get(groups_, groupId); if (group == null) { group = new StaticTrustAnchorGroup(anchors_, groupId); ILOG.J2CsMapping.Collections.Collections.Put(groups_, groupId, group); } if (!(group is StaticTrustAnchorGroup)) { throw new TrustAnchorContainer.Error( "Cannot add a static anchor to the non-static anchor group " + groupId); } ((StaticTrustAnchorGroup)group).add(certificate); }
public override void verifyOriginalPacket_(CertificateV2 trustedCertificate) { if (net.named_data.jndn.security.VerificationHelpers.verifyDataSignature(data_, trustedCertificate)) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.FINE, "OK signature for data `{0}`", data_ .getName().toUri()); try { successCallback_.successCallback(data_); } catch (Exception exception) { logger_.log(ILOG.J2CsMapping.Util.Logging.Level.SEVERE, "Error in successCallback", exception); } setOutcome(true); } else { fail(new ValidationError(net.named_data.jndn.security.v2.ValidationError.INVALID_SIGNATURE, "Invalid signature of data `" + data_.getName().toUri() + "`")); } }
/// <summary> /// Create a new CertificateCacheV2.Entry with the given values. /// </summary> /// /// <param name="certificate">The certificate.</param> /// <param name="removalTime"></param> public Entry(CertificateV2 certificate, double removalTime) { certificate_ = certificate; removalTime_ = removalTime; }
public Anonymous_C1(Validator paramouter_Validator, CertificateV2 certificate_0) { this.certificate = certificate_0; this.outer_Validator = paramouter_Validator; }
/// <summary> /// Process the trust-anchor configuration section and call /// validator_.loadAnchor as needed. /// </summary> /// /// <param name="configSection"></param> /// <param name="inputName">Used for log messages, etc.</param> private void processConfigTrustAnchor(BoostInfoTree configSection, String inputName) { String anchorType = configSection.getFirstValue("type"); if (anchorType == null) { throw new ValidatorConfigError("Expected <trust-anchor.type>"); } if (anchorType.Equals("file", StringComparison.InvariantCultureIgnoreCase)) { // Get trust-anchor.file . String fileName = configSection.getFirstValue("file-name"); if (fileName == null) { throw new ValidatorConfigError( "Expected <trust-anchor.file-name>"); } double refreshPeriod = getRefreshPeriod(configSection); try { validator_.loadAnchor(fileName, fileName, refreshPeriod, false); } catch (TrustAnchorContainer.Error ex) { throw new ValidatorConfigError("Error in loadAnchor: " + ex); } return; } else if (anchorType.Equals("base64", StringComparison.InvariantCultureIgnoreCase)) { // Get trust-anchor.base64-string . String base64String = configSection.getFirstValue("base64-string"); if (base64String == null) { throw new ValidatorConfigError( "Expected <trust-anchor.base64-string>"); } byte[] encoding = net.named_data.jndn.util.Common.base64Decode(base64String); CertificateV2 certificate = new CertificateV2(); try { certificate.wireDecode(new Blob(encoding)); } catch (Exception ex_0) { throw new ValidatorConfigError( "Cannot decode certificate from base64-string: " + ex_0); } try { validator_.loadAnchor("", certificate); } catch (TrustAnchorContainer.Error ex_1) { throw new ValidatorConfigError("Error in loadAnchor: " + ex_1); } return; } else if (anchorType.Equals("dir", StringComparison.InvariantCultureIgnoreCase)) { // Get trust-anchor.dir . String dirString = configSection.getFirstValue("dir"); if (dirString == null) { throw new ValidatorConfigError("Expected <trust-anchor.dir>"); } double refreshPeriod_2 = getRefreshPeriod(configSection); try { validator_ .loadAnchor(dirString, dirString, refreshPeriod_2, true); } catch (TrustAnchorContainer.Error ex_3) { throw new ValidatorConfigError("Error in loadAnchor: " + ex_3); } return; } else if (anchorType.Equals("any", StringComparison.InvariantCultureIgnoreCase)) { shouldBypass_ = true; } else { throw new ValidatorConfigError("Unsupported trust-anchor.type"); } }
/// <summary> /// Add the certificate to the container. /// </summary> /// /// <param name="certificate">The certificate to add, which is copied.</param> public abstract void add(CertificateV2 certificate);
/// <summary> /// Check the certificate against the policy. /// This base class implementation just calls checkPolicy(Data, ...). Your /// derived class may override. /// Depending on implementation of the policy, this check can be done /// synchronously or asynchronously. /// See the checkPolicy(Data) documentation for the semantics. /// </summary> /// /// <param name="certificate">The certificate to check.</param> /// <param name="state">The ValidationState of this validation.</param> /// <param name="continueValidation"></param> public void checkCertificatePolicy(CertificateV2 certificate, ValidationState state, ValidationPolicy.ValidationContinuation continueValidation) { checkPolicy(certificate, state, continueValidation); }
/// <summary> /// Cache the unverified certificate for a period of time (5 minutes). /// </summary> /// /// <param name="certificate">The certificate packet, which is copied.</param> public void cacheUnverifiedCertificate(CertificateV2 certificate) { unverifiedCertificateCache_.insert(certificate); }
/// <summary> /// Verify the signature of the original packet. This is only called by the /// Validator class. /// </summary> /// /// <param name="trustedCertificate">The certificate that signs the original packet.</param> public abstract void verifyOriginalPacket_(CertificateV2 trustedCertificate);
/// <summary> /// Add the certificate to the top of the certificate chain. /// If the certificate chain is empty, then the certificate should be the /// signer of the original packet. If the certificate chain is not empty, then /// the certificate should be the signer of the front of the certificate chain. /// </summary> /// /// @note This function does not verify the signature bits. /// <param name="certificate">The certificate to add, which is copied.</param> public void addCertificate(CertificateV2 certificate) { certificateChain_.Insert(0, new CertificateV2(certificate)); }
/// <summary> /// Load a static trust anchor. Static trust anchors are permanently associated /// with the validator and never expire. /// </summary> /// /// <param name="groupId">The certificate group id.</param> /// <param name="certificate"></param> public void loadAnchor(String groupId, CertificateV2 certificate) { trustAnchors_.insert(groupId, certificate); }
public void continueValidation(CertificateV2 certificate, ValidationState state) { outer_CertificateFetcher.certificateStorage_.cacheUnverifiedCertificate(certificate); outerContinueValidation.continueValidation(certificate, state); }
public void continueValidation(CertificateV2 certificate_0, ValidationState state) { outer_Validator.validateCertificate(certificate_0, state); }