Util.Option <string> GetIdentity(IRoutingMessage routingMessage) { if (routingMessage.SystemProperties.TryGetValue(SystemProperties.ConnectionDeviceId, out string deviceId)) { return(Option.Some(routingMessage.SystemProperties.TryGetValue(SystemProperties.ConnectionModuleId, out string moduleId) ? $"{deviceId}/{moduleId}" : deviceId)); } Events.DeviceIdNotFound(routingMessage); return(Option.None <string>()); }
Util.Option <ICloudProxy> GetCloudProxy(IRoutingMessage routingMessage) { return(this.GetIdentity(routingMessage).Match(id => { Util.Option <ICloudProxy> cloudProxy = this.cloudEndpoint.cloudProxyGetterFunc(id); if (!cloudProxy.HasValue) { Events.IoTHubNotConnected(id); } return cloudProxy; }, () => Option.None <ICloudProxy>())); }
Task <Util.Option <ICloudProxy> > GetCloudProxy(IRoutingMessage routingMessage) { return(this.GetIdentity(routingMessage).Map( async id => { Util.Option <ICloudProxy> cloudProxy = await this.cloudEndpoint.cloudProxyGetterFunc(id); if (!cloudProxy.HasValue) { Events.IoTHubNotConnected(id); } return cloudProxy; }) .GetOrElse(() => Task.FromResult(Option.None <ICloudProxy>()))); }
Util.Option <ICloudProxy> GetCloudProxy(IRoutingMessage routingMessage) { if (routingMessage.SystemProperties.TryGetValue(SystemProperties.ConnectionDeviceId, out string deviceId)) { string id = routingMessage.SystemProperties.TryGetValue(SystemProperties.ConnectionModuleId, out string moduleId) ? $"{deviceId}/{moduleId}" : deviceId; Util.Option <ICloudProxy> cloudProxy = this.cloudEndpoint.cloudProxyGetterFunc(id); if (!cloudProxy.HasValue) { Events.IoTHubNotConnected(id); } return(cloudProxy); } Events.DeviceIdNotFound(routingMessage); return(Option.None <ICloudProxy>()); }
Util.Option <IDeviceProxy> GetDeviceProxy() { this.devicePoxy = this.devicePoxy.Filter(d => d.IsActive) .Map(d => Option.Some(d)) .GetOrElse( () => { Util.Option <IDeviceProxy> currentDeviceProxy = this.moduleEndpoint.connectionManager.GetDeviceConnection(this.moduleEndpoint.moduleId).Filter(d => d.IsActive); if (currentDeviceProxy.HasValue) { if (this.moduleEndpoint.connectionManager.GetSubscriptions(this.moduleEndpoint.moduleId) .Filter(s => s.TryGetValue(DeviceSubscription.ModuleMessages, out bool isActive) && isActive) .HasValue) { return(currentDeviceProxy); } else { Events.NoMessagesSubscription(this.moduleEndpoint.moduleId); } }
public static (bool, Option <string>) ValidateCert(X509Certificate2 remoteCertificate, IList <X509Certificate2> remoteCertificateChain, Option <IList <X509Certificate2> > trustedCACerts) { Preconditions.CheckNotNull(remoteCertificate); Preconditions.CheckNotNull(remoteCertificateChain); Preconditions.CheckNotNull(trustedCACerts); (IList <X509Certificate2> remoteCerts, Option <string> errors) = BuildCertificateList(remoteCertificate, Option.Some(remoteCertificateChain)); if (errors.HasValue) { return(false, errors); } (bool, Option <string>)result = trustedCACerts.Map( caList => { bool match = false; foreach (X509Certificate2 chainElement in remoteCerts) { string thumbprint = GetSha256Thumbprint(chainElement); if (remoteCertificateChain.Any(cert => GetSha256Thumbprint(cert) == thumbprint) && caList.Any(cert => GetSha256Thumbprint(cert) == thumbprint)) { match = true; break; } } return(match ? (true, Option.None <string>()) : (false, Option.Some($"Error validating cert with Subject: {remoteCertificate.SubjectName} Thumbprint: {GetSha256Thumbprint(remoteCertificate)}"))); }) .GetOrElse(() => (true, Option.None <string>())); return(result); }
public static (IList <X509Certificate2>, Option <string>) BuildCertificateList(X509Certificate2 cert, Option <IList <X509Certificate2> > additionalCACertificates) { var chain = new X509Chain { ChainPolicy = { // For performance reasons do not check revocation status. RevocationMode = X509RevocationMode.NoCheck, // Does not check revocation status of the root certificate (sounds like it is meaningless with the option above - ask Simon or Alex) RevocationFlag = X509RevocationFlag.ExcludeRoot, // Certificate Authority can be unknown if it is not issued directly by a well-known CA VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority } }; if (additionalCACertificates.HasValue) { foreach (X509Certificate2 additionalCertificate in additionalCACertificates.GetOrElse(new List <X509Certificate2>())) { if (additionalCertificate != null) { chain.ChainPolicy.ExtraStore.Add(additionalCertificate); } } } try { bool chainBuildSucceeded = chain.Build(cert); X509ChainStatusFlags flags = X509ChainStatusFlags.UntrustedRoot | X509ChainStatusFlags.PartialChain; List <X509ChainStatus> filteredStatus = chain.ChainStatus.Where(cs => !flags.HasFlag(cs.Status)).ToList(); if (!chainBuildSucceeded || filteredStatus.Count > 0) { string errors = $"Certificate with subject: {cert.Subject} failed with errors: "; string s = filteredStatus .Select(c => c.StatusInformation) .Aggregate(errors, (prev, curr) => $"{prev} {curr}"); return(new List <X509Certificate2>(), Option.Some(s)); } IList <X509Certificate2> chainElements = GetCertificatesFromChain(chain); return(chainElements, Option.None <string>()); } finally { chain.Reset(); } }
public static bool ValidateClientCert(X509Certificate2 certificate, IList <X509Certificate2> certificateChain, Option <IList <X509Certificate2> > trustedCACerts, ILogger logger) { Preconditions.CheckNotNull(certificate); Preconditions.CheckNotNull(certificateChain); Preconditions.CheckNotNull(trustedCACerts); if (!ValidateCertExpiry(certificate, logger)) { return(false); } if (IsCACertificate(certificate)) { logger?.LogWarning($"Certificate with subject: {certificate.Subject} was found to be a CA certificate, this is not permitted per the authentication policy"); return(false); } (bool result, Option <string> errors) = ValidateCert(certificate, certificateChain, trustedCACerts); errors.ForEach(v => logger?.LogWarning(v)); return(result); }