audit work, fixed StellaOps.sln warnings/errors, fixed tests, sprints work, new advisories

This commit is contained in:
master
2026-01-07 18:49:59 +02:00
parent 04ec098046
commit 608a7f85c0
866 changed files with 56323 additions and 6231 deletions

View File

@@ -2,6 +2,7 @@ using System;
using System.Buffers;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
@@ -41,7 +42,7 @@ internal static class VexRawRequestMapper
SetIfMissing(metadataBuilder, "source.connector_version", source.Version);
SetIfMissing(metadataBuilder, "source.stream", source.Stream ?? format.ToString().ToLowerInvariant());
SetIfMissing(metadataBuilder, "upstream.id", upstream.UpstreamId);
SetIfMissing(metadataBuilder, "upstream.version", upstream.DocumentVersion ?? retrievedAt.ToString("O"));
SetIfMissing(metadataBuilder, "upstream.version", upstream.DocumentVersion ?? retrievedAt.ToString("O", CultureInfo.InvariantCulture));
SetIfMissing(metadataBuilder, "content.spec_version", content.SpecVersion);
SetIfMissing(metadataBuilder, "content.encoding", content.Encoding);

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Immutable;
using System.Globalization;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
@@ -321,13 +322,13 @@ internal sealed class VexWorkerOrchestratorClient : IVexWorkerOrchestratorClient
errorCode,
errorMessage,
retryAfterSeconds,
state.LastCheckpoint?.ToString("O"),
state.LastCheckpoint?.ToString("O", CultureInfo.InvariantCulture),
idempotencyKey: $"fail-{context.RunId}"),
cancellationToken).ConfigureAwait(false);
await SendRemoteCompletionAsync(
context,
new VexWorkerJobResult(0, 0, state.LastCheckpoint?.ToString("O"), state.LastArtifactHash, now),
new VexWorkerJobResult(0, 0, state.LastCheckpoint?.ToString("O", CultureInfo.InvariantCulture), state.LastArtifactHash, now),
cancellationToken,
success: false,
failureReason: Truncate($"{errorCode}: {errorMessage}", 256)).ConfigureAwait(false);
@@ -447,7 +448,7 @@ internal sealed class VexWorkerOrchestratorClient : IVexWorkerOrchestratorClient
return new VexWorkerCheckpoint(
connectorId,
state.LastCheckpoint?.ToString("O"),
state.LastCheckpoint?.ToString("O", CultureInfo.InvariantCulture),
state.LastUpdated,
state.DocumentDigests.IsDefault ? ImmutableArray<string>.Empty : state.DocumentDigests,
state.ResumeTokens.IsEmpty ? ImmutableDictionary<string, string>.Empty : state.ResumeTokens);

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Immutable;
using System.Globalization;
using System.Linq;
using System.Security.Cryptography;
using Microsoft.Extensions.DependencyInjection;
@@ -135,7 +136,7 @@ internal sealed class DefaultVexProviderRunner : IVexProviderRunner
var jobContext = await _orchestratorClient.StartJobAsync(
_orchestratorOptions.DefaultTenant,
connector.Id,
stateBeforeRun?.LastCheckpoint?.ToString("O"),
stateBeforeRun?.LastCheckpoint?.ToString("O", CultureInfo.InvariantCulture),
cancellationToken).ConfigureAwait(false);
var documentCount = 0;

View File

