Skip to content

Commit ab9648d

Browse files
authored
Show CRL and OCSP URLs in verify output (#7343)
1 parent 23cb0ef commit ab9648d

17 files changed

Lines changed: 407 additions & 0 deletions

File tree

src/NuGet.Core/NuGet.Packaging/Signing/Utility/CertificateUtility.cs

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,16 @@ internal static IReadOnlyList<SignatureLog> X509Certificate2ToLogMessages(X509Ce
5454
issues.Add(SignatureLog.InformationLog($"{indentation}{string.Format(CultureInfo.CurrentCulture, Strings.CertUtilityCertificateIssuer, cert.IssuerName.Name)}"));
5555
issues.Add(SignatureLog.MinimalLog($"{indentation}{string.Format(CultureInfo.CurrentCulture, Strings.CertUtilityCertificateValidity, cert.NotBefore, cert.NotAfter)}"));
5656

57+
foreach (string url in GetCrlDistributionPointUrls(cert))
58+
{
59+
issues.Add(SignatureLog.InformationLog($"{indentation}{string.Format(CultureInfo.CurrentCulture, Strings.CertUtilityCertificateCrlUrl, url)}"));
60+
}
61+
62+
foreach (string url in GetOcspUrls(cert))
63+
{
64+
issues.Add(SignatureLog.InformationLog($"{indentation}{string.Format(CultureInfo.CurrentCulture, Strings.CertUtilityCertificateOcspUrl, url)}"));
65+
}
66+
5767
return issues;
5868
}
5969

@@ -66,6 +76,16 @@ private static void X509Certificate2ToString(X509Certificate2 cert, StringBuilde
6676
certStringBuilder.AppendLine(indentation + string.Format(CultureInfo.CurrentCulture, Strings.CertUtilityCertificateHash, fingerprintAlgorithm.ToString(), certificateFingerprint));
6777
certStringBuilder.AppendLine(indentation + string.Format(CultureInfo.CurrentCulture, Strings.CertUtilityCertificateIssuer, cert.IssuerName.Name));
6878
certStringBuilder.AppendLine(indentation + string.Format(CultureInfo.CurrentCulture, Strings.CertUtilityCertificateValidity, cert.NotBefore, cert.NotAfter));
79+
80+
foreach (string url in GetCrlDistributionPointUrls(cert))
81+
{
82+
certStringBuilder.AppendLine(indentation + string.Format(CultureInfo.CurrentCulture, Strings.CertUtilityCertificateCrlUrl, url));
83+
}
84+
85+
foreach (string url in GetOcspUrls(cert))
86+
{
87+
certStringBuilder.AppendLine(indentation + string.Format(CultureInfo.CurrentCulture, Strings.CertUtilityCertificateOcspUrl, url));
88+
}
6989
}
7090

7191
/// <summary>
@@ -445,5 +465,119 @@ private static bool IsHex(string certificateFingerprint)
445465

446466
return true;
447467
}
468+
469+
/// <summary>
470+
/// Extracts CRL Distribution Point URLs from the certificate's CRL Distribution Points extension (OID 2.5.29.31).
471+
/// </summary>
472+
internal static IReadOnlyList<string> GetCrlDistributionPointUrls(X509Certificate2 cert)
473+
{
474+
const string CrlDistributionPointsOid = "2.5.29.31";
475+
// context-specific primitive tag [6] for uniformResourceIdentifier in GeneralName
476+
const byte GeneralNameUriTag = 0x86;
477+
478+
var urls = new List<string>();
479+
var extension = cert.Extensions[CrlDistributionPointsOid];
480+
481+
if (extension == null)
482+
{
483+
return urls;
484+
}
485+
486+
try
487+
{
488+
// CRLDistributionPoints ::= SEQUENCE OF DistributionPoint
489+
var reader = new DerEncoding.DerSequenceReader(extension.RawData);
490+
491+
while (reader.HasData)
492+
{
493+
// DistributionPoint ::= SEQUENCE { distributionPoint [0] ... }
494+
var dpReader = reader.ReadSequence();
495+
496+
if (dpReader.HasData && dpReader.HasTag(DerEncoding.DerSequenceReader.ContextSpecificConstructedTag0))
497+
{
498+
// distributionPoint [0] CONSTRUCTED
499+
byte[] dpNameData = dpReader.ReadValue((DerEncoding.DerSequenceReader.DerTag)DerEncoding.DerSequenceReader.ContextSpecificConstructedTag0);
500+
var dpNameReader = DerEncoding.DerSequenceReader.CreateForPayload(dpNameData);
501+
502+
if (dpNameReader.HasData && dpNameReader.HasTag(DerEncoding.DerSequenceReader.ContextSpecificConstructedTag0))
503+
{
504+
// fullName [0] CONSTRUCTED = GeneralNames
505+
byte[] fullNameData = dpNameReader.ReadValue((DerEncoding.DerSequenceReader.DerTag)DerEncoding.DerSequenceReader.ContextSpecificConstructedTag0);
506+
var gnReader = DerEncoding.DerSequenceReader.CreateForPayload(fullNameData);
507+
508+
while (gnReader.HasData)
509+
{
510+
byte tag = gnReader.PeekTag();
511+
512+
if (tag == GeneralNameUriTag)
513+
{
514+
byte[] uriBytes = gnReader.ReadValue((DerEncoding.DerSequenceReader.DerTag)GeneralNameUriTag);
515+
urls.Add(Encoding.ASCII.GetString(uriBytes));
516+
}
517+
else
518+
{
519+
gnReader.SkipValue();
520+
}
521+
}
522+
}
523+
}
524+
}
525+
}
526+
catch (System.Security.Cryptography.CryptographicException exception)
527+
{
528+
return [exception.Message];
529+
}
530+
531+
return urls;
532+
}
533+
534+
/// <summary>
535+
/// Extracts OCSP responder URLs from the certificate's Authority Information Access extension (OID 1.3.6.1.5.5.7.1.1).
536+
/// </summary>
537+
internal static IReadOnlyList<string> GetOcspUrls(X509Certificate2 cert)
538+
{
539+
const string AuthorityInfoAccessOid = "1.3.6.1.5.5.7.1.1";
540+
const string OcspAccessMethodOid = "1.3.6.1.5.5.7.48.1";
541+
// context-specific primitive tag [6] for uniformResourceIdentifier in GeneralName
542+
const byte GeneralNameUriTag = 0x86;
543+
544+
var urls = new List<string>();
545+
var extension = cert.Extensions[AuthorityInfoAccessOid];
546+
547+
if (extension == null)
548+
{
549+
return urls;
550+
}
551+
552+
try
553+
{
554+
// AuthorityInfoAccessSyntax ::= SEQUENCE OF AccessDescription
555+
var reader = new DerEncoding.DerSequenceReader(extension.RawData);
556+
557+
while (reader.HasData)
558+
{
559+
// AccessDescription ::= SEQUENCE { accessMethod OID, accessLocation GeneralName }
560+
var adReader = reader.ReadSequence();
561+
string oid = adReader.ReadOidAsString();
562+
563+
if (string.Equals(oid, OcspAccessMethodOid, StringComparison.Ordinal) && adReader.HasData)
564+
{
565+
byte tag = adReader.PeekTag();
566+
567+
if (tag == GeneralNameUriTag)
568+
{
569+
byte[] uriBytes = adReader.ReadValue((DerEncoding.DerSequenceReader.DerTag)GeneralNameUriTag);
570+
urls.Add(Encoding.ASCII.GetString(uriBytes));
571+
}
572+
}
573+
}
574+
}
575+
catch (System.Security.Cryptography.CryptographicException exception)
576+
{
577+
return [exception.Message];
578+
}
579+
580+
return urls;
581+
}
448582
}
449583
}

