public void Read_WithValidInput_ReturnsSigningCertificateV2(HashAlgorithmName hashAlgorithmName) { using (var certificate = _fixture.GetDefaultCertificate()) { var expectedSigningCertificateV2 = SigningCertificateV2.Create(certificate, hashAlgorithmName); var bytes = expectedSigningCertificateV2.Encode(); var actualSigningCertificateV2 = SigningCertificateV2.Read(bytes); Assert.Equal( expectedSigningCertificateV2.Certificates.Count, actualSigningCertificateV2.Certificates.Count); for (var i = 0; i < expectedSigningCertificateV2.Certificates.Count; ++i) { var expectedEssCertIdV2 = expectedSigningCertificateV2.Certificates[i]; var actualEssCertIdV2 = actualSigningCertificateV2.Certificates[i]; Assert.Equal( expectedEssCertIdV2.HashAlgorithm.Algorithm.Value, actualEssCertIdV2.HashAlgorithm.Algorithm.Value); SigningTestUtility.VerifyByteArrays( expectedEssCertIdV2.CertificateHash, actualEssCertIdV2.CertificateHash); Assert.Equal( expectedEssCertIdV2.IssuerSerial.GeneralNames[0].DirectoryName.Name, actualEssCertIdV2.IssuerSerial.GeneralNames[0].DirectoryName.Name); SigningTestUtility.VerifyByteArrays(expectedEssCertIdV2.IssuerSerial.SerialNumber, actualEssCertIdV2.IssuerSerial.SerialNumber); } } }
public void Read_WithMultipleEssCertIds_ReturnsSigningCertificateV2(HashAlgorithmName hashAlgorithmName) { var bcEssCertIdV2_1 = CreateBcEssCertIdV2(hashAlgorithmName, "1"); var bcEssCertIdV2_2 = CreateBcEssCertIdV2(hashAlgorithmName, "2"); var bcEssCertIdV2_3 = CreateBcEssCertIdV2(hashAlgorithmName, "3"); var bcSigningCertificateV2 = new BcSigningCertificateV2( new[] { bcEssCertIdV2_1, bcEssCertIdV2_2, bcEssCertIdV2_3 }); var bytes = bcSigningCertificateV2.GetDerEncoded(); var signingCertificate = SigningCertificateV2.Read(bytes); Assert.Equal(3, signingCertificate.Certificates.Count); Assert.Null(signingCertificate.Policies); SigningTestUtility.VerifyByteArrays( bcEssCertIdV2_1.GetCertHash(), signingCertificate.Certificates[0].CertificateHash); Assert.Null(signingCertificate.Certificates[0].IssuerSerial); SigningTestUtility.VerifyByteArrays( bcEssCertIdV2_2.GetCertHash(), signingCertificate.Certificates[1].CertificateHash); Assert.Null(signingCertificate.Certificates[1].IssuerSerial); SigningTestUtility.VerifyByteArrays( bcEssCertIdV2_3.GetCertHash(), signingCertificate.Certificates[2].CertificateHash); Assert.Null(signingCertificate.Certificates[2].IssuerSerial); }
public void Read_WithNoEssCertIds_ReturnsSigningCertificateV2() { var bcSigningCertificateV2 = new BcSigningCertificateV2(new BcEssCertIdV2[0]); var bytes = bcSigningCertificateV2.GetDerEncoded(); var signingCertificate = SigningCertificateV2.Read(bytes); Assert.Equal(0, signingCertificate.Certificates.Count); Assert.Null(signingCertificate.Policies); }
public void Read_WithPolicyInformation_ReturnsSigningCertificateV2() { var bcEssCertIdV2 = CreateBcEssCertIdV2(HashAlgorithmName.SHA256, "1"); var bcPolicyInfo = new BcPolicyInformation(new DerObjectIdentifier(Oids.AnyPolicy)); var bcSigningCertificateV2 = new BcSigningCertificateV2( new[] { bcEssCertIdV2 }, new[] { bcPolicyInfo }); var bytes = bcSigningCertificateV2.GetDerEncoded(); var signingCertificate = SigningCertificateV2.Read(bytes); Assert.Equal(1, signingCertificate.Certificates.Count); Assert.Equal(1, signingCertificate.Policies.Count); var policyInfo = signingCertificate.Policies[0]; Assert.Equal(bcPolicyInfo.PolicyIdentifier.ToString(), policyInfo.PolicyIdentifier.Value); Assert.Null(policyInfo.PolicyQualifiers); }
public void Read_WithInvalidAsn1_Throws() { Assert.Throws <System.Security.Cryptography.CryptographicException>( () => SigningCertificateV2.Read(new byte[] { 0x30, 0x0b })); }
private static IX509CertificateChain GetCertificates( SignedCms signedCms, SignerInfo signerInfo, SigningCertificateRequirement signingCertificateRequirement, bool isIssuerSerialRequired, Errors errors, SigningSpecifications signingSpecifications, bool includeChain) { if (signedCms == null) { throw new ArgumentNullException(nameof(signedCms)); } if (signingSpecifications == null) { throw new ArgumentNullException(nameof(signingSpecifications)); } if (signerInfo.Certificate == null) { throw new SignatureException(errors.NoCertificate, errors.NoCertificateString); } /* * The signing-certificate and signing-certificate-v2 attributes are described in RFC 2634 and RFC 5035. * * Timestamps * -------------------------------------------------- * RFC 3161 requires the signing-certificate attribute. The RFC 5816 update introduces the newer * signing-certificate-v2 attribute, which may replace or, for backwards compatibility, be present * alongside the older signing-certificate attribute. * * The issuerSerial field is not required, but should be validated if present. * * * Author and repository signatures * -------------------------------------------------- * RFC 5126 (CAdES) requires that exactly one of either of these attributes be present, and also requires that * the issuerSerial field be present. * * * Validation * -------------------------------------------------- * For author and repository signatures: * * the signing-certificate attribute must not be present * the signing-certificate-v2 attribute be present * the issuerSerial field must be present * * * References: * * "Signing Certificate Attribute Definition", RFC 2634 section 5.4 (https://tools.ietf.org/html/rfc2634#section-5.4) * "Certificate Identification", RFC 2634 section 5.4 (https://tools.ietf.org/html/rfc2634#section-5.4.1) * "Enhanced Security Services (ESS) Update: Adding CertID Algorithm Agility", RFC 5035 (https://tools.ietf.org/html/rfc5035) * "Request Format", RFC 3161 section 2.4.1 (https://tools.ietf.org/html/rfc3161#section-2.4.1) * "Signature of Time-Stamp Token", RFC 5816 section 2.2.1 (https://tools.ietf.org/html/rfc5816#section-2.2.1) * "Signing Certificate Reference Attributes", RFC 5126 section 5.7.3 (https://tools.ietf.org/html/rfc5126.html#section-5.7.3) * "ESS signing-certificate Attribute Definition", RFC 5126 section 5.7.3.1 (https://tools.ietf.org/html/rfc5126.html#section-5.7.3.1) * "ESS signing-certificate-v2 Attribute Definition", RFC 5126 section 5.7.3.2 (https://tools.ietf.org/html/rfc5126.html#section-5.7.3.2) */ const string signingCertificateName = "signing-certificate"; const string signingCertificateV2Name = "signing-certificate-v2"; CryptographicAttributeObject signingCertificateAttribute = null; CryptographicAttributeObject signingCertificateV2Attribute = null; foreach (var attribute in signerInfo.SignedAttributes) { switch (attribute.Oid.Value) { case Oids.SigningCertificate: if (signingCertificateAttribute != null) { throw new SignatureException( errors.InvalidSignature, string.Format( CultureInfo.CurrentCulture, Strings.MultipleAttributesDisallowed, signingCertificateName)); } if (attribute.Values.Count != 1) { throw new SignatureException( errors.InvalidSignature, string.Format( CultureInfo.CurrentCulture, Strings.ExactlyOneAttributeValueRequired, signingCertificateName)); } signingCertificateAttribute = attribute; break; case Oids.SigningCertificateV2: if (signingCertificateV2Attribute != null) { throw new SignatureException( errors.InvalidSignature, string.Format( CultureInfo.CurrentCulture, Strings.MultipleAttributesDisallowed, signingCertificateV2Name)); } if (attribute.Values.Count != 1) { throw new SignatureException( errors.InvalidSignature, string.Format( CultureInfo.CurrentCulture, Strings.ExactlyOneAttributeValueRequired, signingCertificateV2Name)); } signingCertificateV2Attribute = attribute; break; } } switch (signingCertificateRequirement) { case SigningCertificateRequirement.OnlyV2: { if (signingCertificateAttribute != null) { throw new SignatureException(errors.InvalidSignature, Strings.SigningCertificateAttributeMustNotBePresent); } if (signingCertificateV2Attribute == null) { throw new SignatureException( errors.InvalidSignature, string.Format(CultureInfo.CurrentCulture, Strings.ExactlyOneAttributeRequired, signingCertificateV2Name)); } } break; case SigningCertificateRequirement.EitherOrBoth: if (signingCertificateAttribute == null && signingCertificateV2Attribute == null) { throw new SignatureException(errors.InvalidSignature, Strings.SigningCertificateV1OrV2AttributeMustBePresent); } break; } if (signingCertificateV2Attribute != null) { var reader = CreateDerSequenceReader(signingCertificateV2Attribute); var signingCertificateV2 = SigningCertificateV2.Read(reader); if (signingCertificateV2.Certificates.Count == 0) { throw new SignatureException(errors.InvalidSignature, Strings.SigningCertificateV2Invalid); } foreach (var essCertIdV2 in signingCertificateV2.Certificates) { if (!signingSpecifications.AllowedHashAlgorithmOids.Contains( essCertIdV2.HashAlgorithm.Algorithm.Value, StringComparer.Ordinal)) { throw new SignatureException(errors.InvalidSignature, Strings.SigningCertificateV2UnsupportedHashAlgorithm); } } if (!IsMatch(signerInfo.Certificate, signingCertificateV2.Certificates[0], errors, isIssuerSerialRequired)) { throw new SignatureException(errors.InvalidSignature, Strings.SigningCertificateV2CertificateNotFound); } } if (signingCertificateAttribute != null) { var reader = CreateDerSequenceReader(signingCertificateAttribute); var signingCertificate = SigningCertificate.Read(reader); if (signingCertificate.Certificates.Count == 0) { throw new SignatureException(errors.InvalidSignature, Strings.SigningCertificateInvalid); } if (!IsMatch(signerInfo.Certificate, signingCertificate.Certificates[0])) { throw new SignatureException(errors.InvalidSignature, Strings.SigningCertificateCertificateNotFound); } } var certificates = GetCertificateChain(signerInfo.Certificate, signedCms.Certificates, includeChain); if (certificates == null || certificates.Count == 0) { throw new SignatureException(errors.ChainBuildingFailed, Strings.CertificateChainBuildFailed); } return(certificates); }