@@ -57,7 +57,7 @@ internal sealed class VerifyingVexRawDocumentSink : IVexRawDocumentSink
if (signature.VerifiedAt is not null)
{
builder["vex.signature.verifiedAt"] = signature.VerifiedAt.Value.ToString("O");
builder["vex.signature.verifiedAt"] = signature.VerifiedAt.Value.ToString("O", CultureInfo.InvariantCulture);
}
if (!string.IsNullOrWhiteSpace(signature.TransparencyLogReference))
@@ -71,7 +71,7 @@ internal sealed class VerifyingVexRawDocumentSink : IVexRawDocumentSink
builder["vex.signature.trust.tenantId"] = signature.Trust.TenantId;
builder["vex.signature.trust.issuerId"] = signature.Trust.IssuerId;
builder["vex.signature.trust.tenantOverrideApplied"] = signature.Trust.TenantOverrideApplied ? "true" : "false";
builder["vex.signature.trust.retrievedAtUtc"] = signature.Trust.RetrievedAtUtc.ToString("O");
builder["vex.signature.trust.retrievedAtUtc"] = signature.Trust.RetrievedAtUtc.ToString("O", CultureInfo.InvariantCulture);
}
return builder.ToImmutable();

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.Metrics;
using System.Globalization;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
@@ -260,7 +261,7 @@ internal sealed class WorkerSignatureVerifier : IVexSignatureVerifier
DateTimeOffset signedAt;
if (metadata.TryGetValue("vex.signature.verifiedAt", out var signedAtRaw)
&& DateTimeOffset.TryParse(signedAtRaw, out var parsedSignedAt))
&& DateTimeOffset.TryParse(signedAtRaw, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var parsedSignedAt))
{
signedAt = parsedSignedAt;
}
@@ -368,7 +369,7 @@ internal sealed class WorkerSignatureVerifier : IVexSignatureVerifier
metadata.TryGetValue("vex.signature.transparencyLogReference", out var tlog);
DateTimeOffset? verifiedAt = null;
if (!string.IsNullOrWhiteSpace(verifiedAtRaw) && DateTimeOffset.TryParse(verifiedAtRaw, out var parsed))
if (!string.IsNullOrWhiteSpace(verifiedAtRaw) && DateTimeOffset.TryParse(verifiedAtRaw, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var parsed))
{
verifiedAt = parsed;
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Immutable;
using System.Globalization;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
@@ -167,7 +168,7 @@ public sealed class VexEvidenceAttestor : IVexEvidenceAttestor
var diagnostics = ImmutableDictionary.CreateBuilder<string, string>();
diagnostics.Add("envelope_hash", ComputeHash(dsseEnvelopeJson));
diagnostics.Add("verified_at", _timeProvider.GetUtcNow().ToString("O"));
diagnostics.Add("verified_at", _timeProvider.GetUtcNow().ToString("O", CultureInfo.InvariantCulture));
_logger.LogDebug("Evidence attestation verified for manifest {ManifestId}", manifest.ManifestId);

View File

@@ -1,4 +1,5 @@
using System;
using System.Globalization;
using System.IO;
using System.Linq;
using Microsoft.Extensions.Logging;
@@ -45,7 +46,7 @@ public static class ConnectorSignerMetadataEnricher
.Add("vex.provenance.bundle.kind", bundle.Kind)
.Add("vex.provenance.bundle.uri", bundle.Uri)
.Add("vex.provenance.bundle.digest", bundle.Digest)
.Add("vex.provenance.bundle.publishedAt", bundle.PublishedAt?.ToUniversalTime().ToString("O"));
.Add("vex.provenance.bundle.publishedAt", bundle.PublishedAt?.ToUniversalTime().ToString("O", CultureInfo.InvariantCulture));
}
}

View File