src/NuGet.Core/NuGet.Packaging/Strings.Designer.cs

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/NuGet.Core/NuGet.Packaging/Strings.resx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,14 @@
271271
<comment>0 - start date
272272
1 - end date</comment>
273273
</data>
274+
<data name="CertUtilityCertificateCrlUrl" xml:space="preserve">
275+
<value>CRL URL: {0}</value>
276+
<comment>0 - CRL distribution point URL</comment>
277+
</data>
278+
<data name="CertUtilityCertificateOcspUrl" xml:space="preserve">
279+
<value>OCSP URL: {0}</value>
280+
<comment>0 - OCSP responder URL</comment>
281+
</data>
274282
<data name="CertUtilityMultipleCertificatesFooter" xml:space="preserve">
275283
<value>... {0} more.</value>
276284
<comment>0 - number of certificates left</comment>

src/NuGet.Core/NuGet.Packaging/xlf/Strings.cs.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@
4444
<note>0 - start date
4545
1 - end date</note>
4646
</trans-unit>
47+
<trans-unit id="CertUtilityCertificateCrlUrl">
48+
<source>CRL URL: {0}</source>
49+
<target state="translated">Adresa URL seznamu CRL: {0}</target>
50+
<note>0 - CRL distribution point URL</note>
51+
</trans-unit>
52+
<trans-unit id="CertUtilityCertificateOcspUrl">
53+
<source>OCSP URL: {0}</source>
54+
<target state="translated">Adresa URL protokolu OCSP: {0}</target>
55+
<note>0 - OCSP responder URL</note>
56+
</trans-unit>
4757
<trans-unit id="CertUtilityMultipleCertificatesFooter">
4858
<source>... {0} more.</source>
4959
<target state="translated">... dalších {0}.</target>

