Skip to content

Commit

Permalink
drafted implementation for PKISolutions/PSPKI#149
Browse files Browse the repository at this point in the history
  • Loading branch information
Crypt32 committed Sep 9, 2021
1 parent 8b808e0 commit 1763201
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 34 deletions.
23 changes: 23 additions & 0 deletions PKI/Cryptography/X509Certificates/IssuingDistributionPointScope.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace SysadminsLV.PKI.Cryptography.X509Certificates {
/// <summary>
/// Represents an X.509 Issuing Distribution Point scope. Only one of choice values can be enabled in IDP extension.
/// </summary>
public enum IssuingDistributionPointScope {
/// <summary>
/// No choice is selected.
/// </summary>
None = 0,
/// <summary>
/// CRL contains only User certificates.
/// </summary>
OnlyUserCerts = 1,
/// <summary>
/// CRL contains only CA certificates.
/// </summary>
OnlyCaCerts = 2,
/// <summary>
/// CRL contains only Attribute certificates.
/// </summary>
OnlyAttributeCerts = 5
}
}
67 changes: 34 additions & 33 deletions PKI/Cryptography/X509Certificates/X509ExtensionOid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,39 @@ namespace SysadminsLV.PKI.Cryptography.X509Certificates {
/// </summary>
/// <remarks>Do not rely on this class until further notice. It is going to change at some point.</remarks>
public static class X509ExtensionOid {
public const String CertificateExtensions = "1.2.840.113549.1.9.14";
public const String CertTemplateInfoV2 = "1.3.6.1.4.1.311.20.2";
public const String CAVersion = "1.3.6.1.4.1.311.21.1";
public const String PreviousCaHash = "1.3.6.1.4.1.311.21.2";
public const String VirtualBaseCRL = "1.3.6.1.4.1.311.21.3";
public const String NextCRLPublish = "1.3.6.1.4.1.311.21.4";
public const String CertificateTemplate = "1.3.6.1.4.1.311.21.7";
public const String ApplicationPolicies = "1.3.6.1.4.1.311.21.10";
public const String ApplicationPolicyMappings = "1.3.6.1.4.1.311.21.11";
public const String ApplicationPolicyConstraints = "1.3.6.1.4.1.311.21.12";
public const String PublishedCrlLocations = "1.3.6.1.4.1.311.21.14";
public const String AuthorityInformationAccess = "1.3.6.1.5.5.7.1.1";
public const String OcspNonce = "1.3.6.1.5.5.7.48.1.2";
public const String OcspCRLReference = "1.3.6.1.5.5.7.48.1.3";
public const String OcspRevNoCheck = "1.3.6.1.5.5.7.48.1.5";
public const String ArchiveCutoff = "1.3.6.1.5.5.7.48.1.6";
public const String ServiceLocator = "1.3.6.1.5.5.7.48.1.7";
public const String SubjectKeyIdentifier = "2.5.29.14";
public const String KeyUsage = "2.5.29.15";
public const String SubjectAlternativeNames = "2.5.29.17";
public const String IssuerAlternativeNames = "2.5.29.18";
public const String BasicConstraints = "2.5.29.19";
public const String CRLNumber = "2.5.29.20";
public const String CRLReasonCode = "2.5.29.21";
public const String DeltaCRLIndicator = "2.5.29.27";
public const String NameConstraints = "2.5.29.30";
public const String CRLDistributionPoints = "2.5.29.31";
public const String CertificatePolicies = "2.5.29.32";
public const String CertificatePolicyMappings = "2.5.29.33";
public const String AuthorityKeyIdentifier = "2.5.29.35";
public const String CertificatePolicyConstraints = "2.5.29.36";
public const String EnhancedKeyUsage = "2.5.29.37";
public const String FreshestCRL = "2.5.29.46";
public const String CertificateExtensions = "1.2.840.113549.1.9.14";
public const String CertTemplateInfoV2 = "1.3.6.1.4.1.311.20.2";
public const String CAVersion = "1.3.6.1.4.1.311.21.1";
public const String PreviousCaHash = "1.3.6.1.4.1.311.21.2";
public const String VirtualBaseCRL = "1.3.6.1.4.1.311.21.3";
public const String NextCRLPublish = "1.3.6.1.4.1.311.21.4";
public const String CertificateTemplate = "1.3.6.1.4.1.311.21.7";
public const String ApplicationPolicies = "1.3.6.1.4.1.311.21.10";
public const String ApplicationPolicyMappings = "1.3.6.1.4.1.311.21.11";
public const String ApplicationPolicyConstraints = "1.3.6.1.4.1.311.21.12";
public const String PublishedCrlLocations = "1.3.6.1.4.1.311.21.14";
public const String AuthorityInformationAccess = "1.3.6.1.5.5.7.1.1";
public const String OcspNonce = "1.3.6.1.5.5.7.48.1.2";
public const String OcspCRLReference = "1.3.6.1.5.5.7.48.1.3";
public const String OcspRevNoCheck = "1.3.6.1.5.5.7.48.1.5";
public const String ArchiveCutoff = "1.3.6.1.5.5.7.48.1.6";
public const String ServiceLocator = "1.3.6.1.5.5.7.48.1.7";
public const String SubjectKeyIdentifier = "2.5.29.14";
public const String KeyUsage = "2.5.29.15";
public const String SubjectAlternativeNames = "2.5.29.17";
public const String IssuerAlternativeNames = "2.5.29.18";
public const String BasicConstraints = "2.5.29.19";
public const String CRLNumber = "2.5.29.20";
public const String CRLReasonCode = "2.5.29.21";
public const String DeltaCRLIndicator = "2.5.29.27";
public const String IssuingDistributionPoint = "2.5.29.28";
public const String NameConstraints = "2.5.29.30";
public const String CRLDistributionPoints = "2.5.29.31";
public const String CertificatePolicies = "2.5.29.32";
public const String CertificatePolicyMappings = "2.5.29.33";
public const String AuthorityKeyIdentifier = "2.5.29.35";
public const String CertificatePolicyConstraints = "2.5.29.36";
public const String EnhancedKeyUsage = "2.5.29.37";
public const String FreshestCRL = "2.5.29.46";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using SysadminsLV.Asn1Parser;

namespace SysadminsLV.PKI.Cryptography.X509Certificates {
public class X509IssuingDistributionPointsExtension : X509Extension {
readonly Oid _oid = new Oid(X509ExtensionOid.IssuingDistributionPoint);

/// <summary>
/// Initializes a new instance of the <see cref="X509IssuingDistributionPointsExtension"/> class using an
/// <see cref="AsnEncodedData"/> object and a value that identifies whether the extension is critical.
/// </summary>
/// <param name="issuingDistributionPoints">The encoded data to use to create the extension.</param>
/// <param name="critical">
/// <strong>True</strong> if the extension is critical; otherwise, <strong>False</strong>.
/// </param>
/// <exception cref="ArgumentException">
/// The data in the <strong>distributionPoints</strong> parameter is not valid extension value.
/// </exception>
public X509IssuingDistributionPointsExtension(AsnEncodedData issuingDistributionPoints, Boolean critical)
: base(X509ExtensionOid.IssuingDistributionPoint, issuingDistributionPoints.RawData, critical) {
decode();
}

/// <summary>
///
/// </summary>
/// <param name="distributionPoint"></param>
/// <param name="onlySomeReason">Specifies whether the CRL is partitioned by a subset of revocation reasons.</param>
/// <param name="indirect">Specifies whether the CRL is indirect CRL.</param>
/// <param name="scope">Specifies the scope for CRL.</param>
public X509IssuingDistributionPointsExtension(X509DistributionPoint distributionPoint, Boolean onlySomeReason, Boolean indirect, IssuingDistributionPointScope scope) {
encode(distributionPoint, onlySomeReason, indirect, scope);
}

/// <summary>
/// Gets the CRL distribution point for this CRL scope. This property can be NULL.
/// </summary>
public X509DistributionPoint DistributionPoint { get; private set; }
/// <summary>
/// Gets a status if CRL scope contains only end entity certificates.
/// </summary>
public Boolean OnlyUserCerts { get; private set; }
/// <summary>
/// Gets a status if CRL scope contains only CA certificates.
/// </summary>
public Boolean OnlyCaCerts { get; private set; }
/// <summary>
/// Gets a status if CRL scope contains only Attribute certificates.
/// </summary>
public Boolean OnlyAttributeCerts { get; private set; }
/// <summary>
/// Gets a status if CRL is partitioned by a subset of revocation reasons.
/// </summary>
public Boolean OnlySomeReasons { get; private set; }
/// <summary>
/// Gets a status if current CRL is indirect CRL.
/// </summary>
public Boolean IndirectCRL { get; private set; }

void encode(X509DistributionPoint distributionPoint, Boolean onlySomeReason, Boolean indirect, IssuingDistributionPointScope scope) {
Oid = _oid;
Critical = true;

var builder = Asn1Builder.Create();
if (distributionPoint != null) {
DistributionPoint = distributionPoint;
builder.AddDerData(new Asn1Reader(distributionPoint.RawData).GetPayload());
}
if (scope == IssuingDistributionPointScope.OnlyUserCerts) {
OnlyUserCerts = true;
builder.AddExplicit(1, x => x.AddBoolean(true));
} else if (scope == IssuingDistributionPointScope.OnlyCaCerts) {
OnlyCaCerts = true;
builder.AddExplicit(2, x => x.AddBoolean(true));
}
if (onlySomeReason) {
OnlySomeReasons = true;
builder.AddExplicit(3, x => x.AddBoolean(true));
}
if (indirect) {
IndirectCRL = true;
builder.AddExplicit(4, x => x.AddBoolean(true));
}
if (scope == IssuingDistributionPointScope.OnlyAttributeCerts) {
OnlyAttributeCerts = true;
builder.AddExplicit(5, x => x.AddBoolean(true));
}

RawData = builder.GetEncoded();
}

void decode() {
var asn = new Asn1Reader(RawData);
if (asn.PayloadLength == 0) {
return;
}

asn.MoveNext();
do {
switch (asn.Tag) {
case 0xa0:
DistributionPoint = new X509DistributionPoint(Asn1Utils.Encode(asn.GetTagRawData(), 48));
break;
case 0xa1:
OnlyUserCerts = Asn1Utils.DecodeBoolean(asn.GetPayload());
break;
case 0xa2:
OnlyCaCerts = Asn1Utils.DecodeBoolean(asn.GetPayload());
break;
case 0xa3:
OnlySomeReasons = Asn1Utils.DecodeBoolean(asn.GetPayload());
break;
case 0xa4:
IndirectCRL = Asn1Utils.DecodeBoolean(asn.GetPayload());
break;
case 0xa5:
OnlyAttributeCerts = Asn1Utils.DecodeBoolean(asn.GetPayload());
break;
}
} while (asn.MoveNextSibling());
}
}
}
/*
IssuingDistributionPoint::= SEQUENCE {
distributionPoint [0] DistributionPointName OPTIONAL,
onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE,
onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE,
onlySomeReasons [3] ReasonFlags OPTIONAL,
indirectCRL [4] BOOLEAN DEFAULT FALSE,
onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE }
*/
4 changes: 3 additions & 1 deletion PKI/PKI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,14 @@
<Compile Include="Cryptography\TspStatusInfo.cs" />
<Compile Include="Cryptography\TspValidationStatus.cs" />
<Compile Include="Cryptography\X509AttributeOid.cs" />
<Compile Include="Cryptography\X509Certificates\IssuingDistributionPointScope.cs" />
<Compile Include="Cryptography\X509Certificates\X509ExtensionOid.cs" />
<Compile Include="Cryptography\X509Certificates\X509CertificateTrustList.cs" />
<Compile Include="Cryptography\X509Certificates\X509CRL2Collection.cs" />
<Compile Include="Cryptography\X509Certificates\X509CertificateTrustListEntryCollection.cs" />
<Compile Include="Cryptography\X509Certificates\X509CertificateTrustListBuilder.cs" />
<Compile Include="Cryptography\X509Certificates\X509CertificateTrustListEntry.cs" />
<Compile Include="Cryptography\X509Certificates\X509IssuingDistributionPointsExtension.cs" />
<Compile Include="Dcom\AdcsBinaryFormat.cs" />
<Compile Include="Dcom\AdcsCAPropertyName.cs" />
<Compile Include="Dcom\AdcsCrlReason.cs" />
Expand Down Expand Up @@ -260,7 +262,7 @@
<Compile Include="Cryptography\X509Certificates\X509CertificatePolicyMappingsExtension.cs" />
<Compile Include="Cryptography\X509Certificates\X509CertificatePropertyType.cs" />
<Compile Include="Cryptography\X509Certificates\X509CrlBuilder.cs" />
<Compile Include="Cryptography\X509Certificates\X509CRLDistributionPoint.cs" />
<Compile Include="Cryptography\X509Certificates\X509DistributionPoint.cs" />
<Compile Include="Cryptography\X509Certificates\X509CrlType.cs" />
<Compile Include="Cryptography\X509Certificates\X509CrossCertificateDistributionPointsExtension.cs" />
<Compile Include="Cryptography\X509Certificates\X509EnrollmentPropertyInfo.cs" />
Expand Down
2 changes: 2 additions & 0 deletions PKI/Utils/CryptographyUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ public static class CryptographyUtils {
return new X509BasicConstraintsExtension(asndata, extension.Critical);
case X509ExtensionOid.CRLNumber:
return new X509CRLNumberExtension(asndata, extension.Critical);
case X509ExtensionOid.IssuingDistributionPoint:
return new X509IssuingDistributionPointsExtension(asndata, extension.Critical);
case X509ExtensionOid.NameConstraints:
return new X509NameConstraintsExtension(asndata);
case X509ExtensionOid.CRLDistributionPoints:
Expand Down

0 comments on commit 1763201

Please sign in to comment.