public void ItFetchesACertificateGroupConfigurationFromTheServiceLayer()
        {
            // Test syntax: "AAA" see https://msdn.microsoft.com/en-us/library/hh694602.aspx
            // *Arrange*: setup the current context, in preparation for the test
            // *Act*:     execute an action in the system under test (SUT)
            // *Assert*:  verify that the test succeeded
            var id            = "Default";
            var configuration = new CertificateGroupConfigurationModel()
            {
                Id = id
            };

            // Inject a fake response when Devices.GetAsync() is invoked
            // Moq Quickstart: https://github.com/Moq/moq4/wiki/Quickstart
            _group.Setup(x => x.GetCertificateGroupConfiguration(id)).ReturnsAsync(configuration);

            // Act
            // Note: don't use "var" so to implicitly assert that the
            // method is returning an object of the expected type. We test only
            // public methods, i.e. to test code inside private methods, we
            // write a test that starts from a public method.
            CertificateGroupConfigurationApiModel result = _target.GetCertificateGroupConfigurationAsync(id).Result;

            // Verify that Devices.GetAsync() has been called, exactly once
            // with the correct parameters
            _group.Verify(x => x.GetCertificateGroupConfiguration(It.Is <string>(s => s == id)), Times.Once);
        }
        public static async Task <CertificateGroupConfigurationModel> UpdateCertificateGroupConfiguration(
            KeyVaultServiceClient keyVaultServiceClient,
            string id,
            CertificateGroupConfigurationModel config)
        {
            if (id.ToLower() != config.Id.ToLower())
            {
                throw new ArgumentException("groupid doesn't match config id");
            }
            string json = await keyVaultServiceClient.GetCertificateConfigurationGroupsAsync().ConfigureAwait(false);

            List <CertificateGroupConfigurationModel> certificateGroupCollection = JsonConvert.DeserializeObject <List <CertificateGroupConfigurationModel> >(json);

            var original = certificateGroupCollection.SingleOrDefault(cg => String.Equals(cg.Id, id, StringComparison.OrdinalIgnoreCase));

            if (original == null)
            {
                throw new ArgumentException("invalid groupid");
            }

            ValidateConfiguration(config);

            var index = certificateGroupCollection.IndexOf(original);

            certificateGroupCollection[index] = config;

            json = JsonConvert.SerializeObject(certificateGroupCollection);

            // update config
            json = await keyVaultServiceClient.PutCertificateConfigurationGroupsAsync(json).ConfigureAwait(false);

            // read it back to verify
            certificateGroupCollection = JsonConvert.DeserializeObject <List <CertificateGroupConfigurationModel> >(json);
            return(certificateGroupCollection.SingleOrDefault(cg => String.Equals(cg.Id, id, StringComparison.OrdinalIgnoreCase)));
        }
        private static CertificateGroupConfigurationModel DefaultConfiguration(string id, string subject, string certType)
        {
            var config = new CertificateGroupConfigurationModel()
            {
                Id                                 = id ?? "Default",
                SubjectName                        = subject ?? "CN=Azure Industrial IoT CA, O=Microsoft Corp.",
                CertificateType                    = CertTypeMap()[Opc.Ua.ObjectTypeIds.RsaSha256ApplicationCertificateType],
                DefaultCertificateLifetime         = 24,
                DefaultCertificateHashSize         = 256,
                DefaultCertificateKeySize          = 2048,
                IssuerCACertificateLifetime        = 60,
                IssuerCACertificateHashSize        = 256,
                IssuerCACertificateKeySize         = 2048,
                IssuerCACrlDistributionPoint       = "http://%servicehost%/certs/crl/%serial%/%group%.crl",
                IssuerCAAuthorityInformationAccess = "http://%servicehost%/certs/issuer/%serial%/%group%.cer"
            };

            if (certType != null)
            {
                var checkedCertType = CertTypeMap().Where(c => c.Value.ToLower() == certType.ToLower()).Single();
                config.CertificateType = checkedCertType.Value;
            }
            ValidateConfiguration(config);
            return(config);
        }
 public static KeyVaultCertificateGroupProvider Create(
     KeyVaultServiceClient keyVaultServiceClient,
     CertificateGroupConfigurationModel certificateGroupConfiguration,
     string serviceHost
     )
 {
     return(new KeyVaultCertificateGroupProvider(keyVaultServiceClient, certificateGroupConfiguration, serviceHost));
 }
 private KeyVaultCertificateGroupProvider(
     KeyVaultServiceClient keyVaultServiceClient,
     CertificateGroupConfigurationModel certificateGroupConfiguration,
     string serviceHost
     ) :
     base(null, certificateGroupConfiguration.ToGdsServerModel())
 {
     _keyVaultServiceClient        = keyVaultServiceClient;
     CertificateGroupConfiguration = certificateGroupConfiguration;
     _serviceHost = serviceHost ?? "localhost";
     Certificate  = null;
     Crl          = null;
 }
