license switch agpl -> busl1, sprints work, new product advisories
This commit is contained in:
@@ -171,6 +171,7 @@ public sealed class QualifiedTimestampVerifier : IQualifiedTimestampVerifier
|
||||
|
||||
// Detect CAdES level
|
||||
var level = DetectCadesLevel(signedCms);
|
||||
ValidateCadesFormat(signedCms, level, errors);
|
||||
|
||||
// Get signing time
|
||||
DateTimeOffset? signingTime = null;
|
||||
@@ -211,18 +212,19 @@ public sealed class QualifiedTimestampVerifier : IQualifiedTimestampVerifier
|
||||
}
|
||||
else
|
||||
{
|
||||
warnings.Add("Expected timestamp attribute not found");
|
||||
errors.Add("Expected timestamp attribute not found");
|
||||
}
|
||||
}
|
||||
|
||||
// Check LTV completeness if required
|
||||
var isLtvComplete = false;
|
||||
if (options.VerifyLtvCompleteness && level >= CadesLevel.CadesLT)
|
||||
var shouldCheckLtv = options.VerifyLtvCompleteness || level >= CadesLevel.CadesLT;
|
||||
if (shouldCheckLtv)
|
||||
{
|
||||
isLtvComplete = VerifyLtvCompleteness(signedCms);
|
||||
if (!isLtvComplete)
|
||||
{
|
||||
warnings.Add("LTV data is incomplete");
|
||||
errors.Add("LTV data is incomplete");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,6 +346,54 @@ public sealed class QualifiedTimestampVerifier : IQualifiedTimestampVerifier
|
||||
return hasRevocationValues && hasCertValues;
|
||||
}
|
||||
|
||||
private static void ValidateCadesFormat(SignedCms signedCms, CadesLevel level, List<string> errors)
|
||||
{
|
||||
var signerInfo = signedCms.SignerInfos[0];
|
||||
var unsignedAttrs = signerInfo.UnsignedAttributes;
|
||||
|
||||
const string archiveTimestampOid = "1.2.840.113549.1.9.16.2.48";
|
||||
const string revocationValuesOid = "1.2.840.113549.1.9.16.2.24";
|
||||
const string certValuesOid = "1.2.840.113549.1.9.16.2.23";
|
||||
const string revocationRefsOid = "1.2.840.113549.1.9.16.2.22";
|
||||
|
||||
if (level >= CadesLevel.CadesT &&
|
||||
!HasUnsignedAttribute(unsignedAttrs, SignatureTimestampOid))
|
||||
{
|
||||
errors.Add("Missing signature timestamp attribute for CAdES-T");
|
||||
}
|
||||
|
||||
if (level >= CadesLevel.CadesC &&
|
||||
!HasUnsignedAttribute(unsignedAttrs, revocationRefsOid))
|
||||
{
|
||||
errors.Add("Missing revocation references for CAdES-C");
|
||||
}
|
||||
|
||||
if (level >= CadesLevel.CadesLT)
|
||||
{
|
||||
if (!HasUnsignedAttribute(unsignedAttrs, revocationValuesOid))
|
||||
{
|
||||
errors.Add("Missing revocation values for CAdES-LT");
|
||||
}
|
||||
|
||||
if (!HasUnsignedAttribute(unsignedAttrs, certValuesOid))
|
||||
{
|
||||
errors.Add("Missing certificate values for CAdES-LT");
|
||||
}
|
||||
}
|
||||
|
||||
if (level >= CadesLevel.CadesLTA &&
|
||||
!HasUnsignedAttribute(unsignedAttrs, archiveTimestampOid))
|
||||
{
|
||||
errors.Add("Missing archive timestamp for CAdES-LTA");
|
||||
}
|
||||
}
|
||||
|
||||
private static bool HasUnsignedAttribute(CryptographicAttributeObjectCollection attributes, string oid)
|
||||
{
|
||||
return attributes.Cast<CryptographicAttributeObject>()
|
||||
.Any(a => a.Oid?.Value == oid);
|
||||
}
|
||||
|
||||
private sealed class TstInfoData
|
||||
{
|
||||
public required string DigestAlgorithm { get; init; }
|
||||
|
||||
Reference in New Issue
Block a user