< Summary

Class:Azure.Security.KeyVault.Certificates.CertificatePolicy
Assembly:Azure.Security.KeyVault.Certificates
File(s):C:\Git\azure-sdk-for-net\sdk\keyvault\Azure.Security.KeyVault.Certificates\src\CertificatePolicy.cs
Covered lines:158
Uncovered lines:24
Coverable lines:182
Total lines:520
Line coverage:86.8% (158 of 182)
Covered branches:115
Total branches:126
Branch coverage:91.2% (115 of 126)

Metrics

MethodCyclomatic complexity Line coverage Branch coverage
.cctor()-100%100%
.ctor(...)-100%100%
.ctor(...)-62.5%50%
.ctor(...)-30%0%
.ctor()-100%100%
get_Default()-100%100%
get_KeyType()-100%100%
get_ReuseKey()-100%100%
get_Exportable()-100%100%
get_KeyCurveName()-100%100%
get_KeySize()-100%100%
get_Subject()-100%100%
get_SubjectAlternativeNames()-0%100%
get_IssuerName()-100%100%
set_IssuerName(...)-100%100%
get_ContentType()-100%100%
get_CertificateType()-100%100%
set_CertificateType(...)-0%100%
get_CertificateTransparency()-100%100%
set_CertificateTransparency(...)-100%100%
get_ValidityInMonths()-100%100%
get_Enabled()-100%100%
get_UpdatedOn()-100%100%
get_CreatedOn()-100%100%
get_KeyUsage()-100%100%
get_EnhancedKeyUsage()-100%100%
get_LifetimeActions()-100%100%
Azure.Security.KeyVault.IJsonDeserializable.ReadProperties(...)-100%100%
Azure.Security.KeyVault.IJsonSerializable.WriteProperties(...)-100%97.37%
ReadKeyProperties(...)-83.33%91.67%
WriteKeyProperties(...)-100%100%
ReadSecretProperties(...)-100%100%
WriteSecretProperties(...)-100%100%
ReadX509CertificateProperties(...)-76.92%93.75%
WriteX509CertificateProperties(...)-63.16%68.75%
ReadAttributesProperties(...)-100%100%
WriteAttributesProperties(...)-100%100%

File(s)

C:\Git\azure-sdk-for-net\sdk\keyvault\Azure.Security.KeyVault.Certificates\src\CertificatePolicy.cs