src/NuGet.Core/NuGet.Packaging/xlf/Strings.de.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@
4444
<note>0 - start date
4545
1 - end date</note>
4646
</trans-unit>
47+
<trans-unit id="CertUtilityCertificateCrlUrl">
48+
<source>CRL URL: {0}</source>
49+
<target state="translated">CRL-URL: {0}</target>
50+
<note>0 - CRL distribution point URL</note>
51+
</trans-unit>
52+
<trans-unit id="CertUtilityCertificateOcspUrl">
53+
<source>OCSP URL: {0}</source>
54+
<target state="translated">OCSP-URL: {0}</target>
55+
<note>0 - OCSP responder URL</note>
56+
</trans-unit>
4757
<trans-unit id="CertUtilityMultipleCertificatesFooter">
4858
<source>... {0} more.</source>
4959
<target state="translated">... {0} weitere.</target>

src/NuGet.Core/NuGet.Packaging/xlf/Strings.es.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@
4444
<note>0 - start date
4545
1 - end date</note>
4646
</trans-unit>
47+
<trans-unit id="CertUtilityCertificateCrlUrl">
48+
<source>CRL URL: {0}</source>
49+
<target state="translated">DIRECCIÓN URL DE CRL: {0}</target>
50+
<note>0 - CRL distribution point URL</note>
51+
</trans-unit>
52+
<trans-unit id="CertUtilityCertificateOcspUrl">
53+
<source>OCSP URL: {0}</source>
54+
<target state="translated">DIRECCIÓN URL DE OCSP: {0}</target>
55+
<note>0 - OCSP responder URL</note>
56+
</trans-unit>
4757
<trans-unit id="CertUtilityMultipleCertificatesFooter">
4858
<source>... {0} more.</source>
4959
<target state="translated">... {0} más.</target>

src/NuGet.Core/NuGet.Packaging/xlf/Strings.fr.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@
4444
<note>0 - start date
4545
1 - end date</note>
4646
</trans-unit>
47+
<trans-unit id="CertUtilityCertificateCrlUrl">
48+
<source>CRL URL: {0}</source>
49+
<target state="translated">URL de la liste de révocation des certificats (CRL) : {0}</target>
50+
<note>0 - CRL distribution point URL</note>
51+
</trans-unit>
52+
<trans-unit id="CertUtilityCertificateOcspUrl">
53+
<source>OCSP URL: {0}</source>
54+
<target state="translated">URL du serveur OCSP : {0}</target>
55+
<note>0 - OCSP responder URL</note>
56+
</trans-unit>
4757
<trans-unit id="CertUtilityMultipleCertificatesFooter">
4858
<source>... {0} more.</source>
4959
<target state="translated">... {0} de plus.</target>

src/NuGet.Core/NuGet.Packaging/xlf/Strings.it.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@
4444
<note>0 - start date
4545
1 - end date</note>
4646
</trans-unit>
47+
<trans-unit id="CertUtilityCertificateCrlUrl">
48+
<source>CRL URL: {0}</source>
49+
<target state="translated">URL CRL: {0}</target>
50+
<note>0 - CRL distribution point URL</note>
51+
</trans-unit>
52+
<trans-unit id="CertUtilityCertificateOcspUrl">
53+
<source>OCSP URL: {0}</source>
54+
<target state="translated">URL OCSP: {0}</target>
55+
<note>0 - OCSP responder URL</note>
56+
</trans-unit>
4757
<trans-unit id="CertUtilityMultipleCertificatesFooter">
4858
<source>... {0} more.</source>
4959
<target state="translated">... altri {0}.</target>

src/NuGet.Core/NuGet.Packaging/xlf/Strings.ja.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@
4444
<note>0 - start date
4545
1 - end date</note>
4646
</trans-unit>
47+
<trans-unit id="CertUtilityCertificateCrlUrl">
48+
<source>CRL URL: {0}</source>
49+
<target state="translated">CRL URL: {0}</target>
50+
<note>0 - CRL distribution point URL</note>
51+
</trans-unit>
52+
<trans-unit id="CertUtilityCertificateOcspUrl">
53+
<source>OCSP URL: {0}</source>
54+
<target state="translated">OCSP URL: {0}</target>
55+
<note>0 - OCSP responder URL</note>
56+
</trans-unit>
4757
<trans-unit id="CertUtilityMultipleCertificatesFooter">
4858
<source>... {0} more.</source>
4959
<target state="translated">... さらに {0}。</target>

src/NuGet.Core/NuGet.Packaging/xlf/Strings.ko.xlf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@
4444
<note>0 - start date
4545
1 - end date</note>
4646
</trans-unit>
47+
<trans-unit id="CertUtilityCertificateCrlUrl">
48+
<source>CRL URL: {0}</source>
49+
<target state="translated">CRL URL: {0}</target>
50+
<note>0 - CRL distribution point URL</note>
51+
</trans-unit>
52+
<trans-unit id="CertUtilityCertificateOcspUrl">
53+
<source>OCSP URL: {0}</source>
54+
<target state="translated">OCSP URL: {0}</target>
55+
<note>0 - OCSP responder URL</note>
56+
</trans-unit>
4757
<trans-unit id="CertUtilityMultipleCertificatesFooter">
4858
<source>... {0} more.</source>
4959
<target state="translated">...기타 {0}개.</target>

0 commit comments

Comments
 (0)