public void Read_WithMultipleEssCertIds_ReturnsSigningCertificate() { var bcEssCertId1 = CreateBcEssCertId("1"); var bcEssCertId2 = CreateBcEssCertId("2"); var bcEssCertId3 = CreateBcEssCertId("3"); var bcSigningCertificate = new BcSigningCertificate( new DerSequence(new DerSequence(bcEssCertId1, bcEssCertId2, bcEssCertId3))); var bytes = bcSigningCertificate.GetDerEncoded(); var signingCertificate = SigningCertificate.Read(bytes); Assert.Equal(3, signingCertificate.Certificates.Count); Assert.Null(signingCertificate.Policies); SignTestUtility.VerifyByteArrays( bcEssCertId1.GetCertHash(), signingCertificate.Certificates[0].CertificateHash); Assert.Null(signingCertificate.Certificates[0].IssuerSerial); SignTestUtility.VerifyByteArrays( bcEssCertId2.GetCertHash(), signingCertificate.Certificates[1].CertificateHash); Assert.Null(signingCertificate.Certificates[1].IssuerSerial); SignTestUtility.VerifyByteArrays( bcEssCertId3.GetCertHash(), signingCertificate.Certificates[2].CertificateHash); Assert.Null(signingCertificate.Certificates[2].IssuerSerial); }
public void Read_WithPolicyInformation_ReturnsSigningCertificate() { var bcEssCertId = CreateBcEssCertId("1"); var bcPolicyInfo = new BcPolicyInformation(new DerObjectIdentifier(Oids.AnyPolicy)); var bcSigningCertificate = new BcSigningCertificate( new DerSequence(new DerSequence(bcEssCertId), new DerSequence(bcPolicyInfo))); var bytes = bcSigningCertificate.GetDerEncoded(); var signingCertificate = SigningCertificate.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 <CryptographicException>( () => SigningCertificate.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); }