#LineLine coverage
 1// Copyright (c) Microsoft Corporation. All rights reserved.
 2// Licensed under the MIT License.
 3
 4using System;
 5using System.Collections.Generic;
 6using System.Text.Json;
 7using Azure.Core;
 8
 9namespace Azure.Security.KeyVault.Certificates
 10{
 11    /// <summary>
 12    /// A policy which governs the lifecycle a properties of a certificate managed by Azure Key Vault.
 13    /// </summary>
 14    public class CertificatePolicy : IJsonSerializable, IJsonDeserializable
 15    {
 16        private const string DefaultSubject = "CN=DefaultPolicy";
 17        private const string DefaultIssuerName = "Self";
 18
 19        private const string KeyTypePropertyName = "kty";
 20        private const string ReuseKeyPropertyName = "reuse_key";
 21        private const string ExportablePropertyName = "exportable";
 22        private const string CurveNamePropertyName = "crv";
 23        private const string KeySizePropertyName = "key_size";
 24        private const string KeyPropsPropertyName = "key_props";
 25        private const string SecretPropsPropertyName = "secret_props";
 26        private const string X509PropsPropertyName = "x509_props";
 27        private const string LifetimeActionsPropertyName = "lifetime_actions";
 28        private const string IssuerPropertyName = "issuer";
 29        private const string AttributesPropertyName = "attributes";
 30        private const string ContentTypePropertyName = "contentType";
 31        private const string SubjectPropertyName = "subject";
 32        private const string SansPropertyName = "sans";
 33        private const string KeyUsagePropertyName = "key_usage";
 34        private const string EkusPropertyName = "ekus";
 35        private const string ValidityMonthsPropertyName = "validity_months";
 36        private const string EnabledPropertyName = "enabled";
 37        private const string CreatedPropertyName = "created";
 38        private const string UpdatedPropertyName = "updated";
 39
 240        private static readonly JsonEncodedText s_keyTypePropertyNameBytes = JsonEncodedText.Encode(KeyTypePropertyName)
 241        private static readonly JsonEncodedText s_reuseKeyPropertyNameBytes = JsonEncodedText.Encode(ReuseKeyPropertyNam
 242        private static readonly JsonEncodedText s_exportablePropertyNameBytes = JsonEncodedText.Encode(ExportablePropert
 243        private static readonly JsonEncodedText s_curveNamePropertyNameBytes = JsonEncodedText.Encode(CurveNamePropertyN
 244        private static readonly JsonEncodedText s_keySizePropertyNameBytes = JsonEncodedText.Encode(KeySizePropertyName)
 245        private static readonly JsonEncodedText s_lifetimeActionsPropertyNameBytes = JsonEncodedText.Encode(LifetimeActi
 246        private static readonly JsonEncodedText s_issuerPropertyNameBytes = JsonEncodedText.Encode(IssuerPropertyName);
 247        private static readonly JsonEncodedText s_attributesPropertyNameBytes = JsonEncodedText.Encode(AttributesPropert
 248        private static readonly JsonEncodedText s_keyPropsPropertyNameBytes = JsonEncodedText.Encode(KeyPropsPropertyNam
 249        private static readonly JsonEncodedText s_secretPropsPropertyNameBytes = JsonEncodedText.Encode(SecretPropsPrope
 250        private static readonly JsonEncodedText s_x509PropsPropertyNameBytes = JsonEncodedText.Encode(X509PropsPropertyN
 251        private static readonly JsonEncodedText s_contentTypePropertyNameBytes = JsonEncodedText.Encode(ContentTypePrope
 252        private static readonly JsonEncodedText s_subjectPropertyNameBytes = JsonEncodedText.Encode(SubjectPropertyName)
 253        private static readonly JsonEncodedText s_sansPropertyNameBytes = JsonEncodedText.Encode(SansPropertyName);
 254        private static readonly JsonEncodedText s_keyUsagePropertyNameBytes = JsonEncodedText.Encode(KeyUsagePropertyNam
 255        private static readonly JsonEncodedText s_ekusPropertyNameBytes = JsonEncodedText.Encode(EkusPropertyName);
 256        private static readonly JsonEncodedText s_validityMonthsPropertyNameBytes = JsonEncodedText.Encode(ValidityMonth
 257        private static readonly JsonEncodedText s_enabledPropertyNameBytes = JsonEncodedText.Encode(EnabledPropertyName)
 58
 59        private IssuerParameters _issuer;
 60
 61        /// <summary>
 62        /// Initializes a new instance of the <see cref="CertificatePolicy"/> class.
 63        /// </summary>
 64        /// <param name="issuerName">The name of an issuer for the certificate, including values from <see cref="WellKno
 65        /// <param name="subject">The subject name of the certificate, such as "CN=contoso.com".</param>
 66        /// <exception cref="ArgumentException"><paramref name="subject"/> or <paramref name="issuerName"/> is empty.</e
 67        /// <exception cref="ArgumentNullException"><paramref name="subject"/> or <paramref name="issuerName"/> is null.
 3868        public CertificatePolicy(string issuerName, string subject)
 69        {
 3870            Argument.AssertNotNullOrEmpty(issuerName, nameof(issuerName));
 3271            Argument.AssertNotNullOrEmpty(subject, nameof(subject));
 72
 2873            IssuerName = issuerName;
 2874            Subject = subject;
 2875        }
 76
 77        /// <summary>
 78        /// Initializes a new instance of the <see cref="CertificatePolicy"/> class.
 79        /// </summary>
 80        /// <param name="issuerName">The name of an issuer for the certificate, including values from <see cref="WellKno
 81        /// <param name="subjectAlternativeNames">The subject alternative names (SANs) of the certificate.</param>
 82        /// <exception cref="ArgumentException"><paramref name="issuerName"/> is empty or <paramref name="subjectAlterna
 83        /// <exception cref="ArgumentNullException"><paramref name="subjectAlternativeNames"/> or <paramref name="issuer
 1084        public CertificatePolicy(string issuerName, SubjectAlternativeNames subjectAlternativeNames)
 85        {
 1086            Argument.AssertNotNullOrEmpty(issuerName, nameof(issuerName));
 887            Argument.AssertNotNull(subjectAlternativeNames, nameof(subjectAlternativeNames));
 488            if (subjectAlternativeNames.IsEmpty)
 89            {
 490                throw new ArgumentException("Value cannot contain empty collection properties.", nameof(subjectAlternati
 91            }
 92
 093            SubjectAlternativeNames = subjectAlternativeNames;
 094            IssuerName = issuerName;
 095        }
 96
 97        /// <summary>
 98        /// Initializes a new instance of the <see cref="CertificatePolicy"/> class.
 99        /// </summary>
 100        /// <param name="issuerName">The name of an issuer for the certificate, including values from <see cref="WellKno
 101        /// <param name="subject">The subject name of the certificate, such as "CN=contoso.com".</param>
 102        /// <param name="subjectAlternativeNames">The subject alternative names (SANs) of the certificate.</param>
 103        /// <exception cref="ArgumentException"><paramref name="subject"/> or <paramref name="issuerName"/> is empty, or
 104        /// <exception cref="ArgumentNullException"><paramref name="subject"/>, <paramref name="issuerName"/>, or <param
 8105        public CertificatePolicy(string issuerName, string subject, SubjectAlternativeNames subjectAlternativeNames)
 106        {
 8107            Argument.AssertNotNullOrEmpty(issuerName, nameof(issuerName));
 4108            Argument.AssertNotNullOrEmpty(subject, nameof(subject));
 0109            Argument.AssertNotNull(subjectAlternativeNames, nameof(subjectAlternativeNames));
 0110            if (subjectAlternativeNames.IsEmpty)
 111            {
 0112                throw new ArgumentException("Value cannot contain empty collection properties.", nameof(subjectAlternati
 113            }
 114
 0115            Subject = subject;
 0116            IssuerName = issuerName;
 0117            SubjectAlternativeNames = subjectAlternativeNames;
 0118        }
 119
 146120        internal CertificatePolicy()
 121        {
 146122        }
 123
 124        /// <summary>
 125        /// Gets a new <see cref="CertificatePolicy"/> suitable for self-signed certificate requests.
 126        /// You should change the <see cref="Subject"/> before passing this policy to create a certificate.
 127        /// </summary>
 2128        public static CertificatePolicy Default => new CertificatePolicy(DefaultIssuerName, DefaultSubject);
 129
 130        /// <summary>
 131        /// Gets or sets the type of backing key to be generated when issuing new certificates.
 132        /// </summary>
 362133        public CertificateKeyType? KeyType { get; set; }
 134
 135        /// <summary>
 136        /// Gets or sets a value indicating whether the certificate key should be reused when rotating the certificate.
 137        /// </summary>
 314138        public bool? ReuseKey { get; set; }
 139
 140        /// <summary>
 141        /// Gets or sets a value indicating whether the certificate key is exportable from the vault or secure certifica
 142        /// </summary>
 304143        public bool? Exportable { get; set; }
 144
 145        /// <summary>
 146        /// Gets or sets the curve which back an Elliptic Curve (EC) key.
 147        /// </summary>
 108148        public CertificateKeyCurveName? KeyCurveName { get; set; }
 149
 150        /// <summary>
 151        /// Gets or sets the size of the RSA key. The value must be a valid RSA key length such as 2048 or 4092.
 152        /// </summary>
 196153        public int? KeySize { get; set; }
 154
 155        /// <summary>
 156        /// Gets the subject name of a certificate.
 157        /// </summary>
 412158        public string Subject { get; internal set; }
 159
 160        /// <summary>
 161        /// Gets the subject alternative names (SANs) of a certificate.
 162        /// </summary>
 0163        public SubjectAlternativeNames SubjectAlternativeNames { get; internal set; }
 164
 165        /// <summary>
 166        /// Gets the name of an issuer for a certificate.
 167        /// </summary>
 168        public string IssuerName
 169        {
 102170            get => _issuer.IssuerName;
 112171            internal set => _issuer.IssuerName = value;
 172        }
 173
 174        /// <summary>
 175        /// Gets or sets the <see cref="CertificateContentType"/> of the certificate when downloaded from GetSecret.
 176        /// </summary>
 400177        public CertificateContentType? ContentType { get; set; }
 178
 179        /// <summary>
 180        /// Gets or sets the certificate type of a certificate.
 181        /// </summary>
 182        public string CertificateType
 183        {
 18184            get => _issuer.CertificateType;
 0185            set => _issuer.CertificateType = value;
 186        }
 187
 188        /// <summary>
 189        /// Gets or sets a value indicating whether a certificate should be published to the certificate transparency li
 190        /// </summary>
 191        public bool? CertificateTransparency
 192        {
 26193            get => _issuer.CertificateTransparency;
 72194            set => _issuer.CertificateTransparency = value;
 195        }
 196
 197        /// <summary>
 198        /// Gets or sets the validity period for a certificate in months.
 199        /// </summary>
 166200        public int? ValidityInMonths { get; set; }
 201
 202        /// <summary>
 203        /// Gets or sets a value indicating whether the certificate is currently enabled. If null, the server default wi
 204        /// </summary>
 174205        public bool? Enabled { get; set; }
 206
 207        /// <summary>
 208        /// Gets a <see cref="DateTimeOffset"/> indicating when the certificate was updated.
 209        /// </summary>
 80210        public DateTimeOffset? UpdatedOn { get; internal set; }
 211
 212        /// <summary>
 213        /// Gets a <see cref="DateTimeOffset"/> indicating when the certificate was created.
 214        /// </summary>
 76215        public DateTimeOffset? CreatedOn { get; internal set; }
 216
 217        /// <summary>
 218        /// Gets the allowed usages for the key of the certificate.
 219        /// </summary>
 1070220        public IList<CertificateKeyUsage> KeyUsage { get; } = new List<CertificateKeyUsage>();
 221
 222        /// <summary>
 223        /// Gets the allowed enhanced key usages (EKUs) of the certificate.
 224        /// </summary>
 418225        public IList<string> EnhancedKeyUsage { get; } = new List<string>();
 226
 227        /// <summary>
 228        /// Gets the actions to be executed at specified times in the certificates lifetime.
 229        /// </summary>
 374230        public IList<LifetimeAction> LifetimeActions { get; } = new List<LifetimeAction>();
 231
 232        void IJsonDeserializable.ReadProperties(JsonElement json)
 233        {
 1120234            foreach (JsonProperty prop in json.EnumerateObject())
 235            {
 490236                switch (prop.Name)
 237                {
 238                    case KeyPropsPropertyName:
 70239                        ReadKeyProperties(prop.Value);
 70240                        break;
 241
 242                    case SecretPropsPropertyName:
 70243                        ReadSecretProperties(prop.Value);
 70244                        break;
 245
 246                    case X509PropsPropertyName:
 70247                        ReadX509CertificateProperties(prop.Value);
 70248                        break;
 249
 250                    case IssuerPropertyName:
 70251                        _issuer.ReadProperties(prop.Value);
 70252                        break;
 253
 254                    case AttributesPropertyName:
 70255                        ReadAttributesProperties(prop.Value);
 70256                        break;
 257
 258                    case LifetimeActionsPropertyName:
 280259                        foreach (JsonElement actionElem in prop.Value.EnumerateArray())
 260                        {
 70261                            LifetimeActions.Add(LifetimeAction.FromJsonObject(actionElem));
 262                        }
 263                        break;
 264
 265                }
 266            }
 70267        }
 268
 269        void IJsonSerializable.WriteProperties(Utf8JsonWriter json)
 270        {
 271            // Key Props
 88272            if (KeyType.HasValue || KeyCurveName.HasValue || KeySize.HasValue || ReuseKey.HasValue || Exportable.HasValu
 273            {
 68274                json.WriteStartObject(s_keyPropsPropertyNameBytes);
 275
 68276                WriteKeyProperties(json);
 277
 68278                json.WriteEndObject();
 279            }
 280
 281            // Secret Props
 88282            if (ContentType.HasValue)
 283            {
 70284                json.WriteStartObject(s_secretPropsPropertyNameBytes);
 285
 70286                WriteSecretProperties(json);
 287
 70288                json.WriteEndObject();
 289            }
 290
 291            // X509 Props
 88292            if (Subject != null || (SubjectAlternativeNames != null && !SubjectAlternativeNames.IsEmpty) || !KeyUsage.Is
 293            {
 74294                json.WriteStartObject(s_x509PropsPropertyNameBytes);
 295
 74296                WriteX509CertificateProperties(json);
 297
 74298                json.WriteEndObject();
 299            }
 300
 301            // Issuer Props
 88302            if (IssuerName != null || CertificateType != null || CertificateTransparency.HasValue)
 303            {
 74304                json.WriteStartObject(s_issuerPropertyNameBytes);
 305
 74306                _issuer.WriteProperties(json);
 307
 74308                json.WriteEndObject();
 309            }
 310
 88311            if (Enabled.HasValue)
 312            {
 4313                json.WriteStartObject(s_attributesPropertyNameBytes);
 314
 4315                WriteAttributesProperties(json);
 316
 4317                json.WriteEndObject();
 318            }
 319
 88320            if (!LifetimeActions.IsNullOrEmpty())
 321            {
 2322                json.WriteStartArray(s_lifetimeActionsPropertyNameBytes);
 323
 8324                foreach (LifetimeAction action in LifetimeActions)
 325                {
 2326                    if (action != null)
 327                    {
 2328                        json.WriteStartObject();
 329
 2330                        ((IJsonSerializable)action).WriteProperties(json);
 331
 2332                        json.WriteEndObject();
 333                    }
 334                }
 335
 2336                json.WriteEndArray();
 337            }
 88338        }
 339
 340        private void ReadKeyProperties(JsonElement json)
 341        {
 700342            foreach (JsonProperty prop in json.EnumerateObject())
 343            {
 280344                switch (prop.Name)
 345                {
 346                    case KeyTypePropertyName:
 70347                        KeyType = prop.Value.GetString();
 70348                        break;
 349
 350                    case ReuseKeyPropertyName:
 70351                        ReuseKey = prop.Value.GetBoolean();
 70352                        break;
 353
 354                    case ExportablePropertyName:
 70355                        Exportable = prop.Value.GetBoolean();
 70356                        break;
 357
 358                    case CurveNamePropertyName:
 0359                        KeyCurveName = prop.Value.GetString();
 0360                        break;
 361
 362                    case KeySizePropertyName:
 70363                        KeySize = prop.Value.GetInt32();
 364                        break;
 365                }
 366            }
 70367        }
 368
 369        private void WriteKeyProperties(Utf8JsonWriter json)
 370        {
 68371            if (KeyType.HasValue)
 372            {
 56373                json.WriteString(s_keyTypePropertyNameBytes, KeyType.ToString());
 374            }
 375
 68376            if (ReuseKey.HasValue)
 377            {
 60378                json.WriteBoolean(s_reuseKeyPropertyNameBytes, ReuseKey.Value);
 379            }
 380
 68381            if (Exportable.HasValue)
 382            {
 60383                json.WriteBoolean(s_exportablePropertyNameBytes, Exportable.Value);
 384            }
 385
 68386            if (KeyCurveName.HasValue)
 387            {
 2388                json.WriteString(s_curveNamePropertyNameBytes, KeyCurveName.ToString());
 389            }
 390
 68391            if (KeySize.HasValue)
 392            {
 8393                json.WriteNumber(s_keySizePropertyNameBytes, KeySize.Value);
 394            }
 68395        }
 396
 397        private void ReadSecretProperties(JsonElement json)
 398        {
 70399            if (json.TryGetProperty(ContentTypePropertyName, out JsonElement contentTypeProp))
 400            {
 70401                ContentType = contentTypeProp.GetString();
 402            }
 70403        }
 404
 405        private void WriteSecretProperties(Utf8JsonWriter json)
 406        {
 70407            if (ContentType.HasValue)
 408            {
 70409                json.WriteString(s_contentTypePropertyNameBytes, ContentType.ToString());
 410            }
 70411        }
 412
 413        private void ReadX509CertificateProperties(JsonElement json)
 414        {
 840415            foreach (JsonProperty prop in json.EnumerateObject())
 416            {
 350417                switch (prop.Name)
 418                {
 419                    case SubjectPropertyName:
 70420                        Subject = prop.Value.GetString();
 70421                        break;
 422
 423                    case SansPropertyName:
 0424                        SubjectAlternativeNames = new SubjectAlternativeNames();
 0425                        ((IJsonDeserializable)SubjectAlternativeNames).ReadProperties(prop.Value);
 0426                        break;
 427
 428                    case KeyUsagePropertyName:
 796429                        foreach (JsonElement usageElem in prop.Value.EnumerateArray())
 430                        {
 328431                            KeyUsage.Add(usageElem.GetString());
 432                        }
 433                        break;
 434
 435                    case EkusPropertyName:
 380436                        foreach (JsonElement usageElem in prop.Value.EnumerateArray())
 437                        {
 120438                            EnhancedKeyUsage.Add(usageElem.GetString());
 439                        }
 440                        break;
 441
 442                    case ValidityMonthsPropertyName:
 70443                        ValidityInMonths = prop.Value.GetInt32();
 444                        break;
 445                }
 446            }
 70447        }
 448
 449        private void WriteX509CertificateProperties(Utf8JsonWriter json)
 450        {
 74451            if (Subject != null)
 452            {
 74453                json.WriteString(s_subjectPropertyNameBytes, Subject);
 454            }
 455
 74456            if (SubjectAlternativeNames != null && !SubjectAlternativeNames.IsEmpty)
 457            {
 0458                json.WriteStartObject(s_sansPropertyNameBytes);
 459
 0460                ((IJsonSerializable)SubjectAlternativeNames).WriteProperties(json);
 461
 0462                json.WriteEndObject();
 463            }
 464
 74465            if (!KeyUsage.IsNullOrEmpty())
 466            {
 56467                json.WriteStartArray(s_keyUsagePropertyNameBytes);
 744468                foreach (CertificateKeyUsage usage in KeyUsage)
 469                {
 316470                    json.WriteStringValue(usage.ToString());
 471                }
 56472                json.WriteEndArray();
 473            }
 474
 74475            if (!EnhancedKeyUsage.IsNullOrEmpty())
 476            {
 0477                json.WriteStartArray(s_ekusPropertyNameBytes);
 0478                foreach (var usage in EnhancedKeyUsage)
 479                {
 0480                    json.WriteStringValue(usage);
 481                }
 0482                json.WriteEndArray();
 483            }
 484
 74485            if (ValidityInMonths.HasValue)
 486            {
 2487                json.WriteNumber(s_validityMonthsPropertyNameBytes, ValidityInMonths.Value);
 488            }
 74489        }
 490
 491        private void ReadAttributesProperties(JsonElement json)
 492        {
 560493            foreach (JsonProperty prop in json.EnumerateObject())
 494            {
 210495                switch (prop.Name)
 496                {
 497                    case EnabledPropertyName:
 70498                        Enabled = prop.Value.GetBoolean();
 70499                        break;
 500
 501                    case CreatedPropertyName:
 70502                        CreatedOn = DateTimeOffset.FromUnixTimeSeconds(prop.Value.GetInt64());
 70503                        break;
 504
 505                    case UpdatedPropertyName:
 70506                        UpdatedOn = DateTimeOffset.FromUnixTimeSeconds(prop.Value.GetInt64());
 507                        break;
 508                }
 509            }
 70510        }
 511
 512        private void WriteAttributesProperties(Utf8JsonWriter json)
 513        {
 4514            if (Enabled.HasValue)
 515            {
 4516                json.WriteBoolean(s_enabledPropertyNameBytes, Enabled.Value);
 517            }
 4518        }
 519    }
 520}