@@ -1,4 +1,5 @@
using System.Collections.Immutable;
using System.Globalization;
namespace StellaOps.Excititor.Connectors.Abstractions;
@@ -20,7 +21,7 @@ public sealed class VexConnectorMetadataBuilder
}
public VexConnectorMetadataBuilder Add(string key, DateTimeOffset value)
=> Add(key, value.ToUniversalTime().ToString("O"));
=> Add(key, value.ToUniversalTime().ToString("O", CultureInfo.InvariantCulture));
public VexConnectorMetadataBuilder AddRange(IEnumerable<KeyValuePair<string, string?>> items)
{

View File

@@ -108,8 +108,8 @@ public sealed class CiscoCsafConnector : VexConnectorBase
builder
.Add("cisco.csaf.advisoryId", advisory.Id)
.Add("cisco.csaf.revision", advisory.Revision)
.Add("cisco.csaf.published", advisory.Published?.ToString("O"))
.Add("cisco.csaf.modified", advisory.LastModified?.ToString("O"))
.Add("cisco.csaf.published", advisory.Published?.ToString("O", CultureInfo.InvariantCulture))
.Add("cisco.csaf.modified", advisory.LastModified?.ToString("O", CultureInfo.InvariantCulture))
.Add("cisco.csaf.sha256", advisory.Sha256);
AddProvenanceMetadata(builder);

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
@@ -258,12 +259,12 @@ public sealed class MsrcCsafConnector : VexConnectorBase
if (summary.LastModifiedDate is not null)
{
builder.Add(LastModifiedMetadataKey, summary.LastModifiedDate.Value.ToString("O"));
builder.Add(LastModifiedMetadataKey, summary.LastModifiedDate.Value.ToString("O", CultureInfo.InvariantCulture));
}
if (summary.ReleaseDate is not null)
{
builder.Add(ReleaseDateMetadataKey, summary.ReleaseDate.Value.ToString("O"));
builder.Add(ReleaseDateMetadataKey, summary.ReleaseDate.Value.ToString("O", CultureInfo.InvariantCulture));
}
if (!string.IsNullOrWhiteSpace(validation.QuarantineReason))
@@ -278,7 +279,7 @@ public sealed class MsrcCsafConnector : VexConnectorBase
if (response.Content.Headers.LastModified is { } lastModified)
{
builder.Add("http.lastModified", lastModified.ToString("O"));
builder.Add("http.lastModified", lastModified.ToString("O", CultureInfo.InvariantCulture));
}
ConnectorSignerMetadataEnricher.Enrich(builder, Descriptor.Id, _logger);
@@ -421,8 +422,8 @@ public sealed class MsrcCsafConnector : VexConnectorBase
builder.Append("?");
builder.Append("$top=").Append(options.PageSize);
builder.Append("&lastModifiedStartDateTime=").Append(Uri.EscapeDataString(from.ToUniversalTime().ToString("O")));
builder.Append("&lastModifiedEndDateTime=").Append(Uri.EscapeDataString(to.ToUniversalTime().ToString("O")));
builder.Append("&lastModifiedStartDateTime=").Append(Uri.EscapeDataString(from.ToUniversalTime().ToString("O", CultureInfo.InvariantCulture)));
builder.Append("&lastModifiedEndDateTime=").Append(Uri.EscapeDataString(to.ToUniversalTime().ToString("O", CultureInfo.InvariantCulture)));
builder.Append("&$orderby=lastModifiedDate");
builder.Append("&locale=").Append(Uri.EscapeDataString(options.Locale));
builder.Append("&api-version=").Append(Uri.EscapeDataString(options.ApiVersion));

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Linq;
using Microsoft.Extensions.Logging;
@@ -111,7 +112,7 @@ public sealed class OciOpenVexAttestationConnector : VexConnectorBase
LogConnectorEvent(LogLevel.Information, "fetch", "OCI attestation fetch completed.", new Dictionary<string, object?>
{
["documents"] = documentCount,
["since"] = context.Since?.ToString("O"),
["since"] = context.Since?.ToString("O", CultureInfo.InvariantCulture),
});
}
@@ -209,7 +210,7 @@ public sealed class OciOpenVexAttestationConnector : VexConnectorBase
if (signature.VerifiedAt is not null)
{
builder["vex.signature.verifiedAt"] = signature.VerifiedAt.Value.ToString("O");
builder["vex.signature.verifiedAt"] = signature.VerifiedAt.Value.ToString("O", CultureInfo.InvariantCulture);
}
if (!string.IsNullOrWhiteSpace(signature.TransparencyLogReference))

View File