Esempio n. 6
0
 public CertificateGroupConfigurationApiModel(string id, CertificateGroupConfigurationModel config)
 {
     this.Id = id;
     this.CertificateType                    = config.CertificateType;
     this.SubjectName                        = config.SubjectName;
     this.DefaultCertificateLifetime         = config.DefaultCertificateLifetime;
     this.DefaultCertificateKeySize          = config.DefaultCertificateKeySize;
     this.DefaultCertificateHashSize         = config.DefaultCertificateHashSize;
     this.IssuerCACertificateLifetime        = config.IssuerCACertificateLifetime;
     this.IssuerCACertificateKeySize         = config.IssuerCACertificateKeySize;
     this.IssuerCACertificateHashSize        = config.IssuerCACertificateHashSize;
     this.IssuerCACrlDistributionPoint       = config.IssuerCACrlDistributionPoint;
     this.IssuerCAAuthorityInformationAccess = config.IssuerCAAuthorityInformationAccess;
 }
Esempio n. 7
0
        public CertificateGroupConfigurationModel ToServiceModel()
        {
            var serviceModel = new CertificateGroupConfigurationModel();

            serviceModel.Id = this.Id;
            serviceModel.CertificateType                    = this.CertificateType;
            serviceModel.SubjectName                        = this.SubjectName;
            serviceModel.DefaultCertificateLifetime         = this.DefaultCertificateLifetime;
            serviceModel.DefaultCertificateKeySize          = this.DefaultCertificateKeySize;
            serviceModel.DefaultCertificateHashSize         = this.DefaultCertificateHashSize;
            serviceModel.IssuerCACertificateLifetime        = this.IssuerCACertificateLifetime;
            serviceModel.IssuerCACertificateKeySize         = this.IssuerCACertificateKeySize;
            serviceModel.IssuerCACertificateHashSize        = this.IssuerCACertificateHashSize;
            serviceModel.IssuerCACrlDistributionPoint       = this.IssuerCACrlDistributionPoint;
            serviceModel.IssuerCAAuthorityInformationAccess = this.IssuerCAAuthorityInformationAccess;
            return(serviceModel);
        }
 /// <inheritdoc/>
 public async Task <CertificateGroupConfigurationModel> UpdateCertificateGroupConfiguration(string id, CertificateGroupConfigurationModel config)
 {
     return(await KeyVaultCertificateGroupProvider.UpdateCertificateGroupConfiguration(_keyVaultServiceClient, id, config).ConfigureAwait(false));
 }
        private static void ValidateConfiguration(CertificateGroupConfigurationModel update)
        {
            char[] delimiters    = new char[] { ' ', '\r', '\n' };
            var    updateIdWords = update.Id.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);

            if (updateIdWords.Length != 1)
            {
                throw new ArgumentException("Invalid number of words in group Id");
            }

            update.Id = updateIdWords[0];

            if (!update.Id.All(char.IsLetterOrDigit))
            {
                throw new ArgumentException("Invalid characters in group Id");
            }

            // verify subject
            var subjectList = Opc.Ua.Utils.ParseDistinguishedName(update.SubjectName);

            if (subjectList == null ||
                subjectList.Count == 0)
            {
                throw new ArgumentException("Invalid Subject");
            }

            if (!subjectList.Any(c => c.StartsWith("CN=", StringComparison.InvariantCulture)))
            {
                throw new ArgumentException("Invalid Subject, must have a common name entry");
            }

            // enforce proper formatting for the subject name string
            update.SubjectName = string.Join(", ", subjectList);

            try
            {
                // only allow specific cert types for now
                var certType = CertTypeMap().Where(c => c.Value.ToLower() == update.CertificateType.ToLower()).Single();
                update.CertificateType = certType.Value;
            }
            catch (Exception)
            {
                throw new ArgumentException("Invalid CertificateType");
            }

            // specify ranges for lifetime (months)
            if (update.DefaultCertificateLifetime < 1 ||
                update.IssuerCACertificateLifetime < 1 ||
                update.DefaultCertificateLifetime * 2 > update.IssuerCACertificateLifetime ||
                update.DefaultCertificateLifetime > 60 ||
                update.IssuerCACertificateLifetime > 1200)
            {
                throw new ArgumentException("Invalid lifetime");
            }

            if (update.DefaultCertificateKeySize < 2048 ||
                update.DefaultCertificateKeySize % 1024 != 0 ||
                update.DefaultCertificateKeySize > 2048)
            {
                throw new ArgumentException("Invalid key size, must be 2048, 3072 or 4096");
            }

            if (update.IssuerCACertificateKeySize < 2048 ||
                update.IssuerCACertificateKeySize % 1024 != 0 ||
                update.IssuerCACertificateKeySize > 4096)
            {
                throw new ArgumentException("Invalid key size, must be 2048, 3072 or 4096");
            }

            if (update.DefaultCertificateKeySize > update.IssuerCACertificateKeySize)
            {
                throw new ArgumentException("Invalid key size, Isser CA key must be >= application key");
            }

            if (update.DefaultCertificateHashSize < 256 ||
                update.DefaultCertificateHashSize % 128 != 0 ||
                update.DefaultCertificateHashSize > 512)
            {
                throw new ArgumentException("Invalid hash size, must be 256, 384 or 512");
            }

            if (update.IssuerCACertificateHashSize < 256 ||
                update.IssuerCACertificateHashSize % 128 != 0 ||
                update.IssuerCACertificateHashSize > 512)
            {
                throw new ArgumentException("Invalid hash size, must be 256, 384 or 512");
            }
        }