@@ -94,7 +94,7 @@ public sealed class OracleCsafConnector : VexConnectorBase
LogConnectorEvent(LogLevel.Information, "fetch.begin", "Starting Oracle CSAF catalogue iteration.", new Dictionary<string, object?>
{
["since"] = since?.ToString("O"),
["since"] = since?.ToString("O", CultureInfo.InvariantCulture),
["entryCount"] = entries.Length,
});
@@ -157,7 +157,7 @@ public sealed class OracleCsafConnector : VexConnectorBase
["entryId"] = entry.Id,
["digest"] = rawDocument.Digest,
["documentUri"] = entry.DocumentUri.ToString(),
["publishedAt"] = entry.PublishedAt.ToString("O"),
["publishedAt"] = entry.PublishedAt.ToString("O", CultureInfo.InvariantCulture),
});
yield return rawDocument;
@@ -193,7 +193,7 @@ public sealed class OracleCsafConnector : VexConnectorBase
{
["stateChanged"] = stateChanged,
["documentsProcessed"] = ingestedCount,
["latestPublished"] = latestPublished == DateTimeOffset.MinValue ? null : latestPublished.ToString("O"),
["latestPublished"] = latestPublished == DateTimeOffset.MinValue ? null : latestPublished.ToString("O", CultureInfo.InvariantCulture),
});
}
@@ -256,7 +256,7 @@ public sealed class OracleCsafConnector : VexConnectorBase
builder.Add("oracle.csaf.revision", entry.Revision);
if (entry.PublishedAt != default)
{
builder.Add("oracle.csaf.published", entry.PublishedAt.ToString("O"));
builder.Add("oracle.csaf.published", entry.PublishedAt.ToString("O", CultureInfo.InvariantCulture));
}
builder.Add("oracle.csaf.sha256", NormalizeDigest(entry.Sha256));

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Runtime.CompilerServices;
@@ -187,7 +188,7 @@ public sealed class RedHatCsafConnector : VexConnectorBase
var metadata = BuildMetadata(builder => builder
.Add("redhat.csaf.entryId", entry.Id)
.Add("redhat.csaf.documentUri", documentUri.ToString())
.Add("redhat.csaf.updated", entry.Updated?.ToString("O")));
.Add("redhat.csaf.updated", entry.Updated?.ToString("O", CultureInfo.InvariantCulture)));
return CreateRawDocument(VexDocumentFormat.Csaf, documentUri, contentBytes, metadata);
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization;
using System.IO.Abstractions;
using System.Net.Http;
using System.Net.Http.Headers;
@@ -283,7 +284,7 @@ public sealed class RancherHubEventClient
}
else if (since is not null)
{
parameters["since"] = since.Value.ToUniversalTime().ToString("O");
parameters["since"] = since.Value.ToUniversalTime().ToString("O", CultureInfo.InvariantCulture);
}
if (!channels.IsDefaultOrEmpty && channels.Length > 0)

View File

@@ -108,7 +108,7 @@ public sealed class RancherHubConnector : VexConnectorBase
LogConnectorEvent(LogLevel.Information, "fetch_start", "Starting Rancher hub event ingestion.", new Dictionary<string, object?>
{
["since"] = checkpoint.EffectiveSince?.ToString("O"),
["since"] = checkpoint.EffectiveSince?.ToString("O", CultureInfo.InvariantCulture),
["cursor"] = checkpoint.Cursor,
["subscriptionUri"] = _metadata.Metadata.Subscription.EventsUri.ToString(),
["offline"] = checkpoint.Cursor is null && _options.PreferOfflineSnapshot,

View File

@@ -368,7 +368,7 @@ public sealed class UbuntuCsafConnector : VexConnectorBase
if (entry.LastModified is { } modified)
{
builder.Add("ubuntu.lastModified", modified.ToString("O"));
builder.Add("ubuntu.lastModified", modified.ToString("O", CultureInfo.InvariantCulture));
}
if (entry.Sha256 is not null)

View File

@@ -18,7 +18,6 @@
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
<PackageReference Include="System.IO.Abstractions.TestingHelpers" />
<PackageReference Include="xunit.runner.visualstudio" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<None Update="Fixtures\**\*">

View File

@@ -26,10 +26,6 @@
<PackageReference Include="Microsoft.Extensions.Logging" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
<PackageReference Include="Moq" />
<PackageReference Include="xunit.runner.visualstudio">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>

View File

@@ -12,7 +12,6 @@
<PackageReference Include="FluentAssertions" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" />
<PackageReference Include="coverlet.collector" PrivateAssets="all" />
<PackageReference Include="xunit.runner.visualstudio" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../../StellaOps.Excititor.WebService/StellaOps.Excititor.WebService.csproj" />